Skip to content

Commit 42e4967

Browse files
authored
[ELF] Don't create copy relocation/canonical PLT entry for a defined symbol (#75095)
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.
1 parent 766bf14 commit 42e4967

File tree

4 files changed

+7
-7
lines changed

4 files changed

+7
-7
lines changed

lld/ELF/Relocations.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,8 +1158,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
11581158
}
11591159

11601160
// When producing an executable, we can perform copy relocations (for
1161-
// STT_OBJECT) and canonical PLT (for STT_FUNC).
1162-
if (!config->shared) {
1161+
// STT_OBJECT) and canonical PLT (for STT_FUNC) if sym is defined by a DSO.
1162+
if (!config->shared && sym.isShared()) {
11631163
if (!canDefineSymbolInExecutable(sym)) {
11641164
errorOrWarn("cannot preempt symbol: " + toString(sym) +
11651165
getLocation(*sec, sym, offset));

lld/test/ELF/got32-i386.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ _start:
2020
# CHECK-NEXT: 4010f5: 8b 1d {{.*}} movl 4202748, %ebx
2121

2222
# RUN: not ld.lld %t.o -o /dev/null -pie 2>&1 | FileCheck %s --check-prefix=ERR
23-
# ERR: error: symbol 'foo' cannot be preempted; recompile with -fPIE
23+
# ERR: error: relocation R_386_GOT32 cannot be used against symbol 'foo'; recompile with -fPIC

lld/test/ELF/got32x-i386.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@
4343

4444
# RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o /dev/null -pie 2>&1 | \
4545
# RUN: FileCheck %s --check-prefix=ERR
46-
# ERR-COUNT-2: error: symbol 'foo' cannot be preempted; recompile with -fPIE
46+
# ERR-COUNT-2: error: relocation R_386_GOT32X cannot be used against symbol 'foo'; recompile with -fPIC

lld/test/ELF/x86-64-dyn-rel-error.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/shared.s -o %t2.o
44
# RUN: ld.lld %t2.o -shared -o %t2.so --threads=1
55
# RUN: not ld.lld -pie %t.o %t2.so -o /dev/null --threads=1 2>&1 | FileCheck %s
6-
# RUN: not ld.lld -shared %t.o %t2.so -o /dev/null --threads=1 2>&1 | FileCheck %s --check-prefixes=CHECK,SHARED
6+
# RUN: not ld.lld -shared %t.o %t2.so -o /dev/null --threads=1 2>&1 | FileCheck %s
77

88
# CHECK: error: relocation R_X86_64_32 cannot be used against symbol 'zed'; recompile with -fPIC
99
# CHECK-NEXT: >>> defined in {{.*}}.so
@@ -14,8 +14,8 @@
1414
# CHECK-NEXT: >>> referenced by {{.*}}.o:(.data+0x4)
1515
# CHECK-EMPTY:
1616
# CHECK-NEXT: error: relocation R_X86_64_64 cannot be used against symbol '_start'; recompile with -fPIC
17-
# SHARED: error: relocation R_X86_64_64 cannot be used against symbol 'main'; recompile with -fPIC
18-
# SHARED: error: relocation R_X86_64_64 cannot be used against symbol 'data'; recompile with -fPIC
17+
# CHECK: error: relocation R_X86_64_64 cannot be used against symbol 'main'; recompile with -fPIC
18+
# CHECK: error: relocation R_X86_64_64 cannot be used against symbol 'data'; recompile with -fPIC
1919
# CHECK-NOT: error:
2020

2121
# RUN: ld.lld --noinhibit-exec %t.o %t2.so -o /dev/null 2>&1 | FileCheck --check-prefix=WARN %s

0 commit comments

Comments
 (0)