diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index a48db2aeeba..9d160ca49b0 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -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) diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index 995a7e77b9f..446fd572ac7 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -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 diff --git a/src/cmd/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go index ee375bfe03c..70be67420b1 100644 --- a/src/cmd/link/internal/ld/xcoff.go +++ b/src/cmd/link/internal/ld/xcoff.go @@ -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