On 22/11/2022 19:12, Bob Plantz via Gcc-help wrote:
I'm using the Arm A64 instruction set on a Raspberry Pi running Raspberry Pi 64-bit. Given the C code:
extern int x, y, z;
void addTwo(void)
{
z = x + y;
}
gcc produces the assembly language:
.arch armv8-a
.file "addTwoGlobal.c"
.text
.align 2
.global addTwo
.type addTwo, %function
addTwo:
adrp x0, :got:x
ldr x0, [x0, #:got_lo12:x]
ldr w1, [x0]
adrp x0, :got:y
ldr x0, [x0, #:got_lo12:y]
ldr w0, [x0]
add w1, w1, w0
adrp x0, :got:z
ldr x0, [x0, #:got_lo12:z]
str w1, [x0]
nop
ret
.size addTwo, .-addTwo
.ident "GCC: (Debian 10.2.1-6) 10.2.1 20210110"
.section .note.GNU-stack,"",@progbits
I believe that the :got: and :got_lo12: modifiers tell the linker to use the address for x from the global offset table for the offset values in the
adrp x0, :got:x
ldr x0, [x0, #:got_lo12:x]
Instructions.
Using gdb, I can see that adrp loads the offset from the pc to the page number of x and that #:got_lo12:x is an immediate value that is the offset of x within that page.
But I cannot find where :got: and :got_lo12: are documented.
The relocation directives should really be documented in GAS (the
assembler), but the text there is pretty short and not very
comprehensive [1]. The relocation names are essentially taken from the
ELF specification for AArch64
(https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst)
and the relocation markers used by GAS largely follow the relocation
names described in that document.
R.
[1]
https://sourceware.org/binutils/docs-2.39/as.html#AArch64_002dRelocations