}
ldr := ctxt.loader
- // .got (and .toc on ppc64)
+ // .got
if len(state.data[sym.SELFGOT]) > 0 {
- sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06)
- if ctxt.IsPPC64() {
- for _, s := range state.data[sym.SELFGOT] {
- // Resolve .TOC. symbol for this object file (ppc64)
-
- toc := ldr.Lookup(".TOC.", int(ldr.SymVersion(s)))
- if toc != 0 {
- ldr.SetSymSect(toc, sect)
- ldr.AddInteriorSym(s, toc)
- ldr.SetSymValue(toc, 0x8000)
- }
- }
- }
+ state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06)
}
/* pointer-free data */
ldr.SetSymSect(ldr.Lookup("_end", 0), ldr.SymSect(end))
}
+ if ctxt.IsPPC64() && ctxt.IsElf() {
+ // Resolve .TOC. symbols for all objects. Only one TOC region is supported. If a
+ // GOT section is present, compute it as suggested by the ELFv2 ABI. Otherwise,
+ // choose a similar offset from the start of the data segment.
+ tocAddr := int64(Segdata.Vaddr) + 0x8000
+ if gotAddr := ldr.SymValue(ctxt.GOT); gotAddr != 0 {
+ tocAddr = gotAddr + 0x8000
+ }
+ for i, _ := range ctxt.DotTOC {
+ if i >= sym.SymVerABICount && i < sym.SymVerStatic { // these versions are not used currently
+ continue
+ }
+ if toc := ldr.Lookup(".TOC.", i); toc != 0 {
+ ldr.SetSymValue(toc, tocAddr)
+ }
+ }
+ }
+
return order
}
if ctxt.IsPPC64() {
ctxt.mkArchSym("TOC", 0, &ctxt.TOC)
- // NB: note the +2 below for DotTOC2 compared to the +1 for
- // DocTOC. This is because loadlibfull() creates an additional
- // syms version during conversion of loader.Sym symbols to
- // *sym.Symbol symbols. Symbols that are assigned this final
- // version are not going to have TOC references, so it should
- // be ok for them to inherit an invalid .TOC. symbol.
- // TODO: revisit the +2, now that loadlibfull is gone.
- ctxt.DotTOC = make([]loader.Sym, ctxt.MaxVersion()+2)
+ ctxt.DotTOC = make([]loader.Sym, ctxt.MaxVersion()+1)
for i := 0; i <= ctxt.MaxVersion(); i++ {
- if i >= 2 && i < sym.SymVerStatic { // these versions are not used currently
+ if i >= sym.SymVerABICount && i < sym.SymVerStatic { // these versions are not used currently
continue
}
ctxt.mkArchSymVec(".TOC.", i, ctxt.DotTOC)