[lld] 1e57038 - [ELF] Pass `Relocation` to relaxGot and relaxTls{GdToIe, GdToLe, LdToLe, IeToLe}

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 23 10:41:35 PST 2020


Author: Fangrui Song
Date: 2020-01-23T10:39:25-08:00
New Revision: 1e57038bf21e445683cc8d7754955bbdec84e580

URL: https://github.com/llvm/llvm-project/commit/1e57038bf21e445683cc8d7754955bbdec84e580
DIFF: https://github.com/llvm/llvm-project/commit/1e57038bf21e445683cc8d7754955bbdec84e580.diff

LOG: [ELF] Pass `Relocation` to relaxGot and relaxTls{GdToIe,GdToLe,LdToLe,IeToLe}

These functions call relocateOne(). This patch is a prerequisite for
making relocateOne() aware of `Symbol` (D73254).

Reviewed By: grimar, nickdesaulniers

Differential Revision: https://reviews.llvm.org/D73250

Added: 
    

Modified: 
    lld/ELF/Arch/AArch64.cpp
    lld/ELF/Arch/PPC.cpp
    lld/ELF/Arch/PPC64.cpp
    lld/ELF/Arch/X86.cpp
    lld/ELF/Arch/X86_64.cpp
    lld/ELF/InputSection.cpp
    lld/ELF/Target.cpp
    lld/ELF/Target.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index df41a12f7454..9ab7058a52bb 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -48,9 +48,12 @@ class AArch64 : public TargetInfo {
   void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
   RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
                           RelExpr expr) const override;
-  void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+  void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
 };
 } // namespace
 
@@ -455,7 +458,8 @@ void AArch64::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
   }
 }
 
-void AArch64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+void AArch64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                             uint64_t val) const {
   // TLSDESC Global-Dynamic relocation are in the form:
   //   adrp    x0, :tlsdesc:v             [R_AARCH64_TLSDESC_ADR_PAGE21]
   //   ldr     x1, [x0, #:tlsdesc_lo12:v  [R_AARCH64_TLSDESC_LD64_LO12]
@@ -467,9 +471,9 @@ void AArch64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   //   movk    x0, #0x10
   //   nop
   //   nop
-  checkUInt(loc, val, 32, type);
+  checkUInt(loc, val, 32, rel.type);
 
-  switch (type) {
+  switch (rel.type) {
   case R_AARCH64_TLSDESC_ADD_LO12:
   case R_AARCH64_TLSDESC_CALL:
     write32le(loc, 0xd503201f); // nop
@@ -485,7 +489,8 @@ void AArch64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   }
 }
 
-void AArch64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
+void AArch64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                             uint64_t val) const {
   // TLSDESC Global-Dynamic relocation are in the form:
   //   adrp    x0, :tlsdesc:v             [R_AARCH64_TLSDESC_ADR_PAGE21]
   //   ldr     x1, [x0, #:tlsdesc_lo12:v  [R_AARCH64_TLSDESC_LD64_LO12]
@@ -498,7 +503,7 @@ void AArch64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
   //   nop
   //   nop
 
-  switch (type) {
+  switch (rel.type) {
   case R_AARCH64_TLSDESC_ADD_LO12:
   case R_AARCH64_TLSDESC_CALL:
     write32le(loc, 0xd503201f); // nop
@@ -516,16 +521,17 @@ void AArch64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
   }
 }
 
-void AArch64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
-  checkUInt(loc, val, 32, type);
+void AArch64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                             uint64_t val) const {
+  checkUInt(loc, val, 32, rel.type);
 
-  if (type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) {
+  if (rel.type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) {
     // Generate MOVZ.
     uint32_t regNo = read32le(loc) & 0x1f;
     write32le(loc, (0xd2a00000 | regNo) | (((val >> 16) & 0xffff) << 5));
     return;
   }
-  if (type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) {
+  if (rel.type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) {
     // Generate MOVK.
     uint32_t regNo = read32le(loc) & 0x1f;
     write32le(loc, (0xf2800000 | regNo) | ((val & 0xffff) << 5));

diff  --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp
index 3c0b0c290b58..1cb50cdf26b1 100644
--- a/lld/ELF/Arch/PPC.cpp
+++ b/lld/ELF/Arch/PPC.cpp
@@ -48,10 +48,14 @@ class PPC final : public TargetInfo {
   RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
                           RelExpr expr) const override;
   int getTlsGdRelaxSkip(RelType type) const override;
-  void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+  void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
 };
 } // namespace
 
@@ -368,8 +372,9 @@ int PPC::getTlsGdRelaxSkip(RelType type) const {
   return 1;
 }
 
-void PPC::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
-  switch (type) {
+void PPC::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                         uint64_t val) const {
+  switch (rel.type) {
   case R_PPC_GOT_TLSGD16: {
     // addi rT, rA, x at got@tlsgd --> lwz rT, x at got@tprel(rA)
     uint32_t insn = readFromHalf16(loc);
@@ -386,8 +391,9 @@ void PPC::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
   }
 }
 
-void PPC::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
-  switch (type) {
+void PPC::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                         uint64_t val) const {
+  switch (rel.type) {
   case R_PPC_GOT_TLSGD16:
     // addi r3, r31, x at got@tlsgd --> addis r3, r2, x at tprel@ha
     writeFromHalf16(loc, 0x3c620000 | ha(val));
@@ -401,8 +407,9 @@ void PPC::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   }
 }
 
-void PPC::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
-  switch (type) {
+void PPC::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+                         uint64_t val) const {
+  switch (rel.type) {
   case R_PPC_GOT_TLSLD16:
     // addi r3, rA, x at got@tlsgd --> addis r3, r2, 0
     writeFromHalf16(loc, 0x3c620000);
@@ -417,15 +424,16 @@ void PPC::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   case R_PPC_DTPREL16_HA:
   case R_PPC_DTPREL16_HI:
   case R_PPC_DTPREL16_LO:
-    relocateOne(loc, type, val);
+    relocateOne(loc, rel.type, val);
     break;
   default:
     llvm_unreachable("unsupported relocation for TLS LD to LE relaxation");
   }
 }
 
-void PPC::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
-  switch (type) {
+void PPC::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                         uint64_t val) const {
+  switch (rel.type) {
   case R_PPC_GOT_TPREL16: {
     // lwz rT, x at got@tprel(rA) --> addis rT, r2, x at tprel@ha
     uint32_t rt = readFromHalf16(loc) & 0x03e00000;

diff  --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index da77a4ddaddf..d82a431fa890 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -155,8 +155,7 @@ getRelaTocSymAndAddend(InputSectionBase *tocSec, uint64_t offset) {
 //   ld/lwa 3, 0(3)           # load the value from the address
 //
 // Returns true if the relaxation is performed.
-bool tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
-                                 uint8_t *bufLoc) {
+bool tryRelaxPPC64TocIndirection(const Relocation &rel, uint8_t *bufLoc) {
   assert(config->tocOptimize);
   if (rel.addend < 0)
     return false;
@@ -187,7 +186,7 @@ bool tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
     return false;
 
   // Add PPC64TocOffset that will be subtracted by relocateOne().
-  target->relaxGot(bufLoc, type, tocRelative + ppc64TocOffset);
+  target->relaxGot(bufLoc, rel, tocRelative + ppc64TocOffset);
   return true;
 }
 
@@ -214,11 +213,16 @@ class PPC64 final : public TargetInfo {
   bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
   RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
                           RelExpr expr) const override;
-  void relaxGot(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+  void relaxGot(uint8_t *loc, const Relocation &rel,
+                uint64_t val) const override;
+  void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
 
   bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
                                         uint8_t stOther) const override;
@@ -364,11 +368,11 @@ uint32_t PPC64::calcEFlags() const {
   return 2;
 }
 
-void PPC64::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
-  switch (type) {
+void PPC64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const {
+  switch (rel.type) {
   case R_PPC64_TOC16_HA:
     // Convert "addis reg, 2, .LC0 at toc@h" to "addis reg, 2, var at toc@h" or "nop".
-    relocateOne(loc, type, val);
+    relocateOne(loc, rel.type, val);
     break;
   case R_PPC64_TOC16_LO_DS: {
     // Convert "ld reg, .LC0 at toc@l(reg)" to "addi reg, reg, var at toc@l" or
@@ -385,7 +389,8 @@ void PPC64::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
   }
 }
 
-void PPC64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+void PPC64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                           uint64_t val) const {
   // Reference: 3.7.4.2 of the 64-bit ELF V2 abi supplement.
   // The general dynamic code sequence for a global `x` will look like:
   // Instruction                    Relocation                Symbol
@@ -401,7 +406,7 @@ void PPC64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   // bl __tls_get_addr(x at tlsgd)      into      nop
   // nop                             into      addi r3, r3, x at tprel@l
 
-  switch (type) {
+  switch (rel.type) {
   case R_PPC64_GOT_TLSGD16_HA:
     writeFromHalf16(loc, 0x60000000); // nop
     break;
@@ -424,7 +429,8 @@ void PPC64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   }
 }
 
-void PPC64::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+void PPC64::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+                           uint64_t val) const {
   // Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement.
   // The local dynamic code sequence for a global `x` will look like:
   // Instruction                    Relocation                Symbol
@@ -440,7 +446,7 @@ void PPC64::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   // bl __tls_get_addr(x at tlsgd)     into      nop
   // nop                            into      addi r3, r3, 4096
 
-  switch (type) {
+  switch (rel.type) {
   case R_PPC64_GOT_TLSLD16_HA:
     writeFromHalf16(loc, 0x60000000); // nop
     break;
@@ -457,7 +463,7 @@ void PPC64::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   case R_PPC64_DTPREL16_DS:
   case R_PPC64_DTPREL16_LO:
   case R_PPC64_DTPREL16_LO_DS:
-    relocateOne(loc, type, val);
+    relocateOne(loc, rel.type, val);
     break;
   default:
     llvm_unreachable("unsupported relocation for TLS LD to LE relaxation");
@@ -489,7 +495,8 @@ unsigned getPPCDFormOp(unsigned secondaryOp) {
   }
 }
 
-void PPC64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
+void PPC64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                           uint64_t val) const {
   // The initial exec code sequence for a global `x` will look like:
   // Instruction                    Relocation                Symbol
   // addis r9, r2, x at got@tprel at ha   R_PPC64_GOT_TPREL16_HA      x
@@ -510,7 +517,7 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
   // indexed load or store instructions.
 
   unsigned offset = (config->ekind == ELF64BEKind) ? 2 : 0;
-  switch (type) {
+  switch (rel.type) {
   case R_PPC64_GOT_TPREL16_HA:
     write32(loc - offset, 0x60000000); // nop
     break;
@@ -971,8 +978,9 @@ RelExpr PPC64::adjustRelaxExpr(RelType type, const uint8_t *data,
 //    thread pointer.
 // Since the nop must directly follow the call, the R_PPC64_TLSGD relocation is
 // used as the relaxation hint for both steps 2 and 3.
-void PPC64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
-  switch (type) {
+void PPC64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                           uint64_t val) const {
+  switch (rel.type) {
   case R_PPC64_GOT_TLSGD16_HA:
     // This is relaxed from addis rT, r2, sym at got@tlsgd at ha to
     //                      addis rT, r2, sym at got@tprel at ha.

diff  --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp
index b4daedc0f5dc..83756e4466c6 100644
--- a/lld/ELF/Arch/X86.cpp
+++ b/lld/ELF/Arch/X86.cpp
@@ -39,10 +39,14 @@ class X86 : public TargetInfo {
 
   RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
                           RelExpr expr) const override;
-  void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+  void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
 };
 } // namespace
 
@@ -320,7 +324,7 @@ void X86::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
   }
 }
 
-void X86::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+void X86::relaxTlsGdToLe(uint8_t *loc, const Relocation &, uint64_t val) const {
   // Convert
   //   leal x at tlsgd(, %ebx, 1),
   //   call __tls_get_addr at plt
@@ -335,7 +339,7 @@ void X86::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   write32le(loc + 5, val);
 }
 
-void X86::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
+void X86::relaxTlsGdToIe(uint8_t *loc, const Relocation &, uint64_t val) const {
   // Convert
   //   leal x at tlsgd(, %ebx, 1),
   //   call __tls_get_addr at plt
@@ -352,14 +356,15 @@ void X86::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
 
 // In some conditions, relocations can be optimized to avoid using GOT.
 // This function does that for Initial Exec to Local Exec case.
-void X86::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
+void X86::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                         uint64_t val) const {
   // Ulrich's document section 6.2 says that @gotntpoff can
   // be used with MOVL or ADDL instructions.
   // @indntpoff is similar to @gotntpoff, but for use in
   // position dependent code.
   uint8_t reg = (loc[-1] >> 3) & 7;
 
-  if (type == R_386_TLS_IE) {
+  if (rel.type == R_386_TLS_IE) {
     if (loc[-1] == 0xa1) {
       // "movl foo at indntpoff,%eax" -> "movl $foo,%eax"
       // This case is 
diff erent from the generic case below because
@@ -375,7 +380,7 @@ void X86::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
       loc[-1] = 0xc0 | reg;
     }
   } else {
-    assert(type == R_386_TLS_GOTIE);
+    assert(rel.type == R_386_TLS_GOTIE);
     if (loc[-2] == 0x8b) {
       // "movl foo at gottpoff(%rip),%reg" -> "movl $foo,%reg"
       loc[-2] = 0xc7;
@@ -389,8 +394,9 @@ void X86::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
   write32le(loc, val);
 }
 
-void X86::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
-  if (type == R_386_TLS_LDO_32) {
+void X86::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+                         uint64_t val) const {
+  if (rel.type == R_386_TLS_LDO_32) {
     write32le(loc, val);
     return;
   }

diff  --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 74b72eb91293..6a104b333469 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -39,11 +39,16 @@ class X86_64 : public TargetInfo {
 
   RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
                           RelExpr expr) const override;
-  void relaxGot(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
-  void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+  void relaxGot(uint8_t *loc, const Relocation &rel,
+                uint64_t val) const override;
+  void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
+  void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+                      uint64_t val) const override;
   bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
                                         uint8_t stOther) const override;
 };
@@ -177,8 +182,9 @@ RelType X86_64::getDynRel(RelType type) const {
   return R_X86_64_NONE;
 }
 
-void X86_64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
-  if (type == R_X86_64_TLSGD) {
+void X86_64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                            uint64_t val) const {
+  if (rel.type == R_X86_64_TLSGD) {
     // Convert
     //   .byte 0x66
     //   leaq x at tlsgd(%rip), %rdi
@@ -201,7 +207,7 @@ void X86_64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
     //   lea x at tlsgd(%rip), %rax
     //   call *(%rax)
     // to the following two instructions.
-    assert(type == R_X86_64_GOTPC32_TLSDESC);
+    assert(rel.type == R_X86_64_GOTPC32_TLSDESC);
     if (memcmp(loc - 3, "\x48\x8d\x05", 3)) {
       error(getErrorLocation(loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used "
                                         "in callq *x at tlsdesc(%rip), %rax");
@@ -217,8 +223,9 @@ void X86_64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
   }
 }
 
-void X86_64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
-  if (type == R_X86_64_TLSGD) {
+void X86_64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                            uint64_t val) const {
+  if (rel.type == R_X86_64_TLSGD) {
     // Convert
     //   .byte 0x66
     //   leaq x at tlsgd(%rip), %rdi
@@ -241,7 +248,7 @@ void X86_64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
     //   lea x at tlsgd(%rip), %rax
     //   call *(%rax)
     // to the following two instructions.
-    assert(type == R_X86_64_GOTPC32_TLSDESC);
+    assert(rel.type == R_X86_64_GOTPC32_TLSDESC);
     if (memcmp(loc - 3, "\x48\x8d\x05", 3)) {
       error(getErrorLocation(loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used "
                                         "in callq *x at tlsdesc(%rip), %rax");
@@ -258,7 +265,8 @@ void X86_64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
 
 // 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_64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
+void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &,
+                            uint64_t val) const {
   uint8_t *inst = loc - 3;
   uint8_t reg = loc[-1] >> 3;
   uint8_t *regSlot = loc - 1;
@@ -299,12 +307,13 @@ void X86_64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
   write32le(loc, val + 4);
 }
 
-void X86_64::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
-  if (type == R_X86_64_DTPOFF64) {
+void X86_64::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+                            uint64_t val) const {
+  if (rel.type == R_X86_64_DTPOFF64) {
     write64le(loc, val);
     return;
   }
-  if (type == R_X86_64_DTPOFF32) {
+  if (rel.type == R_X86_64_DTPOFF32) {
     write32le(loc, val);
     return;
   }
@@ -495,7 +504,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
   write32le(loc, val);
 }
 
-void X86_64::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
+void X86_64::relaxGot(uint8_t *loc, const Relocation &, uint64_t val) const {
   const uint8_t op = loc[-2];
   const uint8_t modRm = loc[-1];
 

diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index aab272f53a73..69a98c1a337d 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -939,29 +939,29 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
     switch (expr) {
     case R_RELAX_GOT_PC:
     case R_RELAX_GOT_PC_NOPIC:
-      target->relaxGot(bufLoc, type, targetVA);
+      target->relaxGot(bufLoc, rel, targetVA);
       break;
     case R_PPC64_RELAX_TOC:
-      if (!tryRelaxPPC64TocIndirection(type, rel, bufLoc))
+      if (!tryRelaxPPC64TocIndirection(rel, bufLoc))
         target->relocateOne(bufLoc, type, targetVA);
       break;
     case R_RELAX_TLS_IE_TO_LE:
-      target->relaxTlsIeToLe(bufLoc, type, targetVA);
+      target->relaxTlsIeToLe(bufLoc, rel, targetVA);
       break;
     case R_RELAX_TLS_LD_TO_LE:
     case R_RELAX_TLS_LD_TO_LE_ABS:
-      target->relaxTlsLdToLe(bufLoc, type, targetVA);
+      target->relaxTlsLdToLe(bufLoc, rel, targetVA);
       break;
     case R_RELAX_TLS_GD_TO_LE:
     case R_RELAX_TLS_GD_TO_LE_NEG:
-      target->relaxTlsGdToLe(bufLoc, type, targetVA);
+      target->relaxTlsGdToLe(bufLoc, rel, targetVA);
       break;
     case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
     case R_RELAX_TLS_GD_TO_IE:
     case R_RELAX_TLS_GD_TO_IE_ABS:
     case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
     case R_RELAX_TLS_GD_TO_IE_GOTPLT:
-      target->relaxTlsGdToIe(bufLoc, type, targetVA);
+      target->relaxTlsGdToIe(bufLoc, rel, targetVA);
       break;
     case R_PPC64_CALL:
       // If this is a call to __tls_get_addr, it may be part of a TLS

diff  --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index d3899d0f18f1..7b0824a387bc 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -155,26 +155,27 @@ RelExpr TargetInfo::adjustRelaxExpr(RelType type, const uint8_t *data,
   return expr;
 }
 
-void TargetInfo::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
+void TargetInfo::relaxGot(uint8_t *loc, const Relocation &rel,
+                          uint64_t val) const {
   llvm_unreachable("Should not have claimed to be relaxable");
 }
 
-void TargetInfo::relaxTlsGdToLe(uint8_t *loc, RelType type,
+void TargetInfo::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
                                 uint64_t val) const {
   llvm_unreachable("Should not have claimed to be relaxable");
 }
 
-void TargetInfo::relaxTlsGdToIe(uint8_t *loc, RelType type,
+void TargetInfo::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
                                 uint64_t val) const {
   llvm_unreachable("Should not have claimed to be relaxable");
 }
 
-void TargetInfo::relaxTlsIeToLe(uint8_t *loc, RelType type,
+void TargetInfo::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
                                 uint64_t val) const {
   llvm_unreachable("Should not have claimed to be relaxable");
 }
 
-void TargetInfo::relaxTlsLdToLe(uint8_t *loc, RelType type,
+void TargetInfo::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
                                 uint64_t val) const {
   llvm_unreachable("Should not have claimed to be relaxable");
 }

diff  --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 949a7bfdf64b..f997c13a462c 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -129,11 +129,16 @@ class TargetInfo {
 
   virtual RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
                                   RelExpr expr) const;
-  virtual void relaxGot(uint8_t *loc, RelType type, uint64_t val) const;
-  virtual void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const;
-  virtual void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const;
-  virtual void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const;
-  virtual void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const;
+  virtual void relaxGot(uint8_t *loc, const Relocation &rel,
+                        uint64_t val) const;
+  virtual void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+                              uint64_t val) const;
+  virtual void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+                              uint64_t val) const;
+  virtual void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+                              uint64_t val) const;
+  virtual void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+                              uint64_t val) const;
 
 protected:
   // On FreeBSD x86_64 the first page cannot be mmaped.
@@ -171,8 +176,7 @@ static inline std::string getErrorLocation(const uint8_t *loc) {
 
 void writePPC32GlinkSection(uint8_t *buf, size_t numEntries);
 
-bool tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
-                                 uint8_t *bufLoc);
+bool tryRelaxPPC64TocIndirection(const Relocation &rel, uint8_t *bufLoc);
 unsigned getPPCDFormOp(unsigned secondaryOp);
 
 // In the PowerPC64 Elf V2 abi a function can have 2 entry points.  The first


        


More information about the llvm-commits mailing list