func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) { // Only emit typedefs for real names. if strings.HasPrefix(name, "map[") { return } if strings.HasPrefix(name, "struct {") { return } if strings.HasPrefix(name, "chan ") { return } if name[0] == '[' || name[0] == '*' { return } if def == nil { ctxt.Diag("dwarf: bad def in dotypedef") } sym := Linklookup(ctxt, dtolsym(def.Sym).Name+"..def", 0) sym.Attr |= AttrHidden sym.Type = obj.SDWARFINFO def.Sym = sym // The typedef entry must be created after the def, // so that future lookups will find the typedef instead // of the real definition. This hooks the typedef into any // circular definition loops, so that gdb can understand them. die := newdie(ctxt, parent, dwarf.DW_ABRV_TYPEDECL, name, 0) newrefattr(die, dwarf.DW_AT_type, sym) }
// Every DIE has at least a AT_name attribute (but it will only be // written out if it is listed in the abbrev). func newdie(ctxt *Link, parent *dwarf.DWDie, abbrev int, name string, version int) *dwarf.DWDie { die := new(dwarf.DWDie) die.Abbrev = abbrev die.Link = parent.Child parent.Child = die newattr(die, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len(name)), name) if name != "" && (abbrev <= dwarf.DW_ABRV_VARIABLE || abbrev >= dwarf.DW_ABRV_NULLTYPE) { if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 { sym := Linklookup(ctxt, dwarf.InfoPrefix+name, version) sym.Attr |= AttrHidden sym.Type = obj.SDWARFINFO die.Sym = sym } } return die }
func newattr(die *dwarf.DWDie, attr uint16, cls int, value int64, data interface{}) *dwarf.DWAttr { a := new(dwarf.DWAttr) a.Link = die.Attr die.Attr = a a.Atr = attr a.Cls = uint8(cls) a.Value = value a.Data = data return a }
// Each DIE (except the root ones) has at least 1 attribute: its // name. getattr moves the desired one to the front so // frequently searched ones are found faster. func getattr(die *dwarf.DWDie, attr uint16) *dwarf.DWAttr { if die.Attr.Atr == attr { return die.Attr } a := die.Attr b := a.Link for b != nil { if b.Atr == attr { a.Link = b.Link b.Link = die.Attr die.Attr = b return b } a = b b = b.Link } return nil }