aboutsummaryrefslogtreecommitdiff
path: root/ELF/Relocations.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-06-16 21:04:14 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-06-16 21:04:14 +0000
commit15f7a1a3796209b21af2817fdf11ca9932165c70 (patch)
treeb27ac12a6f210080b2233100767c839224666505 /ELF/Relocations.cpp
parent2079716dfb3fb7e4e24b8b2e85eb6780b981a0af (diff)
Notes
Diffstat (limited to 'ELF/Relocations.cpp')
-rw-r--r--ELF/Relocations.cpp26
1 files changed, 19 insertions, 7 deletions
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index 98c1349a2f0d..1ac3bce769ee 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -1009,8 +1009,7 @@ ThunkSection *ThunkCreator::getOSThunkSec(OutputSection *OS,
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::getISThunkSec(InputSection *IS, OutputSection *OS) {
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::getISThunkSec(InputSection *IS, OutputSection *OS) {
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::forEachExecInputSection(
// 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();
}