}
if ctxt.IsELF {
- // TODO: We generate a R_X86_64_64 relocation for every R_ADDR, even
- // though it would be more efficient (for the dynamic linker) if we
- // generated R_X86_RELATIVE instead.
- ld.Adddynsym(ctxt, targ)
+ // Generate R_X86_64_RELATIVE relocations for best
+ // efficiency in the dynamic linker.
+ //
+ // As noted above, symbol addresses have not been
+ // assigned yet, so we can't generate the final reloc
+ // entry yet. We ultimately want:
+ //
+ // r_offset = s + r.Off
+ // r_info = R_X86_64_RELATIVE
+ // r_addend = targ + r.Add
+ //
+ // The dynamic linker will set *offset = base address +
+ // addend.
+ //
+ // AddAddrPlus is used for r_offset and r_addend to
+ // generate new R_ADDR relocations that will update
+ // these fields in the 'reloc' phase.
rela := ctxt.Syms.Lookup(".rela", 0)
rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
if r.Siz == 8 {
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_X86_64_64)))
+ rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_X86_64_RELATIVE)))
} else {
- // TODO: never happens, remove.
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_X86_64_32)))
+ ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
}
- rela.AddUint64(ctxt.Arch, uint64(r.Add))
+ rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
r.Type = objabi.ElfRelocOffset // ignore during relocsym
return true
}
}
if ctxt.IsELF {
- // TODO: We generate a R_AARCH64_ABS64 relocation for every R_ADDR, even
- // though it would be more efficient (for the dynamic linker) if we
- // generated R_AARCH64_RELATIVE instead.
- ld.Adddynsym(ctxt, targ)
+ // Generate R_AARCH64_RELATIVE relocations for best
+ // efficiency in the dynamic linker.
+ //
+ // As noted above, symbol addresses have not been
+ // assigned yet, so we can't generate the final reloc
+ // entry yet. We ultimately want:
+ //
+ // r_offset = s + r.Off
+ // r_info = R_AARCH64_RELATIVE
+ // r_addend = targ + r.Add
+ //
+ // The dynamic linker will set *offset = base address +
+ // addend.
+ //
+ // AddAddrPlus is used for r_offset and r_addend to
+ // generate new R_ADDR relocations that will update
+ // these fields in the 'reloc' phase.
rela := ctxt.Syms.Lookup(".rela", 0)
rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
if r.Siz == 8 {
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_AARCH64_ABS64)))
+ rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_AARCH64_RELATIVE)))
} else {
ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
}
- rela.AddUint64(ctxt.Arch, uint64(r.Add))
+ rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
r.Type = objabi.ElfRelocOffset // ignore during relocsym
return true
}