[dev.link] cmd/link: revise representation of dwarfp

Change linker DWARF generation to move away from emitting a single
giant list of DWARF symbols, and instead emit a list of descriptors,
with each descriptor holding the symbols for a specific DWARF section.

While placing all DWARF symbols in a single lists does come in handy
in certain instances, it also creates a lot of confusion and weird
code in other cases, specifically where we want to perform operations
on a section-by-section basis (resulting in code that tries to
re-discover section boundaries by walking/inspecting the list).

Change-Id: I4dac81bd38cba903c9fd7004d613597e76dfb77a
Reviewed-on: https://go-review.googlesource.com/c/go/+/228780
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Than McIntosh 2020-04-17 09:11:57 -04:00
parent 817bd10cae
commit c32b590264
8 changed files with 215 additions and 138 deletions

View file

@ -599,9 +599,11 @@ func (ctxt *Link) reloc() {
wg.Done() wg.Done()
}() }()
go func() { go func() {
for _, s := range dwarfp { for _, si := range dwarfp {
for _, s := range si.syms {
relocsym(target, ldr, reporter, syms, s) relocsym(target, ldr, reporter, syms, s)
} }
}
wg.Done() wg.Done()
}() }()
wg.Wait() wg.Wait()
@ -1042,7 +1044,21 @@ func Dwarfblk(ctxt *Link, out *OutBuf, addr int64, size int64) {
ctxt.Logf("dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset()) ctxt.Logf("dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
} }
writeBlocks(out, ctxt.outSem, dwarfp, addr, size, zeros[:]) // Concatenate the section symbol lists into a single list to pass
// to writeBlocks.
//
// NB: ideally we would do a separate writeBlocks call for each
// section, but this would run the risk of undoing any file offset
// adjustments made during layout.
n := 0
for i := range dwarfp {
n += len(dwarfp[i].syms)
}
syms := make([]*sym.Symbol, 0, n)
for i := range dwarfp {
syms = append(syms, dwarfp[i].syms...)
}
writeBlocks(out, ctxt.outSem, syms, addr, size, zeros[:])
} }
var zeros [512]byte var zeros [512]byte
@ -1963,13 +1979,10 @@ func (state *dodataState) allocateSections(ctxt *Link) {
ctxt.datap = append(ctxt.datap, state.data[symn]...) ctxt.datap = append(ctxt.datap, state.data[symn]...)
} }
var i int // DWARF
for ; i < len(dwarfp); i++ { for i := 0; i < len(dwarfp); i++ {
s := dwarfp[i] // First the section symbol.
if s.Type != sym.SDWARFSECT { s := dwarfp[i].secSym()
break
}
sect = addsection(ctxt.Arch, &Segdwarf, s.Name, 04) sect = addsection(ctxt.Arch, &Segdwarf, s.Name, 04)
sect.Sym = s sect.Sym = s
sect.Align = 1 sect.Align = 1
@ -1979,39 +1992,15 @@ func (state *dodataState) allocateSections(ctxt *Link) {
s.Type = sym.SRODATA s.Type = sym.SRODATA
s.Value = int64(uint64(state.datsize) - sect.Vaddr) s.Value = int64(uint64(state.datsize) - sect.Vaddr)
state.datsize += s.Size state.datsize += s.Size
sect.Length = uint64(state.datsize) - sect.Vaddr curType := s.Type
}
state.checkdatsize(sym.SDWARFSECT)
for i < len(dwarfp) { // Then any sub-symbols for the section symbol.
curType := dwarfp[i].Type subSyms := dwarfp[i].subSyms()
var sect *sym.Section for j := 0; j < len(subSyms); j++ {
var sectname string s := subSyms[j]
switch curType {
case sym.SDWARFINFO:
sectname = ".debug_info"
case sym.SDWARFRANGE:
sectname = ".debug_ranges"
case sym.SDWARFLOC:
sectname = ".debug_loc"
default:
// Error is unrecoverable, so panic.
panic(fmt.Sprintf("unknown DWARF section %v", curType))
}
sect = addsection(ctxt.Arch, &Segdwarf, sectname, 04)
sect.Sym = ctxt.Syms.ROLookup(sectname, 0)
sect.Align = 1
state.datsize = Rnd(state.datsize, int64(sect.Align))
sect.Vaddr = uint64(state.datsize)
for ; i < len(dwarfp); i++ {
s := dwarfp[i]
if s.Type != curType {
break
}
s.Sect = sect s.Sect = sect
s.Type = sym.SRODATA s.Type = sym.SRODATA
s.Value = int64(uint64(state.datsize) - sect.Vaddr) s.Value = int64(uint64(state.datsize) - sect.Vaddr)
s.Attr |= sym.AttrLocal
state.datsize += s.Size state.datsize += s.Size
if ctxt.HeadType == objabi.Haix && curType == sym.SDWARFLOC { if ctxt.HeadType == objabi.Haix && curType == sym.SDWARFLOC {
@ -2504,14 +2493,19 @@ func (ctxt *Link) address() []*sym.Segment {
} }
} }
for _, s := range dwarfp { for _, si := range dwarfp {
for _, s := range si.syms {
if s.Sect != nil { if s.Sect != nil {
s.Value += int64(s.Sect.Vaddr) s.Value += int64(s.Sect.Vaddr)
} }
if s.Sub != nil {
panic(fmt.Sprintf("unexpected sub-sym for %s %s", s.Name, s.Type.String()))
}
for sub := s.Sub; sub != nil; sub = sub.Sub { for sub := s.Sub; sub != nil; sub = sub.Sub {
sub.Value += s.Value sub.Value += s.Value
} }
} }
}
if ctxt.BuildMode == BuildModeShared { if ctxt.BuildMode == BuildModeShared {
s := ctxt.Syms.Lookup("go.link.abihashbytes", 0) s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)

View file

@ -177,14 +177,46 @@ func (c dwctxt2) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets [
var gdbscript string var gdbscript string
var dwarfp2 []loader.Sym // dwarfSecInfo holds information about a DWARF output section,
// specifically a section symbol and a list of symbols contained in
// that section. On the syms list, the first symbol will always be the
// section symbol, then any remaining symbols (if any) will be
// sub-symbols in that section. Note that for some sections (eg:
// .debug_abbrev), the section symbol is all there is (all content is
// contained in it). For other sections (eg: .debug_info), the section
// symbol is empty and all the content is in the sub-symbols. Finally
// there are some sections (eg: .debug_ranges) where it is a mix (both
// the section symbol and the sub-symbols have content)
type dwarfSecInfo struct {
syms []loader.Sym
}
func (d *dwctxt2) writeabbrev() loader.Sym { // secSym returns the section symbol for the section.
func (dsi *dwarfSecInfo) secSym() loader.Sym {
if len(dsi.syms) == 0 {
return 0
}
return dsi.syms[0]
}
// subSyms returns a list of sub-symbols for the section.
func (dsi *dwarfSecInfo) subSyms() []loader.Sym {
if len(dsi.syms) == 0 {
return []loader.Sym{}
}
return dsi.syms[1:]
}
// dwarfp2 stores the collected DWARF symbols created during
// dwarf generation.
var dwarfp2 []dwarfSecInfo
func (d *dwctxt2) writeabbrev() dwarfSecInfo {
abrvs := d.ldr.LookupOrCreateSym(".debug_abbrev", 0) abrvs := d.ldr.LookupOrCreateSym(".debug_abbrev", 0)
u := d.ldr.MakeSymbolUpdater(abrvs) u := d.ldr.MakeSymbolUpdater(abrvs)
u.SetType(sym.SDWARFSECT) u.SetType(sym.SDWARFSECT)
u.AddBytes(dwarf.GetAbbrev()) u.AddBytes(dwarf.GetAbbrev())
return abrvs return dwarfSecInfo{syms: []loader.Sym{abrvs}}
} }
var dwtypes dwarf.DWDie var dwtypes dwarf.DWDie
@ -1294,12 +1326,11 @@ func appendPCDeltaCFA(arch *sys.Arch, b []byte, deltapc, cfa int64) []byte {
return b return b
} }
func (d *dwctxt2) writeframes(syms []loader.Sym) []loader.Sym { func (d *dwctxt2) writeframes() dwarfSecInfo {
fs := d.ldr.LookupOrCreateSym(".debug_frame", 0) fs := d.ldr.LookupOrCreateSym(".debug_frame", 0)
fsd := dwSym(fs) fsd := dwSym(fs)
fsu := d.ldr.MakeSymbolUpdater(fs) fsu := d.ldr.MakeSymbolUpdater(fs)
fsu.SetType(sym.SDWARFSECT) fsu.SetType(sym.SDWARFSECT)
syms = append(syms, fs)
isdw64 := isDwarf64(d.linkctxt) isdw64 := isDwarf64(d.linkctxt)
haslr := haslinkregister(d.linkctxt) haslr := haslinkregister(d.linkctxt)
@ -1443,7 +1474,7 @@ func (d *dwctxt2) writeframes(syms []loader.Sym) []loader.Sym {
} }
} }
return syms return dwarfSecInfo{syms: []loader.Sym{fs}}
} }
/* /*
@ -1464,13 +1495,13 @@ func appendSyms(syms []loader.Sym, src []sym.LoaderSym) []loader.Sym {
return syms return syms
} }
func (d *dwctxt2) writeinfo(syms []loader.Sym, units []*sym.CompilationUnit, abbrevsym loader.Sym, pubNames, pubTypes *pubWriter2) []loader.Sym { func (d *dwctxt2) writeinfo(units []*sym.CompilationUnit, abbrevsym loader.Sym, pubNames, pubTypes *pubWriter2) dwarfSecInfo {
infosec := d.ldr.LookupOrCreateSym(".debug_info", 0) infosec := d.ldr.LookupOrCreateSym(".debug_info", 0)
disu := d.ldr.MakeSymbolUpdater(infosec) disu := d.ldr.MakeSymbolUpdater(infosec)
disu.SetType(sym.SDWARFINFO) disu.SetType(sym.SDWARFINFO)
d.ldr.SetAttrReachable(infosec, true) d.ldr.SetAttrReachable(infosec, true)
syms = append(syms, infosec) syms := []loader.Sym{infosec}
for _, u := range units { for _, u := range units {
compunit := u.DWInfo compunit := u.DWInfo
@ -1548,7 +1579,8 @@ func (d *dwctxt2) writeinfo(syms []loader.Sym, units []*sym.CompilationUnit, abb
pubTypes.endCompUnit(compunit, uint32(cusize)+4) pubTypes.endCompUnit(compunit, uint32(cusize)+4)
syms = append(syms, cu...) syms = append(syms, cu...)
} }
return syms
return dwarfSecInfo{syms: syms}
} }
/* /*
@ -1624,10 +1656,10 @@ func ispubtype(die *dwarf.DWDie) bool {
return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE
} }
func (d *dwctxt2) writegdbscript(syms []loader.Sym) []loader.Sym { func (d *dwctxt2) writegdbscript() dwarfSecInfo {
// TODO (aix): make it available // TODO (aix): make it available
if d.linkctxt.HeadType == objabi.Haix { if d.linkctxt.HeadType == objabi.Haix {
return syms return dwarfSecInfo{}
} }
if d.linkctxt.LinkMode == LinkExternal && d.linkctxt.HeadType == objabi.Hwindows && d.linkctxt.BuildMode == BuildModeCArchive { if d.linkctxt.LinkMode == LinkExternal && d.linkctxt.HeadType == objabi.Hwindows && d.linkctxt.BuildMode == BuildModeCArchive {
// gcc on Windows places .debug_gdb_scripts in the wrong location, which // gcc on Windows places .debug_gdb_scripts in the wrong location, which
@ -1636,21 +1668,19 @@ func (d *dwctxt2) writegdbscript(syms []loader.Sym) []loader.Sym {
// (see fix near writeGDBLinkerScript). // (see fix near writeGDBLinkerScript).
// c-archive users would need to specify the linker script manually. // c-archive users would need to specify the linker script manually.
// For UX it's better not to deal with this. // For UX it's better not to deal with this.
return syms return dwarfSecInfo{}
}
if gdbscript == "" {
return dwarfSecInfo{}
} }
if gdbscript != "" {
gs := d.ldr.LookupOrCreateSym(".debug_gdb_scripts", 0) gs := d.ldr.LookupOrCreateSym(".debug_gdb_scripts", 0)
u := d.ldr.MakeSymbolUpdater(gs) u := d.ldr.MakeSymbolUpdater(gs)
u.SetType(sym.SDWARFSECT) u.SetType(sym.SDWARFSECT)
syms = append(syms, gs)
u.AddUint8(1) // magic 1 byte? u.AddUint8(1) // magic 1 byte?
u.Addstring(gdbscript) u.Addstring(gdbscript)
} return dwarfSecInfo{syms: []loader.Sym{gs}}
return syms
} }
// FIXME: might be worth looking replacing this map with a function // FIXME: might be worth looking replacing this map with a function
@ -1976,8 +2006,8 @@ func dwarfGenerateDebugSyms(ctxt *Link) {
} }
func (d *dwctxt2) dwarfGenerateDebugSyms() { func (d *dwctxt2) dwarfGenerateDebugSyms() {
abbrev := d.writeabbrev() abbrevSec := d.writeabbrev()
syms := []loader.Sym{abbrev} dwarfp2 = append(dwarfp2, abbrevSec)
d.calcCompUnitRanges() d.calcCompUnitRanges()
sort.Sort(compilationUnitByStartPC(d.linkctxt.compUnits)) sort.Sort(compilationUnitByStartPC(d.linkctxt.compUnits))
@ -1987,7 +2017,7 @@ func (d *dwctxt2) dwarfGenerateDebugSyms() {
dlu := d.ldr.MakeSymbolUpdater(debugLine) dlu := d.ldr.MakeSymbolUpdater(debugLine)
dlu.SetType(sym.SDWARFSECT) dlu.SetType(sym.SDWARFSECT)
d.ldr.SetAttrReachable(debugLine, true) d.ldr.SetAttrReachable(debugLine, true)
syms = append(syms, debugLine) dwarfp2 = append(dwarfp2, dwarfSecInfo{syms: []loader.Sym{debugLine}})
debugRanges := d.ldr.LookupOrCreateSym(".debug_ranges", 0) debugRanges := d.ldr.LookupOrCreateSym(".debug_ranges", 0)
dru := d.ldr.MakeSymbolUpdater(debugRanges) dru := d.ldr.MakeSymbolUpdater(debugRanges)
@ -2014,27 +2044,34 @@ func (d *dwctxt2) dwarfGenerateDebugSyms() {
pubNames := newPubWriter2(d, ".debug_pubnames") pubNames := newPubWriter2(d, ".debug_pubnames")
pubTypes := newPubWriter2(d, ".debug_pubtypes") pubTypes := newPubWriter2(d, ".debug_pubtypes")
// Need to reorder symbols so sym.SDWARFINFO is after all sym.SDWARFSECT infoSec := d.writeinfo(d.linkctxt.compUnits, abbrevSec.secSym(), pubNames, pubTypes)
infosyms := d.writeinfo(nil, d.linkctxt.compUnits, abbrev, pubNames, pubTypes)
syms = d.writeframes(syms) framesSec := d.writeframes()
syms = append(syms, pubNames.s, pubTypes.s) dwarfp2 = append(dwarfp2, framesSec)
syms = d.writegdbscript(syms) dwarfp2 = append(dwarfp2, dwarfSecInfo{syms: []loader.Sym{pubNames.s}})
// We are now done writing SDWARFSECT symbols, so we can write dwarfp2 = append(dwarfp2, dwarfSecInfo{syms: []loader.Sym{pubTypes.s}})
// other SDWARF* symbols. gdbScriptSec := d.writegdbscript()
syms = append(syms, infosyms...) if gdbScriptSec.secSym() != 0 {
syms = d.collectlocs(syms, d.linkctxt.compUnits) dwarfp2 = append(dwarfp2, gdbScriptSec)
syms = append(syms, debugRanges) }
dwarfp2 = append(dwarfp2, infoSec)
locSec := d.collectlocs(d.linkctxt.compUnits)
if locSec.secSym() != 0 {
dwarfp2 = append(dwarfp2, locSec)
}
rsyms := []loader.Sym{debugRanges}
for _, unit := range d.linkctxt.compUnits { for _, unit := range d.linkctxt.compUnits {
for _, s := range unit.RangeSyms2 { for _, s := range unit.RangeSyms2 {
syms = append(syms, loader.Sym(s)) rsyms = append(rsyms, loader.Sym(s))
} }
} }
dwarfp2 = syms dwarfp2 = append(dwarfp2, dwarfSecInfo{syms: rsyms})
} }
func (d *dwctxt2) collectlocs(syms []loader.Sym, units []*sym.CompilationUnit) []loader.Sym { func (d *dwctxt2) collectlocs(units []*sym.CompilationUnit) dwarfSecInfo {
empty := true empty := true
syms := []loader.Sym{}
for _, u := range units { for _, u := range units {
for _, fn := range u.FuncDIEs2 { for _, fn := range u.FuncDIEs2 {
relocs := d.ldr.Relocs(loader.Sym(fn)) relocs := d.ldr.Relocs(loader.Sym(fn))
@ -2057,14 +2094,15 @@ func (d *dwctxt2) collectlocs(syms []loader.Sym, units []*sym.CompilationUnit) [
} }
// Don't emit .debug_loc if it's empty -- it makes the ARM linker mad. // Don't emit .debug_loc if it's empty -- it makes the ARM linker mad.
if !empty { if empty {
return dwarfSecInfo{}
}
locsym := d.ldr.LookupOrCreateSym(".debug_loc", 0) locsym := d.ldr.LookupOrCreateSym(".debug_loc", 0)
u := d.ldr.MakeSymbolUpdater(locsym) u := d.ldr.MakeSymbolUpdater(locsym)
u.SetType(sym.SDWARFLOC) u.SetType(sym.SDWARFLOC)
d.ldr.SetAttrReachable(locsym, true) d.ldr.SetAttrReachable(locsym, true)
syms = append(syms, locsym) return dwarfSecInfo{syms: append([]loader.Sym{locsym}, syms...)}
}
return syms
} }
/* /*

View file

@ -24,7 +24,27 @@ func isDwarf64(ctxt *Link) bool {
return ctxt.HeadType == objabi.Haix return ctxt.HeadType == objabi.Haix
} }
var dwarfp []*sym.Symbol // dwarfSecInfo2 is a replica of the dwarfSecInfo struct but with
// *sym.Symbol content instead of loader.Sym content.
type dwarfSecInfo2 struct {
syms []*sym.Symbol
}
func (dsi *dwarfSecInfo2) secSym() *sym.Symbol {
if len(dsi.syms) == 0 {
return nil
}
return dsi.syms[0]
}
func (dsi *dwarfSecInfo2) subSyms() []*sym.Symbol {
if len(dsi.syms) == 0 {
return []*sym.Symbol{}
}
return dsi.syms[1:]
}
var dwarfp []dwarfSecInfo2
/* /*
* Elf. * Elf.
@ -89,19 +109,13 @@ func dwarfcompress(ctxt *Link) {
return return
} }
var start, compressedCount int var compressedCount int
resChannel := make(chan compressedSect) resChannel := make(chan compressedSect)
for i, s := range dwarfp { for i := range dwarfp {
// Find the boundaries between sections and compress
// the whole section once we've found the last of its
// symbols.
if i+1 >= len(dwarfp) || s.Sect != dwarfp[i+1].Sect {
go func(resIndex int, syms []*sym.Symbol) { go func(resIndex int, syms []*sym.Symbol) {
resChannel <- compressedSect{resIndex, compressSyms(ctxt, syms), syms} resChannel <- compressedSect{resIndex, compressSyms(ctxt, syms), syms}
}(compressedCount, dwarfp[start:i+1]) }(compressedCount, dwarfp[i].syms)
compressedCount++ compressedCount++
start = i + 1
}
} }
res := make([]compressedSect, compressedCount) res := make([]compressedSect, compressedCount)
for ; compressedCount > 0; compressedCount-- { for ; compressedCount > 0; compressedCount-- {
@ -109,13 +123,14 @@ func dwarfcompress(ctxt *Link) {
res[r.index] = r res[r.index] = r
} }
var newDwarfp []*sym.Symbol var newDwarfp []dwarfSecInfo2
Segdwarf.Sections = Segdwarf.Sections[:0] Segdwarf.Sections = Segdwarf.Sections[:0]
for _, z := range res { for _, z := range res {
s := z.syms[0] s := z.syms[0]
if z.compressed == nil { if z.compressed == nil {
// Compression didn't help. // Compression didn't help.
newDwarfp = append(newDwarfp, z.syms...) ds := dwarfSecInfo2{syms: z.syms}
newDwarfp = append(newDwarfp, ds)
Segdwarf.Sections = append(Segdwarf.Sections, s.Sect) Segdwarf.Sections = append(Segdwarf.Sections, s.Sect)
} else { } else {
compressedSegName := ".zdebug_" + s.Sect.Name[len(".debug_"):] compressedSegName := ".zdebug_" + s.Sect.Name[len(".debug_"):]
@ -125,7 +140,8 @@ func dwarfcompress(ctxt *Link) {
newSym.P = z.compressed newSym.P = z.compressed
newSym.Size = int64(len(z.compressed)) newSym.Size = int64(len(z.compressed))
newSym.Sect = sect newSym.Sect = sect
newDwarfp = append(newDwarfp, newSym) ds := dwarfSecInfo2{syms: []*sym.Symbol{newSym}}
newDwarfp = append(newDwarfp, ds)
} }
} }
dwarfp = newDwarfp dwarfp = newDwarfp
@ -135,7 +151,8 @@ func dwarfcompress(ctxt *Link) {
// based on Section.Vaddr and Symbol.Value. // based on Section.Vaddr and Symbol.Value.
pos := Segdwarf.Vaddr pos := Segdwarf.Vaddr
var prevSect *sym.Section var prevSect *sym.Section
for _, s := range dwarfp { for _, si := range dwarfp {
for _, s := range si.syms {
s.Value = int64(pos) s.Value = int64(pos)
if s.Sect != prevSect { if s.Sect != prevSect {
s.Sect.Vaddr = uint64(s.Value) s.Sect.Vaddr = uint64(s.Value)
@ -148,7 +165,7 @@ func dwarfcompress(ctxt *Link) {
if ctxt.HeadType == objabi.Hwindows { if ctxt.HeadType == objabi.Hwindows {
pos = uint64(Rnd(int64(pos), PEFILEALIGN)) pos = uint64(Rnd(int64(pos), PEFILEALIGN))
} }
}
} }
Segdwarf.Length = pos - Segdwarf.Vaddr Segdwarf.Length = pos - Segdwarf.Vaddr
} }

View file

@ -1447,8 +1447,14 @@ func Elfemitreloc(ctxt *Link) {
for _, sect := range Segdata.Sections { for _, sect := range Segdata.Sections {
elfrelocsect(ctxt, sect, ctxt.datap) elfrelocsect(ctxt, sect, ctxt.datap)
} }
for _, sect := range Segdwarf.Sections { for i := 0; i < len(Segdwarf.Sections); i++ {
elfrelocsect(ctxt, sect, dwarfp) sect := Segdwarf.Sections[i]
si := dwarfp[i]
if si.secSym() != sect.Sym ||
si.secSym().Sect != sect {
panic("inconsistency between dwarfp and Segdwarf")
}
elfrelocsect(ctxt, sect, si.syms)
} }
} }
@ -2230,11 +2236,10 @@ elfobj:
for _, sect := range Segdata.Sections { for _, sect := range Segdata.Sections {
elfshreloc(ctxt.Arch, sect) elfshreloc(ctxt.Arch, sect)
} }
for _, s := range dwarfp { for _, si := range dwarfp {
if len(s.R) > 0 || s.Type == sym.SDWARFINFO || s.Type == sym.SDWARFLOC { s := si.secSym()
elfshreloc(ctxt.Arch, s.Sect) elfshreloc(ctxt.Arch, s.Sect)
} }
}
// add a .note.GNU-stack section to mark the stack as non-executable // add a .note.GNU-stack section to mark the stack as non-executable
sh := elfshname(".note.GNU-stack") sh := elfshname(".note.GNU-stack")

View file

@ -2820,14 +2820,19 @@ func (ctxt *Link) loadlibfull() {
pclntabFirstFunc = ctxt.loader.Syms[pclntabFirstFunc2] pclntabFirstFunc = ctxt.loader.Syms[pclntabFirstFunc2]
pclntabLastFunc = ctxt.loader.Syms[pclntabLastFunc2] pclntabLastFunc = ctxt.loader.Syms[pclntabLastFunc2]
// Populate dwarfp from dwarfp2. If we see a symbol index on dwarfp2 // Populate dwarfp from dwarfp2. If we see a symbol index
// whose loader.Syms entry is nil, something went wrong. // whose loader.Syms entry is nil, something went wrong.
for _, symIdx := range dwarfp2 { for _, si := range dwarfp2 {
syms := make([]*sym.Symbol, 0, len(si.syms))
for _, symIdx := range si.syms {
s := ctxt.loader.Syms[symIdx] s := ctxt.loader.Syms[symIdx]
if s == nil { if s == nil {
panic(fmt.Sprintf("nil sym for dwarfp2 element %d", symIdx)) panic(fmt.Sprintf("nil sym for dwarfp2 element %d", symIdx))
} }
dwarfp = append(dwarfp, s) s.Attr |= sym.AttrLocal
syms = append(syms, s)
}
dwarfp = append(dwarfp, dwarfSecInfo2{syms: syms})
} }
} }

View file

@ -1065,8 +1065,14 @@ func Machoemitreloc(ctxt *Link) {
for _, sect := range Segdata.Sections { for _, sect := range Segdata.Sections {
machorelocsect(ctxt, sect, ctxt.datap) machorelocsect(ctxt, sect, ctxt.datap)
} }
for _, sect := range Segdwarf.Sections { for i := 0; i < len(Segdwarf.Sections); i++ {
machorelocsect(ctxt, sect, dwarfp) sect := Segdwarf.Sections[i]
si := dwarfp[i]
if si.secSym() != sect.Sym ||
si.secSym().Sect != sect {
panic("inconsistency between dwarfp and Segdwarf")
}
machorelocsect(ctxt, sect, si.syms)
} }
} }

View file

@ -557,11 +557,17 @@ func (f *peFile) emitRelocations(ctxt *Link) {
} }
dwarfLoop: dwarfLoop:
for _, sect := range Segdwarf.Sections { for i := 0; i < len(Segdwarf.Sections); i++ {
sect := Segdwarf.Sections[i]
si := dwarfp[i]
if si.secSym() != sect.Sym ||
si.secSym().Sect != sect {
panic("inconsistency between dwarfp and Segdwarf")
}
for _, pesect := range f.sections { for _, pesect := range f.sections {
if sect.Name == pesect.name { if sect.Name == pesect.name {
pesect.emitRelocations(ctxt.Out, func() int { pesect.emitRelocations(ctxt.Out, func() int {
return relocsect(sect, dwarfp, sect.Vaddr) return relocsect(sect, si.syms, sect.Vaddr)
}) })
continue dwarfLoop continue dwarfLoop
} }

View file

@ -1657,12 +1657,18 @@ func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
} }
dwarfLoop: dwarfLoop:
for _, sect := range Segdwarf.Sections { for i := 0; i < len(Segdwarf.Sections); i++ {
sect := Segdwarf.Sections[i]
si := dwarfp[i]
if si.secSym() != sect.Sym ||
si.secSym().Sect != sect {
panic("inconsistency between dwarfp and Segdwarf")
}
for _, xcoffSect := range f.sections { for _, xcoffSect := range f.sections {
_, subtyp := xcoffGetDwarfSubtype(sect.Name) _, subtyp := xcoffGetDwarfSubtype(sect.Name)
if xcoffSect.Sflags&0xF0000 == subtyp { if xcoffSect.Sflags&0xF0000 == subtyp {
xcoffSect.Srelptr = uint64(ctxt.Out.Offset()) xcoffSect.Srelptr = uint64(ctxt.Out.Offset())
xcoffSect.Snreloc = relocsect(sect, dwarfp, sect.Vaddr) xcoffSect.Snreloc = relocsect(sect, si.syms, sect.Vaddr)
continue dwarfLoop continue dwarfLoop
} }
} }