[lld] r299530 - [ELF] Make createThunks a class [NFC]

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 5 03:30:09 PDT 2017


Author: psmith
Date: Wed Apr  5 05:30:09 2017
New Revision: 299530

URL: http://llvm.org/viewvc/llvm-project?rev=299530&view=rev
Log:
[ELF] Make createThunks a class [NFC]
    
For range extension thunks we will need to repeatedly call createThunks()
until no more thunks are created. We will need to retain the state of
Thunks that we have created so far to avoid recreating them on later
passes. This change does not change the functionality of createThunks().

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


Modified:
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Relocations.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=299530&r1=299529&r2=299530&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed Apr  5 05:30:09 2017
@@ -932,8 +932,9 @@ template <class ELFT> void elf::scanRelo
 // in the Sections vector, and recalculate the InputSection output section
 // offsets.
 // This may invalidate any output section offsets stored outside of InputSection
-static void mergeThunks(OutputSection *OS,
-                        std::vector<ThunkSection *> &Thunks) {
+template <class ELFT>
+void ThunkCreator<ELFT>::mergeThunks(OutputSection *OS,
+                                     std::vector<ThunkSection *> &Thunks) {
   // Order Thunks in ascending OutSecOff
   auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
     return A->OutSecOff < B->OutSecOff;
@@ -961,6 +962,44 @@ static void mergeThunks(OutputSection *O
   OS->assignOffsets();
 }
 
+template <class ELFT>
+ThunkSection *ThunkCreator<ELFT>::getOSThunkSec(ThunkSection *&TS,
+                                                OutputSection *OS) {
+  if (TS == nullptr) {
+    uint32_t Off = 0;
+    for (auto *IS : OS->Sections) {
+      Off = IS->OutSecOff + IS->getSize();
+      if ((IS->Flags & SHF_EXECINSTR) == 0)
+        break;
+    }
+    TS = make<ThunkSection>(OS, Off);
+    ThunkSections[OS].push_back(TS);
+  }
+  return TS;
+}
+
+template <class ELFT>
+ThunkSection *ThunkCreator<ELFT>::getISThunkSec(InputSection *IS,
+                                                OutputSection *OS) {
+  ThunkSection *TS = ThunkedSections.lookup(IS);
+  if (TS)
+    return TS;
+  auto *TOS = cast<OutputSection>(IS->OutSec);
+  TS = make<ThunkSection>(TOS, IS->OutSecOff);
+  ThunkSections[TOS].push_back(TS);
+  ThunkedSections[IS] = TS;
+  return TS;
+}
+
+template <class ELFT>
+std::pair<Thunk *, bool> ThunkCreator<ELFT>::getThunk(SymbolBody &Body,
+                                                      uint32_t Type) {
+  auto res = ThunkedSymbols.insert({&Body, nullptr});
+  if (res.second)
+    res.first->second = addThunk<ELFT>(Type, Body);
+  return std::make_pair(res.first->second, res.second);
+}
+
 // Process all relocations from the InputSections that have been assigned
 // to OutputSections and redirect through Thunks if needed.
 //
@@ -972,48 +1011,8 @@ static void mergeThunks(OutputSection *O
 // FIXME: All Thunks are assumed to be in range of the relocation. Range
 // extension Thunks are not yet supported.
 template <class ELFT>
-bool elf::createThunks(ArrayRef<OutputSection *> OutputSections) {
-  // Track Symbols that already have a Thunk
-  DenseMap<SymbolBody *, Thunk *> ThunkedSymbols;
-  // Track InputSections that have a ThunkSection placed in front
-  DenseMap<InputSection *, ThunkSection *> ThunkedSections;
-  // Track the ThunksSections that need to be inserted into an OutputSection
-  std::map<OutputSection *, std::vector<ThunkSection *>> ThunkSections;
-
-  // Find or create a Thunk for Body for relocation Type
-  auto GetThunk = [&](SymbolBody &Body, uint32_t Type) {
-    auto res = ThunkedSymbols.insert({&Body, nullptr});
-    if (res.second == true)
-      res.first->second = addThunk<ELFT>(Type, Body);
-    return std::make_pair(res.first->second, res.second);
-  };
-
-  // Find or create a ThunkSection to be placed immediately before IS
-  auto GetISThunkSec = [&](InputSection *IS, OutputSection *OS) {
-    ThunkSection *TS = ThunkedSections.lookup(IS);
-    if (TS)
-      return TS;
-    auto *TOS = cast<OutputSection>(IS->OutSec);
-    TS = make<ThunkSection>(TOS, IS->OutSecOff);
-    ThunkSections[TOS].push_back(TS);
-    ThunkedSections[IS] = TS;
-    return TS;
-  };
-  // Find or create a ThunkSection to be placed as last executable section in
-  // OS.
-  auto GetOSThunkSec = [&](ThunkSection *&TS, OutputSection *OS) {
-    if (TS == nullptr) {
-      uint32_t Off = 0;
-      for (auto *IS : OS->Sections) {
-        Off = IS->OutSecOff + IS->getSize();
-        if ((IS->Flags & SHF_EXECINSTR) == 0)
-          break;
-      }
-      TS = make<ThunkSection>(OS, Off);
-      ThunkSections[OS].push_back(TS);
-    }
-    return TS;
-  };
+bool ThunkCreator<ELFT>::createThunks(
+    ArrayRef<OutputSection *> OutputSections) {
   // Create all the Thunks and insert them into synthetic ThunkSections. The
   // ThunkSections are later inserted back into the OutputSection.
 
@@ -1025,23 +1024,23 @@ bool elf::createThunks(ArrayRef<OutputSe
     for (InputSection *IS : OS->Sections) {
       for (Relocation &Rel : IS->Relocations) {
         SymbolBody &Body = *Rel.Sym;
-        if (Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body)) {
-          Thunk *T;
-          bool IsNew;
-          std::tie(T, IsNew) = GetThunk(Body, Rel.Type);
-          if (IsNew) {
-            // Find or create a ThunkSection for the new Thunk
-            ThunkSection *TS;
-            if (auto *TIS = T->getTargetInputSection())
-              TS = GetISThunkSec(TIS, OS);
-            else
-              TS = GetOSThunkSec(OSTS, OS);
-            TS->addThunk(T);
-          }
-          // Redirect relocation to Thunk, we never go via the PLT to a Thunk
-          Rel.Sym = T->ThunkSym;
-          Rel.Expr = fromPlt(Rel.Expr);
+        if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body))
+          continue;
+        Thunk *T;
+        bool IsNew;
+        std::tie(T, IsNew) = getThunk(Body, Rel.Type);
+        if (IsNew) {
+          // Find or create a ThunkSection for the new Thunk
+          ThunkSection *TS;
+          if (auto *TIS = T->getTargetInputSection())
+            TS = getISThunkSec(TIS, OS);
+          else
+            TS = getOSThunkSec(OSTS, OS);
+          TS->addThunk(T);
         }
+        // Redirect relocation to Thunk, we never go via the PLT to a Thunk
+        Rel.Sym = T->ThunkSym;
+        Rel.Expr = fromPlt(Rel.Expr);
       }
     }
   }
@@ -1057,7 +1056,7 @@ template void elf::scanRelocations<ELF32
 template void elf::scanRelocations<ELF64LE>(InputSectionBase &);
 template void elf::scanRelocations<ELF64BE>(InputSectionBase &);
 
-template bool elf::createThunks<ELF32LE>(ArrayRef<OutputSection *>);
-template bool elf::createThunks<ELF32BE>(ArrayRef<OutputSection *>);
-template bool elf::createThunks<ELF64LE>(ArrayRef<OutputSection *>);
-template bool elf::createThunks<ELF64BE>(ArrayRef<OutputSection *>);
+template class elf::ThunkCreator<ELF32LE>;
+template class elf::ThunkCreator<ELF32BE>;
+template class elf::ThunkCreator<ELF64LE>;
+template class elf::ThunkCreator<ELF64BE>;

Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=299530&r1=299529&r2=299530&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Wed Apr  5 05:30:09 2017
@@ -11,6 +11,9 @@
 #define LLD_ELF_RELOCATIONS_H
 
 #include "lld/Core/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include <map>
+#include <vector>
 
 namespace lld {
 namespace elf {
@@ -113,8 +116,29 @@ struct Relocation {
 
 template <class ELFT> void scanRelocations(InputSectionBase &);
 
-template <class ELFT>
-bool createThunks(ArrayRef<OutputSection *> OutputSections);
+class ThunkSection;
+class Thunk;
+
+template <class ELFT> class ThunkCreator {
+public:
+  // Return true if Thunks have been added to OutputSections
+  bool createThunks(ArrayRef<OutputSection *> OutputSections);
+
+private:
+  void mergeThunks(OutputSection *OS, std::vector<ThunkSection *> &Thunks);
+  ThunkSection *getOSThunkSec(ThunkSection *&TS, OutputSection *OS);
+  ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS);
+  std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
+
+  // Track Symbols that already have a Thunk
+  llvm::DenseMap<SymbolBody *, Thunk *> ThunkedSymbols;
+
+  // Track InputSections that have a ThunkSection placed in front
+  llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections;
+
+  // Track the ThunksSections that need to be inserted into an OutputSection
+  std::map<OutputSection *, std::vector<ThunkSection *>> ThunkSections;
+};
 
 // Return a int64_t to make sure we get the sign extension out of the way as
 // early as possible.

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=299530&r1=299529&r2=299530&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Apr  5 05:30:09 2017
@@ -1180,7 +1180,8 @@ template <class ELFT> void Writer<ELFT>:
     // we need to assign addresses so that we can tell if jump instructions
     // are out of range. This will need to turn into a loop that converges
     // when no more Thunks are added
-    if (createThunks<ELFT>(OutputSections))
+    ThunkCreator<ELFT> TC;
+    if (TC.createThunks(OutputSections))
       applySynthetic({In<ELFT>::MipsGot},
                      [](SyntheticSection *SS) { SS->updateAllocSize(); });
   }




More information about the llvm-commits mailing list