summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Relocations.cpp15
-rw-r--r--lld/ELF/Relocations.h9
2 files changed, 17 insertions, 7 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 436979b142a..151e724e1ec 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -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->isCompatibleWith(Type))
- 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 {ET, false};
+ }
+ // No existing compatible Thunk in range, create a new one
+ Thunk *T = addThunk(Type, Body);
+ Res.first->second.push_back(T);
+ return {T, true};
}
// Call Fn on every executable InputSection accessed via the linker script
diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h
index 445308b27ce..fc3e3444ac2 100644
--- a/lld/ELF/Relocations.h
+++ b/lld/ELF/Relocations.h
@@ -144,14 +144,17 @@ private:
std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
ThunkSection *addThunkSection(OutputSection *OS,
std::vector<InputSection *> *, uint64_t Off);
- // Track Symbols that already have a Thunk
- llvm::DenseMap<SymbolBody *, Thunk *> ThunkedSymbols;
+ // Record all the available Thunks for a Symbol
+ llvm::DenseMap<SymbolBody *, std::vector<Thunk *>> ThunkedSymbols;
// Find a Thunk from the Thunks symbol definition, we can use this to find
// the Thunk from a relocation to the Thunks symbol definition.
llvm::DenseMap<SymbolBody *, Thunk *> Thunks;
- // Track InputSections that have a ThunkSection placed in front
+ // Track InputSections that have an inline ThunkSection placed in front
+ // an inline ThunkSection may have control fall through to the section below
+ // so we need to make sure that there is only one of them.
+ // The Mips LA25 Thunk is an example of an inline ThunkSection.
llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections;
// All the ThunkSections that we have created, organised by OutputSection
OpenPOWER on IntegriCloud