https://github.com/alexrp created https://github.com/llvm/llvm-project/pull/185151
Manual backport of #182905 with partial backport of adf7dbc2a8d28d303e0c539f4e7a23561ed3cf29 in `lld/test/ELF/ztext.s`. From 8bc430c26e3103acffcf0cd4713d2ed01213bf33 Mon Sep 17 00:00:00 2001 From: Fangrui Song <[email protected]> Date: Mon, 23 Feb 2026 18:26:56 -0800 Subject: [PATCH] [ELF] Adjust allowed dynamic relocation types for x86-64 (#182905) First, disallow R_X86_64_PC64 - generally only absolute relocations are allowed in getDynRel. glibc and musl don't support R_X86_64_PC64 as dynamic relocations. Second, support R_X86_64_32 as dynamic relocation for the ILP32 ABI (x32). GNU ld's behavior looks like: - R_X86_64_32 => R_X86_64_RELATIVE - R_X86_64_64 with addend 0 => R_X86_64_RELATIVE - R_X86_64_64 with non-zero addend => R_X86_64_RELATIVE64 (unsupported by musl; compilers do not generate such constructs to the best of my knowledge) For now we require R_X86_64_64 to be resolved at link-time for x32. Fix #140465 --- lld/ELF/Arch/X86_64.cpp | 5 ++-- lld/test/ELF/Inputs/ztext.s | 10 ------- lld/test/ELF/x86-x32-abs.s | 34 +++++++++++++++++++++ lld/test/ELF/ztext.s | 60 +++++++++++++++++++++++++------------ 4 files changed, 77 insertions(+), 32 deletions(-) delete mode 100644 lld/test/ELF/Inputs/ztext.s create mode 100644 lld/test/ELF/x86-x32-abs.s diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 9083b5b9ff250..2c34a193140ea 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -80,7 +80,7 @@ X86_64::X86_64(Ctx &ctx) : TargetInfo(ctx) { pltRel = R_X86_64_JUMP_SLOT; relativeRel = R_X86_64_RELATIVE; iRelativeRel = R_X86_64_IRELATIVE; - symbolicRel = R_X86_64_64; + symbolicRel = ctx.arg.is64 ? R_X86_64_64 : R_X86_64_32; tlsDescRel = R_X86_64_TLSDESC; tlsGotRel = R_X86_64_TPOFF64; tlsModuleIndexRel = R_X86_64_DTPMOD64; @@ -469,8 +469,7 @@ void X86_64::writePlt(uint8_t *buf, const Symbol &sym, } RelType X86_64::getDynRel(RelType type) const { - if (type == R_X86_64_64 || type == R_X86_64_PC64 || type == R_X86_64_SIZE32 || - type == R_X86_64_SIZE64) + if (type == symbolicRel || type == R_X86_64_SIZE32 || type == R_X86_64_SIZE64) return type; return R_X86_64_NONE; } diff --git a/lld/test/ELF/Inputs/ztext.s b/lld/test/ELF/Inputs/ztext.s deleted file mode 100644 index f66b3ee1e29bf..0000000000000 --- a/lld/test/ELF/Inputs/ztext.s +++ /dev/null @@ -1,10 +0,0 @@ - .global bar - .type bar, @object - .size bar, 8 -bar: - .quad 0 - - .global zed - .type zed, @function -zed: - nop diff --git a/lld/test/ELF/x86-x32-abs.s b/lld/test/ELF/x86-x32-abs.s new file mode 100644 index 0000000000000..01fd3b7a5c56c --- /dev/null +++ b/lld/test/ELF/x86-x32-abs.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 +## Test R_X86_64_32 relocations in x32 (ILP32) mode. +## In x32, R_X86_64_32 is the pointer-sized absolute relocation. + +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-gnux32 a.s -o a.o +# RUN: ld.lld -shared a.o -o a.so +# RUN: llvm-readelf -r a.so | FileCheck %s + +## Non-resolved non-preemptible R_X86_64_32 get R_X86_64_RELATIVE. +# CHECK: Relocation section '.rela.dyn' at offset {{.*}} contains 2 entries: +# CHECK: R_X86_64_RELATIVE +# CHECK-NEXT: {{.*}} R_X86_64_32 {{.*}} und + 0 + +## R_X86_64_64 is not a supported dynamic relocation in x32 mode. +# RUN: llvm-mc -filetype=obj -triple=x86_64-gnux32 b.s -o b.o +# RUN: not ld.lld -shared b.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR + +# ERR: error: relocation R_X86_64_64 cannot be used against symbol 'und'; recompile with -fPIC +# ERR-NEXT: >>> defined in b.o +# ERR-NEXT: >>> referenced by b.o:(.data+0x0) + +#--- a.s +.globl hid +.hidden hid + +.data +hid: + .long und + .long hid + +#--- b.s +.data + .quad und diff --git a/lld/test/ELF/ztext.s b/lld/test/ELF/ztext.s index 11e89e025e060..1aa4987ccc403 100644 --- a/lld/test/ELF/ztext.s +++ b/lld/test/ELF/ztext.s @@ -1,20 +1,34 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/ztext.s -o %t2.o -# RUN: ld.lld %t2.o -o %t2.so -shared -soname=so +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o +# RUN: ld.lld b.o -o b.so -shared -soname=so -# RUN: ld.lld -z notext %t.o %t2.so -o %t -shared -# RUN: llvm-readobj --dynamic-table -r %t | FileCheck %s -# RUN: ld.lld -z notext %t.o %t2.so -o %t2 -pie -# RUN: llvm-readobj --dynamic-table -r %t2 | FileCheck %s -# RUN: ld.lld -z notext %t.o %t2.so -o %t3 -# RUN: llvm-readobj --dynamic-table -r %t3 | FileCheck --check-prefix=STATIC %s +## -z notext allows text relocations for certain relocation types. +# RUN: ld.lld -z notext a.o b.so -o out -shared +# RUN: llvm-readobj --dynamic-table -r out | FileCheck %s +# RUN: ld.lld -z notext a.o b.so -o out.pie -pie +# RUN: llvm-readobj --dynamic-table -r out.pie | FileCheck %s +# RUN: ld.lld -z notext a.o b.so -o out.exe +# RUN: llvm-readobj --dynamic-table -r out.exe | FileCheck --check-prefix=STATIC %s -# RUN: not ld.lld %t.o %t2.so -o /dev/null -shared 2>&1 | FileCheck --check-prefix=ERR %s -# RUN: not ld.lld -z text %t.o %t2.so -o /dev/null -shared 2>&1 | FileCheck --check-prefix=ERR %s -# ERR: error: relocation R_X86_64_64 cannot be used against symbol 'bar'; recompile with -fPIC +# RUN: not ld.lld a.o b.so -shared 2>&1 | FileCheck --check-prefix=ERR %s --implicit-check-not=error: +# RUN: not ld.lld -z text a.o b.so -shared 2>&1 | FileCheck --check-prefix=ERR %s --implicit-check-not=error: -# If the preference is to have text relocations, don't create plt of copy relocations. +# ERR: error: relocation R_X86_64_64 cannot be used against local symbol; recompile with -fPIC +# ERR-NEXT: >>> defined in a.o +# ERR-NEXT: >>> referenced by a.o:(.text+0x0) +# ERR: error: relocation R_X86_64_64 cannot be used against symbol 'bar'; recompile with -fPIC +# ERR-NEXT: >>> defined in b.so +# ERR-NEXT: >>> referenced by a.o:(.text+0x8) + +## R_X86_64_PC64 is not a supported dynamic relocation. It errors even with -z notext. +# RUN: llvm-mc -filetype=obj -triple=x86_64 pc64.s -o pc64.o +# RUN: not ld.lld -z notext pc64.o b.so -shared 2>&1 | FileCheck --check-prefix=ERR-PC64 %s + +# ERR-PC64: error: relocation R_X86_64_PC64 cannot be used against symbol 'bar'; recompile with -fPIC +# ERR-PC64-NEXT: >>> defined in b.so +# ERR-PC64-NEXT: >>> referenced by pc64.o:(.text+0x0) # CHECK: DynamicSection [ # CHECK: FLAGS TEXTREL @@ -22,9 +36,8 @@ # CHECK: Relocations [ # CHECK-NEXT: Section {{.*}} .rela.dyn { -# CHECK-NEXT: 0x12A0 R_X86_64_RELATIVE - 0x12A0 -# CHECK-NEXT: 0x12A8 R_X86_64_64 bar 0x0 -# CHECK-NEXT: 0x12B0 R_X86_64_PC64 zed 0x0 +# CHECK-NEXT: 0x1268 R_X86_64_RELATIVE - 0x1268 +# CHECK-NEXT: 0x1270 R_X86_64_64 bar 0x0 # CHECK-NEXT: } # CHECK-NEXT: ] @@ -34,12 +47,21 @@ # STATIC: Relocations [ # STATIC-NEXT: Section {{.*}} .rela.dyn { -# STATIC-NEXT: 0x201290 R_X86_64_64 bar 0x0 -# STATIC-NEXT: 0x201298 R_X86_64_PC64 zed 0x0 +# STATIC-NEXT: 0x201258 R_X86_64_64 bar 0x0 # STATIC-NEXT: } # STATIC-NEXT: ] +#--- a.s foo: .quad foo .quad bar -.quad zed - . + +#--- b.s +.global bar +.type bar, @object +.size bar, 8 +bar: +.quad 0 + +#--- pc64.s +.quad bar - . _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
