godwarf: Attempt to load DW_AT_specification if present (#3247)

This commit is contained in:
Frederic Branczyk
2023-01-05 18:45:55 +01:00
committed by GitHub
parent 62335703d2
commit 9c44954860

View File

@ -24,11 +24,13 @@ func (ce compositeEntry) Val(attr dwarf.Attr) interface{} {
return nil return nil
} }
// LoadAbstractOrigin loads the entry corresponding to the // LoadAbstractOriginAndSpecification loads the entry corresponding to the
// DW_AT_abstract_origin of entry and returns a combination of entry and its // DW_AT_abstract_origin and/or DW_AT_specification of entry and returns a
// abstract origin. // combination of entry and its abstract origin. If a DIE has both a
func LoadAbstractOrigin(entry *dwarf.Entry, aordr *dwarf.Reader) (Entry, dwarf.Offset) { // specification and an abstract origin the specification will be ignored, the
ao, ok := entry.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset) // DWARF standard is unclear on how this should be handled
func LoadAbstractOriginAndSpecification(entry *dwarf.Entry, aordr *dwarf.Reader) (Entry, dwarf.Offset) {
ao, ok := getAbstractOriginOrSpecification(entry)
if !ok { if !ok {
return entry, entry.Offset return entry, entry.Offset
} }
@ -43,7 +45,7 @@ func LoadAbstractOrigin(entry *dwarf.Entry, aordr *dwarf.Reader) (Entry, dwarf.O
} }
r = append(r, e) r = append(r, e)
ao, ok = e.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset) ao, ok = getAbstractOriginOrSpecification(e)
if !ok { if !ok {
break break
} }
@ -52,6 +54,18 @@ func LoadAbstractOrigin(entry *dwarf.Entry, aordr *dwarf.Reader) (Entry, dwarf.O
return compositeEntry(r), entry.Offset return compositeEntry(r), entry.Offset
} }
func getAbstractOriginOrSpecification(e *dwarf.Entry) (dwarf.Offset, bool) {
ao, ok := e.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
if ok {
return ao, true
}
sp, ok := e.Val(dwarf.AttrSpecification).(dwarf.Offset)
if ok {
return sp, true
}
return dwarf.Offset(0), false
}
// Tree represents a tree of dwarf objects. // Tree represents a tree of dwarf objects.
type Tree struct { type Tree struct {
Entry Entry
@ -85,7 +99,7 @@ func LoadTree(off dwarf.Offset, dw *dwarf.Data, staticBase uint64) (*Tree, error
if err != nil { if err != nil {
return nil, err return nil, err
} }
r.resolveAbstractEntries(rdr) r.resolveAbstractAndSpecificationEntries(rdr)
return r, nil return r, nil
} }
@ -228,10 +242,10 @@ func rangeContains(a, b [2]uint64) bool {
return a[0] <= b[0] && a[1] >= b[1] return a[0] <= b[0] && a[1] >= b[1]
} }
func (n *Tree) resolveAbstractEntries(rdr *dwarf.Reader) { func (n *Tree) resolveAbstractAndSpecificationEntries(rdr *dwarf.Reader) {
n.Entry, n.Offset = LoadAbstractOrigin(n.Entry.(*dwarf.Entry), rdr) n.Entry, n.Offset = LoadAbstractOriginAndSpecification(n.Entry.(*dwarf.Entry), rdr)
for _, child := range n.Children { for _, child := range n.Children {
child.resolveAbstractEntries(rdr) child.resolveAbstractAndSpecificationEntries(rdr)
} }
} }