From 27144d166b25de731bc26ee5bce861e4574b81bb Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Thu, 11 Jun 2020 14:48:08 -0400 Subject: [PATCH] [dev.link] cmd/link: refactor dwarf gen methods to be comp-unit centric Refactor some of the linker's DWARF generation methods so as to have helper routines that do all the work for a given comp unit for a given section (range, loc, etc). No change in functionality, this is just a reorg in preparation for a later patch in this sequence. Change-Id: I86fc789220326a4e522904a5924c8971d6757189 Reviewed-on: https://go-review.googlesource.com/c/go/+/237677 Reviewed-by: Cherry Zhang Reviewed-by: Jeremy Faller --- src/cmd/link/internal/ld/dwarf.go | 187 ++++++++++++++++-------------- 1 file changed, 99 insertions(+), 88 deletions(-) diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index 89dd4b37f1..d55148d9aa 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -1356,8 +1356,7 @@ func appendPCDeltaCFA(arch *sys.Arch, b []byte, deltapc, cfa int64) []byte { return b } -func (d *dwctxt) writeframes() dwarfSecInfo { - fs := d.ldr.LookupOrCreateSym(".debug_frame", 0) +func (d *dwctxt) writeframes(fs loader.Sym) dwarfSecInfo { fsd := dwSym(fs) fsu := d.ldr.MakeSymbolUpdater(fs) fsu.SetType(sym.SDWARFSECT) @@ -1525,78 +1524,83 @@ func appendSyms(syms []loader.Sym, src []sym.LoaderSym) []loader.Sym { return syms } -func (d *dwctxt) writeinfo(units []*sym.CompilationUnit, abbrevsym loader.Sym) dwarfSecInfo { - - infosec := d.ldr.LookupOrCreateSym(".debug_info", 0) - disu := d.ldr.MakeSymbolUpdater(infosec) - disu.SetType(sym.SDWARFCUINFO) - d.ldr.SetAttrReachable(infosec, true) - syms := []loader.Sym{infosec} +func (d *dwctxt) writeUnitInfo(u *sym.CompilationUnit, abbrevsym loader.Sym) []loader.Sym { + syms := []loader.Sym{} + if len(u.Textp) == 0 && u.DWInfo.Child == nil { + return syms + } - for _, u := range units { - compunit := u.DWInfo - s := d.dtolsym(compunit.Sym) - su := d.ldr.MakeSymbolUpdater(s) + compunit := u.DWInfo + s := d.dtolsym(compunit.Sym) + su := d.ldr.MakeSymbolUpdater(s) - if len(u.Textp) == 0 && u.DWInfo.Child == nil { - continue - } + // Write .debug_info Compilation Unit Header (sec 7.5.1) + // Fields marked with (*) must be changed for 64-bit dwarf + // This must match COMPUNITHEADERSIZE above. + d.createUnitLength(su, 0) // unit_length (*), will be filled in later. + su.AddUint16(d.arch, 4) // dwarf version (appendix F) - // Write .debug_info Compilation Unit Header (sec 7.5.1) - // Fields marked with (*) must be changed for 64-bit dwarf - // This must match COMPUNITHEADERSIZE above. - d.createUnitLength(su, 0) // unit_length (*), will be filled in later. - su.AddUint16(d.arch, 4) // dwarf version (appendix F) + // debug_abbrev_offset (*) + d.addDwarfAddrRef(su, abbrevsym) - // debug_abbrev_offset (*) - d.addDwarfAddrRef(su, abbrevsym) + su.AddUint8(uint8(d.arch.PtrSize)) // address_size - su.AddUint8(uint8(d.arch.PtrSize)) // address_size + ds := dwSym(s) + dwarf.Uleb128put(d, ds, int64(compunit.Abbrev)) + dwarf.PutAttrs(d, ds, compunit.Abbrev, compunit.Attr) - ds := dwSym(s) - dwarf.Uleb128put(d, ds, int64(compunit.Abbrev)) - dwarf.PutAttrs(d, ds, compunit.Abbrev, compunit.Attr) + cu := []loader.Sym{s} + cu = appendSyms(cu, u.AbsFnDIEs) + cu = appendSyms(cu, u.FuncDIEs) + if u.Consts != 0 { + cu = append(cu, loader.Sym(u.Consts)) + } + var cusize int64 + for _, child := range cu { + cusize += int64(len(d.ldr.Data(child))) + } - cu := []loader.Sym{s} - cu = appendSyms(cu, u.AbsFnDIEs) - cu = appendSyms(cu, u.FuncDIEs) - if u.Consts != 0 { - cu = append(cu, loader.Sym(u.Consts)) + for die := compunit.Child; die != nil; die = die.Link { + l := len(cu) + lastSymSz := int64(len(d.ldr.Data(cu[l-1]))) + cu = d.putdie(cu, die) + if lastSymSz != int64(len(d.ldr.Data(cu[l-1]))) { + // putdie will sometimes append directly to the last symbol of the list + cusize = cusize - lastSymSz + int64(len(d.ldr.Data(cu[l-1]))) } - var cusize int64 - for _, child := range cu { + for _, child := range cu[l:] { cusize += int64(len(d.ldr.Data(child))) } + } - for die := compunit.Child; die != nil; die = die.Link { - l := len(cu) - lastSymSz := int64(len(d.ldr.Data(cu[l-1]))) - cu = d.putdie(cu, die) - if lastSymSz != int64(len(d.ldr.Data(cu[l-1]))) { - // putdie will sometimes append directly to the last symbol of the list - cusize = cusize - lastSymSz + int64(len(d.ldr.Data(cu[l-1]))) - } - for _, child := range cu[l:] { - cusize += int64(len(d.ldr.Data(child))) - } - } + culu := d.ldr.MakeSymbolUpdater(cu[len(cu)-1]) + culu.AddUint8(0) // closes compilation unit DIE + cusize++ - culu := d.ldr.MakeSymbolUpdater(cu[len(cu)-1]) - culu.AddUint8(0) // closes compilation unit DIE - cusize++ + // Save size for AIX symbol table. + if d.linkctxt.HeadType == objabi.Haix { + saveDwsectCUSize(".debug_info", d.getPkgFromCUSym(s), uint64(cusize)) + } + if isDwarf64(d.linkctxt) { + cusize -= 12 // exclude the length field. + su.SetUint(d.arch, 4, uint64(cusize)) // 4 because of 0XFFFFFFFF + } else { + cusize -= 4 // exclude the length field. + su.SetUint32(d.arch, 0, uint32(cusize)) + } + return append(syms, cu...) +} - // Save size for AIX symbol table. - if d.linkctxt.HeadType == objabi.Haix { - saveDwsectCUSize(".debug_info", d.getPkgFromCUSym(s), uint64(cusize)) - } - if isDwarf64(d.linkctxt) { - cusize -= 12 // exclude the length field. - su.SetUint(d.arch, 4, uint64(cusize)) // 4 because of 0XFFFFFFFF - } else { - cusize -= 4 // exclude the length field. - su.SetUint32(d.arch, 0, uint32(cusize)) - } - syms = append(syms, cu...) +func (d *dwctxt) writeinfo(units []*sym.CompilationUnit, abbrevsym loader.Sym, infosym loader.Sym) dwarfSecInfo { + + disu := d.ldr.MakeSymbolUpdater(infosym) + disu.SetType(sym.SDWARFCUINFO) + d.ldr.SetAttrReachable(infosym, true) + syms := []loader.Sym{infosym} + + for _, u := range units { + usyms := d.writeUnitInfo(u, abbrevsym) + syms = append(syms, usyms...) } return dwarfSecInfo{syms: syms} @@ -1994,16 +1998,22 @@ func (d *dwctxt) dwarfGenerateDebugSyms() { reversetree(&dwtypes.Child) movetomodule(d.linkctxt, &dwtypes) - infoSec := d.writeinfo(d.linkctxt.compUnits, abbrevSec.secSym()) + infoSym := d.ldr.LookupOrCreateSym(".debug_info", 0) + + infoSec := d.writeinfo(d.linkctxt.compUnits, abbrevSec.secSym(), infoSym) + + frameSym := d.ldr.LookupOrCreateSym(".debug_frame", 0) + frameSec := d.writeframes(frameSym) - framesSec := d.writeframes() - dwarfp = append(dwarfp, framesSec) + dwarfp = append(dwarfp, frameSec) gdbScriptSec := d.writegdbscript() if gdbScriptSec.secSym() != 0 { dwarfp = append(dwarfp, gdbScriptSec) } dwarfp = append(dwarfp, infoSec) - locSec := d.collectlocs(d.linkctxt.compUnits) + locSym := d.ldr.LookupOrCreateSym(".debug_loc", 0) + d.ldr.SetAttrReachable(locSym, true) + locSec := d.collectlocs(locSym) if locSec.secSym() != 0 { dwarfp = append(dwarfp, locSec) } @@ -2017,39 +2027,40 @@ func (d *dwctxt) dwarfGenerateDebugSyms() { dwarfp = append(dwarfp, dwarfSecInfo{syms: rsyms}) } -func (d *dwctxt) collectlocs(units []*sym.CompilationUnit) dwarfSecInfo { - empty := true - syms := []loader.Sym{} - for _, u := range units { - for _, fn := range u.FuncDIEs { - relocs := d.ldr.Relocs(loader.Sym(fn)) - for i := 0; i < relocs.Count(); i++ { - reloc := relocs.At2(i) - if reloc.Type() != objabi.R_DWARFSECREF { - continue - } - rsym := reloc.Sym() - if d.ldr.SymType(rsym) == sym.SDWARFLOC { - d.ldr.SetAttrReachable(rsym, true) - d.ldr.SetAttrNotInSymbolTable(rsym, true) - syms = append(syms, rsym) - empty = false - // One location list entry per function, but many relocations to it. Don't duplicate. - break - } +func (d *dwctxt) collectUnitLocs(u *sym.CompilationUnit, syms []loader.Sym) []loader.Sym { + for _, fn := range u.FuncDIEs { + relocs := d.ldr.Relocs(loader.Sym(fn)) + for i := 0; i < relocs.Count(); i++ { + reloc := relocs.At2(i) + if reloc.Type() != objabi.R_DWARFSECREF { + continue + } + rsym := reloc.Sym() + if d.ldr.SymType(rsym) == sym.SDWARFLOC { + d.ldr.SetAttrReachable(rsym, true) + d.ldr.SetAttrNotInSymbolTable(rsym, true) + syms = append(syms, rsym) + // One location list entry per function, but many relocations to it. Don't duplicate. + break } } } + return syms +} + +func (d *dwctxt) collectlocs(locsym loader.Sym) dwarfSecInfo { + syms := []loader.Sym{} + for _, u := range d.linkctxt.compUnits { + syms = d.collectUnitLocs(u, syms) + } // Don't emit .debug_loc if it's empty -- it makes the ARM linker mad. - if empty { + if len(syms) == 0 { return dwarfSecInfo{} } - locsym := d.ldr.LookupOrCreateSym(".debug_loc", 0) u := d.ldr.MakeSymbolUpdater(locsym) u.SetType(sym.SDWARFLOC) - d.ldr.SetAttrReachable(locsym, true) return dwarfSecInfo{syms: append([]loader.Sym{locsym}, syms...)} } -- 2.48.1