Alpha linker rejects unsupported IFUNC relocation types
Alpha linker now rejects relocations like R_ALPHA_BRADDR and R_ALPHA_REFLONG when used with IFUNCs, preventing incorrect linking.
This commit updates the Alpha linker to reject specific relocation types that cannot correctly refer to IFUNC symbols. Relocations such as R_ALPHA_BRADDR, R_ALPHA_BRSGP, general GP-relative relocations, and R_ALPHA_SREL* directly name the symbol, bypassing the IFUNC resolver. R_ALPHA_REFLONG only has a 32-bit field, insufficient for the resolver’s return address. These invalid relocations are now reported, allowing the linker to report all such errors in a single pass.
In Details
This change implements checks in bfd/elf64-alpha.c to reject relocation types that are incompatible with IFUNC references. IFUNCs require the R_ALPHA_IRELATIVE relocation to store the resolver's address, or a GOT entry. Relocations that directly reference the symbol (e.g., R_ALPHA_BRADDR, R_ALPHA_BRSGP, GP-relative, R_ALPHA_SREL*) do not go through the IFUNC mechanism. R_ALPHA_REFLONG is also incompatible due to its limited 32-bit field. These invalid relocations are diagnosed and reported to the user, enabling the linker to list all such errors during a single link operation.
- IFUNC
- Indirect Function. A mechanism that allows a function call to be resolved at runtime to one of potentially several implementations, typically based on system features or hardware capabilities. This is also known as
GNU_IFUNC. - relocation
- Information in an object file that describes how to modify addresses and other values when linking. Relocations are necessary to correctly place code and data in memory, especially when dealing with shared libraries or position-independent code.
- R_ALPHA_IRELATIVE
- An ELF relocation type specific to the Alpha architecture, used for indirect function calls. It indicates that the relocation value should be the address of the symbol plus an addend, which is typically used to calculate the address of the IFUNC resolver.
- R_ALPHA_BRADDR
- An Alpha-specific ELF relocation type, likely used for branch targets.
- R_ALPHA_REFLONG
- An Alpha-specific ELF relocation type, likely for referencing a long symbol.
- GP-relative relocation
- A type of relocation where the target address is calculated relative to the Global Pointer (GP) register. This is common in some architectures for accessing data efficiently.