github.com/lsg2020/gort@v0.0.0-20220515072951-7a7794baa036/gort_globals.go (about) 1 package gort 2 3 import ( 4 "debug/dwarf" 5 "reflect" 6 "unsafe" 7 8 "github.com/go-delve/delve/pkg/proc" 9 ) 10 11 func (d *DwarfRT) ForeachGlobal(f func(name string, v reflect.Value)) error { 12 if err := d.check(); err != nil { 13 return err 14 } 15 if d.globals == nil { 16 d.loadGlobals() 17 } 18 19 for name, v := range d.globals { 20 f(name, v) 21 } 22 return nil 23 } 24 25 func (d *DwarfRT) FindGlobal(name string) (reflect.Value, error) { 26 if err := d.check(); err != nil { 27 return reflect.Value{}, err 28 } 29 if d.globals == nil { 30 d.loadGlobals() 31 } 32 33 v, ok := d.globals[name] 34 if !ok { 35 return reflect.Value{}, ErrNotFound 36 } 37 return v, nil 38 } 39 40 func (d *DwarfRT) loadGlobals() { 41 d.globals = make(map[string]reflect.Value) 42 43 packageVars := reflect.ValueOf(d.bi).Elem().FieldByName("packageVars") 44 if packageVars.IsValid() { 45 for i := 0; i < packageVars.Len(); i++ { 46 rv := packageVars.Index(i) 47 rName := rv.FieldByName("name") 48 rAddr := rv.FieldByName("addr") 49 rOffset := rv.FieldByName("offset") 50 rCU := rv.FieldByName("cu") 51 if !rName.IsValid() || !rAddr.IsValid() || !rCU.IsValid() || !rOffset.IsValid() { 52 continue 53 } 54 rImage := rCU.Elem().FieldByName("image") 55 if !rImage.IsValid() { 56 continue 57 } 58 rDwarf := rImage.Elem().FieldByName("dwarf") 59 if !rDwarf.IsValid() { 60 continue 61 } 62 image := (*proc.Image)(unsafe.Pointer(rImage.Pointer())) 63 dwarfData := (*dwarf.Data)(unsafe.Pointer(rDwarf.Pointer())) 64 65 reader := image.DwarfReader() 66 reader.Seek(dwarf.Offset(rOffset.Uint())) 67 entry, err := reader.Next() 68 if err != nil || entry == nil || entry.Tag != dwarf.TagVariable { 69 continue 70 } 71 name, ok := entry.Val(dwarf.AttrName).(string) 72 if !ok || rName.String() != name { 73 continue 74 } 75 76 dtyp, err := entryType(dwarfData, entry) 77 if err != nil { 78 continue 79 } 80 dname := dwarfTypeName(dtyp) 81 if dname == "<unspecified>" || dname == "" { 82 continue 83 } 84 85 rtyp, err := d.FindType(dname) 86 if err != nil || rtyp == nil { 87 continue 88 } 89 d.globals[name] = reflect.NewAt(rtyp, unsafe.Pointer(uintptr(rAddr.Uint()))).Elem() 90 } 91 } 92 }