godwarf: Allow extracting a DWARF entry's field (#3258)

Previously it was only possible to extract a value of type `any` using
an attribute name. This poses challenges when fields are allowed to have
different classes, and it is ambiguous how to handle them.
This commit is contained in:
Frederic Branczyk
2023-01-31 17:40:19 +01:00
committed by GitHub
parent 011fe673fe
commit 436fed8ec4
2 changed files with 24 additions and 8 deletions

View File

@ -11,14 +11,22 @@ import (
// entry specified by DW_AT_abstract_origin will be searched recursively. // entry specified by DW_AT_abstract_origin will be searched recursively.
type Entry interface { type Entry interface {
Val(dwarf.Attr) interface{} Val(dwarf.Attr) interface{}
AttrField(dwarf.Attr) *dwarf.Field
} }
type compositeEntry []*dwarf.Entry type compositeEntry []*dwarf.Entry
func (ce compositeEntry) Val(attr dwarf.Attr) interface{} { func (ce compositeEntry) Val(attr dwarf.Attr) interface{} {
if f := ce.AttrField(attr); f != nil {
return f.Val
}
return nil
}
func (ce compositeEntry) AttrField(a dwarf.Attr) *dwarf.Field {
for _, e := range ce { for _, e := range ce {
if r := e.Val(attr); r != nil { if f := e.AttrField(a); f != nil {
return r return f
} }
} }
return nil return nil

View File

@ -1248,9 +1248,17 @@ func debugCallProtocolReg(archName string, version int) (uint64, bool) {
} }
} }
type fakeEntry map[dwarf.Attr]interface{} type fakeEntry map[dwarf.Attr]*dwarf.Field
func (e fakeEntry) Val(attr dwarf.Attr) interface{} { func (e fakeEntry) Val(attr dwarf.Attr) interface{} {
if e[attr] == nil {
return nil
}
return e[attr].Val
}
func (e fakeEntry) AttrField(attr dwarf.Attr) *dwarf.Field {
return e[attr] return e[attr]
} }
@ -1273,11 +1281,11 @@ func regabiMallocgcWorkaround(bi *BinaryInfo) ([]*godwarf.Tree, error) {
if err1 != nil { if err1 != nil {
return nil return nil
} }
var e fakeEntry = map[dwarf.Attr]interface{}{ var e fakeEntry = map[dwarf.Attr]*dwarf.Field{
dwarf.AttrName: name, dwarf.AttrName: &dwarf.Field{Attr: dwarf.AttrName, Val: name, Class: dwarf.ClassString},
dwarf.AttrType: typ.Common().Offset, dwarf.AttrType: &dwarf.Field{Attr: dwarf.AttrType, Val: typ.Common().Offset, Class: dwarf.ClassReference},
dwarf.AttrLocation: []byte{byte(op.DW_OP_reg0) + byte(reg)}, dwarf.AttrLocation: &dwarf.Field{Attr: dwarf.AttrLocation, Val: []byte{byte(op.DW_OP_reg0) + byte(reg)}, Class: dwarf.ClassBlock},
dwarf.AttrVarParam: isret, dwarf.AttrVarParam: &dwarf.Field{Attr: dwarf.AttrVarParam, Val: isret, Class: dwarf.ClassFlag},
} }
return &godwarf.Tree{ return &godwarf.Tree{