Skip to content
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

Merged
merged 1 commit into from
Dec 12, 2023

Conversation

MaskRay
Copy link
Member

@MaskRay MaskRay commented Dec 11, 2023

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.

…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.
@llvmbot
Copy link
Collaborator

llvmbot commented Dec 11, 2023

@llvm/pr-subscribers-lld

@llvm/pr-subscribers-lld-elf

Author: Fangrui Song (MaskRay)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/75095.diff

4 Files Affected:

  • (modified) lld/ELF/Relocations.cpp (+2-2)
  • (modified) lld/test/ELF/got32-i386.s (+1-1)
  • (modified) lld/test/ELF/got32x-i386.s (+1-1)
  • (modified) lld/test/ELF/x86-64-dyn-rel-error.s (+3-3)
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

Copy link
Member

@arichardson arichardson left a 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

@MaskRay MaskRay merged commit 42e4967 into llvm:main Dec 12, 2023
6 checks passed
@MaskRay MaskRay deleted the lld-copy branch December 12, 2023 18:14
@MaskRay
Copy link
Member Author

MaskRay commented Jan 10, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants