// we keep a subset for relocation application.
type ArchSyms struct {
TOC *sym.Symbol
- DotTOC *sym.Symbol
+ DotTOC []*sym.Symbol // for each version
+
GOT *sym.Symbol
PLT *sym.Symbol
GOTPLT *sym.Symbol
// setArchSyms sets up the ArchSyms structure, and must be called before
// relocations are applied.
func (ctxt *Link) setArchSyms() {
- ctxt.TOC = ctxt.Syms.Lookup("TOC", 0)
- ctxt.DotTOC = ctxt.Syms.Lookup(".TOC.", 0)
ctxt.GOT = ctxt.Syms.Lookup(".got", 0)
ctxt.PLT = ctxt.Syms.Lookup(".plt", 0)
ctxt.GOTPLT = ctxt.Syms.Lookup(".got.plt", 0)
ctxt.Dynamic = ctxt.Syms.Lookup(".dynamic", 0)
ctxt.DynSym = ctxt.Syms.Lookup(".dynsym", 0)
ctxt.DynStr = ctxt.Syms.Lookup(".dynstr", 0)
+
+ if ctxt.IsAIX() {
+ ctxt.TOC = ctxt.Syms.Lookup("TOC", 0)
+ ctxt.DotTOC = make([]*sym.Symbol, ctxt.Syms.MaxVersion()+1)
+ for i := 0; i <= ctxt.Syms.MaxVersion(); i++ {
+ if i >= 2 && i < sym.SymVerStatic { // these versions are not used currently
+ continue
+ }
+ ctxt.DotTOC[i] = ctxt.Syms.Lookup(".TOC.", i)
+ }
+ }
}
type Arch struct {
return false
}
+// Return the value of .TOC. for symbol s
+func symtoc(syms *ld.ArchSyms, s *sym.Symbol) int64 {
+ v := s.Version
+ if s.Outer != nil {
+ v = s.Outer.Version
+ }
+
+ toc := syms.DotTOC[v]
+ if toc == nil {
+ ld.Errorf(s, "TOC-relative relocation in object without .TOC.")
+ return 0
+ }
+
+ return toc.Value
+}
+
// archreloctoc relocates a TOC relative symbol.
// If the symbol pointed by this TOC relative symbol is in .data or .bss, the
// default load instruction can be changed to an addi instruction and the
}
return val | int64(uint32(t)&^0xfc000003), true
case objabi.R_POWER_TOC: // S + A - .TOC.
- return ld.Symaddr(r.Sym) + r.Add - syms.DotTOC.Value, true
+ return ld.Symaddr(r.Sym) + r.Add - symtoc(syms, s), true
case objabi.R_POWER_TLS_LE:
// The thread pointer points 0x7000 bytes after the start of the