summaryrefslogtreecommitdiff
path: root/ELF/Relocations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/Relocations.cpp')
-rw-r--r--ELF/Relocations.cpp32
1 files changed, 19 insertions, 13 deletions
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index fd823fe0ed42..52dbe4b583d0 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -557,9 +557,9 @@ static RelExpr adjustExpr(SymbolBody &Body, RelExpr Expr, uint32_t Type,
// the refered symbol can be preemepted to refer to the executable.
if (Config->Shared || (Config->Pic && !isRelExpr(Expr))) {
error("can't create dynamic relocation " + toString(Type) + " against " +
- (Body.getName().empty() ? "local symbol in readonly segment"
+ (Body.getName().empty() ? "local symbol"
: "symbol: " + toString(Body)) +
- getLocation<ELFT>(S, Body, RelOff));
+ " in readonly segment" + getLocation<ELFT>(S, Body, RelOff));
return Expr;
}
@@ -1049,10 +1049,17 @@ ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,
std::pair<Thunk *, bool> ThunkCreator::getThunk(SymbolBody &Body,
uint32_t Type) {
- auto res = ThunkedSymbols.insert({&Body, nullptr});
- if (res.second)
- res.first->second = addThunk(Type, Body);
- return std::make_pair(res.first->second, res.second);
+ auto Res = ThunkedSymbols.insert({&Body, std::vector<Thunk *>()});
+ if (!Res.second) {
+ // Check existing Thunks for Body to see if they can be reused
+ for (Thunk *ET : Res.first->second)
+ if (ET->isCompatibleWith(Type))
+ return std::make_pair(ET, false);
+ }
+ // No existing compatible Thunk in range, create a new one
+ Thunk *T = addThunk(Type, Body);
+ Res.first->second.push_back(T);
+ return std::make_pair(T, true);
}
// Call Fn on every executable InputSection accessed via the linker script
@@ -1066,13 +1073,12 @@ void ThunkCreator::forEachExecInputSection(
OutputSection *OS = Cmd->Sec;
if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
continue;
- if (OutputSectionCommand *C = Script->getCmd(OS))
- for (BaseCommand *BC : C->Commands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
- CurTS = nullptr;
- for (InputSection* IS : ISD->Sections)
- Fn(OS, &ISD->Sections, IS);
- }
+ for (BaseCommand *BC : Cmd->Commands)
+ if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
+ CurTS = nullptr;
+ for (InputSection *IS : ISD->Sections)
+ Fn(OS, &ISD->Sections, IS);
+ }
}
}