break
}
+ // Compute external relocations on the go, and pass to Xcoffreloc1 to stream out.
// Relocation must be ordered by address, so create a list of sorted indices.
- relocs := ldr.ExtRelocs(s)
+ relocs := ldr.Relocs(s)
sorted := make([]int, relocs.Count())
for i := 0; i < relocs.Count(); i++ {
sorted[i] = i
}
sort.Slice(sorted, func(i, j int) bool {
- return relocs.At(sorted[i]).Off() < relocs.At(sorted[j]).Off()
+ return relocs.At2(sorted[i]).Off() < relocs.At2(sorted[j]).Off()
})
for _, ri := range sorted {
- r := relocs.At(ri)
-
- if r.Xsym == 0 {
+ r := relocs.At2(ri)
+ rr, ok := extreloc(ctxt, ldr, s, r, ri)
+ if !ok {
+ continue
+ }
+ if rr.Xsym == 0 {
ldr.Errorf(s, "missing xsym in relocation")
continue
}
- if ldr.SymDynid(r.Xsym) < 0 {
- ldr.Errorf(s, "reloc %s to non-coff symbol %s (outer=%s) %d %d", r.Type(), ldr.SymName(r.Sym()), ldr.SymName(r.Xsym), ldr.SymType(r.Sym()), ldr.SymDynid(r.Xsym))
+ if ldr.SymDynid(rr.Xsym) < 0 {
+ ldr.Errorf(s, "reloc %s to non-coff symbol %s (outer=%s) %d %d", r.Type(), ldr.SymName(r.Sym()), ldr.SymName(rr.Xsym), ldr.SymType(r.Sym()), ldr.SymDynid(rr.Xsym))
}
- if !thearch.Xcoffreloc1(ctxt.Arch, ctxt.Out, ldr, s, r, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-base)) {
+ rv := loader.ExtRelocView{Reloc2: r, ExtReloc: rr}
+ if !thearch.Xcoffreloc1(ctxt.Arch, ctxt.Out, ldr, s, rv, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-base)) {
ldr.Errorf(s, "unsupported obj reloc %d(%s)/%d to %s", r.Type(), r.Type(), r.Siz(), ldr.SymName(r.Sym()))
}
}
// value with the current addresses.
switch rt := r.Type(); rt {
default:
- if target.IsAIX() {
+ if !target.IsAIX() {
return val, nExtReloc, false
}
case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
if rt == objabi.R_POWER_TLS_IE {
nExtReloc = 2 // need two ELF relocations, see elfreloc1
}
- rr.Xadd = r.Add()
- rr.Xsym = rs
return val, nExtReloc, true
case objabi.R_ADDRPOWER,
objabi.R_ADDRPOWER_DS,
objabi.R_ADDRPOWER_GOT,
objabi.R_ADDRPOWER_PCREL:
nExtReloc = 2 // need two ELF relocations, see elfreloc1
-
- // set up addend for eventual relocation via outer symbol.
- rs, off := ld.FoldSubSymbolOffset(ldr, rs)
- rr.Xadd = r.Add() + off
- rst := ldr.SymType(rs)
- if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
- ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
- }
- rr.Xsym = rs
-
if !target.IsAIX() {
return val, nExtReloc, true
}
case objabi.R_CALLPOWER:
nExtReloc = 1
- rr.Xsym = rs
- rr.Xadd = r.Add()
if !target.IsAIX() {
return val, nExtReloc, true
}
return t
}
+func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc2, s loader.Sym) (loader.ExtReloc, bool) {
+ rs := ldr.ResolveABIAlias(r.Sym())
+ var rr loader.ExtReloc
+ switch r.Type() {
+ case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
+ rr.Xadd = r.Add()
+ rr.Xsym = rs
+ return rr, true
+ case objabi.R_ADDRPOWER,
+ objabi.R_ADDRPOWER_DS,
+ objabi.R_ADDRPOWER_TOCREL,
+ objabi.R_ADDRPOWER_TOCREL_DS,
+ objabi.R_ADDRPOWER_GOT,
+ objabi.R_ADDRPOWER_PCREL:
+ // set up addend for eventual relocation via outer symbol.
+ rs, off := ld.FoldSubSymbolOffset(ldr, rs)
+ rr.Xadd = r.Add() + off
+ rst := ldr.SymType(rs)
+ if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
+ ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
+ }
+ rr.Xsym = rs
+ return rr, true
+ case objabi.R_CALLPOWER:
+ rr.Xsym = rs
+ rr.Xadd = r.Add()
+ return rr, true
+ }
+ return rr, false
+}
+
func addpltsym(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym) {
if ldr.SymPlt(s) >= 0 {
return