[lld] r263381 - [ELF][MIPS] Factor out SumVA adjustments into a couple of separate functions. NFC.

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 13 08:37:40 PDT 2016


Author: atanasyan
Date: Sun Mar 13 10:37:38 2016
New Revision: 263381

URL: http://llvm.org/viewvc/llvm-project?rev=263381&view=rev
Log:
[ELF][MIPS] Factor out SumVA adjustments into a couple of separate functions. NFC.

The patch does not reduce the size of the code but makes
InputSectionBase::relocate cleaner a bit.

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

Modified:
    lld/trunk/ELF/InputSection.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=263381&r1=263380&r2=263381&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Sun Mar 13 10:37:38 2016
@@ -176,6 +176,49 @@ uint8_t *InputSectionBase<ELFT>::findMip
   return nullptr;
 }
 
+template <class ELFT, class uintX_t>
+static uintX_t adjustMipsSymVA(uint32_t Type, const ObjectFile<ELFT> &File,
+                               const SymbolBody &Body, uintX_t AddrLoc,
+                               uintX_t SymVA) {
+  if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp)
+    return getMipsGpAddr<ELFT>() - AddrLoc;
+  if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp)
+    return getMipsGpAddr<ELFT>() - AddrLoc + 4;
+  if (&Body == Config->MipsLocalGp)
+    return getMipsGpAddr<ELFT>();
+  if (Body.isLocal() && (Type == R_MIPS_GPREL16 || Type == R_MIPS_GPREL32))
+    // We need to adjust SymVA value in case of R_MIPS_GPREL16/32
+    // relocations because they use the following expression to calculate
+    // the relocation's result for local symbol: S + A + GP0 - G.
+    return SymVA + File.getMipsGp0();
+  return SymVA;
+}
+
+template <class ELFT, class uintX_t>
+static uintX_t getMipsGotVA(const SymbolBody &Body, uintX_t SymVA,
+                            uint8_t *BufLoc, uint8_t *PairedLoc) {
+  if (Body.isLocal()) {
+    // If relocation against MIPS local symbol requires GOT entry, this entry
+    // should be initialized by 'page address'. This address is high 16-bits
+    // of sum the symbol's value and the addend. The addend in that case is
+    // calculated using addends from R_MIPS_GOT16 and paired R_MIPS_LO16
+    // relocations.
+    const endianness E = ELFT::TargetEndianness;
+    uint64_t AHL = read32<E>(BufLoc) << 16;
+    if (PairedLoc)
+      AHL += SignExtend64<16>(read32<E>(PairedLoc));
+    return Out<ELFT>::Got->getMipsLocalPageAddr(SymVA + AHL);
+  }
+  if (!canBePreempted(Body))
+    // For non-local symbols GOT entries should contain their full
+    // addresses. But if such symbol cannot be preempted, we do not
+    // have to put them into the "global" part of GOT and use dynamic
+    // linker to determine their actual addresses. That is why we
+    // create GOT entries for them in the "local" part of GOT.
+    return Out<ELFT>::Got->getMipsLocalFullAddr(Body);
+  return Body.getGotVA<ELFT>();
+}
+
 template <class ELFT>
 template <class RelTy>
 void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
@@ -239,29 +282,10 @@ void InputSectionBase<ELFT>::relocate(ui
     if (Target->needsPlt<ELFT>(Type, Body)) {
       SymVA = Body.getPltVA<ELFT>() + A;
     } else if (Target->needsGot(Type, Body)) {
-      if (Config->EMachine == EM_MIPS && !CBP) {
-        if (Body.isLocal()) {
-          // R_MIPS_GOT16 relocation against local symbol requires index of
-          // a local GOT entry which contains page address corresponds
-          // to sum of the symbol address and addend. The addend in that case
-          // is calculated using addends from R_MIPS_GOT16 and paired
-          // R_MIPS_LO16 relocations.
-          const endianness E = ELFT::TargetEndianness;
-          uint64_t AHL = read32<E>(BufLoc) << 16;
-          if (PairedLoc)
-            AHL += SignExtend64<16>(read32<E>(PairedLoc));
-          SymVA = Out<ELFT>::Got->getMipsLocalPageAddr(SymVA + AHL);
-        } else {
-          // For non-local symbols GOT entries should contain their full
-          // addresses. But if such symbol cannot be preempted, we do not
-          // have to put them into the "global" part of GOT and use dynamic
-          // linker to determine their actual addresses. That is why we
-          // create GOT entries for them in the "local" part of GOT.
-          SymVA = Out<ELFT>::Got->getMipsLocalFullAddr(Body) + A;
-        }
-      } else {
+      if (Config->EMachine == EM_MIPS)
+        SymVA = getMipsGotVA<ELFT>(Body, SymVA, BufLoc, PairedLoc) + A;
+      else
         SymVA = Body.getGotVA<ELFT>() + A;
-      }
       if (Body.IsTls)
         Type = Target->getTlsGotRel(Type);
     } else if (Target->isSizeRel(Type) && CBP) {
@@ -271,18 +295,7 @@ void InputSectionBase<ELFT>::relocate(ui
       // with a possibly incorrect value.
       continue;
     } else if (Config->EMachine == EM_MIPS) {
-      if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp) {
-        SymVA = getMipsGpAddr<ELFT>() - AddrLoc + A;
-      } else if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp) {
-        SymVA = getMipsGpAddr<ELFT>() - AddrLoc + 4 + A;
-      } else if (&Body == Config->MipsLocalGp) {
-        SymVA = getMipsGpAddr<ELFT>() + A;
-      } else if (Type == R_MIPS_GPREL16 || Type == R_MIPS_GPREL32) {
-        // We need to adjust SymVA value in case of R_MIPS_GPREL16/32
-        // relocations because they use the following expression to calculate
-        // the relocation's result for local symbol: S + A + GP0 - G.
-        SymVA += File->getMipsGp0();
-      }
+      SymVA = adjustMipsSymVA<ELFT>(Type, *File, Body, AddrLoc, SymVA) + A;
     } else if (!Target->needsCopyRel<ELFT>(Type, Body) && CBP) {
       continue;
     }




More information about the llvm-commits mailing list