[lld] r369262 - [ELF] Move (copy relocation/canonical PLT) before error checking
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 19 07:30:12 PDT 2019
Author: maskray
Date: Mon Aug 19 07:30:12 2019
New Revision: 369262
URL: http://llvm.org/viewvc/llvm-project?rev=369262&view=rev
Log:
[ELF] Move (copy relocation/canonical PLT) before error checking
In processRelocAux(), we handle errors before copy relocation/canonical PLT.
This makes error checking a bit complex because we have to check for
conditions that will be allowed by copy relocation/canonical PLT.
Instead, move copy relocation/canonical PLT before error checking. This
simplifies the previous clumsy error checking code
`config->shared || (config->pie && expr == R_ABS && type != target->symbolicRel)`
to the simple `config->isPic`. Some diagnostics can be reported in
different ways. The code motion changes diagnostics for some contrived
test cases:
* copy-rel-pie-error.s -> copy-rel-pie2.s:
It was rejected before but accepted now. ld.bfd also accepts the case.
* copy-errors.s: "cannot preempt symbol" changes to "symbol 'bar' has no type"
* got32{,x}-i386.s: the suggestion changes from "-fPIC or -Wl,-z,notext" to "-fPIE"
* x86-64-dyn-rel-error5.s: one diagnostic changes for -pie case
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D66007
Added:
lld/trunk/test/ELF/copy-rel-pie2.s
Removed:
lld/trunk/test/ELF/copy-rel-pie-error.s
Modified:
lld/trunk/ELF/Relocations.cpp
lld/trunk/test/ELF/copy-errors.s
lld/trunk/test/ELF/got32-i386.s
lld/trunk/test/ELF/got32x-i386.s
lld/trunk/test/ELF/x86-64-dyn-rel-error5.s
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=369262&r1=369261&r2=369262&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Mon Aug 19 07:30:12 2019
@@ -993,56 +993,29 @@ static void processRelocAux(InputSection
}
}
- if (!canWrite && (config->isPic && !isRelExpr(expr))) {
- error(
- "can't create dynamic relocation " + toString(type) + " against " +
- (sym.getName().empty() ? "local symbol" : "symbol: " + toString(sym)) +
- " in readonly segment; recompile object files with -fPIC "
- "or pass '-Wl,-z,notext' to allow text relocations in the output" +
- getLocation(sec, sym, offset));
- return;
- }
-
- // Copy relocations (for STT_OBJECT) and canonical PLT (for STT_FUNC) are only
- // possible in an executable.
- //
- // Among R_ABS relocatoin types, symbolicRel has the same size as the word
- // size. Others have fewer bits and may cause runtime overflow in -pie/-shared
- // mode. Disallow them.
- if (config->shared ||
- (config->pie && expr == R_ABS && type != target->symbolicRel)) {
- errorOrWarn(
- "relocation " + toString(type) + " cannot be used against " +
- (sym.getName().empty() ? "local symbol" : "symbol " + toString(sym)) +
- "; recompile with -fPIC" + getLocation(sec, sym, offset));
- return;
- }
-
- // If the symbol is undefined we already reported any relevant errors.
- if (sym.isUndefined())
- return;
-
- if (!canDefineSymbolInExecutable(sym)) {
- error("cannot preempt symbol: " + toString(sym) +
- getLocation(sec, sym, offset));
- return;
- }
+ // When producing an executable, we can perform copy relocations (for
+ // STT_OBJECT) and canonical PLT (for STT_FUNC).
+ if (!config->shared) {
+ if (!canDefineSymbolInExecutable(sym)) {
+ errorOrWarn("cannot preempt symbol: " + toString(sym) +
+ getLocation(sec, sym, offset));
+ return;
+ }
- if (sym.isObject()) {
- // Produce a copy relocation.
- if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
- if (!config->zCopyreloc)
- error("unresolvable relocation " + toString(type) +
- " against symbol '" + toString(*ss) +
- "'; recompile with -fPIC or remove '-z nocopyreloc'" +
- getLocation(sec, sym, offset));
- addCopyRelSymbol<ELFT>(*ss);
+ if (sym.isObject()) {
+ // Produce a copy relocation.
+ if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
+ if (!config->zCopyreloc)
+ error("unresolvable relocation " + toString(type) +
+ " against symbol '" + toString(*ss) +
+ "'; recompile with -fPIC or remove '-z nocopyreloc'" +
+ getLocation(sec, sym, offset));
+ addCopyRelSymbol<ELFT>(*ss);
+ }
+ sec.relocations.push_back({expr, type, offset, addend, &sym});
+ return;
}
- sec.relocations.push_back({expr, type, offset, addend, &sym});
- return;
- }
- if (sym.isFunc()) {
// This handles a non PIC program call to function in a shared library. In
// an ideal world, we could just report an error saying the relocation can
// overflow at runtime. In the real world with glibc, crt1.o has a
@@ -1070,21 +1043,44 @@ static void processRelocAux(InputSection
// compiled without -fPIE/-fPIC and doesn't maintain ebx.
// * If a library definition gets preempted to the executable, it will have
// the wrong ebx value.
- if (config->pie && config->emachine == EM_386)
- errorOrWarn("symbol '" + toString(sym) +
- "' cannot be preempted; recompile with -fPIE" +
- getLocation(sec, sym, offset));
- if (!sym.isInPlt())
- addPltEntry<ELFT>(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
- if (!sym.isDefined())
- replaceWithDefined(
- sym, in.plt,
- target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
- sym.needsPltAddr = true;
- sec.relocations.push_back({expr, type, offset, addend, &sym});
+ if (sym.isFunc()) {
+ if (config->pie && config->emachine == EM_386)
+ errorOrWarn("symbol '" + toString(sym) +
+ "' cannot be preempted; recompile with -fPIE" +
+ getLocation(sec, sym, offset));
+ if (!sym.isInPlt())
+ addPltEntry<ELFT>(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
+ if (!sym.isDefined())
+ replaceWithDefined(
+ sym, in.plt,
+ target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
+ sym.needsPltAddr = true;
+ sec.relocations.push_back({expr, type, offset, addend, &sym});
+ return;
+ }
+ }
+
+ if (config->isPic) {
+ if (!canWrite && !isRelExpr(expr))
+ errorOrWarn(
+ "can't create dynamic relocation " + toString(type) + " against " +
+ (sym.getName().empty() ? "local symbol"
+ : "symbol: " + toString(sym)) +
+ " in readonly segment; recompile object files with -fPIC "
+ "or pass '-Wl,-z,notext' to allow text relocations in the output" +
+ getLocation(sec, sym, offset));
+ else
+ errorOrWarn(
+ "relocation " + toString(type) + " cannot be used against " +
+ (sym.getName().empty() ? "local symbol" : "symbol " + toString(sym)) +
+ "; recompile with -fPIC" + getLocation(sec, sym, offset));
return;
}
+ // If the symbol is undefined we already reported any relevant errors.
+ if (sym.isUndefined())
+ return;
+
errorOrWarn("symbol '" + toString(sym) + "' has no type" +
getLocation(sec, sym, offset));
}
Modified: lld/trunk/test/ELF/copy-errors.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/copy-errors.s?rev=369262&r1=369261&r2=369262&view=diff
==============================================================================
--- lld/trunk/test/ELF/copy-errors.s (original)
+++ lld/trunk/test/ELF/copy-errors.s Mon Aug 19 07:30:12 2019
@@ -4,7 +4,7 @@
// RUN: ld.lld %t2.o -o %t2.so -shared
// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
-// CHECK: cannot preempt symbol: bar
+// CHECK: error: cannot preempt symbol: bar
// CHECK: >>> defined in {{.*}}.so
// CHECK: >>> referenced by {{.*}}.o:(.text+0x1)
@@ -12,7 +12,10 @@
// CHECK-NEXT: >>> defined in {{.*}}.so
// CHECK-NEXT: >>> referenced by {{.*}}.o:(.text+0x6)
-// RUN: not ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s --check-prefix=NOINHIBIT
+// RUN: ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s --check-prefix=NOINHIBIT
+// NOINHIBIT: warning: cannot preempt symbol: bar
+// NOINHIBIT-NEXT: >>> defined in {{.*}}.so
+// NOINHIBIT-NEXT: >>> referenced by {{.*}}.o:(.text+0x1)
// NOINHIBIT: warning: symbol 'zed' has no type
// NOINHIBIT-NEXT: >>> defined in {{.*}}.so
// NOINHIBIT-NEXT: >>> referenced by {{.*}}.o:(.text+0x6)
Removed: lld/trunk/test/ELF/copy-rel-pie-error.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/copy-rel-pie-error.s?rev=369261&view=auto
==============================================================================
--- lld/trunk/test/ELF/copy-rel-pie-error.s (original)
+++ lld/trunk/test/ELF/copy-rel-pie-error.s (removed)
@@ -1,18 +0,0 @@
-// REQUIRES: x86
-// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
-// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
-// RUN: ld.lld %t2.o -o %t2.so -shared
-// RUN: not ld.lld %t.o %t2.so -o /dev/null -pie 2>&1 | FileCheck %s
-
-// CHECK: can't create dynamic relocation R_X86_64_64 against symbol: bar in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
-// CHECK: >>> defined in {{.*}}.so
-// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
-
-// CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
-// CHECK: >>> defined in {{.*}}.so
-// CHECK: >>> referenced by {{.*}}.o:(.text+0x8)
-
-.global _start
-_start:
- .quad bar
- .quad foo
Added: lld/trunk/test/ELF/copy-rel-pie2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/copy-rel-pie2.s?rev=369262&view=auto
==============================================================================
--- lld/trunk/test/ELF/copy-rel-pie2.s (added)
+++ lld/trunk/test/ELF/copy-rel-pie2.s Mon Aug 19 07:30:12 2019
@@ -0,0 +1,13 @@
+// REQUIRES: x86
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t -pie
+// RUN: llvm-readobj -r %t | FileCheck %s
+
+// CHECK: R_X86_64_COPY
+// CHECK: R_X86_64_JUMP_SLOT
+
+.rodata
+.quad bar
+.quad foo
Modified: lld/trunk/test/ELF/got32-i386.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/got32-i386.s?rev=369262&r1=369261&r2=369262&view=diff
==============================================================================
--- lld/trunk/test/ELF/got32-i386.s (original)
+++ lld/trunk/test/ELF/got32-i386.s Mon Aug 19 07:30:12 2019
@@ -20,4 +20,4 @@ _start:
# CHECK: .got 00000004 0000000000402000
# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR
-# ERR: error: can't create dynamic relocation R_386_GOT32 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
+# ERR: error: symbol 'foo' cannot be preempted; recompile with -fPIE
Modified: lld/trunk/test/ELF/got32x-i386.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/got32x-i386.s?rev=369262&r1=369261&r2=369262&view=diff
==============================================================================
--- lld/trunk/test/ELF/got32x-i386.s (original)
+++ lld/trunk/test/ELF/got32x-i386.s Mon Aug 19 07:30:12 2019
@@ -43,5 +43,4 @@
# RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
# RUN: FileCheck %s --check-prefix=ERR
-# ERR: error: can't create dynamic relocation R_386_GOT32X against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
-# ERR: error: can't create dynamic relocation R_386_GOT32X against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
+# ERR-COUNT-2: error: symbol 'foo' cannot be preempted; recompile with -fPIE
Modified: lld/trunk/test/ELF/x86-64-dyn-rel-error5.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/x86-64-dyn-rel-error5.s?rev=369262&r1=369261&r2=369262&view=diff
==============================================================================
--- lld/trunk/test/ELF/x86-64-dyn-rel-error5.s (original)
+++ lld/trunk/test/ELF/x86-64-dyn-rel-error5.s Mon Aug 19 07:30:12 2019
@@ -1,7 +1,7 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
-# RUN: not ld.lld -pie %t.o -o /dev/null 2>&1 | FileCheck %s
-# RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld -pie %t.o -o /dev/null 2>&1 | FileCheck --check-prefixes=CHECK,PIE %s
+# RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck --check-prefixes=CHECK,SHARED %s
## Check we don't create dynamic relocations in a writable section,
## if the number of bits is smaller than the wordsize.
@@ -16,7 +16,9 @@ hidden:
# CHECK-NEXT: >>> referenced by {{.*}}.o:(.data+0x0)
# CHECK: error: relocation R_X86_64_16 cannot be used against local symbol; recompile with -fPIC
# CHECK: error: relocation R_X86_64_32 cannot be used against local symbol; recompile with -fPIC
-# CHECK: error: relocation R_X86_64_32 cannot be used against symbol hidden; recompile with -fPIC
+
+# PIE: error: cannot preempt symbol: hidden
+# SHARED: error: relocation R_X86_64_32 cannot be used against symbol hidden; recompile with -fPIC
.data
.byte local # R_X86_64_8
More information about the llvm-commits
mailing list