AArch64: Optimize zero-valued ADRP relocations for undefined weak symbols
Optimizes zero-valued ADRP relocations for undefined weak symbols on AArch64 by rewriting them as MOVZ, also addressing Cortex-A53 erratum 843419.
This patch introduces an optimization for AArch64 by rewriting zero-valued ADRP relocations targeting undefined weak symbols as MOVZ instructions. This optimization preserves the destination register and honors the --no-relax flag. Additionally, it addresses a Cortex-A53 erratum 843419 by clearing pending entries when an ADRP is rewritten. The change includes new test cases for LP64 and ILP32 modes.
In Details
The AArch64 ELF loader permits ADRP (Add upper address, page) relocations against undefined weak symbols to be emitted as a MOV instruction with a zero immediate. This patch optimizes this by rewriting such ADRP instructions as MOVZ (Move immediate, zero-extended) when the page value is zero. This is particularly relevant for code generation on AArch64, where instruction encoding size and runtime performance are critical. The patch also handles a specific CPU erratum (Cortex-A53 erratum 843419) that is triggered by ADRP instructions in certain contexts.
- ADRP
- Add upper address, page. An AArch64 instruction used to set the high bits of an address, typically for position-independent code.
- RELOCATIONS
- Information in an object file that describes how to modify addresses when linking or loading.
- UNDEFINED WEAK SYMBOLS
- Symbols that are declared weak (meaning they can be overridden by a non-weak symbol) and have no definition provided, acting as placeholders.
- MOVZ
- Move immediate, zero-extended. An AArch64 instruction that moves an immediate value into a register, zero-extending it.
- --no-relax
- A linker option that prevents the linker from adjusting certain relocation values, preserving their original form.
- Cortex-A53 erratum 843419
- A specific hardware bug in the Cortex-A53 processor that affects ADRP instructions in certain scenarios.
- LP64
- A data model where
longand pointers are 64 bits wide, andintis 32 bits. Common on 64-bit Unix-like systems. - ILP32
- A data model where
int,long, and pointers are all 32 bits wide. It is a subset of LP64 and is used on some 64-bit architectures to maintain compatibility.