-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ELF] Don't create copy relocation/canonical PLT entry for a defined symbol #75095
Conversation
…symbol Copy relocations and canonical PLT entries are for symbols defined in a DSO. Currently we create them even for a `Defined`, possibly leading to an output that won't work at run-time (e.g. R_X86_64_JUMP_SLOT referencing a null symbol). ``` % cat a.s .globl _start, main .type main, @function _start: main: ret .rodata .quad main % clang -fuse-ld=lld -pie -nostdlib a.s % readelf -Wr a.out Relocation section '.rela.plt' at offset 0x290 contains 1 entry: Offset Info Type Symbol's Value Symbol's Name + Addend 00000000000033b8 0000000000000007 R_X86_64_JUMP_SLOT 12b0 ``` Report an error instead for the default `-z text` mode. GNU ld reports an error in `-z text` mode as well.
@llvm/pr-subscribers-lld @llvm/pr-subscribers-lld-elf Author: Fangrui Song (MaskRay) ChangesCopy relocations and canonical PLT entries are for symbols defined in a
Report an error instead for the default Full diff: https://github.com/llvm/llvm-project/pull/75095.diff 4 Files Affected:
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index fe3d7f419e84aa..210b4d1eb1a7a6 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1158,8 +1158,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
}
// When producing an executable, we can perform copy relocations (for
- // STT_OBJECT) and canonical PLT (for STT_FUNC).
- if (!config->shared) {
+ // STT_OBJECT) and canonical PLT (for STT_FUNC) if sym is defined by a DSO.
+ if (!config->shared && sym.isShared()) {
if (!canDefineSymbolInExecutable(sym)) {
errorOrWarn("cannot preempt symbol: " + toString(sym) +
getLocation(*sec, sym, offset));
diff --git a/lld/test/ELF/got32-i386.s b/lld/test/ELF/got32-i386.s
index f44719f16dc198..9416e3667b8d6d 100644
--- a/lld/test/ELF/got32-i386.s
+++ b/lld/test/ELF/got32-i386.s
@@ -20,4 +20,4 @@ _start:
# CHECK-NEXT: 4010f5: 8b 1d {{.*}} movl 4202748, %ebx
# RUN: not ld.lld %t.o -o /dev/null -pie 2>&1 | FileCheck %s --check-prefix=ERR
-# ERR: error: symbol 'foo' cannot be preempted; recompile with -fPIE
+# ERR: error: relocation R_386_GOT32 cannot be used against symbol 'foo'; recompile with -fPIC
diff --git a/lld/test/ELF/got32x-i386.s b/lld/test/ELF/got32x-i386.s
index fb12d99bd0fef7..3b19de9c98a05f 100644
--- a/lld/test/ELF/got32x-i386.s
+++ b/lld/test/ELF/got32x-i386.s
@@ -43,4 +43,4 @@
# RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o /dev/null -pie 2>&1 | \
# RUN: FileCheck %s --check-prefix=ERR
-# ERR-COUNT-2: error: symbol 'foo' cannot be preempted; recompile with -fPIE
+# ERR-COUNT-2: error: relocation R_386_GOT32X cannot be used against symbol 'foo'; recompile with -fPIC
diff --git a/lld/test/ELF/x86-64-dyn-rel-error.s b/lld/test/ELF/x86-64-dyn-rel-error.s
index edc2875c6fa63c..a03adf89072f31 100644
--- a/lld/test/ELF/x86-64-dyn-rel-error.s
+++ b/lld/test/ELF/x86-64-dyn-rel-error.s
@@ -3,7 +3,7 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/shared.s -o %t2.o
# RUN: ld.lld %t2.o -shared -o %t2.so --threads=1
# RUN: not ld.lld -pie %t.o %t2.so -o /dev/null --threads=1 2>&1 | FileCheck %s
-# RUN: not ld.lld -shared %t.o %t2.so -o /dev/null --threads=1 2>&1 | FileCheck %s --check-prefixes=CHECK,SHARED
+# RUN: not ld.lld -shared %t.o %t2.so -o /dev/null --threads=1 2>&1 | FileCheck %s
# CHECK: error: relocation R_X86_64_32 cannot be used against symbol 'zed'; recompile with -fPIC
# CHECK-NEXT: >>> defined in {{.*}}.so
@@ -14,8 +14,8 @@
# CHECK-NEXT: >>> referenced by {{.*}}.o:(.data+0x4)
# CHECK-EMPTY:
# CHECK-NEXT: error: relocation R_X86_64_64 cannot be used against symbol '_start'; recompile with -fPIC
-# SHARED: error: relocation R_X86_64_64 cannot be used against symbol 'main'; recompile with -fPIC
-# SHARED: error: relocation R_X86_64_64 cannot be used against symbol 'data'; recompile with -fPIC
+# CHECK: error: relocation R_X86_64_64 cannot be used against symbol 'main'; recompile with -fPIC
+# CHECK: error: relocation R_X86_64_64 cannot be used against symbol 'data'; recompile with -fPIC
# CHECK-NOT: error:
# RUN: ld.lld --noinhibit-exec %t.o %t2.so -o /dev/null 2>&1 | FileCheck --check-prefix=WARN %s
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks correct to me
Here is an example involving both copy relocation/canonical PLT entry. % cat a.s
.globl _start, main
.type main, @function
.type var, @object
_start: main: ret
.data
.globl var
var:
.quad 0
.size var, .-var
.rodata
.quad main
.quad var # previously this refers to the link-time address without an associated dynamic relocation; now we correctly get an error
% ld.lld -pie a.o |
Copy relocations and canonical PLT entries are for symbols defined in a
DSO. Currently we create them even for a
Defined
, possibly leading toan output that won't work at run-time (e.g. R_X86_64_JUMP_SLOT
referencing a null symbol).
Report an error instead for the default
-z text
mode. GNU ld reportsan error in
-z text
mode as well.