github.com/zeebo/goof@v0.0.0-20230907150950-e9457bc94477/troop_globals.go (about) 1 package goof 2 3 import ( 4 "debug/dwarf" 5 "reflect" 6 "regexp" 7 "sort" 8 "strings" 9 "unsafe" 10 11 "github.com/zeebo/errs" 12 ) 13 14 var statictmpRe = regexp.MustCompile(`statictmp_\d+$`) 15 16 func (t *Troop) addGlobals() error { 17 reader := t.data.Reader() 18 19 for { 20 entry, err := reader.Next() 21 if err != nil { 22 return errs.Wrap(err) 23 } 24 if entry == nil { 25 break 26 } 27 28 if entry.Tag != dwarf.TagVariable { 29 continue 30 } 31 32 name, ok := entry.Val(dwarf.AttrName).(string) 33 if !ok { 34 continue 35 } 36 37 // filter out some values that aren't useful and just clutter stuff 38 if strings.Contains(name, "ยท") { 39 continue 40 } 41 if statictmpRe.MatchString(name) { 42 continue 43 } 44 45 loc, err := entryLocation(t.data, entry) 46 if err != nil { 47 continue 48 } 49 50 dtyp, err := entryType(t.data, entry) 51 if err != nil { 52 continue 53 } 54 55 dname := dwarfTypeName(dtyp) 56 if dname == "<unspecified>" || dname == "" { 57 continue 58 } 59 60 rtyp := t.types[dname] 61 if rtyp == nil { 62 continue 63 } 64 65 ptr := unsafe.Pointer(uintptr(loc)) 66 t.globals[name] = reflect.NewAt(rtyp, ptr).Elem() 67 } 68 69 return nil 70 } 71 72 func (t *Troop) Globals() ([]string, error) { 73 if err := t.check(); err != nil { 74 return nil, err 75 } 76 out := make([]string, 0, len(t.globals)) 77 for name := range t.globals { 78 out = append(out, name) 79 } 80 sort.Strings(out) 81 return out, nil 82 } 83 84 func (t *Troop) Global(name string) (reflect.Value, error) { 85 if err := t.check(); err != nil { 86 return reflect.Value{}, t.err 87 } 88 return t.globals[name], nil 89 }