case 8:
o = int64(target.Arch.ByteOrder.Uint64(P[off:]))
}
- var out int64
- var ok bool
- out, needExtReloc, ok = thearch.Archreloc2(target, ldr, syms, &r, &rr, s, o)
+ var rp *loader.ExtReloc
+ if target.IsExternal() {
+ // Don't pass &rr directly to Archreloc2, which will escape rr
+ // even if this case is not taken. Instead, as Archreloc2 will
+ // likely return true, we speculatively add rr to extRelocs
+ // and use that space to pass to Archreloc2.
+ extRelocs = append(extRelocs, rr)
+ rp = &extRelocs[len(extRelocs)-1]
+ }
+ out, needExtReloc1, ok := thearch.Archreloc2(target, ldr, syms, r, rp, s, o)
+ if target.IsExternal() && !needExtReloc1 {
+ // Speculation failed. Undo the append.
+ extRelocs = extRelocs[:len(extRelocs)-1]
+ }
+ needExtReloc = false // already appended
if ok {
o = out
} else {
// indicates a fatal error).
Archreloc func(target *Target, syms *ArchSyms, rel *sym.Reloc, sym *sym.Symbol,
offset int64) (relocatedOffset int64, success bool)
- Archreloc2 func(*Target, *loader.Loader, *ArchSyms, *loader.Reloc2, *loader.ExtReloc, loader.Sym, int64) (int64, bool, bool)
+ Archreloc2 func(*Target, *loader.Loader, *ArchSyms, loader.Reloc2, *loader.ExtReloc, loader.Sym, int64) (int64, bool, bool)
// Archrelocvariant is a second arch-specific hook used for
// relocation processing; it handles relocations where r.Type is
// insufficient to describe the relocation (r.Variant !=
return true
}
-func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r *loader.Reloc2, rr *loader.ExtReloc, sym loader.Sym, val int64) (int64, bool, bool) {
+func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, sym loader.Sym, val int64) (int64, bool, bool) {
return val, false, false
}