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 }