in internal/gocore/dwarf.go [403:460]
func (p *Process) readGlobals() {
d, _ := p.proc.DWARF()
r := d.Reader()
for e, err := r.Next(); e != nil && err == nil; e, err = r.Next() {
if isNonGoCU(e) {
r.SkipChildren()
continue
}
if e.Tag != dwarf.TagVariable {
continue
}
f := e.AttrField(dwarf.AttrLocation)
if f == nil {
continue
}
if f.Class != dwarf.ClassExprLoc {
// Globals are all encoded with this class.
continue
}
loc := f.Val.([]byte)
if len(loc) == 0 || loc[0] != _DW_OP_addr {
continue
}
var a core.Address
if p.proc.PtrSize() == 8 {
a = core.Address(p.proc.ByteOrder().Uint64(loc[1:]))
} else {
a = core.Address(p.proc.ByteOrder().Uint32(loc[1:]))
}
if !p.proc.Writeable(a) {
// Read-only globals can't have heap pointers.
// TODO: keep roots around anyway?
continue
}
f = e.AttrField(dwarf.AttrType)
if f == nil {
continue
}
dt, err := d.Type(f.Val.(dwarf.Offset))
if err != nil {
panic(err)
}
if _, ok := dt.(*dwarf.UnspecifiedType); ok {
continue // Ignore markers like data/edata.
}
nf := e.AttrField(dwarf.AttrName)
if nf == nil {
continue
}
p.globals = append(p.globals, &Root{
Name: nf.Val.(string),
Addr: a,
Type: p.dwarfMap[dt],
Frame: nil,
})
}
}