diff options
-rw-r--r-- | lld/ELF/Relocations.cpp | 114 | ||||
-rw-r--r-- | lld/test/ELF/copy-errors.s | 7 | ||||
-rw-r--r-- | lld/test/ELF/copy-rel-pie-error.s | 18 | ||||
-rw-r--r-- | lld/test/ELF/copy-rel-pie2.s | 13 | ||||
-rw-r--r-- | lld/test/ELF/got32-i386.s | 2 | ||||
-rw-r--r-- | lld/test/ELF/got32x-i386.s | 3 | ||||
-rw-r--r-- | lld/test/ELF/x86-64-dyn-rel-error5.s | 8 |
7 files changed, 80 insertions, 85 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index bb629a0c5c0..9a11acf02fd 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -993,56 +993,29 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type, } } - 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(InputSectionBase &sec, RelExpr expr, RelType type, // 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)); } diff --git a/lld/test/ELF/copy-errors.s b/lld/test/ELF/copy-errors.s index 40f73178557..bf3c79255e8 100644 --- a/lld/test/ELF/copy-errors.s +++ b/lld/test/ELF/copy-errors.s @@ -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) diff --git a/lld/test/ELF/copy-rel-pie-error.s b/lld/test/ELF/copy-rel-pie-error.s deleted file mode 100644 index 379442e1176..00000000000 --- a/lld/test/ELF/copy-rel-pie-error.s +++ /dev/null @@ -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 diff --git a/lld/test/ELF/copy-rel-pie2.s b/lld/test/ELF/copy-rel-pie2.s new file mode 100644 index 00000000000..81cfac4e316 --- /dev/null +++ b/lld/test/ELF/copy-rel-pie2.s @@ -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 diff --git a/lld/test/ELF/got32-i386.s b/lld/test/ELF/got32-i386.s index 0080e1be1eb..a2758dafbaa 100644 --- a/lld/test/ELF/got32-i386.s +++ b/lld/test/ELF/got32-i386.s @@ -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 diff --git a/lld/test/ELF/got32x-i386.s b/lld/test/ELF/got32x-i386.s index 0e601fe7498..c2a662c7964 100644 --- a/lld/test/ELF/got32x-i386.s +++ b/lld/test/ELF/got32x-i386.s @@ -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 diff --git a/lld/test/ELF/x86-64-dyn-rel-error5.s b/lld/test/ELF/x86-64-dyn-rel-error5.s index 6a85ab2986d..483aa986ba9 100644 --- a/lld/test/ELF/x86-64-dyn-rel-error5.s +++ b/lld/test/ELF/x86-64-dyn-rel-error5.s @@ -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 |