github.com/lsg2020/gort@v0.0.0-20220515072951-7a7794baa036/helpers.go (about)

     1  package gort
     2  
     3  import (
     4  	"debug/dwarf"
     5  	"fmt"
     6  	"reflect"
     7  	"unsafe"
     8  
     9  	"github.com/go-delve/delve/pkg/dwarf/godwarf"
    10  	"github.com/go-delve/delve/pkg/proc"
    11  )
    12  
    13  // delve counterpart to runtime.moduledata
    14  type moduleData struct {
    15  	text, etext   uint64
    16  	types, etypes uint64
    17  	typemapVar    *proc.Variable
    18  }
    19  
    20  //go:linkname findType github.com/go-delve/delve/pkg/proc.(*BinaryInfo).findType
    21  func findType(bi *proc.BinaryInfo, name string) (godwarf.Type, error)
    22  
    23  //go:linkname loadModuleData github.com/go-delve/delve/pkg/proc.loadModuleData
    24  func loadModuleData(bi *proc.BinaryInfo, mem proc.MemoryReadWriter) ([]moduleData, error)
    25  
    26  //go:linkname imageToModuleData github.com/go-delve/delve/pkg/proc.(*BinaryInfo).imageToModuleData
    27  func imageToModuleData(bi *proc.BinaryInfo, image *proc.Image, mds []moduleData) *moduleData
    28  
    29  type localMemory int
    30  
    31  func (mem *localMemory) ReadMemory(data []byte, addr uint64) (int, error) {
    32  	buf := entryAddress(uintptr(addr), len(data))
    33  	copy(data, buf)
    34  	return len(data), nil
    35  }
    36  
    37  func (mem *localMemory) WriteMemory(addr uint64, data []byte) (int, error) {
    38  	return 0, ErrNotSupport
    39  }
    40  
    41  func dwarfTypeName(dtyp dwarf.Type) string {
    42  	switch dtyp := dtyp.(type) {
    43  	case *dwarf.StructType:
    44  		return dtyp.StructName
    45  	default:
    46  		name := dtyp.Common().Name
    47  		if name != "" {
    48  			return name
    49  		}
    50  		return dtyp.String()
    51  	}
    52  }
    53  
    54  func entryType(data *dwarf.Data, entry *dwarf.Entry) (dwarf.Type, error) {
    55  	off, ok := entry.Val(dwarf.AttrType).(dwarf.Offset)
    56  	if !ok {
    57  		return nil, fmt.Errorf("unable to find type offset for entry")
    58  	}
    59  	return data.Type(off)
    60  }
    61  
    62  func entryAddress(p uintptr, l int) []byte {
    63  	return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{Data: p, Len: l, Cap: l}))
    64  }
    65  
    66  type Func struct {
    67  	codePtr uintptr
    68  }
    69  
    70  // CreateFuncForCodePtr https://github.com/alangpierce/go-forceexport/blob/8f1d6941cd755b975763ddb1f836561edddac2b8/forceexport.go#L31-L51
    71  func CreateFuncForCodePtr(ftyp reflect.Type, codePtr uint64) reflect.Value {
    72  	// Use reflect.MakeFunc to create a well-formed function value that's
    73  	// guaranteed to be of the right type and guaranteed to be on the heap
    74  	// (so that we can modify it). We give a nil delegate function because
    75  	// it will never actually be called.
    76  	newFuncVal := reflect.MakeFunc(ftyp, nil)
    77  	// Use reflection on the reflect.Value (yep!) to grab the underling
    78  	// function value pointer. Trying to call newFuncVal.Pointer() wouldn't
    79  	// work because it gives the code pointer rather than the function value
    80  	// pointer. The function value is a struct that starts with its code
    81  	// pointer, so we can swap out the code pointer with our desired value.
    82  	funcValuePtr := reflect.ValueOf(newFuncVal).FieldByName("ptr").Pointer()
    83  	funcPtr := (*Func)(unsafe.Pointer(funcValuePtr))
    84  	funcPtr.codePtr = uintptr(codePtr)
    85  	return newFuncVal
    86  }