[lld] r284710 - [ELF] Allow relative exceptions relocations in shared libraries
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 20 02:59:26 PDT 2016
Author: psmith
Date: Thu Oct 20 04:59:26 2016
New Revision: 284710
URL: http://llvm.org/viewvc/llvm-project?rev=284710&view=rev
Log:
[ELF] Allow relative exceptions relocations in shared libraries
The R_ARM_PREL31 and R_ARM_NONE relocations should not be faulted in
shared libraries. In the case of R_ARM_NONE, we have moved the TLS
relaxation hint instruction to R_TLSDESC_CALL so that R_HINT can be used
without side-effects. In the case of R_ARM_PREL31 we permit it to be used
against PLT entries as the personality routines are imported when used in
shared libraries.
Differential Revision: https://reviews.llvm.org/D25721
Added:
lld/trunk/test/ELF/arm-exidx-shared.s (with props)
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/Relocations.h
lld/trunk/ELF/Target.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=284710&r1=284709&r2=284710&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Thu Oct 20 04:59:26 2016
@@ -248,6 +248,7 @@ static typename ELFT::uint getSymVA(uint
const SymbolBody &Body, RelExpr Expr) {
switch (Expr) {
case R_HINT:
+ case R_TLSDESC_CALL:
llvm_unreachable("cannot relocate hint relocs");
case R_TLSLD:
return Out<ELFT>::Got->getTlsIndexOff() + A - Out<ELFT>::Got->getSize();
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=284710&r1=284709&r2=284710&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Thu Oct 20 04:59:26 2016
@@ -143,14 +143,14 @@ static unsigned handleTlsRelocation(uint
return handleNoRelaxTlsRelocation<ELFT>(Type, Body, C, Offset, Addend,
Expr);
- if ((Expr == R_TLSDESC || Expr == R_TLSDESC_PAGE || Expr == R_HINT) &&
+ if ((Expr == R_TLSDESC || Expr == R_TLSDESC_PAGE || Expr == R_TLSDESC_CALL) &&
Config->Shared) {
if (Out<ELFT>::Got->addDynTlsEntry(Body)) {
uintX_t Off = Out<ELFT>::Got->getGlobalDynOffset(Body);
Out<ELFT>::RelaDyn->addReloc(
{Target->TlsDescRel, Out<ELFT>::Got, Off, false, &Body, 0});
}
- if (Expr != R_HINT)
+ if (Expr != R_TLSDESC_CALL)
C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
return 1;
}
@@ -177,7 +177,7 @@ static unsigned handleTlsRelocation(uint
return 1;
}
- if (Expr == R_TLSDESC_PAGE || Expr == R_TLSDESC || Expr == R_HINT ||
+ if (Expr == R_TLSDESC_PAGE || Expr == R_TLSDESC || Expr == R_TLSDESC_CALL ||
Target->isTlsGlobalDynamicRel(Type)) {
if (Config->Shared) {
if (Out<ELFT>::Got->addDynTlsEntry(Body)) {
@@ -304,9 +304,10 @@ static bool isStaticLinkTimeConstant(Rel
// These expressions always compute a constant
if (E == R_SIZE || E == R_GOT_FROM_END || E == R_GOT_OFF ||
E == R_MIPS_GOT_LOCAL_PAGE || E == R_MIPS_GOT_OFF || E == R_MIPS_TLSGD ||
- E == R_GOT_PAGE_PC || E == R_GOT_PC || E == R_PLT_PC || E == R_TLSGD_PC ||
- E == R_TLSGD || E == R_PPC_PLT_OPD || E == R_TLSDESC_PAGE ||
- E == R_HINT || E == R_THUNK_PC || E == R_THUNK_PLT_PC)
+ E == R_GOT_PAGE_PC || E == R_GOT_PC || E == R_PLT_PC ||
+ E == R_TLSGD_PC || E == R_TLSGD || E == R_PPC_PLT_OPD ||
+ E == R_TLSDESC_CALL || E == R_TLSDESC_PAGE || E == R_HINT ||
+ E == R_THUNK_PC || E == R_THUNK_PLT_PC)
return true;
// These never do, except if the entire file is position dependent or if
@@ -621,8 +622,9 @@ static void scanRelocs(InputSectionBase<
continue;
}
- // Ignore "hint" relocation because it is for optional code optimization.
- if (Expr == R_HINT)
+ // Ignore "hint" and TLS Descriptor call relocation because they are
+ // only markers for relaxation.
+ if (Expr == R_HINT || Expr == R_TLSDESC_CALL)
continue;
if (needsPlt(Expr) || Expr == R_THUNK_ABS || Expr == R_THUNK_PC ||
Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=284710&r1=284709&r2=284710&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Thu Oct 20 04:59:26 2016
@@ -61,6 +61,7 @@ enum RelExpr {
R_TLS,
R_TLSDESC,
R_TLSDESC_PAGE,
+ R_TLSDESC_CALL,
R_TLSGD,
R_TLSGD_PC,
R_TLSLD,
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=284710&r1=284709&r2=284710&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Thu Oct 20 04:59:26 2016
@@ -1172,7 +1172,7 @@ RelExpr AArch64TargetInfo::getRelExpr(ui
case R_AARCH64_TLSDESC_ADD_LO12_NC:
return R_TLSDESC;
case R_AARCH64_TLSDESC_CALL:
- return R_HINT;
+ return R_TLSDESC_CALL;
case R_AARCH64_TLSLE_ADD_TPREL_HI12:
case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
return R_TLS;
@@ -1541,6 +1541,7 @@ RelExpr ARMTargetInfo::getRelExpr(uint32
case R_ARM_JUMP24:
case R_ARM_PC24:
case R_ARM_PLT32:
+ case R_ARM_PREL31:
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
@@ -1574,11 +1575,12 @@ RelExpr ARMTargetInfo::getRelExpr(uint32
return R_GOTONLY_PC;
case R_ARM_MOVW_PREL_NC:
case R_ARM_MOVT_PREL:
- case R_ARM_PREL31:
case R_ARM_REL32:
case R_ARM_THM_MOVW_PREL_NC:
case R_ARM_THM_MOVT_PREL:
return R_PC;
+ case R_ARM_NONE:
+ return R_HINT;
case R_ARM_TLS_LE32:
return R_TLS;
}
@@ -1660,8 +1662,6 @@ RelExpr ARMTargetInfo::getThunkExpr(RelE
void ARMTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
uint64_t Val) const {
switch (Type) {
- case R_ARM_NONE:
- break;
case R_ARM_ABS32:
case R_ARM_BASE_PREL:
case R_ARM_GOTOFF32:
Added: lld/trunk/test/ELF/arm-exidx-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-exidx-shared.s?rev=284710&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-exidx-shared.s (added)
+++ lld/trunk/test/ELF/arm-exidx-shared.s Thu Oct 20 04:59:26 2016
@@ -0,0 +1,44 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: ld.lld %t --shared -o %t2 2>&1
+// RUN: llvm-readobj --relocations %t2 | FileCheck %s
+// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXTAB %s
+
+// Check that the relative R_ARM_PREL31 relocation can access a PLT entry
+// for when the personality routine is referenced from a shared library.
+// Also check that the R_ARM_NONE no-op relocation can be used in a shared
+// library.
+ .syntax unified
+// Will produce an ARM.exidx entry with an R_ARM_NONE relocation to
+// __aeabi_unwind_cpp_pr0
+ .section .text.func1, "ax",%progbits
+ .global func1
+func1:
+ .fnstart
+ bx lr
+ .fnend
+
+// Will produce a R_ARM_PREL31 relocation with respect to the PLT entry of
+// __gxx_personality_v0
+ .section .text.func2, "ax",%progbits
+ .global func2
+func2:
+ .fnstart
+ bx lr
+ .personality __gxx_personality_v0
+ .handlerdata
+ .long 0
+ .section .text.func2
+ .fnend
+
+ .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits
+ .global __aeabi_unwind_cpp_pr0
+__aeabi_unwind_cpp_pr0:
+ bx lr
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section (6) .rel.plt {
+// CHECK-NEXT: 0x300C R_ARM_JUMP_SLOT __gxx_personality_v0
+
+// CHECK-EXTAB: Contents of section .ARM.extab.text.func2:
+// 0144 + 0ee0 = 0x1024 = __gxx_personality_v0(PLT)
+// CHECK-EXTAB-NEXT: 0144 e00e0000 b0b0b000 00000000
Propchange: lld/trunk/test/ELF/arm-exidx-shared.s
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lld/trunk/test/ELF/arm-exidx-shared.s
------------------------------------------------------------------------------
svn:keywords = Rev Date Author URL Id
More information about the llvm-commits
mailing list