if weak && !ldr.AttrReachable(rs) {
continue
}
+ if ldr.SymSect(rs) == nil {
+ st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(rs))
+ continue
+ }
+
// The method offset tables using this relocation expect the offset to be relative
// to the start of the first text section, even if there are multiple.
if ldr.SymSect(rs).Name == ".text" {
}
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
}