[lld] r305555 - [ELF] Enable createThunks to be called more than once.

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 16 06:10:09 PDT 2017


Author: psmith
Date: Fri Jun 16 08:10:08 2017
New Revision: 305555

URL: http://llvm.org/viewvc/llvm-project?rev=305555&view=rev
Log:
[ELF] Enable createThunks to be called more than once.
    
In preparation for supporting range extension thunks we now continually
call createThunks() until no more thunks are added. This requires us to
record the thunks we add on each pass and only merge the new ones into the
OutputSection. We also need to check if a Relocation is targeting a thunk
to prevent us from infinitely creating more thunks.
    
Differential Revision: https://reviews.llvm.org/D34034


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=305555&r1=305554&r2=305555&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Fri Jun 16 08:10:08 2017
@@ -1009,8 +1009,7 @@ ThunkSection *ThunkCreator::getOSThunkSe
       if ((IS->Flags & SHF_EXECINSTR) == 0)
         break;
     }
-    CurTS = make<ThunkSection>(OS, Off);
-    ThunkSections[ISR].push_back(CurTS);
+    CurTS = addThunkSection(OS, ISR, Off);
   }
   return CurTS;
 }
@@ -1020,7 +1019,6 @@ ThunkSection *ThunkCreator::getISThunkSe
   if (TS)
     return TS;
   auto *TOS = IS->getParent();
-  TS = make<ThunkSection>(TOS, IS->OutSecOff);
 
   // Find InputSectionRange within TOS that IS is in
   OutputSectionCommand *C = Script->getCmd(TOS);
@@ -1035,11 +1033,20 @@ ThunkSection *ThunkCreator::getISThunkSe
         break;
       }
     }
-  ThunkSections[Range].push_back(TS);
+  TS = addThunkSection(TOS, Range, IS->OutSecOff);
   ThunkedSections[IS] = TS;
   return TS;
 }
 
+ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,
+                                            std::vector<InputSection *> *ISR,
+                                            uint64_t Off) {
+  auto *TS = make<ThunkSection>(OS, Off);
+  ThunkSections[ISR].push_back(TS);
+  return TS;
+}
+
+
 std::pair<Thunk *, bool> ThunkCreator::getThunk(SymbolBody &Body,
                                                 uint32_t Type) {
   auto res = ThunkedSymbols.insert({&Body, nullptr});
@@ -1081,6 +1088,9 @@ void ThunkCreator::forEachExecInputSecti
 // extension Thunks are not yet supported.
 bool ThunkCreator::createThunks(
     ArrayRef<OutputSectionCommand *> OutputSections) {
+  if (Pass > 0)
+    ThunkSections.clear();
+
   // Create all the Thunks and insert them into synthetic ThunkSections. The
   // ThunkSections are later inserted back into the OutputSection.
 
@@ -1088,11 +1098,12 @@ bool ThunkCreator::createThunks(
   // ThunkSections back into the OutputSection as ThunkSections are not always
   // inserted into the same OutputSection as the caller.
   forEachExecInputSection(
-      OutputSections, [=](OutputSection *OS,  std::vector<InputSection*> *ISR,
+      OutputSections, [&](OutputSection *OS,  std::vector<InputSection*> *ISR,
                           InputSection *IS) {
         for (Relocation &Rel : IS->Relocations) {
           SymbolBody &Body = *Rel.Sym;
-          if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body))
+          if (Thunks.find(&Body) != Thunks.end() ||
+              !Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body))
             continue;
           Thunk *T;
           bool IsNew;
@@ -1105,15 +1116,16 @@ bool ThunkCreator::createThunks(
             else
               TS = getOSThunkSec(OS, ISR);
             TS->addThunk(T);
+            Thunks[T->ThunkSym] = T;
           }
           // Redirect relocation to Thunk, we never go via the PLT to a Thunk
           Rel.Sym = T->ThunkSym;
           Rel.Expr = fromPlt(Rel.Expr);
         }
       });
-
   // Merge all created synthetic ThunkSections back into OutputSection
   mergeThunks();
+  ++Pass;
   return !ThunkSections.empty();
 }
 

Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=305555&r1=305554&r2=305555&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Fri Jun 16 08:10:08 2017
@@ -126,6 +126,11 @@ public:
   // Return true if Thunks have been added to OutputSections
   bool createThunks(ArrayRef<OutputSectionCommand *> OutputSections);
 
+  // The number of completed passes of createThunks this permits us
+  // to do one time initialization on Pass 0 and put a limit on the
+  // number of times it can be called to prevent infinite loops.
+  uint32_t Pass = 0;
+
 private:
   void mergeThunks();
   ThunkSection *getOSThunkSec(OutputSection *OS,
@@ -137,14 +142,22 @@ private:
                          InputSection *)>
           Fn);
   std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
-
+  ThunkSection *addThunkSection(OutputSection *OS,
+                                std::vector<InputSection *> *, uint64_t Off);
   // Track Symbols that already have a Thunk
   llvm::DenseMap<SymbolBody *, Thunk *> ThunkedSymbols;
 
+  // Find a Thunk from the Thunks symbol definition, we can use this to find
+  // the Thunk from a relocation to the Thunks symbol definition.
+  llvm::DenseMap<SymbolBody *, Thunk *> Thunks;
+
   // 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
+  // All the ThunkSections that we have created, organised by OutputSection
+  // will contain a mix of ThunkSections that have been created this pass, and
+  // ThunkSections that have been merged into the OutputSection on previous
+  // passes
   std::map<std::vector<InputSection *> *, std::vector<ThunkSection *>>
       ThunkSections;
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=305555&r1=305554&r2=305555&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Jun 16 08:10:08 2017
@@ -1281,9 +1281,12 @@ template <class ELFT> void Writer<ELFT>:
     // are out of range. This will need to turn into a loop that converges
     // when no more Thunks are added
     ThunkCreator TC;
-    if (TC.createThunks(OutputSectionCommands))
+    if (TC.createThunks(OutputSectionCommands)) {
       applySynthetic({InX::MipsGot},
                      [](SyntheticSection *SS) { SS->updateAllocSize(); });
+      if (TC.createThunks(OutputSectionCommands))
+        fatal("All non-range thunks should be created in first call");
+    }
   }
 
   // Fill other section headers. The dynamic table is finalized




More information about the llvm-commits mailing list