You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
static linkers (lld and GNU ld) out of sync with aaelf64 for GOT relocations with addends. #217
Raising this as an ABI issue rather than a two separate toolchain issues as it may be simpler to amend the ABI than try and fix the tools.
When doing a :got: and :got_lo12: expression to a local symbol, the GNU and LLVM assemblers convert this to a GOT generating relocation to the section symbol + addend.
GDAT(S+A) represents a pointer-sized entry in the GOT for address S+A. The entry will be relocated at run time with relocation R_<CLS>_GLOB_DAT(S+A).
G(expr) is the address of the GOT entry for the expression expr.
GNU ld and lld are mishandling this with LLD using something like:
Page(G((GDAT(S)) + A) - Page(P))
G(GDAT(S)) + A
With GNU ld.bfd appearing to ignore the addend A completely
We could say that this is a pair of toolchain bugs, however for LLD in particular some work would need to be done to generate separate GOT slots for S+A rather than just S. This might proove difficult to get accepted for a corner case just for AArch64. While I don't know for certain I expect GNU ld will have a similar problem.
It may be worth altering the ABI to not permit addends, or have them implemented in a way that GNU ld and LLD can both implement. We could then alter the assembler to not use symbol + addend forms for a local symbol.
If we determine that the ABI is correct we can raise toolchain issues and close this as won't fix.
When doing a :got: and :got_lo12: expression to a local symbol, the GNU and LLVM assemblers convert this to a GOT generating relocation to the section symbol + addend.
I consider this assembler issues specifically for AArch64. GNU assembler and LLVM integrated assembler for most other targets suppress local symbol to STT_SECTION conversion for GOT relocations.
This is neglected likely because compilers don't emit such constructs. llvm/llvm-project#63418 is found due to inline assembly uses.
GNU ld and lld are mishandling this with LLD using something like:
Agreed that GNU ld and lld don't comply to the ABI when generating GOT entries.
They create GOT entries based on the symbol, ignoring addend.
ldr x1,[x1, :got_lo12:x]ldr x1,[x1, :got_lo12:y]// affected by this change but I do not recommend this use case.// x86-64 maintainer considers a similar case reasonable: https://sourceware.org/bugzilla/show_bug.cgi?id=26939ldr x1,[x1, :got_lo12:(x+8)]// affected by this change but I do not recommend this use case.ldr x1,[x1, :got_lo12:(.data+0)]ldr x1,[x1, :got_lo12:(.data+8)].datax:.zero 4y:.zero 8
It may be worth altering the ABI to not permit addends, or have them implemented in a way that GNU ld and LLD can both implement. We could then alter the assembler to not use symbol + addend forms for a local symbol.
If we determine that the ABI is correct we can raise toolchain issues and close this as won't fix.
Switching from GDAT(S) to GDAT(S+A) would indeed be disruptive for lld so I hope that we use GDAT(S).
If we change assemblers as mentioned, whether or not the ABI requires GDAT(S) or GDAT(S+A) is largely moot for lld.
Activity
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
MaskRay commentedon Aug 23, 2023
I consider this assembler issues specifically for AArch64. GNU assembler and LLVM integrated assembler for most other targets suppress local symbol to STT_SECTION conversion for GOT relocations.
This is neglected likely because compilers don't emit such constructs. llvm/llvm-project#63418 is found due to inline assembly uses.
Agreed that GNU ld and lld don't comply to the ABI when generating GOT entries.
They create GOT entries based on the symbol, ignoring addend.
If we fix GNU assembler and LLVM integrated assembler to suppress STT_SECTION conversion (https://reviews.llvm.org/D158577 and https://sourceware.org/bugzilla/show_bug.cgi?id=30788), I believe this ABI change (
GDAT(S+A)vsGDAT(S)) is moot, as all reasonable use cases will be unaffected.Switching from
GDAT(S)toGDAT(S+A)would indeed be disruptive for lld so I hope that we useGDAT(S).If we change assemblers as mentioned, whether or not the ABI requires
GDAT(S)orGDAT(S+A)is largely moot for lld.[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[MC,AArch64] Suppress local symbol to STT_SECTION conversion for GOT âĶ
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[aaelf64][pauthabi64] Remove addend in GDAT relocation operation
smithp35 commentedon Jul 2, 2024
I've submitted #272 which removes A from the GDAT(S + A) relocation operation.
[aaelf64][pauthabi64] Remove addend in GDAT relocation operation
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
[MC,AArch64] Suppress local symbol to STT_SECTION conversion for GOT âĶ