[lld] r275235 - Add ILP32 support to X86_64TargetInfo.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 12 16:28:31 PDT 2016


Author: ruiu
Date: Tue Jul 12 18:28:31 2016
New Revision: 275235

URL: http://llvm.org/viewvc/llvm-project?rev=275235&view=rev
Log:
Add ILP32 support to X86_64TargetInfo.

Patch by H.J. Lu.

As x86-64 psABI supports both LP64 and ILP32, this patch adds <ELFT>
template to X86_64TargetInfo.

Differential Revision: http://reviews.llvm.org/D22287

Modified:
    lld/trunk/ELF/Target.cpp

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=275235&r1=275234&r2=275235&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Tue Jul 12 18:28:31 2016
@@ -102,7 +102,7 @@ public:
   void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
 };
 
-class X86_64TargetInfo final : public TargetInfo {
+template <class ELFT> class X86_64TargetInfo final : public TargetInfo {
 public:
   X86_64TargetInfo();
   RelExpr getRelExpr(uint32_t Type, const SymbolBody &S) const override;
@@ -236,7 +236,9 @@ TargetInfo *createTarget() {
   case EM_PPC64:
     return new PPC64TargetInfo();
   case EM_X86_64:
-    return new X86_64TargetInfo();
+    if (Config->EKind == ELF32LEKind)
+      return new X86_64TargetInfo<ELF32LE>();
+    return new X86_64TargetInfo<ELF64LE>();
   }
   fatal("unknown target machine");
 }
@@ -538,7 +540,7 @@ void X86TargetInfo::relaxTlsLdToLe(uint8
   memcpy(Loc - 2, Inst, sizeof(Inst));
 }
 
-X86_64TargetInfo::X86_64TargetInfo() {
+template <class ELFT> X86_64TargetInfo<ELFT>::X86_64TargetInfo() {
   CopyRel = R_X86_64_COPY;
   GotRel = R_X86_64_GLOB_DAT;
   PltRel = R_X86_64_JUMP_SLOT;
@@ -552,7 +554,9 @@ X86_64TargetInfo::X86_64TargetInfo() {
   TlsGdRelaxSkip = 2;
 }
 
-RelExpr X86_64TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
+template <class ELFT>
+RelExpr X86_64TargetInfo<ELFT>::getRelExpr(uint32_t Type,
+                                           const SymbolBody &S) const {
   switch (Type) {
   default:
     return R_ABS;
@@ -580,35 +584,40 @@ RelExpr X86_64TargetInfo::getRelExpr(uin
   }
 }
 
-void X86_64TargetInfo::writeGotPltHeader(uint8_t *Buf) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::writeGotPltHeader(uint8_t *Buf) const {
   // The first entry holds the value of _DYNAMIC. It is not clear why that is
   // required, but it is documented in the psabi and the glibc dynamic linker
   // seems to use it (note that this is relevant for linking ld.so, not any
   // other program).
-  write64le(Buf, Out<ELF64LE>::Dynamic->getVA());
+  write64le(Buf, Out<ELFT>::Dynamic->getVA());
 }
 
-void X86_64TargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &S) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::writeGotPlt(uint8_t *Buf,
+                                         const SymbolBody &S) const {
   // See comments in X86TargetInfo::writeGotPlt.
-  write32le(Buf, S.getPltVA<ELF64LE>() + 6);
+  write32le(Buf, S.getPltVA<ELFT>() + 6);
 }
 
-void X86_64TargetInfo::writePltHeader(uint8_t *Buf) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::writePltHeader(uint8_t *Buf) const {
   const uint8_t PltData[] = {
       0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip)
       0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip)
       0x0f, 0x1f, 0x40, 0x00              // nopl 0x0(rax)
   };
   memcpy(Buf, PltData, sizeof(PltData));
-  uint64_t Got = Out<ELF64LE>::GotPlt->getVA();
-  uint64_t Plt = Out<ELF64LE>::Plt->getVA();
+  uint64_t Got = Out<ELFT>::GotPlt->getVA();
+  uint64_t Plt = Out<ELFT>::Plt->getVA();
   write32le(Buf + 2, Got - Plt + 2); // GOT+8
   write32le(Buf + 8, Got - Plt + 4); // GOT+16
 }
 
-void X86_64TargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
-                                uint64_t PltEntryAddr, int32_t Index,
-                                unsigned RelOff) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
+                                      uint64_t PltEntryAddr, int32_t Index,
+                                      unsigned RelOff) const {
   const uint8_t Inst[] = {
       0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip)
       0x68, 0x00, 0x00, 0x00, 0x00,       // pushq <relocation index>
@@ -621,27 +630,32 @@ void X86_64TargetInfo::writePlt(uint8_t
   write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16);
 }
 
-uint32_t X86_64TargetInfo::getDynRel(uint32_t Type) const {
+template <class ELFT>
+uint32_t X86_64TargetInfo<ELFT>::getDynRel(uint32_t Type) const {
   if (Type == R_X86_64_PC32 || Type == R_X86_64_32)
     errorDynRel(Type);
   return Type;
 }
 
-bool X86_64TargetInfo::isTlsInitialExecRel(uint32_t Type) const {
+template <class ELFT>
+bool X86_64TargetInfo<ELFT>::isTlsInitialExecRel(uint32_t Type) const {
   return Type == R_X86_64_GOTTPOFF;
 }
 
-bool X86_64TargetInfo::isTlsGlobalDynamicRel(uint32_t Type) const {
+template <class ELFT>
+bool X86_64TargetInfo<ELFT>::isTlsGlobalDynamicRel(uint32_t Type) const {
   return Type == R_X86_64_TLSGD;
 }
 
-bool X86_64TargetInfo::isTlsLocalDynamicRel(uint32_t Type) const {
+template <class ELFT>
+bool X86_64TargetInfo<ELFT>::isTlsLocalDynamicRel(uint32_t Type) const {
   return Type == R_X86_64_DTPOFF32 || Type == R_X86_64_DTPOFF64 ||
          Type == R_X86_64_TLSLD;
 }
 
-void X86_64TargetInfo::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
-                                      uint64_t Val) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
+                                            uint64_t Val) const {
   // Convert
   //   .byte 0x66
   //   leaq x at tlsgd(%rip), %rdi
@@ -661,8 +675,9 @@ void X86_64TargetInfo::relaxTlsGdToLe(ui
   relocateOne(Loc + 8, R_X86_64_TPOFF32, Val + 4);
 }
 
-void X86_64TargetInfo::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,
-                                      uint64_t Val) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,
+                                            uint64_t Val) const {
   // Convert
   //   .byte 0x66
   //   leaq x at tlsgd(%rip), %rdi
@@ -684,8 +699,9 @@ void X86_64TargetInfo::relaxTlsGdToIe(ui
 
 // In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to
 // R_X86_64_TPOFF32 so that it does not use GOT.
-void X86_64TargetInfo::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type,
-                                      uint64_t Val) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type,
+                                            uint64_t Val) const {
   uint8_t *Inst = Loc - 3;
   uint8_t Reg = Loc[-1] >> 3;
   uint8_t *RegSlot = Loc - 1;
@@ -725,8 +741,9 @@ void X86_64TargetInfo::relaxTlsIeToLe(ui
   relocateOne(Loc, R_X86_64_TPOFF32, Val + 4);
 }
 
-void X86_64TargetInfo::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type,
-                                      uint64_t Val) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type,
+                                            uint64_t Val) const {
   // Convert
   //   leaq bar at tlsld(%rip), %rdi
   //   callq __tls_get_addr at PLT
@@ -753,8 +770,9 @@ void X86_64TargetInfo::relaxTlsLdToLe(ui
   memcpy(Loc - 3, Inst, sizeof(Inst));
 }
 
-void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
-                                   uint64_t Val) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type,
+                                         uint64_t Val) const {
   switch (Type) {
   case R_X86_64_32:
     checkUInt<32>(Val, Type);
@@ -787,8 +805,10 @@ void X86_64TargetInfo::relocateOne(uint8
   }
 }
 
-RelExpr X86_64TargetInfo::adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
-                                          RelExpr RelExpr) const {
+template <class ELFT>
+RelExpr X86_64TargetInfo<ELFT>::adjustRelaxExpr(uint32_t Type,
+                                                const uint8_t *Data,
+                                                RelExpr RelExpr) const {
   if (Type != R_X86_64_GOTPCRELX && Type != R_X86_64_REX_GOTPCRELX)
     return RelExpr;
   const uint8_t Op = Data[-2];
@@ -816,8 +836,9 @@ RelExpr X86_64TargetInfo::adjustRelaxExp
 // "Intel 64 and IA-32 Architectures Software Developer's Manual V2"
 // (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/
 //    64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf)
-void X86_64TargetInfo::relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
-                                     uint8_t ModRm) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::relaxGotNoPic(uint8_t *Loc, uint64_t Val,
+                                           uint8_t Op, uint8_t ModRm) const {
   const uint8_t Rex = Loc[-3];
   // Convert "test %reg, foo at GOTPCREL(%rip)" to "test $foo, %reg".
   if (Op == 0x85) {
@@ -879,7 +900,8 @@ void X86_64TargetInfo::relaxGotNoPic(uin
   relocateOne(Loc, R_X86_64_PC32, Val);
 }
 
-void X86_64TargetInfo::relaxGot(uint8_t *Loc, uint64_t Val) const {
+template <class ELFT>
+void X86_64TargetInfo<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const {
   const uint8_t Op = Loc[-2];
   const uint8_t ModRm = Loc[-1];
 




More information about the llvm-commits mailing list