forked from OSchip/llvm-project
[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
This commit is contained in:
parent
28f03bbcbb
commit
8f7565b6f2
|
@ -967,33 +967,38 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
|
||||||
// in the Sections vector, and recalculate the InputSection output section
|
// in the Sections vector, and recalculate the InputSection output section
|
||||||
// offsets.
|
// offsets.
|
||||||
// This may invalidate any output section offsets stored outside of InputSection
|
// This may invalidate any output section offsets stored outside of InputSection
|
||||||
void ThunkCreator::mergeThunks(OutputSection *OS,
|
void ThunkCreator::mergeThunks() {
|
||||||
std::vector<ThunkSection *> &Thunks) {
|
for (auto &KV : ThunkSections) {
|
||||||
// Order Thunks in ascending OutSecOff
|
std::vector<InputSection *> *ISR = KV.first;
|
||||||
auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
|
std::vector<ThunkSection *> &Thunks = KV.second;
|
||||||
return A->OutSecOff < B->OutSecOff;
|
|
||||||
};
|
|
||||||
std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
|
|
||||||
|
|
||||||
// Merge sorted vectors of Thunks and InputSections by OutSecOff
|
// Order Thunks in ascending OutSecOff
|
||||||
std::vector<InputSection *> Tmp;
|
auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
|
||||||
Tmp.reserve(OS->Sections.size() + Thunks.size());
|
return A->OutSecOff < B->OutSecOff;
|
||||||
auto MergeCmp = [](const InputSection *A, const InputSection *B) {
|
};
|
||||||
// std::merge requires a strict weak ordering.
|
std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
|
||||||
if (A->OutSecOff < B->OutSecOff)
|
|
||||||
return true;
|
// Merge sorted vectors of Thunks and InputSections by OutSecOff
|
||||||
if (A->OutSecOff == B->OutSecOff)
|
std::vector<InputSection *> Tmp;
|
||||||
// Check if Thunk is immediately before any specific Target InputSection
|
Tmp.reserve(ISR->size() + Thunks.size());
|
||||||
// for example Mips LA25 Thunks.
|
auto MergeCmp = [](const InputSection *A, const InputSection *B) {
|
||||||
if (auto *TA = dyn_cast<ThunkSection>(A))
|
// std::merge requires a strict weak ordering.
|
||||||
if (TA && TA->getTargetInputSection() == B)
|
if (A->OutSecOff < B->OutSecOff)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
if (A->OutSecOff == B->OutSecOff)
|
||||||
};
|
// Check if Thunk is immediately before any specific Target InputSection
|
||||||
std::merge(OS->Sections.begin(), OS->Sections.end(), Thunks.begin(),
|
// for example Mips LA25 Thunks.
|
||||||
Thunks.end(), std::back_inserter(Tmp), MergeCmp);
|
if (auto *TA = dyn_cast<ThunkSection>(A))
|
||||||
OS->Sections = std::move(Tmp);
|
if (TA && TA->getTargetInputSection() == B)
|
||||||
OS->assignOffsets();
|
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,
|
ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS,
|
||||||
|
@ -1006,7 +1011,7 @@ ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TS = make<ThunkSection>(OS, Off);
|
TS = make<ThunkSection>(OS, Off);
|
||||||
ThunkSections[OS].push_back(TS);
|
ThunkSections[&OS->Sections].push_back(TS);
|
||||||
}
|
}
|
||||||
return TS;
|
return TS;
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1022,7 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) {
|
||||||
return TS;
|
return TS;
|
||||||
auto *TOS = IS->getParent();
|
auto *TOS = IS->getParent();
|
||||||
TS = make<ThunkSection>(TOS, IS->OutSecOff);
|
TS = make<ThunkSection>(TOS, IS->OutSecOff);
|
||||||
ThunkSections[TOS].push_back(TS);
|
ThunkSections[&TOS->Sections].push_back(TS);
|
||||||
ThunkedSections[IS] = TS;
|
ThunkedSections[IS] = TS;
|
||||||
return TS;
|
return TS;
|
||||||
}
|
}
|
||||||
|
@ -1074,8 +1079,7 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge all created synthetic ThunkSections back into OutputSection
|
// Merge all created synthetic ThunkSections back into OutputSection
|
||||||
for (auto &KV : ThunkSections)
|
mergeThunks();
|
||||||
mergeThunks(KV.first, KV.second);
|
|
||||||
return !ThunkSections.empty();
|
return !ThunkSections.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ public:
|
||||||
bool createThunks(ArrayRef<OutputSection *> OutputSections);
|
bool createThunks(ArrayRef<OutputSection *> OutputSections);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void mergeThunks(OutputSection *OS, std::vector<ThunkSection *> &Thunks);
|
void mergeThunks();
|
||||||
ThunkSection *getOSThunkSec(ThunkSection *&TS, OutputSection *OS);
|
ThunkSection *getOSThunkSec(ThunkSection *&TS, OutputSection *OS);
|
||||||
ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS);
|
ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS);
|
||||||
std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
|
std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
|
||||||
|
@ -138,7 +138,8 @@ private:
|
||||||
llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections;
|
llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections;
|
||||||
|
|
||||||
// Track the ThunksSections that need to be inserted into an OutputSection
|
// Track the ThunksSections that need to be inserted into an OutputSection
|
||||||
std::map<OutputSection *, std::vector<ThunkSection *>> ThunkSections;
|
std::map<std::vector<InputSection *> *, std::vector<ThunkSection *>>
|
||||||
|
ThunkSections;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a int64_t to make sure we get the sign extension out of the way as
|
// Return a int64_t to make sure we get the sign extension out of the way as
|
||||||
|
|
Loading…
Reference in New Issue