[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