The existing code for IRELATIVE relocations in ARM uses the built-in support by setting Target->IRelativeRel to R_ARM_IRELATIVE.
Unfortunately when trying to run a lld produced executable with an IRELATIVE relocation using the glibc dynamic loader ld-linux-armhf.so.3 I get an "unexpected PLT reloc type" error message.
Looking into sysdeps/arm/dl-machine.h it seems like R_ARM_IRELATIVE is only supported in the rel.dyn section of the PLT. This is probably a legacy of ARM having a single .got section.
This change does the following for ARM targets:
- Puts the got entry used by the IRELATIVE relocation into .got rather than .got.plt
- Puts the IRELATIVE relocation into .rel.dyn rather than .rel.plt
- defines rel_iplt_start and rel_iplt_end around .rel.dyn rather than .rel.plt
- Always adds .rel.dyn when there are IRELATIVE relocations even when static linking. This follows the same pattern as .rel.plt
- Passes the GotVA of the symbol to the PLT generation code rather than the GotPltVA for an ARM IRelative relocation
- If there is no .got.plt section (static linking) then use a dummy zero address for the PLT header as there is no .got.plt address.
Review questions:
- This patch is a bit messy, but I've not got many ideas that would make it much cleaner. It is possible that some of the tests could be moved into functions and they could be abstracted away from ARM, for example if (Target->IRelInPLT) ...
- On ARM GNU ld can use an auxiliary PLT OutputSection called .iplt exclusively for ifuncs. Following this implementation choice might make the implementation a little cleaner in some places but it would probably mean more code-changes overall.
- It could be possible to not output the PLT header if there are only IRELATIVE entries, this would mean changing some code that has assumptions that there is always a PLT header.
Unfortunately the static glibc has an IRELATIVE relocation for memcpy on ARM so anyone trying to do static linking will hit the error message.
dl-machine.h reference:
https://fossies.org/dox/glibc-2.24/arm_2dl-machine_8h_source.html
The .rel.plt code is elf_machine_lazy_rel() at the bottom of the file. The .rel.dyn is elf_machine_rela()
x86_64, x86_32 and AArch64 has IRELATIVE support in both functions, ppc64 like ARM only has support in rel.dyn. The lld support for ppc doesn't support IRELATIVE so there isn't anything broken there.