[lld] r363059 - [ELF] Make the rule to create relative relocations in a writable section stricter
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 11 05:59:30 PDT 2019
Author: maskray
Date: Tue Jun 11 05:59:30 2019
New Revision: 363059
URL: http://llvm.org/viewvc/llvm-project?rev=363059&view=rev
Log:
[ELF] Make the rule to create relative relocations in a writable section stricter
The current rule is loose: `!Sym.IsPreemptible || Expr == R_GOT`.
When the symbol is non-preemptable, this allows absolute relocation
types with smaller numbers of bits, e.g. R_X86_64_{8,16,32}. They are
disallowed by ld.bfd and gold, e.g.
ld.bfd: a.o: relocation R_X86_64_8 against `.text' can not be used when making a shared object; recompile with -fPIC
This patch:
a) Add TargetInfo::SymbolicRel to represent relocation types that resolve to a
symbol value (e.g. R_AARCH_ABS64, R_386_32, R_X86_64_64).
As a side benefit, we currently (ab)use GotRel (R_*_GLOB_DAT) to resolve
GOT slots that are link-time constants. Since we now use Target->SymbolRel
to do the job, we can remove R_*_GLOB_DAT from relocateOne() for all targets.
R_*_GLOB_DAT cannot be used as static relocation types.
b) Change the condition to `!Sym.IsPreemptible && Type != Target->SymbolicRel || Expr == R_GOT`.
Some tests are caught by the improved error checking (ld.bfd/gold also
issue errors on them). Many misuse .long where .quad should be used
instead.
Reviewed By: ruiu
Differential Revision: https://reviews.llvm.org/D63121
Added:
lld/trunk/test/ELF/x86-64-dyn-rel-error5.s
Modified:
lld/trunk/ELF/Arch/AArch64.cpp
lld/trunk/ELF/Arch/AMDGPU.cpp
lld/trunk/ELF/Arch/ARM.cpp
lld/trunk/ELF/Arch/Hexagon.cpp
lld/trunk/ELF/Arch/Mips.cpp
lld/trunk/ELF/Arch/PPC.cpp
lld/trunk/ELF/Arch/PPC64.cpp
lld/trunk/ELF/Arch/SPARCV9.cpp
lld/trunk/ELF/Arch/X86.cpp
lld/trunk/ELF/Arch/X86_64.cpp
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/Target.h
lld/trunk/test/ELF/linkerscript/visibility.s
lld/trunk/test/ELF/merge-string-error.s
lld/trunk/test/ELF/pack-dyn-relocs-loop.s
lld/trunk/test/ELF/relocation-before-merge-start.s
lld/trunk/test/ELF/relocation-past-merge-end.s
Modified: lld/trunk/ELF/Arch/AArch64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/AArch64.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/AArch64.cpp (original)
+++ lld/trunk/ELF/Arch/AArch64.cpp Tue Jun 11 05:59:30 2019
@@ -59,6 +59,7 @@ AArch64::AArch64() {
GotRel = R_AARCH64_GLOB_DAT;
NoneRel = R_AARCH64_NONE;
PltRel = R_AARCH64_JUMP_SLOT;
+ SymbolicRel = R_AARCH64_ABS64;
TlsDescRel = R_AARCH64_TLSDESC;
TlsGotRel = R_AARCH64_TLS_TPREL64;
PltEntrySize = 16;
@@ -258,7 +259,6 @@ void AArch64::relocateOne(uint8_t *Loc,
write32le(Loc, Val);
break;
case R_AARCH64_ABS64:
- case R_AARCH64_GLOB_DAT:
case R_AARCH64_PREL64:
write64le(Loc, Val);
break;
Modified: lld/trunk/ELF/Arch/AMDGPU.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/AMDGPU.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/AMDGPU.cpp (original)
+++ lld/trunk/ELF/Arch/AMDGPU.cpp Tue Jun 11 05:59:30 2019
@@ -35,6 +35,7 @@ AMDGPU::AMDGPU() {
RelativeRel = R_AMDGPU_RELATIVE64;
GotRel = R_AMDGPU_ABS64;
NoneRel = R_AMDGPU_NONE;
+ SymbolicRel = R_AMDGPU_ABS64;
}
static uint32_t getEFlags(InputFile *File) {
Modified: lld/trunk/ELF/Arch/ARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/ARM.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/ARM.cpp (original)
+++ lld/trunk/ELF/Arch/ARM.cpp Tue Jun 11 05:59:30 2019
@@ -52,6 +52,7 @@ ARM::ARM() {
GotRel = R_ARM_GLOB_DAT;
NoneRel = R_ARM_NONE;
PltRel = R_ARM_JUMP_SLOT;
+ SymbolicRel = R_ARM_ABS32;
TlsGotRel = R_ARM_TLS_TPOFF32;
TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
TlsOffsetRel = R_ARM_TLS_DTPOFF32;
@@ -377,7 +378,6 @@ void ARM::relocateOne(uint8_t *Loc, RelT
switch (Type) {
case R_ARM_ABS32:
case R_ARM_BASE_PREL:
- case R_ARM_GLOB_DAT:
case R_ARM_GOTOFF32:
case R_ARM_GOT_BREL:
case R_ARM_GOT_PREL:
Modified: lld/trunk/ELF/Arch/Hexagon.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/Hexagon.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/Hexagon.cpp (original)
+++ lld/trunk/ELF/Arch/Hexagon.cpp Tue Jun 11 05:59:30 2019
@@ -40,6 +40,7 @@ Hexagon::Hexagon() {
PltRel = R_HEX_JMP_SLOT;
RelativeRel = R_HEX_RELATIVE;
GotRel = R_HEX_GLOB_DAT;
+ SymbolicRel = R_HEX_32;
// The zero'th GOT entry is reserved for the address of _DYNAMIC. The
// next 3 are reserved for the dynamic loader.
Modified: lld/trunk/ELF/Arch/Mips.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/Mips.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/Mips.cpp (original)
+++ lld/trunk/ELF/Arch/Mips.cpp Tue Jun 11 05:59:30 2019
@@ -59,11 +59,13 @@ template <class ELFT> MIPS<ELFT>::MIPS()
if (ELFT::Is64Bits) {
RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
+ SymbolicRel = R_MIPS_64;
TlsGotRel = R_MIPS_TLS_TPREL64;
TlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
TlsOffsetRel = R_MIPS_TLS_DTPREL64;
} else {
RelativeRel = R_MIPS_REL32;
+ SymbolicRel = R_MIPS_32;
TlsGotRel = R_MIPS_TLS_TPREL32;
TlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
TlsOffsetRel = R_MIPS_TLS_DTPREL32;
Modified: lld/trunk/ELF/Arch/PPC.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC.cpp (original)
+++ lld/trunk/ELF/Arch/PPC.cpp Tue Jun 11 05:59:30 2019
@@ -135,6 +135,7 @@ PPC::PPC() {
PltRel = R_PPC_JMP_SLOT;
RelativeRel = R_PPC_RELATIVE;
IRelativeRel = R_PPC_IRELATIVE;
+ SymbolicRel = R_PPC_ADDR32;
GotBaseSymInGotPlt = false;
GotHeaderEntriesNum = 3;
GotPltHeaderEntriesNum = 0;
@@ -288,7 +289,6 @@ void PPC::relocateOne(uint8_t *Loc, RelT
write16(Loc, Val);
break;
case R_PPC_ADDR32:
- case R_PPC_GLOB_DAT:
case R_PPC_REL32:
write32(Loc, Val);
break;
Modified: lld/trunk/ELF/Arch/PPC64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC64.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC64.cpp (original)
+++ lld/trunk/ELF/Arch/PPC64.cpp Tue Jun 11 05:59:30 2019
@@ -288,6 +288,7 @@ PPC64::PPC64() {
PltRel = R_PPC64_JMP_SLOT;
RelativeRel = R_PPC64_RELATIVE;
IRelativeRel = R_PPC64_IRELATIVE;
+ SymbolicRel = R_PPC64_ADDR64;
PltEntrySize = 4;
GotBaseSymInGotPlt = false;
GotHeaderEntriesNum = 1;
Modified: lld/trunk/ELF/Arch/SPARCV9.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/SPARCV9.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/SPARCV9.cpp (original)
+++ lld/trunk/ELF/Arch/SPARCV9.cpp Tue Jun 11 05:59:30 2019
@@ -37,6 +37,7 @@ SPARCV9::SPARCV9() {
NoneRel = R_SPARC_NONE;
PltRel = R_SPARC_JMP_SLOT;
RelativeRel = R_SPARC_RELATIVE;
+ SymbolicRel = R_SPARC_64;
PltEntrySize = 32;
PltHeaderSize = 4 * PltEntrySize;
@@ -114,7 +115,6 @@ void SPARCV9::relocateOne(uint8_t *Loc,
break;
case R_SPARC_64:
case R_SPARC_UA64:
- case R_SPARC_GLOB_DAT:
// V-xword64
write64be(Loc, Val);
break;
Modified: lld/trunk/ELF/Arch/X86.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/X86.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/X86.cpp (original)
+++ lld/trunk/ELF/Arch/X86.cpp Tue Jun 11 05:59:30 2019
@@ -52,6 +52,7 @@ X86::X86() {
PltRel = R_386_JUMP_SLOT;
IRelativeRel = R_386_IRELATIVE;
RelativeRel = R_386_RELATIVE;
+ SymbolicRel = R_386_32;
TlsGotRel = R_386_TLS_TPOFF;
TlsModuleIndexRel = R_386_TLS_DTPMOD32;
TlsOffsetRel = R_386_TLS_DTPOFF32;
@@ -291,7 +292,6 @@ void X86::relocateOne(uint8_t *Loc, RelT
write16le(Loc, Val);
break;
case R_386_32:
- case R_386_GLOB_DAT:
case R_386_GOT32:
case R_386_GOT32X:
case R_386_GOTOFF:
Modified: lld/trunk/ELF/Arch/X86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/X86_64.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/X86_64.cpp (original)
+++ lld/trunk/ELF/Arch/X86_64.cpp Tue Jun 11 05:59:30 2019
@@ -55,6 +55,7 @@ X86_64::X86_64() {
PltRel = R_X86_64_JUMP_SLOT;
RelativeRel = R_X86_64_RELATIVE;
IRelativeRel = R_X86_64_IRELATIVE;
+ SymbolicRel = R_X86_64_64;
TlsDescRel = R_X86_64_TLSDESC;
TlsGotRel = R_X86_64_TPOFF64;
TlsModuleIndexRel = R_X86_64_DTPMOD64;
@@ -387,7 +388,6 @@ void X86_64::relocateOne(uint8_t *Loc, R
break;
case R_X86_64_64:
case R_X86_64_DTPOFF64:
- case R_X86_64_GLOB_DAT:
case R_X86_64_PC64:
case R_X86_64_SIZE64:
case R_X86_64_GOT64:
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Tue Jun 11 05:59:30 2019
@@ -861,19 +861,19 @@ static void addGotEntry(Symbol &Sym) {
bool IsLinkTimeConstant =
!Sym.IsPreemptible && (!Config->Pic || isAbsolute(Sym));
if (IsLinkTimeConstant) {
- In.Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym});
+ In.Got->Relocations.push_back({Expr, Target->SymbolicRel, Off, 0, &Sym});
return;
}
// Otherwise, we emit a dynamic relocation to .rel[a].dyn so that
// the GOT slot will be fixed at load-time.
if (!Sym.isTls() && !Sym.IsPreemptible && Config->Pic && !isAbsolute(Sym)) {
- addRelativeReloc(In.Got, Off, &Sym, 0, R_ABS, Target->GotRel);
+ addRelativeReloc(In.Got, Off, &Sym, 0, R_ABS, Target->SymbolicRel);
return;
}
- Main->RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel,
- In.Got, Off, &Sym, 0,
- Sym.IsPreemptible ? R_ADDEND : R_ABS, Target->GotRel);
+ Main->RelaDyn->addReloc(
+ Sym.isTls() ? Target->TlsGotRel : Target->GotRel, In.Got, Off, &Sym, 0,
+ Sym.IsPreemptible ? R_ADDEND : R_ABS, Target->SymbolicRel);
}
// Return true if we can define a symbol in the executable that
@@ -919,10 +919,10 @@ static void processRelocAux(InputSection
}
bool CanWrite = (Sec.Flags & SHF_WRITE) || !Config->ZText;
if (CanWrite) {
- // R_GOT refers to a position in the got, even if the symbol is preemptible.
- bool IsPreemptibleValue = Sym.IsPreemptible && Expr != R_GOT;
-
- if (!IsPreemptibleValue) {
+ if ((!Sym.IsPreemptible && Type == Target->SymbolicRel) || Expr == R_GOT) {
+ // If this is a symbolic relocation to a non-preemptable symbol, or an
+ // R_GOT, its address is its link-time value plus load address. Represent
+ // it with a relative relocation.
addRelativeReloc(&Sec, Offset, &Sym, Addend, Expr, Type);
return;
} else if (RelType Rel = Target->getDynRel(Type)) {
@@ -967,11 +967,18 @@ static void processRelocAux(InputSection
return;
}
- // Copy relocations are only possible if we are creating an executable.
- if (Config->Shared) {
- errorOrWarn("relocation " + toString(Type) +
- " cannot be used against symbol " + toString(Sym) +
- "; recompile with -fPIC" + getLocation(Sec, Sym, Offset));
+ // 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;
}
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Tue Jun 11 05:59:30 2019
@@ -95,6 +95,7 @@ public:
RelType PltRel;
RelType RelativeRel;
RelType IRelativeRel;
+ RelType SymbolicRel;
RelType TlsDescRel;
RelType TlsGotRel;
RelType TlsModuleIndexRel;
Modified: lld/trunk/test/ELF/linkerscript/visibility.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/visibility.s?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/visibility.s (original)
+++ lld/trunk/test/ELF/linkerscript/visibility.s Tue Jun 11 05:59:30 2019
@@ -19,4 +19,4 @@
.data
.hidden foo
- .long foo
+ .quad foo
Modified: lld/trunk/test/ELF/merge-string-error.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/merge-string-error.s?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/test/ELF/merge-string-error.s (original)
+++ lld/trunk/test/ELF/merge-string-error.s Tue Jun 11 05:59:30 2019
@@ -6,6 +6,6 @@
.asciz "abc"
.data
- .long .rodata.str1.1 + 4
+ .quad .rodata.str1.1 + 4
// CHECK: merge-string-error.s.tmp.o:(.rodata.str1.1): offset is outside the section
Modified: lld/trunk/test/ELF/pack-dyn-relocs-loop.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/pack-dyn-relocs-loop.s?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/test/ELF/pack-dyn-relocs-loop.s (original)
+++ lld/trunk/test/ELF/pack-dyn-relocs-loop.s Tue Jun 11 05:59:30 2019
@@ -46,7 +46,7 @@
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x10004
// CHECK-NEXT: Offset: 0x10004
-// CHECK-NEXT: Size: 12
+// CHECK-NEXT: Size: 24
.data
@@ -54,9 +54,9 @@
.section foo,"aw"
foof:
-.long foof
-.long bar-53
-.long bar
+.quad foof
+.quad bar-53
+.quad bar
.section x,"a"
.zero 65036
Modified: lld/trunk/test/ELF/relocation-before-merge-start.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocation-before-merge-start.s?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/test/ELF/relocation-before-merge-start.s (original)
+++ lld/trunk/test/ELF/relocation-before-merge-start.s Tue Jun 11 05:59:30 2019
@@ -4,6 +4,6 @@
// CHECK: relocation-before-merge-start.s.tmp.o:(.foo): offset is outside the section
.data
-.long .foo - 1
+.quad .foo - 1
.section .foo,"aM", at progbits,4
.quad 0
Modified: lld/trunk/test/ELF/relocation-past-merge-end.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocation-past-merge-end.s?rev=363059&r1=363058&r2=363059&view=diff
==============================================================================
--- lld/trunk/test/ELF/relocation-past-merge-end.s (original)
+++ lld/trunk/test/ELF/relocation-past-merge-end.s Tue Jun 11 05:59:30 2019
@@ -4,6 +4,6 @@
// CHECK: relocation-past-merge-end.s.tmp.o:(.foo): offset is outside the section
.data
-.long .foo + 10
+.quad .foo + 10
.section .foo,"aM", at progbits,4
.quad 0
Added: 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=363059&view=auto
==============================================================================
--- lld/trunk/test/ELF/x86-64-dyn-rel-error5.s (added)
+++ lld/trunk/test/ELF/x86-64-dyn-rel-error5.s Tue Jun 11 05:59:30 2019
@@ -0,0 +1,26 @@
+# 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
+
+## Check we don't create dynamic relocations in a writable section,
+## if the number of bits is smaller than the wordsize.
+
+.globl hidden
+.hidden hidden
+local:
+hidden:
+
+# CHECK: error: relocation R_X86_64_8 cannot be used against local symbol; recompile with -fPIC
+# CHECK-NEXT: >>> defined in {{.*}}.o
+# 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
+
+.data
+.byte local # R_X86_64_8
+.short local # R_X86_64_16
+.long local # R_X86_64_32
+
+.long hidden # R_X86_64_32
More information about the llvm-commits
mailing list