From 7b8270424e8f12d7825ffc9ff2d892c004dcb26b Mon Sep 17 00:00:00 2001 From: George Rimar Date: Thu, 16 Mar 2017 10:40:50 +0000 Subject: [PATCH] [ELF] Detemplate ThunkSection and Thunk classes. NFC. llvm-svn: 297939 --- lld/ELF/Relocations.cpp | 26 +++++------ lld/ELF/SyntheticSections.cpp | 21 +++------ lld/ELF/SyntheticSections.h | 6 +-- lld/ELF/Thunks.cpp | 87 ++++++++++++++++------------------- lld/ELF/Thunks.h | 10 ++-- 5 files changed, 67 insertions(+), 83 deletions(-) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 64bc37b8165e..818947876798 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -863,9 +863,9 @@ template void scanRelocations(InputSectionBase &S) { // This may invalidate any output section offsets stored outside of InputSection template static void mergeThunks(OutputSection *OS, - std::vector *> &Thunks) { + std::vector &Thunks) { // Order Thunks in ascending OutSecOff - auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) { + auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) { return A->OutSecOff < B->OutSecOff; }; std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp); @@ -880,7 +880,7 @@ static void mergeThunks(OutputSection *OS, if (A->OutSecOff == B->OutSecOff) // Check if Thunk is immediately before any specific Target InputSection // for example Mips LA25 Thunks. - if (auto *TA = dyn_cast>(A)) + if (auto *TA = dyn_cast(A)) if (TA && TA->getTargetInputSection() == B) return true; return false; @@ -904,11 +904,11 @@ static void mergeThunks(OutputSection *OS, template bool createThunks(ArrayRef OutputSections) { // Track Symbols that already have a Thunk - DenseMap *> ThunkedSymbols; + DenseMap ThunkedSymbols; // Track InputSections that have a ThunkSection placed in front - DenseMap *> ThunkedSections; + DenseMap ThunkedSections; // Track the ThunksSections that need to be inserted into an OutputSection - std::map *>> ThunkSections; + std::map> ThunkSections; // Find or create a Thunk for Body for relocation Type auto GetThunk = [&](SymbolBody &Body, uint32_t Type) { @@ -920,18 +920,18 @@ bool createThunks(ArrayRef OutputSections) { // Find or create a ThunkSection to be placed immediately before IS auto GetISThunkSec = [&](InputSection *IS, OutputSection *OS) { - ThunkSection *TS = ThunkedSections.lookup(IS); + ThunkSection *TS = ThunkedSections.lookup(IS); if (TS) return TS; auto *TOS = cast(IS->OutSec); - TS = make>(TOS, IS->OutSecOff); + TS = make(TOS, IS->OutSecOff); ThunkSections[TOS].push_back(TS); ThunkedSections[IS] = TS; return TS; }; // Find or create a ThunkSection to be placed as last executable section in // OS. - auto GetOSThunkSec = [&](ThunkSection *&TS, OutputSection *OS) { + auto GetOSThunkSec = [&](ThunkSection *&TS, OutputSection *OS) { if (TS == nullptr) { uint32_t Off = 0; for (auto *IS : OS->Sections) { @@ -939,7 +939,7 @@ bool createThunks(ArrayRef OutputSections) { if ((IS->Flags & SHF_EXECINSTR) == 0) break; } - TS = make>(OS, Off); + TS = make(OS, Off); ThunkSections[OS].push_back(TS); } return TS; @@ -955,18 +955,18 @@ bool createThunks(ArrayRef OutputSections) { if (OS == nullptr) continue; - ThunkSection *OSTS = nullptr; + ThunkSection *OSTS = nullptr; for (InputSection *IS : OS->Sections) { for (Relocation &Rel : IS->Relocations) { SymbolBody &Body = *Rel.Sym; if (Target->needsThunk(Rel.Expr, Rel.Type, IS->template getFile(), Body)) { - Thunk *T; + Thunk *T; bool IsNew; std::tie(T, IsNew) = GetThunk(Body, Rel.Type); if (IsNew) { // Find or create a ThunkSection for the new Thunk - ThunkSection *TS; + ThunkSection *TS; if (auto *TIS = T->getTargetInputSection()) TS = GetISThunkSec(TIS, OS); else diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b2221206bde7..48f9b11aa818 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2234,15 +2234,14 @@ void ARMExidxSentinelSection::writeTo(uint8_t *Buf) { write32le(Buf + 4, 0x1); } -template -ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off) +ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off) : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, - sizeof(typename ELFT::uint), ".text.thunk") { + Config->is64Bit() ? 8 : 4, ".text.thunk") { this->OutSec = OS; this->OutSecOff = Off; } -template void ThunkSection::addThunk(Thunk *T) { +void ThunkSection::addThunk(Thunk *T) { uint64_t Off = alignTo(Size, T->alignment); T->Offset = Off; Thunks.push_back(T); @@ -2250,14 +2249,13 @@ template void ThunkSection::addThunk(Thunk *T) { Size = Off + T->size(); } -template void ThunkSection::writeTo(uint8_t *Buf) { - for (const Thunk *T : Thunks) +void ThunkSection::writeTo(uint8_t *Buf) { + for (const Thunk *T : Thunks) T->writeTo(Buf + T->Offset, *this); } -template -InputSection *ThunkSection::getTargetInputSection() const { - const Thunk *T = Thunks.front(); +InputSection *ThunkSection::getTargetInputSection() const { + const Thunk *T = Thunks.front(); return T->getTargetInputSection(); } @@ -2389,11 +2387,6 @@ template class elf::ARMExidxSentinelSection; template class elf::ARMExidxSentinelSection; template class elf::ARMExidxSentinelSection; -template class elf::ThunkSection; -template class elf::ThunkSection; -template class elf::ThunkSection; -template class elf::ThunkSection; - template class elf::EhFrameSection; template class elf::EhFrameSection; template class elf::EhFrameSection; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index aabd9c73b7d6..5139763eabbe 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -727,7 +727,7 @@ public: // A container for one or more linker generated thunks. Instances of these // thunks including ARM interworking and Mips LA25 PI to non-PI thunks. -template class ThunkSection : public SyntheticSection { +class ThunkSection : public SyntheticSection { public: // ThunkSection in OS, with desired OutSecOff of Off ThunkSection(OutputSection *OS, uint64_t Off); @@ -736,13 +736,13 @@ public: // Thunk is given offset from start of this InputSection // Thunk defines a symbol in this InputSection that can be used as target // of a relocation - void addThunk(Thunk *T); + void addThunk(Thunk *T); size_t getSize() const override { return Size; } void writeTo(uint8_t *Buf) override; InputSection *getTargetInputSection() const; private: - std::vector *> Thunks; + std::vector Thunks; size_t Size = 0; }; diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp index 3fcf225949d4..3204ae8a4a99 100644 --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -50,56 +50,54 @@ namespace { // Specific ARM Thunk implementations. The naming convention is: // Source State, TargetState, Target Requirement, ABS or PI, Range -template -class ARMToThumbV7ABSLongThunk final : public Thunk { +template class ARMToThumbV7ABSLongThunk final : public Thunk { public: - ARMToThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) {} + ARMToThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) {} uint32_t size() const override { return 12; } - void writeTo(uint8_t *Buf, ThunkSection &IS) const override; - void addSymbols(ThunkSection &IS) override; + void writeTo(uint8_t *Buf, ThunkSection &IS) const override; + void addSymbols(ThunkSection &IS) override; }; -template class ARMToThumbV7PILongThunk final : public Thunk { +template class ARMToThumbV7PILongThunk final : public Thunk { public: - ARMToThumbV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) {} + ARMToThumbV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) {} uint32_t size() const override { return 16; } - void writeTo(uint8_t *Buf, ThunkSection &IS) const override; - void addSymbols(ThunkSection &IS) override; + void writeTo(uint8_t *Buf, ThunkSection &IS) const override; + void addSymbols(ThunkSection &IS) override; }; -template -class ThumbToARMV7ABSLongThunk final : public Thunk { +template class ThumbToARMV7ABSLongThunk final : public Thunk { public: - ThumbToARMV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) { + ThumbToARMV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) { this->alignment = 2; } uint32_t size() const override { return 10; } - void writeTo(uint8_t *Buf, ThunkSection &IS) const override; - void addSymbols(ThunkSection &IS) override; + void writeTo(uint8_t *Buf, ThunkSection &IS) const override; + void addSymbols(ThunkSection &IS) override; }; -template class ThumbToARMV7PILongThunk final : public Thunk { +template class ThumbToARMV7PILongThunk final : public Thunk { public: - ThumbToARMV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) { + ThumbToARMV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) { this->alignment = 2; } uint32_t size() const override { return 12; } - void writeTo(uint8_t *Buf, ThunkSection &IS) const override; - void addSymbols(ThunkSection &IS) override; + void writeTo(uint8_t *Buf, ThunkSection &IS) const override; + void addSymbols(ThunkSection &IS) override; }; // MIPS LA25 thunk -template class MipsThunk final : public Thunk { +template class MipsThunk final : public Thunk { public: - MipsThunk(const SymbolBody &Dest) : Thunk(Dest) {} + MipsThunk(const SymbolBody &Dest) : Thunk(Dest) {} uint32_t size() const override { return 16; } - void writeTo(uint8_t *Buf, ThunkSection &IS) const override; - void addSymbols(ThunkSection &IS) override; + void writeTo(uint8_t *Buf, ThunkSection &IS) const override; + void addSymbols(ThunkSection &IS) override; InputSection *getTargetInputSection() const override; }; @@ -113,7 +111,7 @@ template static uint64_t getARMThunkDestVA(const SymbolBody &S) { template void ARMToThumbV7ABSLongThunk::writeTo(uint8_t *Buf, - ThunkSection &IS) const { + ThunkSection &IS) const { const uint8_t Data[] = { 0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S @@ -126,7 +124,7 @@ void ARMToThumbV7ABSLongThunk::writeTo(uint8_t *Buf, } template -void ARMToThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) { +void ARMToThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) { this->ThunkSym = addSyntheticLocal( Saver.save("__ARMToThumbv7ABSLongThunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); @@ -135,7 +133,7 @@ void ARMToThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) { template void ThumbToARMV7ABSLongThunk::writeTo(uint8_t *Buf, - ThunkSection &IS) const { + ThunkSection &IS) const { const uint8_t Data[] = { 0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S 0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S @@ -148,7 +146,7 @@ void ThumbToARMV7ABSLongThunk::writeTo(uint8_t *Buf, } template -void ThumbToARMV7ABSLongThunk::addSymbols(ThunkSection &IS) { +void ThumbToARMV7ABSLongThunk::addSymbols(ThunkSection &IS) { this->ThunkSym = addSyntheticLocal( Saver.save("__ThumbToARMv7ABSLongThunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); @@ -157,7 +155,7 @@ void ThumbToARMV7ABSLongThunk::addSymbols(ThunkSection &IS) { template void ARMToThumbV7PILongThunk::writeTo(uint8_t *Buf, - ThunkSection &IS) const { + ThunkSection &IS) const { const uint8_t Data[] = { 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) +8) 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P+4) +8) @@ -172,7 +170,7 @@ void ARMToThumbV7PILongThunk::writeTo(uint8_t *Buf, } template -void ARMToThumbV7PILongThunk::addSymbols(ThunkSection &IS) { +void ARMToThumbV7PILongThunk::addSymbols(ThunkSection &IS) { this->ThunkSym = addSyntheticLocal( Saver.save("__ARMToThumbV7PILongThunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); @@ -181,7 +179,7 @@ void ARMToThumbV7PILongThunk::addSymbols(ThunkSection &IS) { template void ThumbToARMV7PILongThunk::writeTo(uint8_t *Buf, - ThunkSection &IS) const { + ThunkSection &IS) const { const uint8_t Data[] = { 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4) 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P+4) + 4) @@ -196,7 +194,7 @@ void ThumbToARMV7PILongThunk::writeTo(uint8_t *Buf, } template -void ThumbToARMV7PILongThunk::addSymbols(ThunkSection &IS) { +void ThumbToARMV7PILongThunk::addSymbols(ThunkSection &IS) { this->ThunkSym = addSyntheticLocal( Saver.save("__ThumbToARMV7PILongThunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); @@ -205,7 +203,7 @@ void ThumbToARMV7PILongThunk::addSymbols(ThunkSection &IS) { // Write MIPS LA25 thunk code to call PIC function from the non-PIC one. template -void MipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const { +void MipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const { const endianness E = ELFT::TargetEndianness; uint64_t S = this->Destination.template getVA(); @@ -217,7 +215,7 @@ void MipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const { Target->relocateOne(Buf + 8, R_MIPS_LO16, S); } -template void MipsThunk::addSymbols(ThunkSection &IS) { +template void MipsThunk::addSymbols(ThunkSection &IS) { this->ThunkSym = addSyntheticLocal( Saver.save("__LA25Thunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); @@ -229,14 +227,13 @@ InputSection *MipsThunk::getTargetInputSection() const { return dyn_cast(DR->Section); } -template -Thunk::Thunk(const SymbolBody &D) : Destination(D), Offset(0) {} +Thunk::Thunk(const SymbolBody &D) : Destination(D), Offset(0) {} -template Thunk::~Thunk() = default; +Thunk::~Thunk() = default; // Creates a thunk for Thumb-ARM interworking. template -static Thunk *addThunkArm(uint32_t Reloc, SymbolBody &S) { +static Thunk *addThunkArm(uint32_t Reloc, SymbolBody &S) { // ARM relocations need ARM to Thumb interworking Thunks. // Thumb relocations need Thumb to ARM relocations. // Use position independent Thunks if we require position independent code. @@ -256,11 +253,11 @@ static Thunk *addThunkArm(uint32_t Reloc, SymbolBody &S) { fatal("unrecognized relocation type"); } -template static Thunk *addThunkMips(SymbolBody &S) { +template static Thunk *addThunkMips(SymbolBody &S) { return make>(S); } -template Thunk *addThunk(uint32_t RelocType, SymbolBody &S) { +template Thunk *addThunk(uint32_t RelocType, SymbolBody &S) { if (Config->EMachine == EM_ARM) return addThunkArm(RelocType, S); else if (Config->EMachine == EM_MIPS) @@ -269,15 +266,9 @@ template Thunk *addThunk(uint32_t RelocType, SymbolBody &S) { return nullptr; } -template Thunk *addThunk(uint32_t, SymbolBody &); -template Thunk *addThunk(uint32_t, SymbolBody &); -template Thunk *addThunk(uint32_t, SymbolBody &); -template Thunk *addThunk(uint32_t, SymbolBody &); - -template class Thunk; -template class Thunk; -template class Thunk; -template class Thunk; - +template Thunk *addThunk(uint32_t, SymbolBody &); +template Thunk *addThunk(uint32_t, SymbolBody &); +template Thunk *addThunk(uint32_t, SymbolBody &); +template Thunk *addThunk(uint32_t, SymbolBody &); } // end namespace elf } // end namespace lld diff --git a/lld/ELF/Thunks.h b/lld/ELF/Thunks.h index c0c410bbb25c..a9f49279f3f2 100644 --- a/lld/ELF/Thunks.h +++ b/lld/ELF/Thunks.h @@ -15,7 +15,7 @@ namespace lld { namespace elf { class SymbolBody; -template class ThunkSection; +class ThunkSection; // Class to describe an instance of a Thunk. // A Thunk is a code-sequence inserted by the linker in between a caller and // the callee. The relocation to the callee is redirected to the Thunk, which @@ -25,17 +25,17 @@ template class ThunkSection; // // Thunks can be created for DefinedRegular, Shared and Undefined Symbols. // Thunks are assigned to synthetic ThunkSections -template class Thunk { +class Thunk { public: Thunk(const SymbolBody &Destination); virtual ~Thunk(); virtual uint32_t size() const { return 0; } - virtual void writeTo(uint8_t *Buf, ThunkSection &IS) const {} + virtual void writeTo(uint8_t *Buf, ThunkSection &IS) const {} // All Thunks must define at least one symbol ThunkSym so that we can // redirect relocations to it. - virtual void addSymbols(ThunkSection &IS) {} + virtual void addSymbols(ThunkSection &IS) {} // Some Thunks must be placed immediately before their Target as they elide // a branch and fall through to the first Symbol in the Target. @@ -51,7 +51,7 @@ public: // For a Relocation to symbol S create a Thunk to be added to a synthetic // ThunkSection. At present there are implementations for ARM and Mips Thunks. -template Thunk *addThunk(uint32_t RelocType, SymbolBody &S); +template Thunk *addThunk(uint32_t RelocType, SymbolBody &S); } // namespace elf } // namespace lld