[lld] r270277 - Refactor R_RELAX_TLS_* value computation.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri May 20 14:23:53 PDT 2016


Author: rafael
Date: Fri May 20 16:23:52 2016
New Revision: 270277

URL: http://llvm.org/viewvc/llvm-project?rev=270277&view=rev
Log:
Refactor R_RELAX_TLS_* value computation.

This makes it explicit that each R_RELAX_TLS_* is equivalent to some
other expression.

With this I think we are at a sweet spot for how much is done in
Target.cpp. I did experiment with moving *all* the value math out of it.
It has the advantage that we know the final value in target independent
code, but it gets quite verbose.

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=270277&r1=270276&r2=270277&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri May 20 16:23:52 2016
@@ -135,15 +135,44 @@ static uint64_t getAArch64Page(uint64_t
   return Expr & (~static_cast<uint64_t>(0xFFF));
 }
 
+// For computing values, each R_RELAX_TLS_* corresponds to whatever expression
+// the target uses in the mode this is being relaxed into. For example, anything
+// that relaxes to LE just needs an R_TLS since that is what is used if we
+// had a local exec expression to begin with.
+static RelExpr getRelaxedExpr(RelExpr Expr) {
+  switch (Expr) {
+  default:
+    return Expr;
+  case R_RELAX_TLS_GD_TO_LE:
+    if (Config->EMachine == EM_386)
+      return R_NEG_TLS;
+    return R_TLS;
+  case R_RELAX_TLS_GD_TO_IE:
+    if (Config->EMachine == EM_386)
+      return R_GOT_FROM_END;
+    return R_GOT_PC;
+  case R_RELAX_TLS_IE_TO_LE:
+  case R_RELAX_TLS_LD_TO_LE:
+    return R_TLS;
+  }
+}
+
 template <class ELFT>
 static typename ELFT::uint
 getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P,
          const SymbolBody &Body, uint8_t *BufLoc,
          const elf::ObjectFile<ELFT> &File, RelExpr Expr) {
   typedef typename ELFT::uint uintX_t;
+  Expr = getRelaxedExpr(Expr);
+
   switch (Expr) {
   case R_HINT:
     llvm_unreachable("cannot relocate hint relocs");
+  case R_RELAX_TLS_GD_TO_LE:
+  case R_RELAX_TLS_GD_TO_IE:
+  case R_RELAX_TLS_IE_TO_LE:
+  case R_RELAX_TLS_LD_TO_LE:
+    llvm_unreachable("Should have been mapped");
   case R_TLSLD:
     return Out<ELFT>::Got->getTlsIndexOff() + A -
            Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
@@ -168,7 +197,6 @@ getSymVA(uint32_t Type, typename ELFT::u
   case R_GOTREL:
     return Body.getVA<ELFT>(A) - Out<ELFT>::Got->getVA();
   case R_GOT_FROM_END:
-  case R_RELAX_TLS_GD_TO_IE:
     return Body.getGotOffset<ELFT>() + A -
            Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
   case R_GOT:
@@ -176,13 +204,9 @@ getSymVA(uint32_t Type, typename ELFT::u
   case R_GOT_PAGE_PC:
     return getAArch64Page(Body.getGotVA<ELFT>() + A) - getAArch64Page(P);
   case R_GOT_PC:
-  case R_RELAX_TLS_GD_TO_IE_PC:
     return Body.getGotVA<ELFT>() + A - P;
   case R_GOTONLY_PC:
     return Out<ELFT>::Got->getVA() + A - P;
-  case R_RELAX_TLS_GD_TO_LE:
-  case R_RELAX_TLS_IE_TO_LE:
-  case R_RELAX_TLS_LD_TO_LE:
   case R_TLS:
     if (Target->TcbSize)
       return Body.getVA<ELFT>(A) +
@@ -308,7 +332,6 @@ void InputSectionBase<ELFT>::relocate(ui
     case R_RELAX_TLS_GD_TO_LE:
       Target->relaxTlsGdToLe(BufLoc, Type, SymVA);
       break;
-    case R_RELAX_TLS_GD_TO_IE_PC:
     case R_RELAX_TLS_GD_TO_IE:
       Target->relaxTlsGdToIe(BufLoc, Type, SymVA);
       break;

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=270277&r1=270276&r2=270277&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Fri May 20 16:23:52 2016
@@ -47,7 +47,6 @@ enum RelExpr {
   R_PPC_PLT_OPD,
   R_PPC_TOC,
   R_RELAX_TLS_GD_TO_IE,
-  R_RELAX_TLS_GD_TO_IE_PC,
   R_RELAX_TLS_GD_TO_LE,
   R_RELAX_TLS_IE_TO_LE,
   R_RELAX_TLS_LD_TO_LE,

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=270277&r1=270276&r2=270277&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri May 20 16:23:52 2016
@@ -400,7 +400,7 @@ void X86TargetInfo::relaxTlsGdToLe(uint8
       0x81, 0xe8, 0x00, 0x00, 0x00, 0x00  // subl 0(%ebx), %eax
   };
   memcpy(Loc - 3, Inst, sizeof(Inst));
-  relocateOne(Loc + 5, R_386_32, -Val);
+  relocateOne(Loc + 5, R_386_32, Val);
 }
 
 void X86TargetInfo::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=270277&r1=270276&r2=270277&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri May 20 16:23:52 2016
@@ -336,9 +336,8 @@ static unsigned handleTlsRelocation(uint
     // Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
     // depending on the symbol being locally defined or not.
     if (Body.isPreemptible()) {
-      Expr =
-          Expr == R_TLSGD_PC ? R_RELAX_TLS_GD_TO_IE_PC : R_RELAX_TLS_GD_TO_IE;
-      C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
+      C.Relocations.push_back(
+          {R_RELAX_TLS_GD_TO_IE, Type, Offset, Addend, &Body});
       if (!Body.isInGot()) {
         Out<ELFT>::Got->addEntry(Body);
         Out<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, Out<ELFT>::Got,




More information about the llvm-commits mailing list