1. AArch64 Relocation Reference
1.1. Introduction
AArch64 relocation operators such as :abs_g0_nc:, :pg_hi21:, and :lo12: instruct the assembler and linker how to encode symbol references into instruction immediate fields.
1.2. Relocation Conventions
Symbol |
Meaning |
|---|---|
|
Runtime address of referenced symbol |
|
Relocation addend |
|
Address of relocation site |
|
Relocation result before masking |
|
|
|
Global Offset Table |
1.3. Group Relocations
1.3.1. Unsigned Absolute Relocations
Operator |
Relocation |
Operation |
Inst |
Bits |
Range Check |
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
none |
|
|
|
|
|
|
|
|
|
|
|
none |
|
|
|
|
|
|
|
|
|
|
|
none |
|
|
|
|
|
none |
1.3.2. Signed Absolute Relocations
Operator |
Relocation |
Operation |
Inst |
Bits |
Range Check |
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1.3.3. Example: Building a 64-bit Constant
movz x1, #:abs_g3:u64
movk x1, #:abs_g2_nc:u64
movk x1, #:abs_g1_nc:u64
movk x1, #:abs_g0_nc:u64
1.4. PC-Relative Address Relocations
Operator |
Relocation |
Expression |
Instruction |
Encoded Bits |
Range Check |
Alignment |
|---|---|---|---|---|---|---|
implicit |
|
|
literal |
|
|
|
implicit |
|
|
|
|
|
none |
|
|
|
|
|
|
none |
|
|
|
|
|
none |
none |
LD_PREL_LO19alignment: The literalldrinstruction addresses 4-byte-aligned literals;X(S+A-P) must therefore be divisible by 4. The linker encodesX >> 2into the 19-bit field and emits a warning ifX & 3 != 0.
1.4.1. Typical ADRP + ADD Sequence
adrp x0, :pg_hi21:foo
add x0, x0, #:lo12:foo
1.5. Low 12-bit Relocations
Operator |
Relocation |
Used By |
Immediate Extracted |
|---|---|---|---|
|
|
|
|
|
|
byte loads/stores |
|
|
|
halfword loads/stores |
|
|
|
word loads/stores |
|
|
|
doubleword loads/stores |
|
|
|
128-bit accesses |
|
1.6. Control Flow Relocations
Relocation |
Instruction |
Expression |
Encoded Bits |
Reach |
Alignment |
Out-of-range |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
error |
|
|
|
|
|
|
error |
|
|
|
|
|
|
trampoline |
|
|
|
|
|
|
trampoline |
Alignment: All four control-flow relocations encode
X >> 2into their immediate field, soX(S+A-P) must be divisible by 4. The linker emits an error ifX & 3 != 0.Out-of-range (
JUMP26/CALL26): When the branch target is beyond ±128 MB the linker inserts a trampoline stub for range extension rather than reporting an overflow error.TSTBR14andCONDBR19have no trampoline support; exceeding their range is a hard error.
1.7. Common Prefix Cheat Sheet
Prefix |
Meaning |
|---|---|
|
Bits 15:0 |
|
Bits 31:16 |
|
Bits 47:32 |
|
Bits 63:48 |
|
No overflow check |
|
Signed relocation |
|
ADRP page-relative high 21 bits |
|
Low 12 bits |
1.8. Large Memory Model Relocations
The small and medium code models typically use ADRP+ADD sequences and are limited by the reach of ADRP. Large memory models use MOVZ/MOVK relocation sequences to construct arbitrary 64-bit addresses.
Relocation |
Operator |
Instruction |
Bits Loaded |
Range Check |
|---|---|---|---|---|
|
|
|
[15:0] |
|
|
|
|
[15:0] |
none |
|
|
|
[31:16] |
|
|
|
|
[31:16] |
none |
|
|
|
[47:32] |
|
|
|
|
[47:32] |
none |
|
|
|
[63:48] |
none |
1.8.1. Example
movz x0, #:abs_g3:foo
movk x0, #:abs_g2_nc:foo
movk x0, #:abs_g1_nc:foo
movk x0, #:abs_g0_nc:foo
Resulting relocation sequence:
R_AARCH64_MOVW_UABS_G3
R_AARCH64_MOVW_UABS_G2_NC
R_AARCH64_MOVW_UABS_G1_NC
R_AARCH64_MOVW_UABS_G0_NC
1.8.2. GOT-Based Large Model Relocations
Relocation |
Purpose |
|---|---|
|
Compute GOT page address |
|
Load GOT entry offset |
|
Dynamic linker fills GOT entry |
|
PLT/GOT function resolution |
1.8.3. Reach Comparison
Scheme |
Reach |
|---|---|
|
Approximately ±1 MB |
|
Approximately ±4 GB |
|
Full 64-bit address space |
GOT-based sequence |
Full 64-bit address space |
1.9. AArch64 Code Models
1.9.1. Small Code Model
Assumptions:
Code and static data are reachable using PC-relative addressing.
Symbols are typically accessed using
ADRP + ADDorADRP + LDR/STR.
Common relocations:
Relocation |
Purpose |
|---|---|
|
ADRP page calculation |
|
ADD low 12 bits |
|
8-bit load/store offset |
|
16-bit load/store offset |
|
32-bit load/store offset |
|
64-bit load/store offset |
Example:
adrp x0, :pg_hi21:global
add x0, x0, #:lo12:global
1.9.2. Medium Code Model
Assumptions:
Code remains reachable through branch relocations.
Data may reside outside the ADRP reach window.
Large objects are frequently accessed through the GOT.
Common relocations:
Relocation |
Purpose |
|---|---|
|
Compute GOT page |
|
Access GOT entry |
|
Dynamic linker fills GOT |
|
Function resolution via PLT/GOT |
Example:
adrp x0, :got:symbol
ldr x0, [x0, #:got_lo12:symbol]
1.9.3. Large Code Model
Assumptions:
Code and data may be located anywhere in the 64-bit address space.
Full-width addresses are materialized using MOVZ/MOVK relocation sequences.
Common relocations:
Relocation |
|---|
|
|
|
|
|
|
|
Example:
movz x0, #:abs_g3:symbol
movk x0, #:abs_g2_nc:symbol
movk x0, #:abs_g1_nc:symbol
movk x0, #:abs_g0_nc:symbol
1.10. References
1.10.1. Official AArch64 ELF ABI Specification
1.10.1.1. Current Source (GitHub)
ELF for the Arm® 64-bit Architecture (AArch64)
https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst
1.10.1.2. AAELF64 Repository Directory
https://github.com/ARM-software/abi-aa/tree/main/aaelf64
1.10.2. Recommended Sections
When implementing linker relocations, the most useful sections are:
Relocation Processing
Static AArch64 Relocations
Dynamic Relocations
GOT and PLT Relocations
TLS Relocations
Code Models
Program Loading and Dynamic Linking