[lld] 42e4967 - [ELF] Don't create copy relocation/canonical PLT entry for a defined symbol (#75095)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 12 10:14:39 PST 2023


Author: Fangrui Song
Date: 2023-12-12T10:14:36-08:00
New Revision: 42e4967140e345923a43f809ba69be57200f46ae

URL: https://github.com/llvm/llvm-project/commit/42e4967140e345923a43f809ba69be57200f46ae
DIFF: https://github.com/llvm/llvm-project/commit/42e4967140e345923a43f809ba69be57200f46ae.diff

LOG: [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.

Added: 
    

Modified: 
    lld/ELF/Relocations.cpp
    lld/test/ELF/got32-i386.s
    lld/test/ELF/got32x-i386.s
    lld/test/ELF/x86-64-dyn-rel-error.s

Removed: 
    


################################################################################
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


        


More information about the llvm-commits mailing list