github.com/lsg2020/gort@v0.0.0-20220515072951-7a7794baa036/examples/test/main.go (about) 1 package main 2 3 import ( 4 "debug/dwarf" 5 "fmt" 6 "log" 7 "os" 8 "reflect" 9 "runtime" 10 "unsafe" 11 12 "github.com/go-delve/delve/pkg/dwarf/godwarf" 13 "github.com/go-delve/delve/pkg/proc" 14 ) 15 16 func main() { 17 path, err := os.Executable() 18 if err != nil { 19 log.Fatalln(err) 20 } 21 22 bi := proc.NewBinaryInfo(runtime.GOOS, runtime.GOARCH) 23 err = bi.LoadBinaryInfo(path, 0, nil) 24 if err != nil { 25 log.Fatalln(err) 26 } 27 mds, err := loadModuleData(bi, new(localMemory)) 28 if err != nil { 29 log.Fatalln(err) 30 } 31 32 types, err := bi.Types() 33 if err != nil { 34 log.Fatalln(err) 35 } 36 37 for _, name := range types { 38 dwarfType, err := findType(bi, name) 39 if err != nil { 40 continue 41 } 42 43 typeAddr, err := dwarfToRuntimeType(bi, mds, dwarfType, name) 44 if err != nil { 45 continue 46 } 47 48 typ := reflect.TypeOf(*(*interface{})(unsafe.Pointer(&typeAddr))) 49 log.Printf("load type name:%s type:%s\n", name, typ) 50 } 51 } 52 53 // delve counterpart to runtime.moduledata 54 type moduleData struct { 55 text, etext uint64 56 types, etypes uint64 57 typemapVar *proc.Variable 58 } 59 60 //go:linkname findType github.com/go-delve/delve/pkg/proc.(*BinaryInfo).findType 61 func findType(bi *proc.BinaryInfo, name string) (godwarf.Type, error) 62 63 //go:linkname loadModuleData github.com/go-delve/delve/pkg/proc.loadModuleData 64 func loadModuleData(bi *proc.BinaryInfo, mem proc.MemoryReadWriter) ([]moduleData, error) 65 66 //go:linkname imageToModuleData github.com/go-delve/delve/pkg/proc.(*BinaryInfo).imageToModuleData 67 func imageToModuleData(bi *proc.BinaryInfo, image *proc.Image, mds []moduleData) *moduleData 68 69 type localMemory int 70 71 func (mem *localMemory) ReadMemory(data []byte, addr uint64) (int, error) { 72 buf := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{Data: uintptr(addr), Len: len(data), Cap: len(data)})) 73 copy(data, buf) 74 return len(data), nil 75 } 76 77 func (mem *localMemory) WriteMemory(addr uint64, data []byte) (int, error) { 78 return 0, fmt.Errorf("not support") 79 } 80 81 func dwarfToRuntimeType(bi *proc.BinaryInfo, mds []moduleData, typ godwarf.Type, name string) (typeAddr uint64, err error) { 82 if typ.Common().Index >= len(bi.Images) { 83 return 0, fmt.Errorf("could not find image for type %s", name) 84 } 85 img := bi.Images[typ.Common().Index] 86 rdr := img.DwarfReader() 87 rdr.Seek(typ.Common().Offset) 88 e, err := rdr.Next() 89 if err != nil { 90 return 0, fmt.Errorf("could not find dwarf entry for type:%s err:%s", name, err) 91 } 92 entryName, ok := e.Val(dwarf.AttrName).(string) 93 if !ok || entryName != name { 94 return 0, fmt.Errorf("could not find name for type:%s entry:%s", name, entryName) 95 } 96 off, ok := e.Val(godwarf.AttrGoRuntimeType).(uint64) 97 if !ok || off == 0 { 98 return 0, fmt.Errorf("could not find runtime type for type:%s", name) 99 } 100 101 md := imageToModuleData(bi, img, mds) 102 if md == nil { 103 return 0, fmt.Errorf("could not find module data for type %s", name) 104 } 105 106 typeAddr = md.types + off 107 if typeAddr < md.types || typeAddr >= md.etypes { 108 return off, nil 109 } 110 return typeAddr, nil 111 }