aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Arzilli <alessandro.arzilli@gmail.com>2019-03-05 09:58:58 +0100
committerHeschi Kreinick <heschi@google.com>2019-03-06 23:18:15 +0000
commit4d8a37a6d98e9524300ce669affa3f820965bc41 (patch)
treeda7f14b965c1fdd4696d540242641d5808c00e80
parent1a6c0c6baf658fd64ecbd87a6d94aa75f4ae23b6 (diff)
downloadgo-4d8a37a6d98e9524300ce669affa3f820965bc41.tar.xz
cmd/link: fix contents of debug_pubnames/debug_pubtypes
The contents of debug_pubnames and debug_pubtypes have been wrong since Go 1.12. CL golang.org/cl/137235 moved global variables DIE to their respective compilation unit, unfortunately writepub can't emit correct sections for anything but the first compilation unit. This commit moves the code generating debug_pubnames and debug_pubtypes inside writeinfo and fixes it. Gets rid of a number of unnecessary relocations as well as a hack that writeinfo used to communicate to writepub the size of each compilation unit. Fixes #30573 Change-Id: Ibdaa80c02746ae81661c2cfe1d218092c5ae9236 Reviewed-on: https://go-review.googlesource.com/c/go/+/165337 Run-TryBot: Alessandro Arzilli <alessandro.arzilli@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
-rw-r--r--src/cmd/link/internal/ld/dwarf.go137
1 files changed, 80 insertions, 57 deletions
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index 0b17985da5..995a7e77b9 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -264,15 +264,6 @@ func newrefattr(die *dwarf.DWDie, attr uint16, ref *sym.Symbol) *dwarf.DWAttr {
return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, ref)
}
-func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.DWDie) []*sym.Symbol {
- for ; die != nil; die = die.Link {
- syms = putdie(linkctxt, ctxt, syms, die)
- }
- syms[len(syms)-1].AddUint8(0)
-
- return syms
-}
-
func dtolsym(s dwarf.Sym) *sym.Symbol {
if s == nil {
return nil
@@ -294,7 +285,10 @@ func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.D
dwarf.Uleb128put(ctxt, s, int64(die.Abbrev))
dwarf.PutAttrs(ctxt, s, die.Abbrev, die.Attr)
if dwarf.HasChildren(die) {
- return putdies(linkctxt, ctxt, syms, die.Child)
+ for die := die.Child; die != nil; die = die.Link {
+ syms = putdie(linkctxt, ctxt, syms, die)
+ }
+ syms[len(syms)-1].AddUint8(0)
}
return syms
}
@@ -1517,7 +1511,7 @@ const (
COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
)
-func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevsym *sym.Symbol) []*sym.Symbol {
+func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevsym *sym.Symbol, pubNames, pubTypes *pubWriter) []*sym.Symbol {
infosec := ctxt.Syms.Lookup(".debug_info", 0)
infosec.Type = sym.SDWARFINFO
infosec.Attr |= sym.AttrReachable
@@ -1533,6 +1527,9 @@ func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevs
continue
}
+ pubNames.beginCompUnit(compunit)
+ pubTypes.beginCompUnit(compunit)
+
// 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.
@@ -1553,11 +1550,32 @@ func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevs
if u.consts != nil {
cu = append(cu, u.consts)
}
- cu = putdies(ctxt, dwarfctxt, cu, compunit.Child)
var cusize int64
for _, child := range cu {
cusize += child.Size
}
+
+ for die := compunit.Child; die != nil; die = die.Link {
+ l := len(cu)
+ lastSymSz := cu[l-1].Size
+ cu = putdie(ctxt, dwarfctxt, cu, die)
+ if ispubname(die) {
+ pubNames.add(die, cusize)
+ }
+ if ispubtype(die) {
+ pubTypes.add(die, cusize)
+ }
+ if lastSymSz != cu[l-1].Size {
+ // putdie will sometimes append directly to the last symbol of the list
+ cusize = cusize - lastSymSz + cu[l-1].Size
+ }
+ for _, child := range cu[l:] {
+ cusize += child.Size
+ }
+ }
+ cu[len(cu)-1].AddUint8(0) // closes compilation unit DIE
+ cusize++
+
// Save size for AIX symbol table.
if ctxt.HeadType == objabi.Haix {
saveDwsectCUSize(".debug_info", getPkgFromCUSym(s), uint64(cusize))
@@ -1569,9 +1587,8 @@ func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevs
cusize -= 4 // exclude the length field.
s.SetUint32(ctxt.Arch, 0, uint32(cusize))
}
- // Leave a breadcrumb for writepub. This does not
- // appear in the DWARF output.
- newattr(compunit, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, cusize, 0)
+ pubNames.endCompUnit(compunit, uint32(cusize)+4)
+ pubTypes.endCompUnit(compunit, uint32(cusize)+4)
syms = append(syms, cu...)
}
return syms
@@ -1595,52 +1612,57 @@ func ispubtype(die *dwarf.DWDie) bool {
return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE
}
-func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*sym.Symbol) []*sym.Symbol {
+type pubWriter struct {
+ ctxt *Link
+ s *sym.Symbol
+ sname string
+
+ sectionstart int64
+ culengthOff int64
+}
+
+func newPubWriter(ctxt *Link, sname string) *pubWriter {
s := ctxt.Syms.Lookup(sname, 0)
s.Type = sym.SDWARFSECT
- syms = append(syms, s)
-
- for _, u := range ctxt.compUnits {
- if len(u.lib.Textp) == 0 && u.dwinfo.Child == nil {
- continue
- }
- compunit := u.dwinfo
- sectionstart := s.Size
- culength := uint32(getattr(compunit, dwarf.DW_AT_byte_size).Value) + 4
+ return &pubWriter{ctxt: ctxt, s: s, sname: sname}
+}
- // Write .debug_pubnames/types Header (sec 6.1.1)
- createUnitLength(ctxt, s, 0) // unit_length (*), will be filled in later.
- s.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
- addDwarfAddrRef(ctxt, s, dtolsym(compunit.Sym)) // debug_info_offset (of the Comp unit Header)
- addDwarfAddrField(ctxt, s, uint64(culength)) // debug_info_length
+func (pw *pubWriter) beginCompUnit(compunit *dwarf.DWDie) {
+ pw.sectionstart = pw.s.Size
- for die := compunit.Child; die != nil; die = die.Link {
- if !ispub(die) {
- continue
- }
- dwa := getattr(die, dwarf.DW_AT_name)
- name := dwa.Data.(string)
- if die.Sym == nil {
- fmt.Println("Missing sym for ", name)
- }
- addDwarfAddrRef(ctxt, s, dtolsym(die.Sym))
- Addstring(s, name)
- }
+ // Write .debug_pubnames/types Header (sec 6.1.1)
+ createUnitLength(pw.ctxt, pw.s, 0) // unit_length (*), will be filled in later.
+ pw.s.AddUint16(pw.ctxt.Arch, 2) // dwarf version (appendix F)
+ addDwarfAddrRef(pw.ctxt, pw.s, dtolsym(compunit.Sym)) // debug_info_offset (of the Comp unit Header)
+ pw.culengthOff = pw.s.Size
+ addDwarfAddrField(pw.ctxt, pw.s, uint64(0)) // debug_info_length, will be filled in later.
- addDwarfAddrField(ctxt, s, 0) // Null offset
+}
- // On AIX, save the current size of this compilation unit.
- if ctxt.HeadType == objabi.Haix {
- saveDwsectCUSize(sname, getPkgFromCUSym(dtolsym(compunit.Sym)), uint64(s.Size-sectionstart))
- }
- if isDwarf64(ctxt) {
- s.SetUint(ctxt.Arch, sectionstart+4, uint64(s.Size-sectionstart)-12) // exclude the length field.
- } else {
- s.SetUint32(ctxt.Arch, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
- }
+func (pw *pubWriter) add(die *dwarf.DWDie, offset int64) {
+ dwa := getattr(die, dwarf.DW_AT_name)
+ name := dwa.Data.(string)
+ if die.Sym == nil {
+ fmt.Println("Missing sym for ", name)
}
+ addDwarfAddrField(pw.ctxt, pw.s, uint64(offset))
+ Addstring(pw.s, name)
+}
- return syms
+func (pw *pubWriter) endCompUnit(compunit *dwarf.DWDie, culength uint32) {
+ addDwarfAddrField(pw.ctxt, pw.s, 0) // Null offset
+
+ // On AIX, save the current size of this compilation unit.
+ if pw.ctxt.HeadType == objabi.Haix {
+ saveDwsectCUSize(pw.sname, getPkgFromCUSym(dtolsym(compunit.Sym)), uint64(pw.s.Size-pw.sectionstart))
+ }
+ if isDwarf64(pw.ctxt) {
+ pw.s.SetUint(pw.ctxt.Arch, pw.sectionstart+4, uint64(pw.s.Size-pw.sectionstart)-12) // exclude the length field.
+ pw.s.SetUint(pw.ctxt.Arch, pw.culengthOff, uint64(culength))
+ } else {
+ pw.s.SetUint32(pw.ctxt.Arch, pw.sectionstart, uint32(pw.s.Size-pw.sectionstart)-4) // exclude the length field.
+ pw.s.SetUint32(pw.ctxt.Arch, pw.culengthOff, culength)
+ }
}
func writegdbscript(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
@@ -1878,13 +1900,14 @@ func dwarfGenerateDebugSyms(ctxt *Link) {
reversetree(&dwtypes.Child)
movetomodule(ctxt, &dwtypes)
+ pubNames := newPubWriter(ctxt, ".debug_pubnames")
+ pubTypes := newPubWriter(ctxt, ".debug_pubtypes")
+
// Need to reorder symbols so sym.SDWARFINFO is after all sym.SDWARFSECT
- // (but we need to generate dies before writepub)
- infosyms := writeinfo(ctxt, nil, ctxt.compUnits, abbrev)
+ infosyms := writeinfo(ctxt, nil, ctxt.compUnits, abbrev, pubNames, pubTypes)
syms = writeframes(ctxt, syms)
- syms = writepub(ctxt, ".debug_pubnames", ispubname, syms)
- syms = writepub(ctxt, ".debug_pubtypes", ispubtype, syms)
+ syms = append(syms, pubNames.s, pubTypes.s)
syms = writegdbscript(ctxt, syms)
// Now we're done writing SDWARFSECT symbols, so we can write
// other SDWARF* symbols.