mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
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>
This commit is contained in:
parent
1a6c0c6baf
commit
4d8a37a6d9
|
@ -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)
|
||||
return &pubWriter{ctxt: ctxt, s: s, sname: sname}
|
||||
}
|
||||
|
||||
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
|
||||
func (pw *pubWriter) beginCompUnit(compunit *dwarf.DWDie) {
|
||||
pw.sectionstart = pw.s.Size
|
||||
|
||||
// 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
|
||||
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.
|
||||
|
||||
for die := compunit.Child; die != nil; die = die.Link {
|
||||
if !ispub(die) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
addDwarfAddrRef(ctxt, s, dtolsym(die.Sym))
|
||||
Addstring(s, name)
|
||||
}
|
||||
addDwarfAddrField(pw.ctxt, pw.s, uint64(offset))
|
||||
Addstring(pw.s, name)
|
||||
}
|
||||
|
||||
addDwarfAddrField(ctxt, s, 0) // Null offset
|
||||
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 ctxt.HeadType == objabi.Haix {
|
||||
saveDwsectCUSize(sname, getPkgFromCUSym(dtolsym(compunit.Sym)), uint64(s.Size-sectionstart))
|
||||
if pw.ctxt.HeadType == objabi.Haix {
|
||||
saveDwsectCUSize(pw.sname, getPkgFromCUSym(dtolsym(compunit.Sym)), uint64(pw.s.Size-pw.sectionstart))
|
||||
}
|
||||
if isDwarf64(ctxt) {
|
||||
s.SetUint(ctxt.Arch, sectionstart+4, uint64(s.Size-sectionstart)-12) // exclude the length field.
|
||||
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 {
|
||||
s.SetUint32(ctxt.Arch, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
return syms
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
Loading…
Reference in a new issue