[lld] r266604 - Have getRelExpr handle all cases on x86.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 18 05:07:20 PDT 2016


Author: rafael
Date: Mon Apr 18 07:07:13 2016
New Revision: 266604

URL: http://llvm.org/viewvc/llvm-project?rev=266604&view=rev
Log:
Have getRelExpr handle all cases on x86.

This requires adding a few more expression types, but is already a small
simplification. Having Writer.cpp know the exact expression will also
allow further simplifications.

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=266604&r1=266603&r2=266604&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Mon Apr 18 07:07:13 2016
@@ -159,9 +159,11 @@ 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;
   switch (Expr) {
   case R_TLSLD:
-    return Out<ELFT>::Got->getTlsIndexVA() + A;
+    return Out<ELFT>::Got->getTlsIndexOff() + A -
+           Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
   case R_TLSLD_PC:
     return Out<ELFT>::Got->getTlsIndexVA() + A - P;
   case R_THUNK:
@@ -169,7 +171,8 @@ getSymVA(uint32_t Type, typename ELFT::u
   case R_PPC_TOC:
     return getPPC64TocBase() + A;
   case R_TLSGD:
-    return Out<ELFT>::Got->getGlobalDynAddr(Body) + A;
+    return Out<ELFT>::Got->getGlobalDynOffset(Body) + A -
+           Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
   case R_TLSGD_PC:
     return Out<ELFT>::Got->getGlobalDynAddr(Body) + A - P;
   case R_PLT:
@@ -179,6 +182,11 @@ getSymVA(uint32_t Type, typename ELFT::u
     return Body.getPltVA<ELFT>() + A - P;
   case R_SIZE:
     return Body.getSize<ELFT>() + A;
+  case R_GOTREL:
+    return Body.getVA<ELFT>(A) - Out<ELFT>::Got->getVA();
+  case R_GOT_FROM_END:
+    return Body.getGotOffset<ELFT>() + A -
+           Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
   case R_GOT:
   case R_RELAX_TLS_GD_TO_IE:
     return Body.getGotVA<ELFT>() + A;
@@ -187,6 +195,12 @@ getSymVA(uint32_t Type, typename ELFT::u
   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_TLS:
+    return Body.getVA<ELFT>(A) - Out<ELF32LE>::TlsPhdr->p_memsz;
+  case R_NEG_TLS:
+    return Out<ELF32LE>::TlsPhdr->p_memsz - Body.getVA<ELFT>(A);
   case R_ABS:
   case R_RELAX_TLS_GD_TO_LE:
   case R_RELAX_TLS_IE_TO_LE:

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=266604&r1=266603&r2=266604&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Mon Apr 18 07:07:13 2016
@@ -29,11 +29,15 @@ template <class ELFT> class OutputSectio
 enum RelExpr {
   R_ABS,
   R_GOT,
+  R_GOTONLY_PC,
+  R_GOTREL,
+  R_GOT_FROM_END,
   R_GOT_PAGE_PC,
   R_GOT_PC,
   R_MIPS_GOT,
   R_MIPS_GOT_LOCAL,
   R_MIPS_GP0,
+  R_NEG_TLS,
   R_PAGE_PC,
   R_PC,
   R_PLT,
@@ -48,6 +52,7 @@ enum RelExpr {
   R_RELAX_TLS_LD_TO_LE,
   R_SIZE,
   R_THUNK,
+  R_TLS,
   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=266604&r1=266603&r2=266604&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Mon Apr 18 07:07:13 2016
@@ -372,12 +372,20 @@ RelExpr X86TargetInfo::getRelExpr(uint32
     return R_TLSLD;
   case R_386_PLT32:
   case R_386_PC32:
-  case R_386_GOTPC:
     return R_PC;
-  case R_386_GOT32:
-  case R_386_TLS_GOTIE:
+  case R_386_GOTPC:
+    return R_GOTONLY_PC;
   case R_386_TLS_IE:
     return R_GOT;
+  case R_386_GOT32:
+  case R_386_TLS_GOTIE:
+    return R_GOT_FROM_END;
+  case R_386_GOTOFF:
+    return R_GOTREL;
+  case R_386_TLS_LE:
+    return R_TLS;
+  case R_386_TLS_LE_32:
+    return R_NEG_TLS;
   }
 }
 
@@ -507,38 +515,8 @@ uint64_t X86TargetInfo::getImplicitAdden
 
 void X86TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
                                 uint64_t Val) const {
-  switch (Type) {
-  case R_386_32:
-  case R_386_PC32:
-  case R_386_PLT32:
-  case R_386_TLS_IE:
-  case R_386_TLS_LDO_32:
-    write32le(Loc, Val);
-    break;
-  case R_386_GOTOFF:
-    write32le(Loc, Val - Out<ELF32LE>::Got->getVA());
-    break;
-  case R_386_GOTPC:
-    write32le(Loc, Val + Out<ELF32LE>::Got->getVA());
-    break;
-  case R_386_GOT32:
-  case R_386_TLS_GD:
-  case R_386_TLS_LDM: {
-    uint64_t V = Val - Out<ELF32LE>::Got->getVA() -
-                 Out<ELF32LE>::Got->getNumEntries() * 4;
-    checkInt<32>(V, Type);
-    write32le(Loc, V);
-    break;
-  }
-  case R_386_TLS_LE:
-    write32le(Loc, Val - Out<ELF32LE>::TlsPhdr->p_memsz);
-    break;
-  case R_386_TLS_LE_32:
-    write32le(Loc, Out<ELF32LE>::TlsPhdr->p_memsz - Val);
-    break;
-  default:
-    fatal("unrecognized reloc " + Twine(Type));
-  }
+  checkInt<32>(Val, Type);
+  write32le(Loc, Val);
 }
 
 bool X86TargetInfo::needsDynRelative(uint32_t Type) const {
@@ -623,13 +601,13 @@ void X86TargetInfo::relaxTlsIeToLe(uint8
     else
       *Op = 0x80 | Reg | (Reg << 3);
   }
-  relocateOne(Loc, R_386_TLS_LE, Val);
+  relocateOne(Loc, R_386_TLS_LE, Val - Out<ELF32LE>::TlsPhdr->p_memsz);
 }
 
 void X86TargetInfo::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type,
                                    uint64_t Val) const {
   if (Type == R_386_TLS_LDO_32) {
-    relocateOne(Loc, R_386_TLS_LE, Val);
+    relocateOne(Loc, R_386_TLS_LE, Val - Out<ELF32LE>::TlsPhdr->p_memsz);
     return;
   }
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=266604&r1=266603&r2=266604&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Apr 18 07:07:13 2016
@@ -563,7 +563,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
 
     // If a relocation needs GOT, we create a GOT slot for the symbol.
     if (Expr == R_GOT || Expr == R_MIPS_GOT || Expr == R_MIPS_GOT_LOCAL ||
-        Expr == R_GOT_PAGE_PC || Expr == R_GOT_PC) {
+        Expr == R_GOT_PAGE_PC || Expr == R_GOT_PC || Expr == R_GOT_FROM_END) {
       uint32_t T = Body.isTls() ? Target->getTlsGotRel(Type) : Type;
       C.Relocations.push_back({Expr, T, Offset, Addend, &Body});
       if (Body.isInGot())




More information about the llvm-commits mailing list