mirror of
https://github.com/golang/go
synced 2024-11-23 14:40:02 -07:00
cmd/link: enable DWARF with external linker on aix/ppc64
In order to allow DWARF with ld, the symbol table is adapted. In internal linkmode, each package is considered as a .FILE. However, current version of ld is crashing on a few programs because of relocations between DWARF symbols. Considering all packages as part of one .FILE seems to bypass this bug. As it might be fixed in a future release, the size of each package in DWARF sections is still retrieved and can be used when it's fixed. Moreover, it's improving internal linkmode which should have done it anyway. Change-Id: If3d023fe118b24b9f0f46d201a4849eee8d5e333 Reviewed-on: https://go-review.googlesource.com/c/go/+/164006 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
b37b35edd7
commit
3cf89e509b
@ -1773,6 +1773,12 @@ func (ctxt *Link) dodata() {
|
||||
s.Value = int64(uint64(datsize) - sect.Vaddr)
|
||||
s.Attr |= sym.AttrLocal
|
||||
datsize += s.Size
|
||||
|
||||
if ctxt.HeadType == objabi.Haix && curType == sym.SDWARFLOC {
|
||||
// Update the size of .debug_loc for this symbol's
|
||||
// package.
|
||||
addDwsectCUSize(".debug_loc", s.File, uint64(s.Size))
|
||||
}
|
||||
}
|
||||
sect.Length = uint64(datsize) - sect.Vaddr
|
||||
checkdatsize(ctxt, datsize, curType)
|
||||
|
@ -1342,13 +1342,20 @@ func writelines(ctxt *Link, unit *compilationUnit, ls *sym.Symbol) {
|
||||
}
|
||||
|
||||
// writepcranges generates the DW_AT_ranges table for compilation unit cu.
|
||||
func writepcranges(ctxt *Link, cu *dwarf.DWDie, base *sym.Symbol, pcs []dwarf.Range, ranges *sym.Symbol) {
|
||||
func writepcranges(ctxt *Link, unit *compilationUnit, base *sym.Symbol, pcs []dwarf.Range, ranges *sym.Symbol) {
|
||||
var dwarfctxt dwarf.Context = dwctxt{ctxt}
|
||||
|
||||
unitLengthOffset := ranges.Size
|
||||
|
||||
// Create PC ranges for this CU.
|
||||
newattr(cu, dwarf.DW_AT_ranges, dwarf.DW_CLS_PTR, ranges.Size, ranges)
|
||||
newattr(cu, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, base.Value, base)
|
||||
newattr(unit.dwinfo, dwarf.DW_AT_ranges, dwarf.DW_CLS_PTR, ranges.Size, ranges)
|
||||
newattr(unit.dwinfo, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, base.Value, base)
|
||||
dwarf.PutRanges(dwarfctxt, ranges, nil, pcs)
|
||||
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
addDwsectCUSize(".debug_ranges", unit.lib.String(), uint64(ranges.Size-unitLengthOffset))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1500,6 +1507,10 @@ func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
|
||||
fs.AddAddr(ctxt.Arch, s)
|
||||
fs.AddUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range
|
||||
fs.AddBytes(deltaBuf)
|
||||
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
addDwsectCUSize(".debug_frame", s.File, fdeLength+uint64(lengthFieldSize))
|
||||
}
|
||||
}
|
||||
return syms
|
||||
}
|
||||
@ -1705,11 +1716,11 @@ func dwarfEnabled(ctxt *Link) bool {
|
||||
}
|
||||
|
||||
if ctxt.LinkMode == LinkExternal {
|
||||
// TODO(aix): enable DWARF
|
||||
switch {
|
||||
case ctxt.IsELF:
|
||||
case ctxt.HeadType == objabi.Hdarwin:
|
||||
case ctxt.HeadType == objabi.Hwindows:
|
||||
case ctxt.HeadType == objabi.Haix:
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@ -1730,6 +1741,11 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
|
||||
return
|
||||
}
|
||||
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
// Initial map used to store package size for each DWARF section.
|
||||
dwsectCUSize = make(map[string]uint64)
|
||||
}
|
||||
|
||||
ctxt.compUnitByPackage = make(map[*sym.Library]*compilationUnit)
|
||||
|
||||
// Forctxt.Diagnostic messages.
|
||||
@ -1829,6 +1845,10 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
|
||||
if ctxt.HeadType == objabi.Hdarwin {
|
||||
removeDwarfAddrListBaseAddress(ctxt, dsym, rangeSym, false)
|
||||
}
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
addDwsectCUSize(".debug_ranges", unit.lib.String(), uint64(rangeSym.Size))
|
||||
|
||||
}
|
||||
unit.rangeSyms = append(unit.rangeSyms, rangeSym)
|
||||
}
|
||||
|
||||
@ -1891,7 +1911,7 @@ func dwarfGenerateDebugSyms(ctxt *Link) {
|
||||
continue
|
||||
}
|
||||
writelines(ctxt, u, debugLine)
|
||||
writepcranges(ctxt, u.dwinfo, u.lib.Textp[0], u.pcs, debugRanges)
|
||||
writepcranges(ctxt, u, u.lib.Textp[0], u.pcs, debugRanges)
|
||||
}
|
||||
|
||||
// newdie adds DIEs to the *beginning* of the parent's DIE list.
|
||||
@ -2162,6 +2182,10 @@ func saveDwsectCUSize(sname string, pkgname string, size uint64) {
|
||||
dwsectCUSize[sname+"."+pkgname] = size
|
||||
}
|
||||
|
||||
func addDwsectCUSize(sname string, pkgname string, size uint64) {
|
||||
dwsectCUSize[sname+"."+pkgname] += size
|
||||
}
|
||||
|
||||
// getPkgFromCUSym returns the package name for the compilation unit
|
||||
// represented by s.
|
||||
// The prefix dwarf.InfoPrefix+".pkg." needs to be removed in order to get
|
||||
|
@ -501,7 +501,7 @@ func xcoffGetDwarfSubtype(str string) (string, uint32) {
|
||||
case ".debug_pubtypes":
|
||||
return ".dwpbtyp", SSUBTYP_DWPBTYP
|
||||
case ".debug_ranges":
|
||||
return ".dwrnge", SSUBTYP_DWRNGES
|
||||
return ".dwrnges", SSUBTYP_DWRNGES
|
||||
}
|
||||
// never used
|
||||
return "", 0
|
||||
@ -661,13 +661,20 @@ func (f *xcoffFile) writeSymbolNewFile(ctxt *Link, name string, firstEntry uint6
|
||||
|
||||
/* Dwarf */
|
||||
for _, sect := range Segdwarf.Sections {
|
||||
// Find the size of this corresponding package DWARF compilation unit.
|
||||
// This size is set during DWARF generation (see dwarf.go).
|
||||
dwsize := getDwsectCUSize(sect.Name, name)
|
||||
// .debug_abbrev is commun to all packages and not found with the previous function
|
||||
if sect.Name == ".debug_abbrev" {
|
||||
s := ctxt.Syms.Lookup(sect.Name, 0)
|
||||
dwsize = uint64(s.Size)
|
||||
var dwsize uint64
|
||||
if ctxt.LinkMode == LinkInternal {
|
||||
// Find the size of this corresponding package DWARF compilation unit.
|
||||
// This size is set during DWARF generation (see dwarf.go).
|
||||
dwsize = getDwsectCUSize(sect.Name, name)
|
||||
// .debug_abbrev is commun to all packages and not found with the previous function
|
||||
if sect.Name == ".debug_abbrev" {
|
||||
s := ctxt.Syms.ROLookup(sect.Name, 0)
|
||||
dwsize = uint64(s.Size)
|
||||
|
||||
}
|
||||
} else {
|
||||
// There is only one .FILE with external linking.
|
||||
dwsize = sect.Length
|
||||
}
|
||||
|
||||
// get XCOFF name
|
||||
@ -679,6 +686,20 @@ func (f *xcoffFile) writeSymbolNewFile(ctxt *Link, name string, firstEntry uint6
|
||||
Nscnum: f.getXCOFFscnum(sect),
|
||||
Nnumaux: 1,
|
||||
}
|
||||
|
||||
if currSymSrcFile.csectAux == nil {
|
||||
// Dwarf relocations need the symbol number of .dw* symbols.
|
||||
// It doesn't need to know it for each package, one is enough.
|
||||
// currSymSrcFile.csectAux == nil means first package.
|
||||
dws := ctxt.Syms.Lookup(sect.Name, 0)
|
||||
dws.Dynid = int32(f.symbolCount)
|
||||
|
||||
if sect.Name == ".debug_frame" && ctxt.LinkMode != LinkExternal {
|
||||
// CIE size must be added to the first package.
|
||||
dwsize += 48
|
||||
}
|
||||
}
|
||||
|
||||
f.addSymbol(s)
|
||||
|
||||
// update the DWARF section offset in this file
|
||||
@ -764,10 +785,25 @@ func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x *sym.Symbol) []xcoffSym {
|
||||
} else {
|
||||
// Current file has changed. New C_FILE, C_DWARF, etc must be generated.
|
||||
if currSymSrcFile.name != x.File {
|
||||
// update previous file values
|
||||
xfile.updatePreviousFile(ctxt, false)
|
||||
currSymSrcFile.name = x.File
|
||||
f.writeSymbolNewFile(ctxt, x.File, uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
|
||||
if ctxt.LinkMode == LinkInternal {
|
||||
// update previous file values
|
||||
xfile.updatePreviousFile(ctxt, false)
|
||||
currSymSrcFile.name = x.File
|
||||
f.writeSymbolNewFile(ctxt, x.File, uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
|
||||
} else {
|
||||
// With external linking, ld will crash if there is several
|
||||
// .FILE and DWARF debugging enable, somewhere during
|
||||
// the relocation phase.
|
||||
// Therefore, all packages are merged under a fake .FILE
|
||||
// "go_functions".
|
||||
// TODO(aix); remove once ld has been fixed or the triggering
|
||||
// relocation has been found and fixed.
|
||||
if currSymSrcFile.name == "" {
|
||||
currSymSrcFile.name = x.File
|
||||
f.writeSymbolNewFile(ctxt, "go_functions", uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1119,9 +1155,6 @@ func (ctxt *Link) doxcoff() {
|
||||
Exitf("-d is not available on AIX")
|
||||
}
|
||||
|
||||
// Initial map used to store compilation unit size for each DWARF section (see dwarf.go).
|
||||
dwsectCUSize = make(map[string]uint64)
|
||||
|
||||
// TOC
|
||||
toc := ctxt.Syms.Lookup("TOC", 0)
|
||||
toc.Type = sym.SXCOFFTOC
|
||||
@ -1634,7 +1667,18 @@ func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
|
||||
s.xcoffSect.Snreloc += n
|
||||
}
|
||||
|
||||
// TODO(aix): DWARF relocations
|
||||
dwarfLoop:
|
||||
for _, sect := range Segdwarf.Sections {
|
||||
for _, xcoffSect := range f.sections {
|
||||
_, subtyp := xcoffGetDwarfSubtype(sect.Name)
|
||||
if xcoffSect.Sflags&0xF0000 == subtyp {
|
||||
xcoffSect.Srelptr = uint64(ctxt.Out.Offset())
|
||||
xcoffSect.Snreloc = relocsect(sect, dwarfp, sect.Vaddr)
|
||||
continue dwarfLoop
|
||||
}
|
||||
}
|
||||
Errorf(nil, "emitRelocations: could not find %q section", sect.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// xcoffCreateExportFile creates a file with exported symbols for
|
||||
|
Loading…
Reference in New Issue
Block a user