From 8f7565b6f233fa9b66e1721533c7a97001abdf44 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Tue, 6 Jun 2017 09:42:44 +0000 Subject: [PATCH] [ELF] Refactor ThunkCreator to not key on OutputSection for Thunks In preparation for inserting Thunks into InputSectionDescriptions this simple change associates added Thunks with a vector of InputSections instead of an OutputSection. As of now we are just using OutputSection::Sections. Differential Revision: https://reviews.llvm.org/D33832 llvm-svn: 304782 --- lld/ELF/Relocations.cpp | 64 ++++++++++++++++++++++------------------- lld/ELF/Relocations.h | 5 ++-- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 54cc6dd89d46..bbbc706ff40c 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -967,33 +967,38 @@ template void elf::scanRelocations(InputSectionBase &S) { // in the Sections vector, and recalculate the InputSection output section // offsets. // This may invalidate any output section offsets stored outside of InputSection -void ThunkCreator::mergeThunks(OutputSection *OS, - std::vector &Thunks) { - // Order Thunks in ascending OutSecOff - auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) { - return A->OutSecOff < B->OutSecOff; - }; - std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp); +void ThunkCreator::mergeThunks() { + for (auto &KV : ThunkSections) { + std::vector *ISR = KV.first; + std::vector &Thunks = KV.second; - // Merge sorted vectors of Thunks and InputSections by OutSecOff - std::vector Tmp; - Tmp.reserve(OS->Sections.size() + Thunks.size()); - auto MergeCmp = [](const InputSection *A, const InputSection *B) { - // std::merge requires a strict weak ordering. - if (A->OutSecOff < B->OutSecOff) - return true; - if (A->OutSecOff == B->OutSecOff) - // Check if Thunk is immediately before any specific Target InputSection - // for example Mips LA25 Thunks. - if (auto *TA = dyn_cast(A)) - if (TA && TA->getTargetInputSection() == B) - return true; - return false; - }; - std::merge(OS->Sections.begin(), OS->Sections.end(), Thunks.begin(), - Thunks.end(), std::back_inserter(Tmp), MergeCmp); - OS->Sections = std::move(Tmp); - OS->assignOffsets(); + // Order Thunks in ascending OutSecOff + auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) { + return A->OutSecOff < B->OutSecOff; + }; + std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp); + + // Merge sorted vectors of Thunks and InputSections by OutSecOff + std::vector Tmp; + Tmp.reserve(ISR->size() + Thunks.size()); + auto MergeCmp = [](const InputSection *A, const InputSection *B) { + // std::merge requires a strict weak ordering. + if (A->OutSecOff < B->OutSecOff) + return true; + if (A->OutSecOff == B->OutSecOff) + // Check if Thunk is immediately before any specific Target InputSection + // for example Mips LA25 Thunks. + if (auto *TA = dyn_cast(A)) + if (TA && TA->getTargetInputSection() == B) + return true; + return false; + }; + std::merge(ISR->begin(), ISR->end(), Thunks.begin(), Thunks.end(), + std::back_inserter(Tmp), MergeCmp); + OutputSection *OS = Thunks.front()->getParent(); + OS->Sections = std::move(Tmp); + OS->assignOffsets(); + } } ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS, @@ -1006,7 +1011,7 @@ ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS, break; } TS = make(OS, Off); - ThunkSections[OS].push_back(TS); + ThunkSections[&OS->Sections].push_back(TS); } return TS; } @@ -1017,7 +1022,7 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) { return TS; auto *TOS = IS->getParent(); TS = make(TOS, IS->OutSecOff); - ThunkSections[TOS].push_back(TS); + ThunkSections[&TOS->Sections].push_back(TS); ThunkedSections[IS] = TS; return TS; } @@ -1074,8 +1079,7 @@ bool ThunkCreator::createThunks(ArrayRef OutputSections) { } // Merge all created synthetic ThunkSections back into OutputSection - for (auto &KV : ThunkSections) - mergeThunks(KV.first, KV.second); + mergeThunks(); return !ThunkSections.empty(); } diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h index 206f0d9423c9..44b356a258d1 100644 --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -126,7 +126,7 @@ public: bool createThunks(ArrayRef OutputSections); private: - void mergeThunks(OutputSection *OS, std::vector &Thunks); + void mergeThunks(); ThunkSection *getOSThunkSec(ThunkSection *&TS, OutputSection *OS); ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS); std::pair getThunk(SymbolBody &Body, uint32_t Type); @@ -138,7 +138,8 @@ private: llvm::DenseMap ThunkedSections; // Track the ThunksSections that need to be inserted into an OutputSection - std::map> ThunkSections; + std::map *, std::vector> + ThunkSections; }; // Return a int64_t to make sure we get the sign extension out of the way as