diff options
author | Peter Smith <peter.smith@linaro.org> | 2017-07-05 09:53:33 +0000 |
---|---|---|
committer | Peter Smith <peter.smith@linaro.org> | 2017-07-05 09:53:33 +0000 |
commit | fa2376427886a1ad404f1c4b3a1da38c7822d656 (patch) | |
tree | 14c2b301064e0b3befb3aa37c5aeaca75f70650a | |
parent | ebe56283bc1a8d9111fe776c63016a7e60d43cc5 (diff) | |
download | bcm5719-llvm-fa2376427886a1ad404f1c4b3a1da38c7822d656.tar.gz bcm5719-llvm-fa2376427886a1ad404f1c4b3a1da38c7822d656.zip |
[ELF] Allow multiple thunks to be added for a symbol.
This change permits there to be more than one thunk to be associated with
a symbol. For interworking thunks we only require one thunk, but range
extension thunks may require more than one.
Differential Revision: https://reviews.llvm.org/D34037
llvm-svn: 307136
-rw-r--r-- | lld/ELF/Relocations.cpp | 15 | ||||
-rw-r--r-- | lld/ELF/Relocations.h | 9 |
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 |