Addresses and Relocations¶
A symbol's address and the value stored at that symbol are different results. Inspect relocations before linking, then check both results from C.
Course examples on GitHub
Before you start¶
Complete memory and arrays. You can distinguish a pointer from a pointed-to value and build a C/assembly executable.
Outcome: explain a page-plus-offset address and locate the linker work in an object file. Run in a fresh directory on the Pi.
Choose the address operation¶
| Form | Result |
|---|---|
adr x0, symbol |
Nearby PC-relative byte address |
adrp x0, symbol |
PC-relative 4 KiB page base |
add x0, x0, :lo12:symbol |
Add the low page offset |
ldr x0, [x0] |
Read eight bytes from an already formed address |
ldr x0, symbol |
Literal load of the value at a nearby label |
ldr x0, =symbol |
GNU pseudo-instruction requesting an address constant |
ADR has a signed 21-bit byte displacement; ADRP uses a signed 21-bit displacement scaled by 4096. The 4 KiB unit is an instruction encoding unit, not a promise about the Linux system page size. Range and relocation validity still depend on the linked layout.
Build the address lab¶
The data symbol below is local to the assembly file, so the linker can bind it directly in this PIE executable. This is not a template for interposable symbols in arbitrary shared libraries.
Before linking, look for relocations including R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADD_ABS_LO12_NC. The linked disassembly has resolved locations; a linker may relax a sequence. Do not require every tool version to display identical addresses or aliases.
Why a plausible address can be wrong¶
ADRP alone omits the low offset. An offset from a different symbol forms the wrong address. A literal load returns the stored bytes, not their address. An absolute pointer copied from yesterday's GDB output is not a symbol reference.
For a preemptible external object in a shared library, the compiler may use a GOT entry instead of directly binding the object's page. Compare gcc -S -fPIC output for an extern variable and inspect relocations; do not paste a GOT sequence into this local-symbol lab without identifying which pointer it loads.
If linking reports an out-of-range relocation, investigate symbol visibility and layout. Do not suppress the error with arbitrary address constants. See GNU AArch64 relocations for assembler notation.
Check your understanding¶
If value_address returned 42 rather than a pointer, why would the caller's dereference be invalid?
Compare your reasoning
The caller expects a readable address. The integer 42 is the contents, not the location of that contents; dereferencing it violates the contract.
Continue the course¶
Previous: Memory, Arrays and Loads · Course roadmap · Next: Functions, Stack and the ABI