[dev.link] cmd/link: demote dwarf {range,loc} sub-symbols to aux

When the compiler emits DWARF for a function F, in addition to the
text symbol for F, it emits a set of sibling or child symbols that
carry the various DWARF bits for F (for example, go.info.F,
go.ranges.F, go.loc.F, and so on).

Prior to the linker modernization work, name lookup was the way you
made your way from a function symbol to one of its child DWARF
symbols. We now have a new mechanism (aux symbols), so there is really
no need for the DWARF sub-symbols to be named or to be dupok.

This patch converts DWARF "range" and "loc" sub-symbols to be pure aux
syms: unnamed, and connected to their parent text symbol only via aux
data. This should presumably have performance benefits in that we add
fewer symbols to the linker lookup tables.

Other related DWARF sub-symbols (ex: go.line.*) will be handled in a
subsequent patch.

Change-Id: Iae3ec2d42452962d4afc1df4a1bd89ccdeadc6e4
Reviewed-on: https://go-review.googlesource.com/c/go/+/222673
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Than McIntosh 2020-03-09 11:42:03 -04:00
parent a6ae6d35e6
commit 8634642f9a
6 changed files with 44 additions and 27 deletions

View file

@ -21,12 +21,6 @@ import (
// InfoPrefix is the prefix for all the symbols containing DWARF info entries. // InfoPrefix is the prefix for all the symbols containing DWARF info entries.
const InfoPrefix = "go.info." const InfoPrefix = "go.info."
// RangePrefix is the prefix for all the symbols containing DWARF location lists.
const LocPrefix = "go.loc."
// RangePrefix is the prefix for all the symbols containing DWARF range lists.
const RangePrefix = "go.range."
// DebugLinesPrefix is the prefix for all the symbols containing DWARF debug_line information from the compiler. // DebugLinesPrefix is the prefix for all the symbols containing DWARF debug_line information from the compiler.
const DebugLinesPrefix = "go.debuglines." const DebugLinesPrefix = "go.debuglines."

View file

@ -205,9 +205,13 @@ func (ctxt *Link) dwarfSym(s *LSym) (dwarfInfoSym, dwarfLocSym, dwarfRangesSym,
if s.Func.dwarfInfoSym == nil { if s.Func.dwarfInfoSym == nil {
s.Func.dwarfInfoSym = ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name) s.Func.dwarfInfoSym = ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name)
if ctxt.Flag_locationlists { if ctxt.Flag_locationlists {
s.Func.dwarfLocSym = ctxt.LookupDerived(s, dwarf.LocPrefix+s.Name) s.Func.dwarfLocSym = &LSym{
Type: objabi.SDWARFLOC,
}
}
s.Func.dwarfRangesSym = &LSym{
Type: objabi.SDWARFRANGE,
} }
s.Func.dwarfRangesSym = ctxt.LookupDerived(s, dwarf.RangePrefix+s.Name)
if s.WasInlined() { if s.WasInlined() {
s.Func.dwarfAbsFnSym = ctxt.DwFixups.AbsFuncDwarfSym(s) s.Func.dwarfAbsFnSym = ctxt.DwFixups.AbsFuncDwarfSym(s)
} }

View file

@ -307,14 +307,14 @@ func (w *writer) Aux(s *LSym) {
} }
o.Write(w.Writer) o.Write(w.Writer)
} }
if s.Func.dwarfLocSym != nil { if s.Func.dwarfLocSym != nil && s.Func.dwarfLocSym.Size != 0 {
o := goobj2.Aux{ o := goobj2.Aux{
Type: goobj2.AuxDwarfLoc, Type: goobj2.AuxDwarfLoc,
Sym: makeSymRef(s.Func.dwarfLocSym), Sym: makeSymRef(s.Func.dwarfLocSym),
} }
o.Write(w.Writer) o.Write(w.Writer)
} }
if s.Func.dwarfRangesSym != nil { if s.Func.dwarfRangesSym != nil && s.Func.dwarfRangesSym.Size != 0 {
o := goobj2.Aux{ o := goobj2.Aux{
Type: goobj2.AuxDwarfRanges, Type: goobj2.AuxDwarfRanges,
Sym: makeSymRef(s.Func.dwarfRangesSym), Sym: makeSymRef(s.Func.dwarfRangesSym),
@ -343,10 +343,10 @@ func nAuxSym(s *LSym) int {
if s.Func.dwarfInfoSym != nil { if s.Func.dwarfInfoSym != nil {
n++ n++
} }
if s.Func.dwarfLocSym != nil { if s.Func.dwarfLocSym != nil && s.Func.dwarfLocSym.Size != 0 {
n++ n++
} }
if s.Func.dwarfRangesSym != nil { if s.Func.dwarfRangesSym != nil && s.Func.dwarfRangesSym.Size != 0 {
n++ n++
} }
if s.Func.dwarfDebugLinesSym != nil { if s.Func.dwarfDebugLinesSym != nil {
@ -419,6 +419,18 @@ func genFuncInfoSyms(ctxt *Link) {
infosyms = append(infosyms, isym) infosyms = append(infosyms, isym)
s.Func.FuncInfoSym = isym s.Func.FuncInfoSym = isym
b.Reset() b.Reset()
dwsyms := []*LSym{s.Func.dwarfRangesSym, s.Func.dwarfLocSym}
for _, s := range dwsyms {
if s == nil || s.Size == 0 {
continue
}
s.PkgIdx = goobj2.PkgIdxSelf
s.SymIdx = symidx
s.Set(AttrIndexed, true)
symidx++
infosyms = append(infosyms, s)
}
} }
ctxt.defs = append(ctxt.defs, infosyms...) ctxt.defs = append(ctxt.defs, infosyms...)
} }

View file

@ -139,17 +139,10 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int) {
ctxt.Text = append(ctxt.Text, s) ctxt.Text = append(ctxt.Text, s)
// Set up DWARF entries for s. // Set up DWARF entries for s.
info, loc, ranges, _, lines := ctxt.dwarfSym(s) info, _, _, _, lines := ctxt.dwarfSym(s)
info.Type = objabi.SDWARFINFO info.Type = objabi.SDWARFINFO
info.Set(AttrDuplicateOK, s.DuplicateOK()) info.Set(AttrDuplicateOK, s.DuplicateOK())
if loc != nil { ctxt.Data = append(ctxt.Data, info)
loc.Type = objabi.SDWARFLOC
loc.Set(AttrDuplicateOK, s.DuplicateOK())
ctxt.Data = append(ctxt.Data, loc)
}
ranges.Type = objabi.SDWARFRANGE
ranges.Set(AttrDuplicateOK, s.DuplicateOK())
ctxt.Data = append(ctxt.Data, info, ranges)
lines.Type = objabi.SDWARFLINES lines.Type = objabi.SDWARFLINES
lines.Set(AttrDuplicateOK, s.DuplicateOK()) lines.Set(AttrDuplicateOK, s.DuplicateOK())
ctxt.Data = append(ctxt.Data, lines) ctxt.Data = append(ctxt.Data, lines)

View file

@ -1934,8 +1934,11 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
r := &relocs[ri] r := &relocs[ri]
if r.Type == objabi.R_DWARFSECREF { if r.Type == objabi.R_DWARFSECREF {
rsym := r.Sym rsym := r.Sym
// NB: there should be a better way to do this that doesn't involve materializing the symbol name and doing string prefix+suffix checks.
rsn := d.ldr.SymName(rsym) rsn := d.ldr.SymName(rsym)
if len(rsn) == 0 {
continue
}
// NB: there should be a better way to do this that doesn't involve materializing the symbol name and doing string prefix+suffix checks.
if strings.HasPrefix(rsn, dwarf.InfoPrefix) && strings.HasSuffix(rsn, dwarf.AbstractFuncSuffix) && !d.ldr.AttrOnList(rsym) { if strings.HasPrefix(rsn, dwarf.InfoPrefix) && strings.HasSuffix(rsn, dwarf.AbstractFuncSuffix) && !d.ldr.AttrOnList(rsym) {
// abstract function // abstract function
d.ldr.SetAttrOnList(rsym, true) d.ldr.SetAttrOnList(rsym, true)
@ -2129,8 +2132,7 @@ func (d *dwctxt2) collectlocs(syms []loader.Sym, units []*sym.CompilationUnit) [
if reloc.Type != objabi.R_DWARFSECREF { if reloc.Type != objabi.R_DWARFSECREF {
continue continue
} }
sn := d.ldr.SymName(reloc.Sym) if d.ldr.SymType(reloc.Sym) == sym.SDWARFLOC {
if strings.HasPrefix(sn, dwarf.LocPrefix) {
d.ldr.SetAttrReachable(reloc.Sym, true) d.ldr.SetAttrReachable(reloc.Sym, true)
d.ldr.SetAttrNotInSymbolTable(reloc.Sym, true) d.ldr.SetAttrNotInSymbolTable(reloc.Sym, true)
syms = append(syms, reloc.Sym) syms = append(syms, reloc.Sym)

View file

@ -1856,6 +1856,7 @@ func (l *Loader) PropagateLoaderChangesToSymbols(toconvert []Sym, syms *sym.Symb
sn := l.SymName(cand) sn := l.SymName(cand)
sv := l.SymVersion(cand) sv := l.SymVersion(cand)
st := l.SymType(cand)
if sv < 0 { if sv < 0 {
sv = anonVerReplacement sv = anonVerReplacement
} }
@ -1866,7 +1867,7 @@ func (l *Loader) PropagateLoaderChangesToSymbols(toconvert []Sym, syms *sym.Symb
if sn == "" { if sn == "" {
// Don't install anonymous symbols in the lookup tab. // Don't install anonymous symbols in the lookup tab.
if s == nil { if s == nil {
s := l.allocSym(sn, sv) s = l.allocSym(sn, sv)
l.installSym(cand, s) l.installSym(cand, s)
} }
isnew = true isnew = true
@ -1885,7 +1886,7 @@ func (l *Loader) PropagateLoaderChangesToSymbols(toconvert []Sym, syms *sym.Symb
// Always copy these from new to old. // Always copy these from new to old.
s.Value = l.SymValue(cand) s.Value = l.SymValue(cand)
s.Type = l.SymType(cand) s.Type = st
// If the data for a symbol has increased in size, make sure // If the data for a symbol has increased in size, make sure
// we bring the new content across. // we bring the new content across.
@ -1914,7 +1915,10 @@ func (l *Loader) PropagateLoaderChangesToSymbols(toconvert []Sym, syms *sym.Symb
// If this symbol has any DWARF file relocations, we need to // If this symbol has any DWARF file relocations, we need to
// make sure that the relocations are copied back over, since // make sure that the relocations are copied back over, since
// DWARF-gen alters the offset values for these relocs. // DWARF-gen alters the offset values for these relocs. Also:
// if this is an info symbol and it refers to a previously
// unseen range/loc symbol, we'll need to fix up relocations
// for it as well.
relocs := l.Relocs(cand) relocs := l.Relocs(cand)
rslice = relocs.ReadSyms(rslice) rslice = relocs.ReadSyms(rslice)
for ri := range rslice { for ri := range rslice {
@ -1922,6 +1926,14 @@ func (l *Loader) PropagateLoaderChangesToSymbols(toconvert []Sym, syms *sym.Symb
relfix = true relfix = true
break break
} }
if st != sym.SDWARFINFO {
continue
}
rst := l.SymType(rslice[ri].Sym)
if rst == sym.SDWARFRANGE || rst == sym.SDWARFLOC {
relfix = true
break
}
} }
if relfix { if relfix {