Skip to content

Commit 8a2e00e

Browse files
committedJun 6, 2017
[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
1 parent 8f7565b commit 8a2e00e

File tree

2 files changed

+48
-31
lines changed

2 files changed

+48
-31
lines changed
 

‎lld/ELF/Relocations.cpp

+41-30
Original file line numberDiff line numberDiff line change
@@ -1001,19 +1001,18 @@ void ThunkCreator::mergeThunks() {
10011001
}
10021002
}
10031003

1004-
ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS,
1005-
OutputSection *OS) {
1006-
if (TS == nullptr) {
1004+
ThunkSection *ThunkCreator::getOSThunkSec(OutputSection *OS) {
1005+
if (CurTS == nullptr) {
10071006
uint32_t Off = 0;
10081007
for (auto *IS : OS->Sections) {
10091008
Off = IS->OutSecOff + IS->getSize();
10101009
if ((IS->Flags & SHF_EXECINSTR) == 0)
10111010
break;
10121011
}
1013-
TS = make<ThunkSection>(OS, Off);
1014-
ThunkSections[&OS->Sections].push_back(TS);
1012+
CurTS = make<ThunkSection>(OS, Off);
1013+
ThunkSections[&OS->Sections].push_back(CurTS);
10151014
}
1016-
return TS;
1015+
return CurTS;
10171016
}
10181017

10191018
ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) {
@@ -1035,6 +1034,20 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(SymbolBody &Body,
10351034
return std::make_pair(res.first->second, res.second);
10361035
}
10371036

1037+
// Call Fn on every executable InputSection accessed via the linker script
1038+
// InputSectionDescription::Sections.
1039+
void ThunkCreator::forEachExecInputSection(
1040+
ArrayRef<OutputSection *> OutputSections,
1041+
std::function<void(OutputSection *, InputSection *)> Fn) {
1042+
for (OutputSection *OS : OutputSections) {
1043+
if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
1044+
continue;
1045+
CurTS = nullptr;
1046+
for (InputSection *IS : OS->Sections)
1047+
Fn(OS, IS);
1048+
}
1049+
}
1050+
10381051
// Process all relocations from the InputSections that have been assigned
10391052
// to OutputSections and redirect through Thunks if needed.
10401053
//
@@ -1052,31 +1065,29 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
10521065
// We separate the creation of ThunkSections from the insertion of the
10531066
// ThunkSections back into the OutputSection as ThunkSections are not always
10541067
// inserted into the same OutputSection as the caller.
1055-
for (OutputSection *OS : OutputSections) {
1056-
ThunkSection *OSTS = nullptr;
1057-
for (InputSection *IS : OS->Sections) {
1058-
for (Relocation &Rel : IS->Relocations) {
1059-
SymbolBody &Body = *Rel.Sym;
1060-
if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body))
1061-
continue;
1062-
Thunk *T;
1063-
bool IsNew;
1064-
std::tie(T, IsNew) = getThunk(Body, Rel.Type);
1065-
if (IsNew) {
1066-
// Find or create a ThunkSection for the new Thunk
1067-
ThunkSection *TS;
1068-
if (auto *TIS = T->getTargetInputSection())
1069-
TS = getISThunkSec(TIS, OS);
1070-
else
1071-
TS = getOSThunkSec(OSTS, OS);
1072-
TS->addThunk(T);
1068+
forEachExecInputSection(
1069+
OutputSections, [=](OutputSection *OS, InputSection *IS) {
1070+
for (Relocation &Rel : IS->Relocations) {
1071+
SymbolBody &Body = *Rel.Sym;
1072+
if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body))
1073+
continue;
1074+
Thunk *T;
1075+
bool IsNew;
1076+
std::tie(T, IsNew) = getThunk(Body, Rel.Type);
1077+
if (IsNew) {
1078+
// Find or create a ThunkSection for the new Thunk
1079+
ThunkSection *TS;
1080+
if (auto *TIS = T->getTargetInputSection())
1081+
TS = getISThunkSec(TIS, OS);
1082+
else
1083+
TS = getOSThunkSec(OS);
1084+
TS->addThunk(T);
1085+
}
1086+
// Redirect relocation to Thunk, we never go via the PLT to a Thunk
1087+
Rel.Sym = T->ThunkSym;
1088+
Rel.Expr = fromPlt(Rel.Expr);
10731089
}
1074-
// Redirect relocation to Thunk, we never go via the PLT to a Thunk
1075-
Rel.Sym = T->ThunkSym;
1076-
Rel.Expr = fromPlt(Rel.Expr);
1077-
}
1078-
}
1079-
}
1090+
});
10801091

10811092
// Merge all created synthetic ThunkSections back into OutputSection
10821093
mergeThunks();

‎lld/ELF/Relocations.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,11 @@ class ThunkCreator {
127127

128128
private:
129129
void mergeThunks();
130-
ThunkSection *getOSThunkSec(ThunkSection *&TS, OutputSection *OS);
130+
ThunkSection *getOSThunkSec(OutputSection *OS);
131131
ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS);
132+
void forEachExecInputSection(
133+
ArrayRef<OutputSection *> OutputSections,
134+
std::function<void(OutputSection *, InputSection *)> Fn);
132135
std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
133136

134137
// Track Symbols that already have a Thunk
@@ -140,6 +143,9 @@ class ThunkCreator {
140143
// Track the ThunksSections that need to be inserted into an OutputSection
141144
std::map<std::vector<InputSection *> *, std::vector<ThunkSection *>>
142145
ThunkSections;
146+
147+
// The ThunkSection for this vector of InputSections
148+
ThunkSection *CurTS;
143149
};
144150

145151
// Return a int64_t to make sure we get the sign extension out of the way as

0 commit comments

Comments
 (0)
Please sign in to comment.