[dev.link] cmd/{compile,link}: split SDWARFINFO symtype into sub-types

This change splits the SDWARFINFO symbol type (a generic container of
DWARF content) into separate sub-classes. The new symbol types are

 SDWARFCUINFO    comp unit DIE, also CU info and CU packagename syms
 SDWARFCONST     constant DIE
 SDWARFFCN       subprogram DIE (default and concrete)
 SDWARFABSFCN    abstract function DIE
 SDWARFTYPE      type DIE
 SDWARFVAR       global variable DIE

Advantage of doing this: in the linker there are several places where
we have to iterate over a symbol's relocations to pick out references
to specific classes of DWARF sub-symbols (for example, looking for all
abstract function DIEs referenced by a subprogram DIE, or looking at
all the type DIEs used in a subprogram DIE). By splitting SDWARFINFO
into parts clients can now look only at the relocation target's sym
type as opposed to having to materialize the target sym name, or do a
lookup.

Change-Id: I4e0ee3216d3c8f1a78bec3d296c01e95b3d025b5
Reviewed-on: https://go-review.googlesource.com/c/go/+/234684
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
Than McIntosh 2020-05-20 13:51:59 -04:00
parent de1f07d56d
commit 96ec09da48
9 changed files with 95 additions and 54 deletions

View file

@ -1488,7 +1488,7 @@ func recordFlags(flags ...string) {
return return
} }
s := Ctxt.Lookup(dwarf.CUInfoPrefix + "producer." + myimportpath) s := Ctxt.Lookup(dwarf.CUInfoPrefix + "producer." + myimportpath)
s.Type = objabi.SDWARFINFO s.Type = objabi.SDWARFCUINFO
// Sometimes (for example when building tests) we can link // Sometimes (for example when building tests) we can link
// together two package main archives. So allow dups. // together two package main archives. So allow dups.
s.Set(obj.AttrDuplicateOK, true) s.Set(obj.AttrDuplicateOK, true)
@ -1500,7 +1500,7 @@ func recordFlags(flags ...string) {
// compiled, so that the linker can save it in the compile unit's DIE. // compiled, so that the linker can save it in the compile unit's DIE.
func recordPackageName() { func recordPackageName() {
s := Ctxt.Lookup(dwarf.CUInfoPrefix + "packagename." + myimportpath) s := Ctxt.Lookup(dwarf.CUInfoPrefix + "packagename." + myimportpath)
s.Type = objabi.SDWARFINFO s.Type = objabi.SDWARFCUINFO
// Sometimes (for example when building tests) we can link // Sometimes (for example when building tests) we can link
// together two package main archives. So allow dups. // together two package main archives. So allow dups.
s.Set(obj.AttrDuplicateOK, true) s.Set(obj.AttrDuplicateOK, true)

View file

@ -205,7 +205,7 @@ func (ctxt *Link) dwarfSym(s *LSym) (dwarfInfoSym, dwarfLocSym, dwarfRangesSym,
} }
if s.Func.dwarfInfoSym == nil { if s.Func.dwarfInfoSym == nil {
s.Func.dwarfInfoSym = &LSym{ s.Func.dwarfInfoSym = &LSym{
Type: objabi.SDWARFINFO, Type: objabi.SDWARFFCN,
} }
if ctxt.Flag_locationlists { if ctxt.Flag_locationlists {
s.Func.dwarfLocSym = &LSym{ s.Func.dwarfLocSym = &LSym{
@ -296,7 +296,7 @@ func (ctxt *Link) DwarfIntConst(myimportpath, name, typename string, val int64)
return return
} }
s := ctxt.LookupInit(dwarf.ConstInfoPrefix+myimportpath, func(s *LSym) { s := ctxt.LookupInit(dwarf.ConstInfoPrefix+myimportpath, func(s *LSym) {
s.Type = objabi.SDWARFINFO s.Type = objabi.SDWARFCONST
ctxt.Data = append(ctxt.Data, s) ctxt.Data = append(ctxt.Data, s)
}) })
dwarf.PutIntConst(dwCtxt{ctxt}, s, ctxt.Lookup(dwarf.InfoPrefix+typename), myimportpath+"."+name, val) dwarf.PutIntConst(dwCtxt{ctxt}, s, ctxt.Lookup(dwarf.InfoPrefix+typename), myimportpath+"."+name, val)
@ -422,7 +422,7 @@ func (ft *DwarfFixupTable) SetPrecursorFunc(s *LSym, fn interface{}) {
// the back end. // the back end.
absfn := ft.ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name+dwarf.AbstractFuncSuffix) absfn := ft.ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name+dwarf.AbstractFuncSuffix)
absfn.Set(AttrDuplicateOK, true) absfn.Set(AttrDuplicateOK, true)
absfn.Type = objabi.SDWARFINFO absfn.Type = objabi.SDWARFABSFCN
ft.ctxt.Data = append(ft.ctxt.Data, absfn) ft.ctxt.Data = append(ft.ctxt.Data, absfn)
// In the case of "late" inlining (inlines that happen during // In the case of "late" inlining (inlines that happen during

View file

@ -428,7 +428,8 @@ func writeAuxSymDebug(ctxt *Link, par *LSym, aux *LSym) {
// Most aux symbols (ex: funcdata) are not interesting-- // Most aux symbols (ex: funcdata) are not interesting--
// pick out just the DWARF ones for now. // pick out just the DWARF ones for now.
if aux.Type != objabi.SDWARFLOC && if aux.Type != objabi.SDWARFLOC &&
aux.Type != objabi.SDWARFINFO && aux.Type != objabi.SDWARFFCN &&
aux.Type != objabi.SDWARFABSFCN &&
aux.Type != objabi.SDWARFLINES && aux.Type != objabi.SDWARFLINES &&
aux.Type != objabi.SDWARFRANGE { aux.Type != objabi.SDWARFRANGE {
return return

View file

@ -56,7 +56,12 @@ const (
// Thread-local data that is initially all 0s // Thread-local data that is initially all 0s
STLSBSS STLSBSS
// Debugging data // Debugging data
SDWARFINFO SDWARFCUINFO
SDWARFCONST
SDWARFFCN
SDWARFABSFCN
SDWARFTYPE
SDWARFVAR
SDWARFRANGE SDWARFRANGE
SDWARFLOC SDWARFLOC
SDWARFLINES SDWARFLINES

View file

@ -16,17 +16,22 @@ func _() {
_ = x[SBSS-5] _ = x[SBSS-5]
_ = x[SNOPTRBSS-6] _ = x[SNOPTRBSS-6]
_ = x[STLSBSS-7] _ = x[STLSBSS-7]
_ = x[SDWARFINFO-8] _ = x[SDWARFCUINFO-8]
_ = x[SDWARFRANGE-9] _ = x[SDWARFCONST-9]
_ = x[SDWARFLOC-10] _ = x[SDWARFFCN-10]
_ = x[SDWARFLINES-11] _ = x[SDWARFABSFCN-11]
_ = x[SABIALIAS-12] _ = x[SDWARFTYPE-12]
_ = x[SLIBFUZZER_EXTRA_COUNTER-13] _ = x[SDWARFVAR-13]
_ = x[SDWARFRANGE-14]
_ = x[SDWARFLOC-15]
_ = x[SDWARFLINES-16]
_ = x[SABIALIAS-17]
_ = x[SLIBFUZZER_EXTRA_COUNTER-18]
} }
const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIASSLIBFUZZER_EXTRA_COUNTER" const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSABIALIASSLIBFUZZER_EXTRA_COUNTER"
var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 61, 72, 81, 92, 101, 125} var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 63, 74, 83, 95, 105, 114, 125, 134, 145, 154, 178}
func (i SymKind) String() string { func (i SymKind) String() string {
if i >= SymKind(len(_SymKind_index)-1) { if i >= SymKind(len(_SymKind_index)-1) {

View file

@ -277,24 +277,37 @@ func (d *dwctxt) newdie(parent *dwarf.DWDie, abbrev int, name string, version in
newattr(die, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len(name)), name) 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) { // Sanity check: all DIEs created in the linker should have a non-empty
// Q: do we need version here? My understanding is that all these // name and be version zero.
// symbols should be version 0. if name == "" || version != 0 {
if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 { panic("nameless or version non-zero DWARF DIE")
if abbrev == dwarf.DW_ABRV_COMPUNIT { }
// Avoid collisions with "real" symbol names.
name = fmt.Sprintf(".pkg.%s.%d", name, len(d.linkctxt.compUnits)) var st sym.SymKind
} switch abbrev {
ds := d.ldr.LookupOrCreateSym(dwarf.InfoPrefix+name, version) case dwarf.DW_ABRV_FUNCTYPEPARAM, dwarf.DW_ABRV_DOTDOTDOT, dwarf.DW_ABRV_STRUCTFIELD, dwarf.DW_ABRV_ARRAYRANGE:
dsu := d.ldr.MakeSymbolUpdater(ds) // There are no relocations against these dies, and their names
dsu.SetType(sym.SDWARFINFO) // are not unique, so don't create a symbol.
d.ldr.SetAttrNotInSymbolTable(ds, true) return die
d.ldr.SetAttrReachable(ds, true) case dwarf.DW_ABRV_COMPUNIT, dwarf.DW_ABRV_COMPUNIT_TEXTLESS:
die.Sym = dwSym(ds) // Avoid collisions with "real" symbol names.
if abbrev >= dwarf.DW_ABRV_NULLTYPE && abbrev <= dwarf.DW_ABRV_TYPEDECL { name = fmt.Sprintf(".pkg.%s.%d", name, len(d.linkctxt.compUnits))
d.tmap[name] = ds st = sym.SDWARFCUINFO
} case dwarf.DW_ABRV_VARIABLE:
} st = sym.SDWARFVAR
default:
// Everything else is assigned a type of SDWARFTYPE. that
// this also includes loose ends such as STRUCT_FIELD.
st = sym.SDWARFTYPE
}
ds := d.ldr.LookupOrCreateSym(dwarf.InfoPrefix+name, version)
dsu := d.ldr.MakeSymbolUpdater(ds)
dsu.SetType(st)
d.ldr.SetAttrNotInSymbolTable(ds, true)
d.ldr.SetAttrReachable(ds, true)
die.Sym = dwSym(ds)
if abbrev >= dwarf.DW_ABRV_NULLTYPE && abbrev <= dwarf.DW_ABRV_TYPEDECL {
d.tmap[name] = ds
} }
return die return die
@ -480,7 +493,7 @@ func (d *dwctxt) dotypedef(parent *dwarf.DWDie, gotype loader.Sym, name string,
// to be an anonymous symbol (we want this for perf reasons). // to be an anonymous symbol (we want this for perf reasons).
tds := d.ldr.CreateExtSym("", 0) tds := d.ldr.CreateExtSym("", 0)
tdsu := d.ldr.MakeSymbolUpdater(tds) tdsu := d.ldr.MakeSymbolUpdater(tds)
tdsu.SetType(sym.SDWARFINFO) tdsu.SetType(sym.SDWARFTYPE)
def.Sym = dwSym(tds) def.Sym = dwSym(tds)
d.ldr.SetAttrNotInSymbolTable(tds, true) d.ldr.SetAttrNotInSymbolTable(tds, true)
d.ldr.SetAttrReachable(tds, true) d.ldr.SetAttrReachable(tds, true)
@ -850,7 +863,7 @@ func (d *dwctxt) mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valna
name := mkinternaltypename(typename, keyname, valname) name := mkinternaltypename(typename, keyname, valname)
symname := dwarf.InfoPrefix + name symname := dwarf.InfoPrefix + name
s := d.ldr.Lookup(symname, 0) s := d.ldr.Lookup(symname, 0)
if s != 0 && d.ldr.SymType(s) == sym.SDWARFINFO { if s != 0 && d.ldr.SymType(s) == sym.SDWARFTYPE {
return s return s
} }
die := d.newdie(&dwtypes, abbrev, name, 0) die := d.newdie(&dwtypes, abbrev, name, 0)
@ -1122,7 +1135,8 @@ func getCompilationDir() string {
func (d *dwctxt) importInfoSymbol(ctxt *Link, dsym loader.Sym) { func (d *dwctxt) importInfoSymbol(ctxt *Link, dsym loader.Sym) {
d.ldr.SetAttrReachable(dsym, true) d.ldr.SetAttrReachable(dsym, true)
d.ldr.SetAttrNotInSymbolTable(dsym, true) d.ldr.SetAttrNotInSymbolTable(dsym, true)
if d.ldr.SymType(dsym) != sym.SDWARFINFO { dst := d.ldr.SymType(dsym)
if dst != sym.SDWARFCONST && dst != sym.SDWARFABSFCN {
log.Fatalf("error: DWARF info sym %d/%s with incorrect type %s", dsym, d.ldr.SymName(dsym), d.ldr.SymType(dsym).String()) log.Fatalf("error: DWARF info sym %d/%s with incorrect type %s", dsym, d.ldr.SymName(dsym), d.ldr.SymType(dsym).String())
} }
relocs := d.ldr.Relocs(dsym) relocs := d.ldr.Relocs(dsym)
@ -1492,7 +1506,7 @@ func (d *dwctxt) writeinfo(units []*sym.CompilationUnit, abbrevsym loader.Sym, p
infosec := d.ldr.LookupOrCreateSym(".debug_info", 0) infosec := d.ldr.LookupOrCreateSym(".debug_info", 0)
disu := d.ldr.MakeSymbolUpdater(infosec) disu := d.ldr.MakeSymbolUpdater(infosec)
disu.SetType(sym.SDWARFINFO) disu.SetType(sym.SDWARFCUINFO)
d.ldr.SetAttrReachable(infosec, true) d.ldr.SetAttrReachable(infosec, true)
syms := []loader.Sym{infosec} syms := []loader.Sym{infosec}
@ -1814,7 +1828,11 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
ctxt.runtimeCU = unit ctxt.runtimeCU = unit
} }
unit.DWInfo = d.newdie(&dwroot, dwarf.DW_ABRV_COMPUNIT, unit.Lib.Pkg, 0) cuabrv := dwarf.DW_ABRV_COMPUNIT
if len(unit.Textp) == 0 {
cuabrv = dwarf.DW_ABRV_COMPUNIT_TEXTLESS
}
unit.DWInfo = d.newdie(&dwroot, cuabrv, unit.Lib.Pkg, 0)
newattr(unit.DWInfo, dwarf.DW_AT_language, dwarf.DW_CLS_CONSTANT, int64(dwarf.DW_LANG_Go), 0) newattr(unit.DWInfo, dwarf.DW_AT_language, dwarf.DW_CLS_CONSTANT, int64(dwarf.DW_LANG_Go), 0)
// OS X linker requires compilation dir or absolute path in comp unit name to output debug info. // OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
compDir := getCompilationDir() compDir := getCompilationDir()
@ -1850,10 +1868,6 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
} }
newattr(unit.DWInfo, dwarf.DW_AT_go_package_name, dwarf.DW_CLS_STRING, int64(len(pkgname)), pkgname) newattr(unit.DWInfo, dwarf.DW_AT_go_package_name, dwarf.DW_CLS_STRING, int64(len(pkgname)), pkgname)
if len(unit.Textp) == 0 {
unit.DWInfo.Abbrev = dwarf.DW_ABRV_COMPUNIT_TEXTLESS
}
// Scan all functions in this compilation unit, create DIEs for all // Scan all functions in this compilation unit, create DIEs for all
// referenced types, create the file table for debug_line, find all // referenced types, create the file table for debug_line, find all
// referenced abstract functions. // referenced abstract functions.

View file

@ -1539,7 +1539,7 @@ func (l *Loader) GetFuncDwarfAuxSyms(fnSymIdx Sym) (auxDwarfInfo, auxDwarfLoc, a
switch a.Type() { switch a.Type() {
case goobj2.AuxDwarfInfo: case goobj2.AuxDwarfInfo:
auxDwarfInfo = l.resolve(r, a.Sym()) auxDwarfInfo = l.resolve(r, a.Sym())
if l.SymType(auxDwarfInfo) != sym.SDWARFINFO { if l.SymType(auxDwarfInfo) != sym.SDWARFFCN {
panic("aux dwarf info sym with wrong type") panic("aux dwarf info sym with wrong type")
} }
case goobj2.AuxDwarfLoc: case goobj2.AuxDwarfLoc:
@ -2105,7 +2105,7 @@ func topLevelSym(sname string, skind sym.SymKind) bool {
return true return true
} }
switch skind { switch skind {
case sym.SDWARFINFO, sym.SDWARFRANGE, sym.SDWARFLOC, sym.SDWARFLINES, sym.SGOFUNC: case sym.SDWARFFCN, sym.SDWARFABSFCN, sym.SDWARFTYPE, sym.SDWARFCONST, sym.SDWARFCUINFO, sym.SDWARFRANGE, sym.SDWARFLOC, sym.SDWARFLINES, sym.SGOFUNC:
return true return true
default: default:
return false return false

View file

@ -108,7 +108,13 @@ const (
// Sections for debugging information // Sections for debugging information
SDWARFSECT SDWARFSECT
SDWARFINFO // DWARF symbol types
SDWARFCUINFO
SDWARFCONST
SDWARFFCN
SDWARFABSFCN
SDWARFTYPE
SDWARFVAR
SDWARFRANGE SDWARFRANGE
SDWARFLOC SDWARFLOC
SDWARFLINES SDWARFLINES
@ -128,7 +134,12 @@ var AbiSymKindToSymKind = [...]SymKind{
SBSS, SBSS,
SNOPTRBSS, SNOPTRBSS,
STLSBSS, STLSBSS,
SDWARFINFO, SDWARFCUINFO,
SDWARFCONST,
SDWARFFCN,
SDWARFABSFCN,
SDWARFTYPE,
SDWARFVAR,
SDWARFRANGE, SDWARFRANGE,
SDWARFLOC, SDWARFLOC,
SDWARFLINES, SDWARFLINES,

View file

@ -1,4 +1,4 @@
// Code generated by "stringer -type=SymKind"; DO NOT EDIT. // Code generated by "stringer -type=SymKindstringer -type=SymKind"; DO NOT EDIT.
package sym package sym
@ -56,16 +56,21 @@ func _() {
_ = x[SHOSTOBJ-45] _ = x[SHOSTOBJ-45]
_ = x[SUNDEFEXT-46] _ = x[SUNDEFEXT-46]
_ = x[SDWARFSECT-47] _ = x[SDWARFSECT-47]
_ = x[SDWARFINFO-48] _ = x[SDWARFCUINFO-48]
_ = x[SDWARFRANGE-49] _ = x[SDWARFCONST-49]
_ = x[SDWARFLOC-50] _ = x[SDWARFFCN-50]
_ = x[SDWARFLINES-51] _ = x[SDWARFABSFCN-51]
_ = x[SABIALIAS-52] _ = x[SDWARFTYPE-52]
_ = x[SDWARFVAR-53]
_ = x[SDWARFRANGE-54]
_ = x[SDWARFLOC-55]
_ = x[SDWARFLINES-56]
_ = x[SABIALIAS-57]
} }
const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_EXTRA_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIAS" const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_EXTRA_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSABIALIAS"
var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 337, 344, 349, 361, 373, 390, 407, 416, 426, 434, 443, 453, 463, 474, 483, 494, 503} var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 337, 344, 349, 361, 373, 390, 407, 416, 426, 434, 443, 453, 465, 476, 485, 497, 507, 516, 527, 536, 547, 556}
func (i SymKind) String() string { func (i SymKind) String() string {
if i >= SymKind(len(_SymKind_index)-1) { if i >= SymKind(len(_SymKind_index)-1) {