abi-aa
abi-aa copied to clipboard
Undefined weak symbol's address
Section 5.6.1 (https://github.com/ARM-software/abi-aa/blob/844a79fd4c77252a11342709e3b27b2c9f590cf1/aaelf64/aaelf64.rst#weak-references) says the following.
During linking, the symbol value of an undefined weak reference is:
- Zero if the relocation type is absolute
- The address of the place if the relocation type is pc-relative.
It looks like the second bullet point doesn't match the linker's actual behavior. Calling an unresolved weak symbol on AArch64 is expected to be equivalent to nop and just increments the program counter to the next instruction. Here is an excerpt from the real object file as an example.
$ aarch64-linux-gnu-objdump -dr /usr/aarch64-linux-gnu/lib/crti.o
0000000000000000 <call_weak_fn>:
0: 90000000 adrp x0, 0 <__gmon_start__>
0: R_AARCH64_ADR_GOT_PAGE __gmon_start__
4: f9400000 ldr x0, [x0]
4: R_AARCH64_LD64_GOT_LO12_NC __gmon_start__
8: b4000040 cbz x0, 10 <call_weak_fn+0x10>
c: 14000000 b 0 <__gmon_start__>
c: R_AARCH64_JUMP26 __gmon_start__
10: d65f03c0 ret
If __gmon_start__
is undefined in the above code, b
would fall into an infinite loop instead of behaving as nop if the address of __gmon_start__
is evaluated to the address of the relocated place. It needs to be evaluated to PC+4 instead.
It looks like it's a spec bug.