summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Smith <peter.smith@linaro.org>2017-06-06 10:06:48 +0000
committerPeter Smith <peter.smith@linaro.org>2017-06-06 10:06:48 +0000
commit8a2e00e631c24f37abb83b96dadbab8bb66893f6 (patch)
tree139745107923646bc1d39f285ddb9246eacdc084
parent8f7565b6f233fa9b66e1721533c7a97001abdf44 (diff)
downloadbcm5719-llvm-8a2e00e631c24f37abb83b96dadbab8bb66893f6.tar.gz
bcm5719-llvm-8a2e00e631c24f37abb83b96dadbab8bb66893f6.zip
[ELF] Refactor CreateThunks to extract the iteration through InputSections.
In preparation for inserting Thunks into InputSectionDescription::Sections extract the loop that finds InputSections that may have calls that need Thunks. This isn't much benefit now but this will be useful when we have to extract the InputSectionDescriptions::Sections from the script. Differential Revision: https://reviews.llvm.org/D33834 llvm-svn: 304783
-rw-r--r--lld/ELF/Relocations.cpp71
-rw-r--r--lld/ELF/Relocations.h8
2 files changed, 48 insertions, 31 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index bbbc706ff40..3a0e6faf08e 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1001,19 +1001,18 @@ void ThunkCreator::mergeThunks() {
}
}
-ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS,
- OutputSection *OS) {
- if (TS == nullptr) {
+ThunkSection *ThunkCreator::getOSThunkSec(OutputSection *OS) {
+ if (CurTS == 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->Sections].push_back(TS);
+ CurTS = make<ThunkSection>(OS, Off);
+ ThunkSections[&OS->Sections].push_back(CurTS);
}
- return TS;
+ return CurTS;
}
ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) {
@@ -1035,6 +1034,20 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(SymbolBody &Body,
return std::make_pair(res.first->second, res.second);
}
+// Call Fn on every executable InputSection accessed via the linker script
+// InputSectionDescription::Sections.
+void ThunkCreator::forEachExecInputSection(
+ ArrayRef<OutputSection *> OutputSections,
+ std::function<void(OutputSection *, InputSection *)> Fn) {
+ for (OutputSection *OS : OutputSections) {
+ if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
+ continue;
+ CurTS = nullptr;
+ for (InputSection *IS : OS->Sections)
+ Fn(OS, IS);
+ }
+}
+
// Process all relocations from the InputSections that have been assigned
// to OutputSections and redirect through Thunks if needed.
//
@@ -1052,31 +1065,29 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
// We separate the creation of ThunkSections from the insertion of the
// ThunkSections back into the OutputSection as ThunkSections are not always
// inserted into the same OutputSection as the caller.
- for (OutputSection *OS : OutputSections) {
- ThunkSection *OSTS = nullptr;
- for (InputSection *IS : OS->Sections) {
- for (Relocation &Rel : IS->Relocations) {
- SymbolBody &Body = *Rel.Sym;
- 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);
+ forEachExecInputSection(
+ OutputSections, [=](OutputSection *OS, InputSection *IS) {
+ for (Relocation &Rel : IS->Relocations) {
+ SymbolBody &Body = *Rel.Sym;
+ 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(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);
}
- // 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();
diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h
index 44b356a258d..3d1bf421ecc 100644
--- a/lld/ELF/Relocations.h
+++ b/lld/ELF/Relocations.h
@@ -127,8 +127,11 @@ public:
private:
void mergeThunks();
- ThunkSection *getOSThunkSec(ThunkSection *&TS, OutputSection *OS);
+ ThunkSection *getOSThunkSec(OutputSection *OS);
ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS);
+ void forEachExecInputSection(
+ ArrayRef<OutputSection *> OutputSections,
+ std::function<void(OutputSection *, InputSection *)> Fn);
std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
// Track Symbols that already have a Thunk
@@ -140,6 +143,9 @@ private:
// Track the ThunksSections that need to be inserted into an OutputSection
std::map<std::vector<InputSection *> *, std::vector<ThunkSection *>>
ThunkSections;
+
+ // The ThunkSection for this vector of InputSections
+ ThunkSection *CurTS;
};
// Return a int64_t to make sure we get the sign extension out of the way as
OpenPOWER on IntegriCloud