[lld] r315617 - Handle MIPS-specific addend rules in computeAddend().

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 12 13:42:15 PDT 2017


Author: ruiu
Date: Thu Oct 12 13:42:15 2017
New Revision: 315617

URL: http://llvm.org/viewvc/llvm-project?rev=315617&view=rev
Log:
Handle MIPS-specific addend rules in computeAddend().

This patch merges computeAddend and computeMipsAddend.

Getting an addend for a relocation is usually pretty easy:
it is either in the r_addend field (if RELA) or in a target
section (if REL).

However, MIPS has many special rules that are different from
other ELF ABIs. I don't think there were technical reasons to
be different, but the reality is that they are different.
It is unfortunate that we had to pass many parameters to
computeAddend, but it seems unavoidable because of MIPS.

Modified:
    lld/trunk/ELF/Relocations.cpp

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=315617&r1=315616&r2=315617&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Thu Oct 12 13:42:15 2017
@@ -299,14 +299,16 @@ handleTlsRelocation(RelType Type, Symbol
   return 0;
 }
 
-static uint32_t getMipsPairType(RelType Type, const SymbolBody &Sym) {
+static RelType getMipsPairType(RelType Type, bool IsLocal) {
   switch (Type) {
   case R_MIPS_HI16:
     return R_MIPS_LO16;
   case R_MIPS_GOT16:
-    return Sym.isLocal() ? R_MIPS_LO16 : R_MIPS_NONE;
+    // I don't know why these relocations had to be defined like this,
+    // but they are handled differently when they refer to local symbols.
+    return IsLocal ? R_MIPS_LO16 : R_MIPS_NONE;
   case R_MICROMIPS_GOT16:
-    return Sym.isLocal() ? R_MICROMIPS_LO16 : R_MIPS_NONE;
+    return IsLocal ? R_MICROMIPS_LO16 : R_MIPS_NONE;
   case R_MIPS_PCHI16:
     return R_MIPS_PCLO16;
   case R_MICROMIPS_HI16:
@@ -631,30 +633,15 @@ static RelExpr adjustExpr(SymbolBody &Bo
   return Expr;
 }
 
-// Returns an addend of a given relocation. If it is RELA, an addend
-// is in a relocation itself. If it is REL, we need to read it from an
-// input section.
-template <class ELFT, class RelTy>
-static int64_t computeAddend(const RelTy &Rel, const uint8_t *Buf) {
-  RelType Type = Rel.getType(Config->IsMips64EL);
-  int64_t A = RelTy::IsRela
-                  ? getAddend<ELFT>(Rel)
-                  : Target->getImplicitAddend(Buf + Rel.r_offset, Type);
-
-  if (Config->EMachine == EM_PPC64 && Config->Pic && Type == R_PPC64_TOC)
-    A += getPPC64TocBase();
-  return A;
-}
-
 // MIPS has an odd notion of "paired" relocations to calculate addends.
 // For example, if a relocation is of R_MIPS_HI16, there must be a
 // R_MIPS_LO16 relocation after that, and an addend is calculated using
 // the two relocations.
 template <class ELFT, class RelTy>
-static int64_t computeMipsAddend(const RelTy &Rel, InputSectionBase &Sec,
-                                 RelExpr Expr, SymbolBody &Body,
-                                 const RelTy *End) {
-  if (Expr == R_MIPS_GOTREL && Body.isLocal())
+static int64_t computeMipsAddend(const RelTy &Rel, const RelTy *End,
+                                 InputSectionBase &Sec, RelExpr Expr,
+                                 bool IsLocal) {
+  if (Expr == R_MIPS_GOTREL && IsLocal)
     return Sec.getFile<ELFT>()->MipsGp0;
 
   // The ABI says that the paired relocation is used only for REL.
@@ -663,7 +650,7 @@ static int64_t computeMipsAddend(const R
     return 0;
 
   RelType Type = Rel.getType(Config->IsMips64EL);
-  uint32_t PairTy = getMipsPairType(Type, Body);
+  uint32_t PairTy = getMipsPairType(Type, IsLocal);
   if (PairTy == R_MIPS_NONE)
     return 0;
 
@@ -672,20 +659,41 @@ static int64_t computeMipsAddend(const R
 
   // To make things worse, paired relocations might not be contiguous in
   // the relocation table, so we need to do linear search. *sigh*
-  for (const RelTy *RI = &Rel; RI != End; ++RI) {
-    if (RI->getType(Config->IsMips64EL) != PairTy)
-      continue;
-    if (RI->getSymbol(Config->IsMips64EL) != SymIndex)
-      continue;
-
-    return Target->getImplicitAddend(Buf + RI->r_offset, PairTy);
-  }
+  for (const RelTy *RI = &Rel; RI != End; ++RI)
+    if (RI->getType(Config->IsMips64EL) == PairTy &&
+        RI->getSymbol(Config->IsMips64EL) == SymIndex)
+      return Target->getImplicitAddend(Buf + RI->r_offset, PairTy);
 
   warn("can't find matching " + toString(PairTy) + " relocation for " +
        toString(Type));
   return 0;
 }
 
+// Returns an addend of a given relocation. If it is RELA, an addend
+// is in a relocation itself. If it is REL, we need to read it from an
+// input section.
+template <class ELFT, class RelTy>
+static int64_t computeAddend(const RelTy &Rel, const RelTy *End,
+                             InputSectionBase &Sec, RelExpr Expr,
+                             bool IsLocal) {
+  int64_t Addend;
+  RelType Type = Rel.getType(Config->IsMips64EL);
+
+  if (RelTy::IsRela) {
+    Addend = getAddend<ELFT>(Rel);
+  } else {
+    const uint8_t *Buf = Sec.Data.data();
+    Addend = Target->getImplicitAddend(Buf + Rel.r_offset, Type);
+  }
+
+  if (Config->EMachine == EM_PPC64 && Config->Pic && Type == R_PPC64_TOC)
+    Addend += getPPC64TocBase();
+  if (Config->EMachine == EM_MIPS)
+    Addend += computeMipsAddend<ELFT>(Rel, End, Sec, Expr, IsLocal);
+
+  return Addend;
+}
+
 // Report an undefined symbol if necessary.
 // Returns true if this function printed out an error message.
 template <class ELFT>
@@ -860,8 +868,7 @@ static void scanRelocs(InputSectionBase
 
     // Handle yet another MIPS-ness.
     if (isMipsGprel(Type)) {
-      int64_t Addend = computeAddend<ELFT>(Rel, Sec.Data.data()) +
-                       computeMipsAddend<ELFT>(Rel, Sec, Expr, Body, End);
+      int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Body.isLocal());
       Sec.Relocations.push_back({R_MIPS_GOTREL, Type, Offset, Addend, &Body});
       continue;
     }
@@ -898,9 +905,7 @@ static void scanRelocs(InputSectionBase
       InX::Got->HasGotOffRel = true;
 
     // Read an addend.
-    int64_t Addend = computeAddend<ELFT>(Rel, Sec.Data.data());
-    if (Config->EMachine == EM_MIPS)
-      Addend += computeMipsAddend<ELFT>(Rel, Sec, Expr, Body, End);
+    int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Body.isLocal());
 
     // Process some TLS relocations, including relaxing TLS relocations.
     // Note that this function does not handle all TLS relocations.




More information about the llvm-commits mailing list