[llvm-branch-commits] [lld] 572d183 - [ELF] Add TargetInfo::adjustGotPcExpr for `R_GOT_PC` relaxations. NFC

Fangrui Song via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Nov 25 08:48:07 PST 2020


Author: Fangrui Song
Date: 2020-11-25T08:43:26-08:00
New Revision: 572d18397cf0d8808ec85f9bd51471cd80266c27

URL: https://github.com/llvm/llvm-project/commit/572d18397cf0d8808ec85f9bd51471cd80266c27
DIFF: https://github.com/llvm/llvm-project/commit/572d18397cf0d8808ec85f9bd51471cd80266c27.diff

LOG: [ELF] Add TargetInfo::adjustGotPcExpr for `R_GOT_PC` relaxations. NFC

With this change, `TargetInfo::adjustRelaxExpr` is only related to TLS
relaxations and a subsequent clean-up can delete the `data` parameter.

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

Added: 
    

Modified: 
    lld/ELF/Arch/PPC64.cpp
    lld/ELF/Arch/X86_64.cpp
    lld/ELF/Relocations.cpp
    lld/ELF/Target.cpp
    lld/ELF/Target.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index 8a3de2b3cbb2..a18cf9591125 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -384,6 +384,8 @@ 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;
+  RelExpr adjustGotPcExpr(RelType type, int64_t addend,
+                          const uint8_t *loc) const override;
   void relaxGot(uint8_t *loc, const Relocation &rel,
                 uint64_t val) const override;
   void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
@@ -1392,20 +1394,23 @@ bool PPC64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
 
 RelExpr PPC64::adjustRelaxExpr(RelType type, const uint8_t *data,
                                RelExpr expr) const {
+  if (type != R_PPC64_GOT_TLSGD_PCREL34 && expr == R_RELAX_TLS_GD_TO_IE)
+    return R_RELAX_TLS_GD_TO_IE_GOT_OFF;
+  if (expr == R_RELAX_TLS_LD_TO_LE)
+    return R_RELAX_TLS_LD_TO_LE_ABS;
+  return expr;
+}
+
+RelExpr PPC64::adjustGotPcExpr(RelType type, int64_t addend,
+                               const uint8_t *loc) const {
   if ((type == R_PPC64_GOT_PCREL34 || type == R_PPC64_PCREL_OPT) &&
       config->pcRelOptimize) {
     // It only makes sense to optimize pld since paddi means that the address
     // of the object in the GOT is required rather than the object itself.
-    assert(data && "Expecting an instruction encoding here");
-    if ((readPrefixedInstruction(data) & 0xfc000000) == 0xe4000000)
+    if ((readPrefixedInstruction(loc) & 0xfc000000) == 0xe4000000)
       return R_PPC64_RELAX_GOT_PC;
   }
-
-  if (type != R_PPC64_GOT_TLSGD_PCREL34 && expr == R_RELAX_TLS_GD_TO_IE)
-    return R_RELAX_TLS_GD_TO_IE_GOT_OFF;
-  if (expr == R_RELAX_TLS_LD_TO_LE)
-    return R_RELAX_TLS_LD_TO_LE_ABS;
-  return expr;
+  return R_GOT_PC;
 }
 
 // Reference: 3.7.4.1 of the 64-bit ELF V2 abi supplement.

diff  --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 93fd8ecb7c8e..618922844238 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -40,8 +40,8 @@ class X86_64 : public TargetInfo {
   void applyJumpInstrMod(uint8_t *loc, JumpModType type,
                          unsigned size) const override;
 
-  RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
-                          RelExpr expr) const override;
+  RelExpr adjustGotPcExpr(RelType type, int64_t addend,
+                          const uint8_t *loc) const override;
   void relaxGot(uint8_t *loc, const Relocation &rel,
                 uint64_t val) const override;
   void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
@@ -728,12 +728,12 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   }
 }
 
-RelExpr X86_64::adjustRelaxExpr(RelType type, const uint8_t *data,
-                                RelExpr relExpr) const {
+RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend,
+                                const uint8_t *loc) const {
   if (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX)
-    return relExpr;
-  const uint8_t op = data[-2];
-  const uint8_t modRm = data[-1];
+    return R_GOT_PC;
+  const uint8_t op = loc[-2];
+  const uint8_t modRm = loc[-1];
 
   // FIXME: When PIC is disabled and foo is defined locally in the
   // lower 32 bit address space, memory operand in mov can be converted into
@@ -748,11 +748,11 @@ RelExpr X86_64::adjustRelaxExpr(RelType type, const uint8_t *data,
 
   // We don't support test/binop instructions without a REX prefix.
   if (type == R_X86_64_GOTPCRELX)
-    return relExpr;
+    return R_GOT_PC;
 
   // Relaxation of test, adc, add, and, cmp, or, sbb, sub, xor.
   // If PIC then no relaxation is available.
-  return config->isPic ? relExpr : R_RELAX_GOT_PC_NOPIC;
+  return config->isPic ? R_GOT_PC : R_RELAX_GOT_PC_NOPIC;
 }
 
 // A subset of relaxations can only be applied for no-PIC. This method

diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index abb21f1d7274..115957ffefe1 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1361,9 +1361,7 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
   // runtime, because the main executable is always at the beginning of a search
   // list. We can leverage that fact.
   if (!sym.isPreemptible && (!sym.isGnuIFunc() || config->zIfuncNoplt)) {
-    if (expr == R_GOT_PC && !isAbsoluteValue(sym)) {
-      expr = target->adjustRelaxExpr(type, relocatedAddr, expr);
-    } else {
+    if (expr != R_GOT_PC) {
       // The 0x8000 bit of r_addend of R_PPC_PLTREL24 is used to choose call
       // stub type. It should be ignored if optimized to R_PC.
       if (config->emachine == EM_PPC && expr == R_PPC32_PLTREL)
@@ -1375,6 +1373,8 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
             type == R_HEX_GD_PLT_B22_PCREL_X ||
             type == R_HEX_GD_PLT_B32_PCREL_X)))
       expr = fromPlt(expr);
+    } else if (!isAbsoluteValue(sym)) {
+      expr = target->adjustGotPcExpr(type, addend, relocatedAddr);
     }
   }
 

diff  --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 6abd8b452e23..324c07dc7fda 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -155,6 +155,11 @@ RelExpr TargetInfo::adjustRelaxExpr(RelType type, const uint8_t *data,
   return expr;
 }
 
+RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend,
+                                    const uint8_t *data) const {
+  return R_GOT_PC;
+}
+
 void TargetInfo::relaxGot(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 9399ecf526f4..d59d7422e42d 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -150,6 +150,8 @@ class TargetInfo {
 
   virtual RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
                                   RelExpr expr) const;
+  virtual RelExpr adjustGotPcExpr(RelType type, int64_t addend,
+                                  const uint8_t *loc) const;
   virtual void relaxGot(uint8_t *loc, const Relocation &rel,
                         uint64_t val) const;
   virtual void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,


        


More information about the llvm-branch-commits mailing list