diff options
-rw-r--r-- | lld/ELF/Driver.cpp | 6 | ||||
-rw-r--r-- | lld/ELF/EhFrame.cpp | 23 | ||||
-rw-r--r-- | lld/ELF/EhFrame.h | 5 | ||||
-rw-r--r-- | lld/ELF/GdbIndex.cpp | 20 | ||||
-rw-r--r-- | lld/ELF/GdbIndex.h | 2 | ||||
-rw-r--r-- | lld/ELF/ICF.cpp | 20 | ||||
-rw-r--r-- | lld/ELF/InputFiles.cpp | 18 | ||||
-rw-r--r-- | lld/ELF/InputFiles.h | 14 | ||||
-rw-r--r-- | lld/ELF/InputSection.cpp | 144 | ||||
-rw-r--r-- | lld/ELF/InputSection.h | 86 | ||||
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 39 | ||||
-rw-r--r-- | lld/ELF/LinkerScript.h | 8 | ||||
-rw-r--r-- | lld/ELF/MapFile.cpp | 10 | ||||
-rw-r--r-- | lld/ELF/MarkLive.cpp | 37 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 49 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 4 | ||||
-rw-r--r-- | lld/ELF/Relocations.cpp | 65 | ||||
-rw-r--r-- | lld/ELF/Relocations.h | 4 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 20 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.h | 4 | ||||
-rw-r--r-- | lld/ELF/Symbols.cpp | 9 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 9 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 82 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 8 | ||||
-rw-r--r-- | lld/ELF/Target.cpp | 12 | ||||
-rw-r--r-- | lld/ELF/Thunks.cpp | 18 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 33 | ||||
-rw-r--r-- | lld/ELF/Writer.h | 2 |
28 files changed, 385 insertions, 366 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 5663ede7902..1b5446c3dc8 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -844,7 +844,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { // Beyond this point, no new files are added. // Aggregate all input sections into one place. for (elf::ObjectFile<ELFT> *F : Symtab.getObjectFiles()) - for (InputSectionBase<ELFT> *S : F->getSections()) + for (InputSectionBase *S : F->getSections()) if (S && S != &InputSection<ELFT>::Discarded) Symtab.Sections.push_back(S); for (BinaryFile *F : Symtab.getBinaryFiles()) @@ -860,11 +860,11 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { // MergeInputSection::splitIntoPieces needs to be called before // any call of MergeInputSection::getOffset. Do that. forEach(Symtab.Sections.begin(), Symtab.Sections.end(), - [](InputSectionBase<ELFT> *S) { + [](InputSectionBase *S) { if (!S->Live) return; if (Decompressor::isCompressedELFSection(S->Flags, S->Name)) - S->uncompress(); + S->uncompress<ELFT>(); if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(S)) MS->splitIntoPieces(); }); diff --git a/lld/ELF/EhFrame.cpp b/lld/ELF/EhFrame.cpp index 5f037dffb4e..245c3b5a845 100644 --- a/lld/ELF/EhFrame.cpp +++ b/lld/ELF/EhFrame.cpp @@ -38,13 +38,14 @@ using namespace lld::elf; namespace { template <class ELFT> class EhReader { public: - EhReader(InputSectionBase<ELFT> *S, ArrayRef<uint8_t> D) : IS(S), D(D) {} + EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {} size_t readEhRecordSize(); uint8_t getFdeEncoding(); private: template <class P> void failOn(const P *Loc, const Twine &Msg) { - fatal(IS->getLocation((const uint8_t *)Loc - IS->Data.data()) + ": " + Msg); + fatal(IS->getLocation<ELFT>((const uint8_t *)Loc - IS->Data.data()) + ": " + + Msg); } uint8_t readByte(); @@ -53,13 +54,13 @@ private: void skipLeb128(); void skipAugP(); - InputSectionBase<ELFT> *IS; + InputSectionBase *IS; ArrayRef<uint8_t> D; }; } template <class ELFT> -size_t elf::readEhRecordSize(InputSectionBase<ELFT> *S, size_t Off) { +size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) { return EhReader<ELFT>(S, S->Data.slice(Off)).readEhRecordSize(); } @@ -153,7 +154,7 @@ template <class ELFT> void EhReader<ELFT>::skipAugP() { } template <class ELFT> uint8_t elf::getFdeEncoding(EhSectionPiece *P) { - auto *IS = static_cast<InputSectionBase<ELFT> *>(P->ID); + auto *IS = static_cast<InputSectionBase *>(P->ID); return EhReader<ELFT>(IS, P->data()).getFdeEncoding(); } @@ -200,14 +201,10 @@ template <class ELFT> uint8_t EhReader<ELFT>::getFdeEncoding() { return DW_EH_PE_absptr; } -template size_t elf::readEhRecordSize<ELF32LE>(InputSectionBase<ELF32LE> *S, - size_t Off); -template size_t elf::readEhRecordSize<ELF32BE>(InputSectionBase<ELF32BE> *S, - size_t Off); -template size_t elf::readEhRecordSize<ELF64LE>(InputSectionBase<ELF64LE> *S, - size_t Off); -template size_t elf::readEhRecordSize<ELF64BE>(InputSectionBase<ELF64BE> *S, - size_t Off); +template size_t elf::readEhRecordSize<ELF32LE>(InputSectionBase *S, size_t Off); +template size_t elf::readEhRecordSize<ELF32BE>(InputSectionBase *S, size_t Off); +template size_t elf::readEhRecordSize<ELF64LE>(InputSectionBase *S, size_t Off); +template size_t elf::readEhRecordSize<ELF64BE>(InputSectionBase *S, size_t Off); template uint8_t elf::getFdeEncoding<ELF32LE>(EhSectionPiece *P); template uint8_t elf::getFdeEncoding<ELF32BE>(EhSectionPiece *P); diff --git a/lld/ELF/EhFrame.h b/lld/ELF/EhFrame.h index cadc93d3a2e..4e2b6f83a29 100644 --- a/lld/ELF/EhFrame.h +++ b/lld/ELF/EhFrame.h @@ -14,11 +14,10 @@ namespace lld { namespace elf { -template <class ELFT> class InputSectionBase; +class InputSectionBase; struct EhSectionPiece; -template <class ELFT> -size_t readEhRecordSize(InputSectionBase<ELFT> *S, size_t Off); +template <class ELFT> size_t readEhRecordSize(InputSectionBase *S, size_t Off); template <class ELFT> uint8_t getFdeEncoding(EhSectionPiece *P); } } diff --git a/lld/ELF/GdbIndex.cpp b/lld/ELF/GdbIndex.cpp index 762144dd0a9..df56b0951e2 100644 --- a/lld/ELF/GdbIndex.cpp +++ b/lld/ELF/GdbIndex.cpp @@ -70,10 +70,12 @@ template <class ELFT> GdbIndexBuilder<ELFT>::GdbIndexBuilder(InputSection<ELFT> *DebugInfoSec) : DebugInfoSec(DebugInfoSec) { if (Expected<std::unique_ptr<object::ObjectFile>> Obj = - object::ObjectFile::createObjectFile(DebugInfoSec->getFile()->MB)) + object::ObjectFile::createObjectFile( + DebugInfoSec->template getFile<ELFT>()->MB)) Dwarf.reset(new DWARFContextInMemory(*Obj.get(), this)); else - error(toString(DebugInfoSec->getFile()) + ": error creating DWARF context"); + error(toString(DebugInfoSec->template getFile<ELFT>()) + + ": error creating DWARF context"); } template <class ELFT> @@ -150,11 +152,11 @@ GdbSymbol **GdbHashTab::findSlot(uint32_t Hash, size_t Offset) { } template <class ELFT> -static InputSectionBase<ELFT> * -findSection(ArrayRef<InputSectionBase<ELFT> *> Arr, uint64_t Offset) { - for (InputSectionBase<ELFT> *S : Arr) +static InputSectionBase *findSection(ArrayRef<InputSectionBase *> Arr, + uint64_t Offset) { + for (InputSectionBase *S : Arr) if (S && S != &InputSection<ELFT>::Discarded) - if (Offset >= S->Offset && Offset < S->Offset + S->getSize()) + if (Offset >= S->Offset && Offset < S->Offset + S->getSize<ELFT>()) return S; return nullptr; } @@ -167,11 +169,11 @@ GdbIndexBuilder<ELFT>::readAddressArea(size_t CurrentCU) { DWARFAddressRangesVector Ranges; CU->collectAddressRanges(Ranges); - ArrayRef<InputSectionBase<ELFT> *> Sections = - DebugInfoSec->getFile()->getSections(); + ArrayRef<InputSectionBase *> Sections = + DebugInfoSec->template getFile<ELFT>()->getSections(); for (std::pair<uint64_t, uint64_t> &R : Ranges) - if (InputSectionBase<ELFT> *S = findSection(Sections, R.first)) + if (InputSectionBase *S = findSection<ELFT>(Sections, R.first)) Ret.push_back( {S, R.first - S->Offset, R.second - S->Offset, CurrentCU}); ++CurrentCU; diff --git a/lld/ELF/GdbIndex.h b/lld/ELF/GdbIndex.h index c761ea173a8..0cdf986723c 100644 --- a/lld/ELF/GdbIndex.h +++ b/lld/ELF/GdbIndex.h @@ -21,7 +21,7 @@ template <class ELFT> class InputSection; // Struct represents single entry of address area of gdb index. template <class ELFT> struct AddressEntry { - InputSectionBase<ELFT> *Section; + InputSectionBase *Section; uint64_t LowAddress; uint64_t HighAddress; size_t CuIndex; diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp index e1f9c50839c..8dace92fe97 100644 --- a/lld/ELF/ICF.cpp +++ b/lld/ELF/ICF.cpp @@ -155,7 +155,7 @@ private: // Returns a hash value for S. Note that the information about // relocation targets is not included in the hash value. template <class ELFT> static uint32_t getHash(InputSection<ELFT> *S) { - return hash_combine(S->Flags, S->getSize(), S->NumRelocations); + return hash_combine(S->Flags, S->template getSize<ELFT>(), S->NumRelocations); } // Returns true if section S is subject of ICF. @@ -224,12 +224,13 @@ template <class ELFT> bool ICF<ELFT>::equalsConstant(const InputSection<ELFT> *A, const InputSection<ELFT> *B) { if (A->NumRelocations != B->NumRelocations || A->Flags != B->Flags || - A->getSize() != B->getSize() || A->Data != B->Data) + A->template getSize<ELFT>() != B->template getSize<ELFT>() || + A->Data != B->Data) return false; if (A->AreRelocsRela) - return constantEq(A->relas(), B->relas()); - return constantEq(A->rels(), B->rels()); + return constantEq(A->template relas<ELFT>(), B->template relas<ELFT>()); + return constantEq(A->template rels<ELFT>(), B->template rels<ELFT>()); } // Compare two lists of relocations. Returns true if all pairs of @@ -240,8 +241,8 @@ bool ICF<ELFT>::variableEq(const InputSection<ELFT> *A, ArrayRef<RelTy> RelsA, const InputSection<ELFT> *B, ArrayRef<RelTy> RelsB) { auto Eq = [&](const RelTy &RA, const RelTy &RB) { // The two sections must be identical. - SymbolBody &SA = A->getFile()->getRelocTargetSym(RA); - SymbolBody &SB = B->getFile()->getRelocTargetSym(RB); + SymbolBody &SA = A->template getFile<ELFT>()->getRelocTargetSym(RA); + SymbolBody &SB = B->template getFile<ELFT>()->getRelocTargetSym(RB); if (&SA == &SB) return true; @@ -278,8 +279,9 @@ template <class ELFT> bool ICF<ELFT>::equalsVariable(const InputSection<ELFT> *A, const InputSection<ELFT> *B) { if (A->AreRelocsRela) - return variableEq(A, A->relas(), B, B->relas()); - return variableEq(A, A->rels(), B, B->rels()); + return variableEq(A, A->template relas<ELFT>(), B, + B->template relas<ELFT>()); + return variableEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>()); } template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t Begin, size_t End) { @@ -336,7 +338,7 @@ void ICF<ELFT>::forEachClass(std::function<void(size_t, size_t)> Fn) { // The main function of ICF. template <class ELFT> void ICF<ELFT>::run() { // Collect sections to merge. - for (InputSectionBase<ELFT> *Sec : Symtab<ELFT>::X->Sections) + for (InputSectionBase *Sec : Symtab<ELFT>::X->Sections) if (auto *S = dyn_cast<InputSection<ELFT>>(Sec)) if (isEligible(S)) Sections.push_back(S); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index ffee291bcec..b5e7cb59004 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -93,7 +93,7 @@ template <class ELFT> void elf::ObjectFile<ELFT>::initializeDwarfLine() { // Returns source line information for a given offset // using DWARF debug info. template <class ELFT> -std::string elf::ObjectFile<ELFT>::getLineInfo(InputSectionBase<ELFT> *S, +std::string elf::ObjectFile<ELFT>::getLineInfo(InputSectionBase *S, uintX_t Offset) { if (!DwarfLine) initializeDwarfLine(); @@ -327,12 +327,11 @@ void elf::ObjectFile<ELFT>::initializeSections( } template <class ELFT> -InputSectionBase<ELFT> * -elf::ObjectFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) { +InputSectionBase *elf::ObjectFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) { uint32_t Idx = Sec.sh_info; if (Idx >= Sections.size()) fatal(toString(this) + ": invalid relocated section index: " + Twine(Idx)); - InputSectionBase<ELFT> *Target = Sections[Idx]; + InputSectionBase *Target = Sections[Idx]; // Strictly speaking, a relocation section must be included in the // group of the section it relocates. However, LLVM 3.3 and earlier @@ -346,7 +345,7 @@ elf::ObjectFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) { } template <class ELFT> -InputSectionBase<ELFT> * +InputSectionBase * elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec, StringRef SectionStringTable) { StringRef Name = @@ -369,7 +368,7 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec, // section with it. Target can be discarded, for example // if it is a duplicated member of SHT_GROUP section, we // do not create or proccess relocatable sections then. - InputSectionBase<ELFT> *Target = getRelocTarget(Sec); + InputSectionBase *Target = getRelocTarget(Sec); if (!Target) return nullptr; @@ -456,12 +455,11 @@ template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() { } template <class ELFT> -InputSectionBase<ELFT> * -elf::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { +InputSectionBase *elf::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { uint32_t Index = this->getSectionIndex(Sym); if (Index >= Sections.size()) fatal(toString(this) + ": invalid section index: " + Twine(Index)); - InputSectionBase<ELFT> *S = Sections[Index]; + InputSectionBase *S = Sections[Index]; // We found that GNU assembler 2.17.50 [FreeBSD] 2007-07-03 could // generate broken objects. STT_SECTION/STT_NOTYPE symbols can be @@ -483,7 +481,7 @@ elf::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { template <class ELFT> SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) { int Binding = Sym->getBinding(); - InputSectionBase<ELFT> *Sec = getSection(*Sym); + InputSectionBase *Sec = getSection(*Sym); uint8_t StOther = Sym->st_other; uint8_t Type = Sym->getType(); diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 95888061d87..78bc2cc0efd 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -156,8 +156,8 @@ public: explicit ObjectFile(MemoryBufferRef M); void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); - ArrayRef<InputSectionBase<ELFT> *> getSections() const { return Sections; } - InputSectionBase<ELFT> *getSection(const Elf_Sym &Sym) const; + ArrayRef<InputSectionBase *> getSections() const { return Sections; } + InputSectionBase *getSection(const Elf_Sym &Sym) const; SymbolBody &getSymbolBody(uint32_t SymbolIndex) const { if (SymbolIndex >= SymbolBodies.size()) @@ -173,7 +173,7 @@ public: // Returns source line information for a given offset. // If no information is available, returns "". - std::string getLineInfo(InputSectionBase<ELFT> *S, uintX_t Offset); + std::string getLineInfo(InputSectionBase *S, uintX_t Offset); // MIPS GP0 value defined by this file. This value represents the gp value // used to create the relocatable object and required to support @@ -190,15 +190,15 @@ private: initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); void initializeSymbols(); void initializeDwarfLine(); - InputSectionBase<ELFT> *getRelocTarget(const Elf_Shdr &Sec); - InputSectionBase<ELFT> *createInputSection(const Elf_Shdr &Sec, - StringRef SectionStringTable); + InputSectionBase *getRelocTarget(const Elf_Shdr &Sec); + InputSectionBase *createInputSection(const Elf_Shdr &Sec, + StringRef SectionStringTable); bool shouldMerge(const Elf_Shdr &Sec); SymbolBody *createSymbolBody(const Elf_Sym *Sym); // List of all sections defined by this file. - std::vector<InputSectionBase<ELFT> *> Sections; + std::vector<InputSectionBase *> Sections; // List of all symbols referenced or defined by this file. std::vector<SymbolBody *> SymbolBodies; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 44febd504ad..d3a2213d241 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -34,11 +34,9 @@ using namespace lld; using namespace lld::elf; // Returns a string to construct an error message. -template <class ELFT> -std::string lld::toString(const InputSectionBase<ELFT> *Sec) { +std::string lld::toString(const InputSectionBase *Sec) { // File can be absent if section is synthetic. - std::string FileName = - Sec->getFile() ? Sec->getFile()->getName() : "<internal>"; + std::string FileName = Sec->File ? Sec->File->getName() : "<internal>"; return (FileName + ":(" + Sec->Name + ")").str(); } @@ -50,13 +48,11 @@ static ArrayRef<uint8_t> getSectionContents(elf::ObjectFile<ELFT> *File, return check(File->getObj().getSectionContents(Hdr)); } -template <class ELFT> -InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File, - uintX_t Flags, uint32_t Type, - uintX_t Entsize, uint32_t Link, - uint32_t Info, uintX_t Addralign, - ArrayRef<uint8_t> Data, StringRef Name, - Kind SectionKind) +InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags, + uint32_t Type, uint64_t Entsize, + uint32_t Link, uint32_t Info, + uint64_t Addralign, ArrayRef<uint8_t> Data, + StringRef Name, Kind SectionKind) : InputSectionData(SectionKind, Name, Data, !Config->GcSections || !(Flags & SHF_ALLOC)), File(File), Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), @@ -79,9 +75,9 @@ InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File, } template <class ELFT> -InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File, - const Elf_Shdr *Hdr, StringRef Name, - Kind SectionKind) +InputSectionBase::InputSectionBase(elf::ObjectFile<ELFT> *File, + const typename ELFT::Shdr *Hdr, + StringRef Name, Kind SectionKind) : InputSectionBase(File, Hdr->sh_flags & ~SHF_INFO_LINK, Hdr->sh_type, Hdr->sh_entsize, Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign, getSectionContents(File, Hdr), Name, @@ -89,7 +85,7 @@ InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File, this->Offset = Hdr->sh_offset; } -template <class ELFT> size_t InputSectionBase<ELFT>::getSize() const { +template <class ELFT> size_t InputSectionBase::getSize() const { if (auto *S = dyn_cast<SyntheticSection<ELFT>>(this)) return S->getSize(); @@ -97,7 +93,8 @@ template <class ELFT> size_t InputSectionBase<ELFT>::getSize() const { } template <class ELFT> -typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const { +uint64_t InputSectionBase::getOffset(uint64_t Offset) const { + typedef typename ELFT::uint uintX_t; switch (kind()) { case Regular: return cast<InputSection<ELFT>>(this)->OutSecOff + Offset; @@ -105,7 +102,7 @@ typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const { // For synthetic sections we treat offset -1 as the end of the section. // The same approach is used for synthetic symbols (DefinedSynthetic). return cast<InputSection<ELFT>>(this)->OutSecOff + - (Offset == uintX_t(-1) ? getSize() : Offset); + (Offset == uintX_t(-1) ? getSize<ELFT>() : Offset); case EHFrame: // The file crtbeginT.o has relocations pointing to the start of an empty // .eh_frame that is known to be the first in the link. It does that to @@ -121,7 +118,7 @@ typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const { } template <class ELFT> -OutputSectionBase *InputSectionBase<ELFT>::getOutputSection() const { +OutputSectionBase *InputSectionBase::getOutputSection() const { if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(this)) return MS->MergeSec ? MS->MergeSec->OutSec : nullptr; return OutSec; @@ -129,7 +126,7 @@ OutputSectionBase *InputSectionBase<ELFT>::getOutputSection() const { // Uncompress section contents. Note that this function is called // from parallel_for_each, so it must be thread-safe. -template <class ELFT> void InputSectionBase<ELFT>::uncompress() { +template <class ELFT> void InputSectionBase::uncompress() { Decompressor Dec = check(Decompressor::create( Name, toStringRef(Data), ELFT::TargetEndianness == llvm::support::little, ELFT::Is64Bits)); @@ -149,34 +146,33 @@ template <class ELFT> void InputSectionBase<ELFT>::uncompress() { } template <class ELFT> -typename ELFT::uint -InputSectionBase<ELFT>::getOffset(const DefinedRegular<ELFT> &Sym) const { - return getOffset(Sym.Value); +uint64_t InputSectionBase::getOffset(const DefinedRegular<ELFT> &Sym) const { + return getOffset<ELFT>(Sym.Value); } template <class ELFT> -InputSectionBase<ELFT> *InputSectionBase<ELFT>::getLinkOrderDep() const { +InputSectionBase *InputSectionBase::getLinkOrderDep() const { if ((Flags & SHF_LINK_ORDER) && Link != 0) - return getFile()->getSections()[Link]; + return getFile<ELFT>()->getSections()[Link]; return nullptr; } // Returns a source location string. Used to construct an error message. template <class ELFT> -std::string InputSectionBase<ELFT>::getLocation(typename ELFT::uint Offset) { +std::string InputSectionBase::getLocation(uint64_t Offset) { // First check if we can get desired values from debugging information. - std::string LineInfo = File->getLineInfo(this, Offset); + std::string LineInfo = getFile<ELFT>()->getLineInfo(this, Offset); if (!LineInfo.empty()) return LineInfo; // File->SourceFile contains STT_FILE symbol that contains a // source file name. If it's missing, we use an object file name. - std::string SrcFile = File->SourceFile; + std::string SrcFile = getFile<ELFT>()->SourceFile; if (SrcFile.empty()) SrcFile = toString(File); // Find a function symbol that encloses a given location. - for (SymbolBody *B : File->getSymbols()) + for (SymbolBody *B : getFile<ELFT>()->getSymbols()) if (auto *D = dyn_cast<DefinedRegular<ELFT>>(B)) if (D->Section == this && D->Type == STT_FUNC) if (D->Value <= Offset && Offset < D->Value + D->Size) @@ -186,31 +182,31 @@ std::string InputSectionBase<ELFT>::getLocation(typename ELFT::uint Offset) { return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str(); } -template <class ELFT> -InputSection<ELFT>::InputSection() : InputSectionBase<ELFT>() {} +template <class ELFT> InputSection<ELFT>::InputSection() : InputSectionBase() {} template <class ELFT> InputSection<ELFT>::InputSection(uintX_t Flags, uint32_t Type, uintX_t Addralign, ArrayRef<uint8_t> Data, StringRef Name, Kind K) - : InputSectionBase<ELFT>(nullptr, Flags, Type, - /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Addralign, - Data, Name, K) {} + : InputSectionBase(nullptr, Flags, Type, + /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Addralign, Data, + Name, K) {} template <class ELFT> InputSection<ELFT>::InputSection(elf::ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name) - : InputSectionBase<ELFT>(F, Header, Name, Base::Regular) {} + : InputSectionBase(F, Header, Name, InputSectionBase::Regular) {} template <class ELFT> bool InputSection<ELFT>::classof(const InputSectionData *S) { - return S->kind() == Base::Regular || S->kind() == Base::Synthetic; + return S->kind() == InputSectionBase::Regular || + S->kind() == InputSectionBase::Synthetic; } template <class ELFT> -InputSectionBase<ELFT> *InputSection<ELFT>::getRelocatedSection() { +InputSectionBase *InputSection<ELFT>::getRelocatedSection() { assert(this->Type == SHT_RELA || this->Type == SHT_REL); - ArrayRef<InputSectionBase<ELFT> *> Sections = this->File->getSections(); + ArrayRef<InputSectionBase *> Sections = this->getFile<ELFT>()->getSections(); return Sections[this->Info]; } @@ -220,7 +216,7 @@ InputSectionBase<ELFT> *InputSection<ELFT>::getRelocatedSection() { template <class ELFT> template <class RelTy> void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { - InputSectionBase<ELFT> *RelocatedSection = getRelocatedSection(); + InputSectionBase *RelocatedSection = getRelocatedSection(); // Loop is slow and have complexity O(N*M), where N - amount of // relocations and M - amount of symbols in symbol table. @@ -228,7 +224,7 @@ void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { // simple linear search. for (const RelTy &Rel : Rels) { uint32_t Type = Rel.getType(Config->Mips64EL); - SymbolBody &Body = this->File->getRelocTargetSym(Rel); + SymbolBody &Body = this->getFile<ELFT>()->getRelocTargetSym(Rel); Elf_Rela *P = reinterpret_cast<Elf_Rela *>(Buf); Buf += sizeof(RelTy); @@ -239,7 +235,7 @@ void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { // Output section VA is zero for -r, so r_offset is an offset within the // section, but for --emit-relocs it is an virtual address. P->r_offset = RelocatedSection->OutSec->Addr + - RelocatedSection->getOffset(Rel.r_offset); + RelocatedSection->getOffset<ELFT>(Rel.r_offset); P->setSymbolAndType(In<ELFT>::SymTab->getSymbolIndex(&Body), Type, Config->Mips64EL); @@ -253,8 +249,7 @@ void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { // avoid having to parse and recreate .eh_frame, we just replace any // relocation in it pointing to discarded sections with R_*_NONE, which // hopefully creates a frame that is ignored at runtime. - InputSectionBase<ELFT> *Section = - cast<DefinedRegular<ELFT>>(Body).Section; + InputSectionBase *Section = cast<DefinedRegular<ELFT>>(Body).Section; if (Section == &InputSection<ELFT>::Discarded) { P->setSymbolAndType(0, 0, false); continue; @@ -457,15 +452,15 @@ template <class RelTy> void InputSection<ELFT>::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) { for (const RelTy &Rel : Rels) { uint32_t Type = Rel.getType(Config->Mips64EL); - uintX_t Offset = this->getOffset(Rel.r_offset); + uintX_t Offset = this->getOffset<ELFT>(Rel.r_offset); uint8_t *BufLoc = Buf + Offset; int64_t Addend = getAddend<ELFT>(Rel); if (!RelTy::IsRela) Addend += Target->getImplicitAddend(BufLoc, Type); - SymbolBody &Sym = this->File->getRelocTargetSym(Rel); + SymbolBody &Sym = this->getFile<ELFT>()->getRelocTargetSym(Rel); if (Target->getRelExpr(Type, Sym) != R_ABS) { - error(this->getLocation(Offset) + ": has non-ABS reloc"); + error(this->getLocation<ELFT>(Offset) + ": has non-ABS reloc"); return; } @@ -478,23 +473,28 @@ void InputSection<ELFT>::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) { } } +template <class ELFT> ObjectFile<ELFT> *InputSectionBase::getFile() const { + return cast_or_null<ObjectFile<ELFT>>(File); +} + template <class ELFT> -void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd) { +void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) { // scanReloc function in Writer.cpp constructs Relocations // vector only for SHF_ALLOC'ed sections. For other sections, // we handle relocations directly here. auto *IS = dyn_cast<InputSection<ELFT>>(this); if (IS && !(IS->Flags & SHF_ALLOC)) { if (IS->AreRelocsRela) - IS->relocateNonAlloc(Buf, IS->relas()); + IS->relocateNonAlloc(Buf, IS->template relas<ELFT>()); else - IS->relocateNonAlloc(Buf, IS->rels()); + IS->relocateNonAlloc(Buf, IS->template rels<ELFT>()); return; } + typedef typename ELFT::uint uintX_t; const unsigned Bits = sizeof(uintX_t) * 8; for (const Relocation &Rel : Relocations) { - uintX_t Offset = getOffset(Rel.Offset); + uintX_t Offset = getOffset<ELFT>(Rel.Offset); uint8_t *BufLoc = Buf + Offset; uint32_t Type = Rel.Type; @@ -562,7 +562,7 @@ template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) { // Iterate over all relocation sections that apply to this section. uint8_t *BufEnd = Buf + OutSecOff + Data.size(); - this->relocate(Buf, BufEnd); + this->relocate<ELFT>(Buf, BufEnd); } template <class ELFT> @@ -575,7 +575,7 @@ void InputSection<ELFT>::replace(InputSection<ELFT> *Other) { template <class ELFT> EhInputSection<ELFT>::EhInputSection(elf::ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name) - : InputSectionBase<ELFT>(F, Header, Name, InputSectionBase<ELFT>::EHFrame) { + : InputSectionBase(F, Header, Name, InputSectionBase::EHFrame) { // Mark .eh_frame sections as live by default because there are // usually no relocations that point to .eh_frames. Otherwise, // the garbage collector would drop all .eh_frame sections. @@ -584,7 +584,7 @@ EhInputSection<ELFT>::EhInputSection(elf::ObjectFile<ELFT> *F, template <class ELFT> bool EhInputSection<ELFT>::classof(const InputSectionData *S) { - return S->kind() == InputSectionBase<ELFT>::EHFrame; + return S->kind() == InputSectionBase::EHFrame; } // Returns the index of the first relocation that points to a region between @@ -615,9 +615,9 @@ template <class ELFT> void EhInputSection<ELFT>::split() { if (this->NumRelocations) { if (this->AreRelocsRela) - split(this->relas()); + split(this->relas<ELFT>()); else - split(this->rels()); + split(this->rels<ELFT>()); return; } split(makeArrayRef<typename ELFT::Rela>(nullptr, nullptr)); @@ -689,7 +689,7 @@ template <class ELFT> MergeInputSection<ELFT>::MergeInputSection(elf::ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name) - : InputSectionBase<ELFT>(F, Header, Name, InputSectionBase<ELFT>::Merge) {} + : InputSectionBase(F, Header, Name, InputSectionBase::Merge) {} // This function is called after we obtain a complete list of input sections // that need to be linked. This is responsible to split section contents @@ -712,7 +712,7 @@ template <class ELFT> void MergeInputSection<ELFT>::splitIntoPieces() { template <class ELFT> bool MergeInputSection<ELFT>::classof(const InputSectionData *S) { - return S->kind() == InputSectionBase<ELFT>::Merge; + return S->kind() == InputSectionBase::Merge; } // Do binary search to get a section piece at a given input offset. @@ -780,11 +780,6 @@ typename ELFT::uint MergeInputSection<ELFT>::getOffset(uintX_t Offset) const { return Piece.OutputOff + Addend; } -template class elf::InputSectionBase<ELF32LE>; -template class elf::InputSectionBase<ELF32BE>; -template class elf::InputSectionBase<ELF64LE>; -template class elf::InputSectionBase<ELF64BE>; - template class elf::InputSection<ELF32LE>; template class elf::InputSection<ELF32BE>; template class elf::InputSection<ELF64LE>; @@ -800,7 +795,26 @@ template class elf::MergeInputSection<ELF32BE>; template class elf::MergeInputSection<ELF64LE>; template class elf::MergeInputSection<ELF64BE>; -template std::string lld::toString(const InputSectionBase<ELF32LE> *); -template std::string lld::toString(const InputSectionBase<ELF32BE> *); -template std::string lld::toString(const InputSectionBase<ELF64LE> *); -template std::string lld::toString(const InputSectionBase<ELF64BE> *); +template void InputSectionBase::uncompress<ELF32LE>(); +template void InputSectionBase::uncompress<ELF32BE>(); +template void InputSectionBase::uncompress<ELF64LE>(); +template void InputSectionBase::uncompress<ELF64BE>(); + +template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF32LE>() const; +template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF32BE>() const; +template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF64LE>() const; +template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF64BE>() const; + +template OutputSectionBase *InputSectionBase::getOutputSection<ELF32LE>() const; +template OutputSectionBase *InputSectionBase::getOutputSection<ELF32BE>() const; +template OutputSectionBase *InputSectionBase::getOutputSection<ELF64LE>() const; +template OutputSectionBase *InputSectionBase::getOutputSection<ELF64BE>() const; + +template uint64_t +InputSectionBase::getOffset(const DefinedRegular<ELF32LE> &Sym) const; +template uint64_t +InputSectionBase::getOffset(const DefinedRegular<ELF32BE> &Sym) const; +template uint64_t +InputSectionBase::getOffset(const DefinedRegular<ELF64LE> &Sym) const; +template uint64_t +InputSectionBase::getOffset(const DefinedRegular<ELF64BE> &Sym) const; diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index e647c0be590..0846d64f9e4 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -72,23 +72,15 @@ public: }; // This corresponds to a section of an input file. -template <class ELFT> class InputSectionBase : public InputSectionData { -protected: - typedef typename ELFT::Chdr Elf_Chdr; - typedef typename ELFT::Rel Elf_Rel; - typedef typename ELFT::Rela Elf_Rela; - typedef typename ELFT::Shdr Elf_Shdr; - typedef typename ELFT::Sym Elf_Sym; - typedef typename ELFT::uint uintX_t; - +class InputSectionBase : public InputSectionData { +public: // The file this section is from. - ObjectFile<ELFT> *File; + InputFile *File; -public: // These corresponds to the fields in Elf_Shdr. - uintX_t Flags; - uintX_t Offset = 0; - uintX_t Entsize; + uint64_t Flags; + uint64_t Offset = 0; + uint64_t Entsize; uint32_t Type; uint32_t Link; uint32_t Info; @@ -99,26 +91,31 @@ public: AreRelocsRela = false; } - InputSectionBase(ObjectFile<ELFT> *File, const Elf_Shdr *Header, + template <class ELFT> + InputSectionBase(ObjectFile<ELFT> *File, const typename ELFT::Shdr *Header, StringRef Name, Kind SectionKind); - InputSectionBase(ObjectFile<ELFT> *File, uintX_t Flags, uint32_t Type, - uintX_t Entsize, uint32_t Link, uint32_t Info, - uintX_t Addralign, ArrayRef<uint8_t> Data, StringRef Name, + + InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type, + uint64_t Entsize, uint32_t Link, uint32_t Info, + uint64_t Addralign, ArrayRef<uint8_t> Data, StringRef Name, Kind SectionKind); OutputSectionBase *OutSec = nullptr; // Relocations that refer to this section. - const Elf_Rel *FirstRelocation = nullptr; + const void *FirstRelocation = nullptr; unsigned NumRelocations : 31; unsigned AreRelocsRela : 1; - ArrayRef<Elf_Rel> rels() const { + template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const { assert(!AreRelocsRela); - return llvm::makeArrayRef(FirstRelocation, NumRelocations); + return llvm::makeArrayRef( + static_cast<const typename ELFT::Rel *>(FirstRelocation), + NumRelocations); } - ArrayRef<Elf_Rela> relas() const { + template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const { assert(AreRelocsRela); - return llvm::makeArrayRef(static_cast<const Elf_Rela *>(FirstRelocation), - NumRelocations); + return llvm::makeArrayRef( + static_cast<const typename ELFT::Rela *>(FirstRelocation), + NumRelocations); } // This pointer points to the "real" instance of this instance. @@ -126,30 +123,36 @@ public: // Repl pointer of one section points to another section. So, // if you need to get a pointer to this instance, do not use // this but instead this->Repl. - InputSectionBase<ELFT> *Repl; + InputSectionBase *Repl; // InputSections that are dependent on us (reverse dependency for GC) - llvm::TinyPtrVector<InputSectionBase<ELFT> *> DependentSections; + llvm::TinyPtrVector<InputSectionBase *> DependentSections; // Returns the size of this section (even if this is a common or BSS.) - size_t getSize() const; + template <class ELFT> size_t getSize() const; - OutputSectionBase *getOutputSection() const; + template <class ELFT> OutputSectionBase *getOutputSection() const; - ObjectFile<ELFT> *getFile() const { return File; } - llvm::object::ELFFile<ELFT> getObj() const { return File->getObj(); } - uintX_t getOffset(const DefinedRegular<ELFT> &Sym) const; - InputSectionBase *getLinkOrderDep() const; + template <class ELFT> ObjectFile<ELFT> *getFile() const; + + template <class ELFT> llvm::object::ELFFile<ELFT> getObj() const { + return getFile<ELFT>()->getObj(); + } + + template <class ELFT> + uint64_t getOffset(const DefinedRegular<ELFT> &Sym) const; + + template <class ELFT> InputSectionBase *getLinkOrderDep() const; // Translate an offset in the input section to an offset in the output // section. - uintX_t getOffset(uintX_t Offset) const; + template <class ELFT> uint64_t getOffset(uint64_t Offset) const; - void uncompress(); + template <class ELFT> void uncompress(); // Returns a source location string. Used to construct an error message. - std::string getLocation(uintX_t Offset); + template <class ELFT> std::string getLocation(uint64_t Offset); - void relocate(uint8_t *Buf, uint8_t *BufEnd); + template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd); }; // SectionPiece represents a piece of splittable section contents. @@ -168,7 +171,7 @@ static_assert(sizeof(SectionPiece) == 2 * sizeof(size_t), "SectionPiece is too big"); // This corresponds to a SHF_MERGE section of an input file. -template <class ELFT> class MergeInputSection : public InputSectionBase<ELFT> { +template <class ELFT> class MergeInputSection : public InputSectionBase { typedef typename ELFT::uint uintX_t; typedef typename ELFT::Sym Elf_Sym; typedef typename ELFT::Shdr Elf_Shdr; @@ -243,7 +246,7 @@ struct EhSectionPiece : public SectionPiece { }; // This corresponds to a .eh_frame section of an input file. -template <class ELFT> class EhInputSection : public InputSectionBase<ELFT> { +template <class ELFT> class EhInputSection : public InputSectionBase { public: typedef typename ELFT::Shdr Elf_Shdr; typedef typename ELFT::uint uintX_t; @@ -258,8 +261,7 @@ public: }; // This corresponds to a non SHF_MERGE section of an input file. -template <class ELFT> class InputSection : public InputSectionBase<ELFT> { - typedef InputSectionBase<ELFT> Base; +template <class ELFT> class InputSection : public InputSectionBase { typedef typename ELFT::Shdr Elf_Shdr; typedef typename ELFT::Rela Elf_Rela; typedef typename ELFT::Rel Elf_Rel; @@ -286,7 +288,7 @@ public: static bool classof(const InputSectionData *S); - InputSectionBase<ELFT> *getRelocatedSection(); + InputSectionBase *getRelocatedSection(); template <class RelTy> void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels); @@ -305,7 +307,7 @@ private: template <class ELFT> InputSection<ELFT> InputSection<ELFT>::Discarded; } // namespace elf -template <class ELFT> std::string toString(const elf::InputSectionBase<ELFT> *); +std::string toString(const elf::InputSectionBase *); } // namespace lld #endif diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 7c9328d845a..fa603828c54 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -181,14 +181,13 @@ bool BytesDataCommand::classof(const BaseCommand *C) { template <class ELFT> LinkerScript<ELFT>::LinkerScript() = default; template <class ELFT> LinkerScript<ELFT>::~LinkerScript() = default; -template <class ELFT> static StringRef basename(InputSectionBase<ELFT> *S) { - if (S->getFile()) - return sys::path::filename(S->getFile()->getName()); +static StringRef basename(InputSectionBase *S) { + if (S->File) + return sys::path::filename(S->File->getName()); return ""; } -template <class ELFT> -bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { +template <class ELFT> bool LinkerScript<ELFT>::shouldKeep(InputSectionBase *S) { for (InputSectionDescription *ID : Opt.KeptSections) if (ID->FilePat.match(basename(S))) for (SectionPattern &P : ID->SectionPatterns) @@ -227,12 +226,12 @@ getComparator(SortSectionPolicy K) { } template <class ELFT> -static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, +static bool matchConstraints(ArrayRef<InputSectionBase *> Sections, ConstraintKind Kind) { if (Kind == ConstraintKind::NoConstraint) return true; bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) { - auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2); + auto *Sec = static_cast<InputSectionBase *>(Sec2); return Sec->Flags & SHF_WRITE; }); return (IsRW && Kind == ConstraintKind::ReadWrite) || @@ -253,7 +252,7 @@ void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) { for (SectionPattern &Pat : I->SectionPatterns) { size_t SizeBefore = I->Sections.size(); - for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) { + for (InputSectionBase *S : Symtab<ELFT>::X->Sections) { if (S->Assigned) continue; // For -emit-relocs we have to ignore entries like @@ -295,8 +294,8 @@ void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) { } template <class ELFT> -void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) { - for (InputSectionBase<ELFT> *S : V) { +void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase *> V) { + for (InputSectionBase *S : V) { S->Live = false; if (S == In<ELFT>::ShStrTab) error("discarding .shstrtab section is not allowed"); @@ -305,9 +304,9 @@ void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) { } template <class ELFT> -std::vector<InputSectionBase<ELFT> *> +std::vector<InputSectionBase *> LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { - std::vector<InputSectionBase<ELFT> *> Ret; + std::vector<InputSectionBase *> Ret; for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { auto *Cmd = dyn_cast<InputSectionDescription>(Base.get()); @@ -315,7 +314,7 @@ LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { continue; computeInputSections(Cmd); for (InputSectionData *S : Cmd->Sections) - Ret.push_back(static_cast<InputSectionBase<ELFT> *>(S)); + Ret.push_back(static_cast<InputSectionBase *>(S)); } return Ret; @@ -343,7 +342,7 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { } if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { - std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); + std::vector<InputSectionBase *> V = createInputSectionList(*Cmd); // The output section name `/DISCARD/' is special. // Any input section assigned to it is discarded. @@ -360,7 +359,7 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { // Because we'll iterate over Commands many more times, the easiest // way to "make it as if it wasn't present" is to just remove it. if (!matchConstraints<ELFT>(V, Cmd->Constraint)) { - for (InputSectionBase<ELFT> *S : V) + for (InputSectionBase *S : V) S->Assigned = false; Opt.Commands.erase(Iter); --I; @@ -378,12 +377,12 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { // given value is larger or smaller than the original section alignment. if (Cmd->SubalignExpr) { uint32_t Subalign = Cmd->SubalignExpr(0); - for (InputSectionBase<ELFT> *S : V) + for (InputSectionBase *S : V) S->Alignment = Subalign; } // Add input sections to an output section. - for (InputSectionBase<ELFT> *S : V) + for (InputSectionBase *S : V) Factory.addInputSec(S, Cmd->Name); } } @@ -393,7 +392,7 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { template <class ELFT> void LinkerScript<ELFT>::addOrphanSections( OutputSectionFactory<ELFT> &Factory) { - for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) + for (InputSectionBase *S : Symtab<ELFT>::X->Sections) if (S->Live && !S->OutSec) Factory.addInputSec(S, getOutputSectionName(S->Name)); } @@ -410,7 +409,7 @@ template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) { uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; Pos = alignTo(Pos, S->Alignment); S->OutSecOff = Pos - CurOutSec->Addr; - Pos += S->getSize(); + Pos += S->template getSize<ELFT>(); // Update output section size after adding each section. This is so that // SIZEOF works correctly in the case below: @@ -502,7 +501,7 @@ template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) { if (Sec->empty()) continue; - auto *IB = static_cast<InputSectionBase<ELFT> *>(ID); + auto *IB = static_cast<InputSectionBase *>(ID); if (!IB->Live) continue; switchTo(IB->OutSec); diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index fe7c3629272..3735355a8dc 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -31,7 +31,7 @@ namespace elf { class DefinedCommon; class ScriptParser; class SymbolBody; -template <class ELFT> class InputSectionBase; +class InputSectionBase; template <class ELFT> class InputSection; class OutputSectionBase; template <class ELFT> class OutputSectionFactory; @@ -259,7 +259,7 @@ public: uint32_t getFiller(StringRef Name); void writeDataBytes(StringRef Name, uint8_t *Buf); bool hasLMA(StringRef Name); - bool shouldKeep(InputSectionBase<ELFT> *S); + bool shouldKeep(InputSectionBase *S); void assignOffsets(OutputSectionCommand *Cmd); void placeOrphanSections(); void assignAddresses(std::vector<PhdrEntry> &Phdrs); @@ -283,9 +283,9 @@ private: void computeInputSections(InputSectionDescription *); void setDot(Expr E, const Twine &Loc, bool InSec = false); - void discard(ArrayRef<InputSectionBase<ELFT> *> V); + void discard(ArrayRef<InputSectionBase *> V); - std::vector<InputSectionBase<ELFT> *> + std::vector<InputSectionBase *> createInputSectionList(OutputSectionCommand &Cmd); // "ScriptConfig" is a bit too long, so define a short name for it. diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index 84a869a4aa2..c341049fb68 100644 --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -66,17 +66,17 @@ static void writeInputSection(raw_fd_ostream &OS, const InputSection<ELFT> *IS, int Width = ELFT::Is64Bits ? 16 : 8; StringRef Name = IS->Name; if (Name != PrevName) { - writeInSecLine(OS, Width, IS->OutSec->Addr + IS->OutSecOff, IS->getSize(), - IS->Alignment, Name); + writeInSecLine(OS, Width, IS->OutSec->Addr + IS->OutSecOff, + IS->template getSize<ELFT>(), IS->Alignment, Name); OS << '\n'; PrevName = Name; } - elf::ObjectFile<ELFT> *File = IS->getFile(); + elf::ObjectFile<ELFT> *File = IS->template getFile<ELFT>(); if (!File) return; - writeFileLine(OS, Width, IS->OutSec->Addr + IS->OutSecOff, IS->getSize(), - IS->Alignment, toString(File)); + writeFileLine(OS, Width, IS->OutSec->Addr + IS->OutSecOff, + IS->template getSize<ELFT>(), IS->Alignment, toString(File)); OS << '\n'; for (SymbolBody *Sym : File->getSymbols()) { diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index db477d88489..2593bfe57b6 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -45,34 +45,33 @@ namespace { // A resolved relocation. The Sec and Offset fields are set if the relocation // was resolved to an offset within a section. template <class ELFT> struct ResolvedReloc { - InputSectionBase<ELFT> *Sec; + InputSectionBase *Sec; typename ELFT::uint Offset; }; } // end anonymous namespace template <class ELFT> -static typename ELFT::uint getAddend(InputSectionBase<ELFT> &Sec, +static typename ELFT::uint getAddend(InputSectionBase &Sec, const typename ELFT::Rel &Rel) { return Target->getImplicitAddend(Sec.Data.begin() + Rel.r_offset, Rel.getType(Config->Mips64EL)); } template <class ELFT> -static typename ELFT::uint getAddend(InputSectionBase<ELFT> &Sec, +static typename ELFT::uint getAddend(InputSectionBase &Sec, const typename ELFT::Rela &Rel) { return Rel.r_addend; } template <class ELFT, class RelT> -static ResolvedReloc<ELFT> resolveReloc(InputSectionBase<ELFT> &Sec, - RelT &Rel) { - SymbolBody &B = Sec.getFile()->getRelocTargetSym(Rel); +static ResolvedReloc<ELFT> resolveReloc(InputSectionBase &Sec, RelT &Rel) { + SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); auto *D = dyn_cast<DefinedRegular<ELFT>>(&B); if (!D || !D->Section) return {nullptr, 0}; typename ELFT::uint Offset = D->Value; if (D->isSection()) - Offset += getAddend(Sec, Rel); + Offset += getAddend<ELFT>(Sec, Rel); return {D->Section->Repl, Offset}; } @@ -81,13 +80,13 @@ template <class ELFT> static void forEachSuccessor(InputSection<ELFT> &Sec, std::function<void(ResolvedReloc<ELFT>)> Fn) { if (Sec.AreRelocsRela) { - for (const typename ELFT::Rela &Rel : Sec.relas()) - Fn(resolveReloc(Sec, Rel)); + for (const typename ELFT::Rela &Rel : Sec.template relas<ELFT>()) + Fn(resolveReloc<ELFT>(Sec, Rel)); } else { - for (const typename ELFT::Rel &Rel : Sec.rels()) - Fn(resolveReloc(Sec, Rel)); + for (const typename ELFT::Rel &Rel : Sec.template rels<ELFT>()) + Fn(resolveReloc<ELFT>(Sec, Rel)); } - for (InputSectionBase<ELFT> *IS : Sec.DependentSections) + for (InputSectionBase *IS : Sec.DependentSections) Fn({IS, 0}); } @@ -118,7 +117,7 @@ scanEhFrameSection(EhInputSection<ELFT> &EH, ArrayRef<RelTy> Rels, if (read32<E>(Piece.data().data() + 4) == 0) { // This is a CIE, we only need to worry about the first relocation. It is // known to point to the personality function. - Enqueue(resolveReloc(EH, Rels[FirstRelI])); + Enqueue(resolveReloc<ELFT>(EH, Rels[FirstRelI])); continue; } // This is a FDE. The relocations point to the described function or to @@ -129,7 +128,7 @@ scanEhFrameSection(EhInputSection<ELFT> &EH, ArrayRef<RelTy> Rels, const RelTy &Rel = Rels[I2]; if (Rel.r_offset >= PieceEnd) break; - ResolvedReloc<ELFT> R = resolveReloc(EH, Rels[I2]); + ResolvedReloc<ELFT> R = resolveReloc<ELFT>(EH, Rels[I2]); if (!R.Sec || R.Sec == &InputSection<ELFT>::Discarded) continue; if (R.Sec->Flags & SHF_EXECINSTR) @@ -151,15 +150,15 @@ scanEhFrameSection(EhInputSection<ELFT> &EH, EH.split(); if (EH.AreRelocsRela) - scanEhFrameSection(EH, EH.relas(), Enqueue); + scanEhFrameSection(EH, EH.template relas<ELFT>(), Enqueue); else - scanEhFrameSection(EH, EH.rels(), Enqueue); + scanEhFrameSection(EH, EH.template rels<ELFT>(), Enqueue); } // We do not garbage-collect two types of sections: // 1) Sections used by the loader (.init, .fini, .ctors, .dtors or .jcr) // 2) Non-allocatable sections which typically contain debugging information -template <class ELFT> static bool isReserved(InputSectionBase<ELFT> *Sec) { +template <class ELFT> static bool isReserved(InputSectionBase *Sec) { switch (Sec->Type) { case SHT_FINI_ARRAY: case SHT_INIT_ARRAY: @@ -237,13 +236,13 @@ template <class ELFT> void elf::markLive() { // Preserve special sections and those which are specified in linker // script KEEP command. - for (InputSectionBase<ELFT> *Sec : Symtab<ELFT>::X->Sections) { + for (InputSectionBase *Sec : Symtab<ELFT>::X->Sections) { // .eh_frame is always marked as live now, but also it can reference to // sections that contain personality. We preserve all non-text sections // referred by .eh_frame here. if (auto *EH = dyn_cast_or_null<EhInputSection<ELFT>>(Sec)) scanEhFrameSection<ELFT>(*EH, Enqueue); - if (isReserved(Sec) || Script<ELFT>::X->shouldKeep(Sec)) + if (isReserved<ELFT>(Sec) || Script<ELFT>::X->shouldKeep(Sec)) Enqueue({Sec, 0}); } diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 15d467a7922..3b3cb806cd4 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -92,8 +92,8 @@ static bool compareByFilePosition(InputSection<ELFT> *A, if (A->kind() == InputSectionData::Synthetic || B->kind() == InputSectionData::Synthetic) return false; - auto *LA = cast<InputSection<ELFT>>(A->getLinkOrderDep()); - auto *LB = cast<InputSection<ELFT>>(B->getLinkOrderDep()); + auto *LA = cast<InputSection<ELFT>>(A->template getLinkOrderDep<ELFT>()); + auto *LB = cast<InputSection<ELFT>>(B->template getLinkOrderDep<ELFT>()); OutputSectionBase *AOut = LA->OutSec; OutputSectionBase *BOut = LB->OutSec; if (AOut != BOut) @@ -111,7 +111,7 @@ template <class ELFT> void OutputSection<ELFT>::finalize() { // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We // need to translate the InputSection sh_link to the OutputSection sh_link, // all InputSections in the OutputSection have the same dependency. - if (auto *D = this->Sections.front()->getLinkOrderDep()) + if (auto *D = this->Sections.front()->template getLinkOrderDep<ELFT>()) this->Link = D->OutSec->SectionIndex; } @@ -126,7 +126,7 @@ template <class ELFT> void OutputSection<ELFT>::finalize() { this->Link = In<ELFT>::SymTab->OutSec->SectionIndex; // sh_info for SHT_REL[A] sections should contain the section header index of // the section to which the relocation applies. - InputSectionBase<ELFT> *S = First->getRelocatedSection(); + InputSectionBase *S = First->getRelocatedSection(); this->Info = S->OutSec->SectionIndex; } @@ -157,7 +157,7 @@ template <class ELFT> void OutputSection<ELFT>::assignOffsets() { for (InputSection<ELFT> *S : Sections) { Off = alignTo(Off, S->Alignment); S->OutSecOff = Off; - Off += S->getSize(); + Off += S->template getSize<ELFT>(); } this->Size = Off; } @@ -221,12 +221,12 @@ static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); } template <class ELFT> static bool compCtors(const InputSection<ELFT> *A, const InputSection<ELFT> *B) { - bool BeginA = isCrtbegin(A->getFile()->getName()); - bool BeginB = isCrtbegin(B->getFile()->getName()); + bool BeginA = isCrtbegin(A->template getFile<ELFT>()->getName()); + bool BeginB = isCrtbegin(B->template getFile<ELFT>()->getName()); if (BeginA != BeginB) return BeginA; - bool EndA = isCrtend(A->getFile()->getName()); - bool EndB = isCrtend(B->getFile()->getName()); + bool EndA = isCrtend(A->template getFile<ELFT>()->getName()); + bool EndB = isCrtend(B->template getFile<ELFT>()->getName()); if (EndA != EndB) return EndB; StringRef X = A->Name; @@ -297,7 +297,8 @@ CieRecord *EhOutputSection<ELFT>::addCie(EhSectionPiece &Piece, SymbolBody *Personality = nullptr; unsigned FirstRelI = Piece.FirstRelocation; if (FirstRelI != (unsigned)-1) - Personality = &Sec->getFile()->getRelocTargetSym(Rels[FirstRelI]); + Personality = + &Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]); // Search for an existing CIE by CIE contents/relocation target pair. CieRecord *Cie = &CieMap[{Piece.data(), Personality}]; @@ -321,11 +322,11 @@ bool EhOutputSection<ELFT>::isFdeLive(EhSectionPiece &Piece, if (FirstRelI == (unsigned)-1) return false; const RelTy &Rel = Rels[FirstRelI]; - SymbolBody &B = Sec->getFile()->getRelocTargetSym(Rel); + SymbolBody &B = Sec->template getFile<ELFT>()->getRelocTargetSym(Rel); auto *D = dyn_cast<DefinedRegular<ELFT>>(&B); if (!D || !D->Section) return false; - InputSectionBase<ELFT> *Target = D->Section->Repl; + InputSectionBase *Target = D->Section->Repl; return Target && Target->Live; } @@ -380,9 +381,9 @@ void EhOutputSection<ELFT>::addSection(InputSectionData *C) { if (Sec->NumRelocations) { if (Sec->AreRelocsRela) - addSectionAux(Sec, Sec->relas()); + addSectionAux(Sec, Sec->template relas<ELFT>()); else - addSectionAux(Sec, Sec->rels()); + addSectionAux(Sec, Sec->template rels<ELFT>()); return; } addSectionAux(Sec, makeArrayRef<Elf_Rela>(nullptr, nullptr)); @@ -464,7 +465,7 @@ template <class ELFT> void EhOutputSection<ELFT>::writeTo(uint8_t *Buf) { } for (EhInputSection<ELFT> *S : Sections) - S->relocate(Buf, nullptr); + S->template relocate<ELFT>(Buf, nullptr); // Construct .eh_frame_hdr. .eh_frame_hdr is a binary search table // to get a FDE from an address to which FDE is applied. So here @@ -482,12 +483,12 @@ template <class ELFT> void EhOutputSection<ELFT>::writeTo(uint8_t *Buf) { } template <class ELFT> -static typename ELFT::uint getOutFlags(InputSectionBase<ELFT> *S) { +static typename ELFT::uint getOutFlags(InputSectionBase *S) { return S->Flags & ~SHF_GROUP & ~SHF_COMPRESSED; } template <class ELFT> -static SectionKey createKey(InputSectionBase<ELFT> *C, StringRef OutsecName) { +static SectionKey createKey(InputSectionBase *C, StringRef OutsecName) { // The ELF spec just says // ---------------------------------------------------------------- // In the first phase, input sections that match in name, type and @@ -564,23 +565,23 @@ static bool canMergeToProgbits(unsigned Type) { Type == SHT_NOTE; } -template <class ELFT> static void reportDiscarded(InputSectionBase<ELFT> *IS) { +template <class ELFT> static void reportDiscarded(InputSectionBase *IS) { if (!Config->PrintGcSections) return; message("removing unused section from '" + IS->Name + "' in file '" + - IS->getFile()->getName()); + IS->getFile<ELFT>()->getName()); } template <class ELFT> -void OutputSectionFactory<ELFT>::addInputSec(InputSectionBase<ELFT> *IS, +void OutputSectionFactory<ELFT>::addInputSec(InputSectionBase *IS, StringRef OutsecName) { if (!IS->Live) { - reportDiscarded(IS); + reportDiscarded<ELFT>(IS); return; } - SectionKey Key = createKey(IS, OutsecName); - uintX_t Flags = getOutFlags(IS); + SectionKey Key = createKey<ELFT>(IS, OutsecName); + uintX_t Flags = getOutFlags<ELFT>(IS); OutputSectionBase *&Sec = Map[Key]; if (Sec) { if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags)) @@ -596,7 +597,7 @@ void OutputSectionFactory<ELFT>::addInputSec(InputSectionBase<ELFT> *IS, Sec->Flags |= Flags; } else { uint32_t Type = IS->Type; - if (IS->kind() == InputSectionBase<ELFT>::EHFrame) { + if (IS->kind() == InputSectionBase::EHFrame) { Out<ELFT>::EhFrame->addSection(IS); return; } diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index a2ab3b049a2..f2198b41061 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -25,7 +25,7 @@ class SymbolBody; struct EhSectionPiece; template <class ELFT> class EhInputSection; template <class ELFT> class InputSection; -template <class ELFT> class InputSectionBase; +class InputSectionBase; template <class ELFT> class MergeInputSection; template <class ELFT> class OutputSection; template <class ELFT> class ObjectFile; @@ -227,7 +227,7 @@ template <class ELFT> class OutputSectionFactory { public: OutputSectionFactory(std::vector<OutputSectionBase *> &OutputSections); ~OutputSectionFactory(); - void addInputSec(InputSectionBase<ELFT> *IS, StringRef OutsecName); + void addInputSec(InputSectionBase *IS, StringRef OutsecName); private: llvm::SmallDenseMap<SectionKey, OutputSectionBase *> Map; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 0842331f87d..731023dc244 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -91,11 +91,10 @@ static bool isPreemptible(const SymbolBody &Body, uint32_t Type) { // handling in to the separate function we can simplify the code and do not // pollute `handleTlsRelocation` by ARM and MIPS `ifs` statements. template <class ELFT, class GOT> -static unsigned handleNoRelaxTlsRelocation(GOT *Got, uint32_t Type, - SymbolBody &Body, - InputSectionBase<ELFT> &C, - typename ELFT::uint Offset, - int64_t Addend, RelExpr Expr) { +static unsigned +handleNoRelaxTlsRelocation(GOT *Got, uint32_t Type, SymbolBody &Body, + InputSectionBase &C, typename ELFT::uint Offset, + int64_t Addend, RelExpr Expr) { typedef typename ELFT::uint uintX_t; auto addModuleReloc = [](SymbolBody &Body, GOT *Got, uintX_t Off, bool LD) { // The Dynamic TLS Module Index Relocation can be statically resolved to 1 @@ -136,7 +135,7 @@ static unsigned handleNoRelaxTlsRelocation(GOT *Got, uint32_t Type, // Returns the number of relocations processed. template <class ELFT> static unsigned -handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase<ELFT> &C, +handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) { if (!(C.Flags & SHF_ALLOC)) return 0; @@ -314,10 +313,9 @@ static bool isRelExpr(RelExpr Expr) { } template <class ELFT> -static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type, - const SymbolBody &Body, - InputSectionBase<ELFT> &S, - typename ELFT::uint RelOff) { +static bool +isStaticLinkTimeConstant(RelExpr E, uint32_t Type, const SymbolBody &Body, + InputSectionBase &S, typename ELFT::uint RelOff) { // These expressions always compute a constant if (isRelExprOneOf<R_SIZE, R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_TLSGD, @@ -356,7 +354,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type, return true; if (&Body == ElfSym<ELFT>::MipsGpDisp) return true; - error(S.getLocation(RelOff) + ": relocation " + toString(Type) + + error(S.getLocation<ELFT>(RelOff) + ": relocation " + toString(Type) + " cannot refer to absolute symbol '" + toString(Body) + "' defined in " + toString(Body.File)); return true; @@ -509,7 +507,7 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol<ELFT> *SS) { template <class ELFT> static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body, bool IsWrite, RelExpr Expr, uint32_t Type, - const uint8_t *Data, InputSectionBase<ELFT> &S, + const uint8_t *Data, InputSectionBase &S, typename ELFT::uint RelOff) { bool Preemptible = isPreemptible(Body, Type); if (Body.isGnuIFunc()) { @@ -528,7 +526,7 @@ static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body, // only memory. We can hack around it if we are producing an executable and // the refered symbol can be preemepted to refer to the executable. if (Config->Shared || (Config->pic() && !isRelExpr(Expr))) { - error(S.getLocation(RelOff) + ": can't create dynamic relocation " + + error(S.getLocation<ELFT>(RelOff) + ": can't create dynamic relocation " + toString(Type) + " against " + (Body.getName().empty() ? "local symbol in readonly segment" : "symbol '" + toString(Body) + "'") + @@ -536,8 +534,8 @@ static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body, return Expr; } if (Body.getVisibility() != STV_DEFAULT) { - error(S.getLocation(RelOff) + ": cannot preempt symbol '" + toString(Body) + - "' defined in " + toString(Body.File)); + error(S.getLocation<ELFT>(RelOff) + ": cannot preempt symbol '" + + toString(Body) + "' defined in " + toString(Body.File)); return Expr; } if (Body.isObject()) { @@ -545,8 +543,8 @@ static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body, auto *B = cast<SharedSymbol<ELFT>>(&Body); if (!B->NeedsCopy) { if (Config->ZNocopyreloc) - error(S.getLocation(RelOff) + ": unresolvable relocation " + toString(Type) - + " against symbol '" + toString(*B) + + error(S.getLocation<ELFT>(RelOff) + ": unresolvable relocation " + + toString(Type) + " against symbol '" + toString(*B) + "'; recompile with -fPIC or remove '-z nocopyreloc'"); addCopyRelSymbol(B); @@ -610,7 +608,7 @@ static int64_t computeAddend(const elf::ObjectFile<ELFT> &File, } template <class ELFT> -static void reportUndefined(SymbolBody &Sym, InputSectionBase<ELFT> &S, +static void reportUndefined(SymbolBody &Sym, InputSectionBase &S, typename ELFT::uint Offset) { bool CanBeExternal = Sym.symbol()->computeBinding() != STB_LOCAL && Sym.getVisibility() == STV_DEFAULT; @@ -618,8 +616,8 @@ static void reportUndefined(SymbolBody &Sym, InputSectionBase<ELFT> &S, (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal)) return; - std::string Msg = - S.getLocation(Offset) + ": undefined symbol '" + toString(Sym) + "'"; + std::string Msg = S.getLocation<ELFT>(Offset) + ": undefined symbol '" + + toString(Sym) + "'"; if (Config->UnresolvedSymbols == UnresolvedPolicy::WarnAll || (Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal)) @@ -658,7 +656,7 @@ mergeMipsN32RelTypes(uint32_t Type, uint32_t Offset, RelTy *I, RelTy *E) { // complicates things for the dynamic linker and means we would have to reserve // space for the extra PT_LOAD even if we end up not using it. template <class ELFT, class RelTy> -static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) { +static void scanRelocs(InputSectionBase &C, ArrayRef<RelTy> Rels) { typedef typename ELFT::uint uintX_t; bool IsWrite = C.Flags & SHF_WRITE; @@ -667,7 +665,7 @@ static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) { In<ELFT>::RelaDyn->addReloc(Reloc); }; - const elf::ObjectFile<ELFT> *File = C.getFile(); + const elf::ObjectFile<ELFT> *File = C.getFile<ELFT>(); ArrayRef<uint8_t> SectionData = C.Data; const uint8_t *Buf = SectionData.begin(); @@ -693,7 +691,7 @@ static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) { // We only report undefined symbols if they are referenced somewhere in the // code. if (!Body.isLocal() && Body.isUndefined() && !Body.symbol()->isWeak()) - reportUndefined(Body, C, RI.r_offset); + reportUndefined<ELFT>(Body, C, RI.r_offset); RelExpr Expr = Target->getRelExpr(Type, Body); bool Preemptible = isPreemptible(Body, Type); @@ -762,7 +760,7 @@ static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) { // We don't know anything about the finaly symbol. Just ask the dynamic // linker to handle the relocation for us. if (!Target->isPicRel(Type)) - error(C.getLocation(Offset) + ": relocation " + toString(Type) + + error(C.getLocation<ELFT>(Offset) + ": relocation " + toString(Type) + " cannot be used against shared object; recompile with -fPIC."); AddDyn({Target->getDynRel(Type), &C, Offset, false, &Body, Addend}); @@ -853,11 +851,11 @@ static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) { } } -template <class ELFT> void scanRelocations(InputSectionBase<ELFT> &S) { +template <class ELFT> void scanRelocations(InputSectionBase &S) { if (S.AreRelocsRela) - scanRelocs(S, S.relas()); + scanRelocs<ELFT>(S, S.relas<ELFT>()); else - scanRelocs(S, S.rels()); + scanRelocs<ELFT>(S, S.rels<ELFT>()); } // Insert the Thunks for OutputSection OS into their designated place @@ -940,7 +938,7 @@ void createThunks(ArrayRef<OutputSectionBase *> OutputSections) { if (TS == nullptr) { uint32_t Off = 0; for (auto *IS : OS->Sections) { - Off = IS->OutSecOff + IS->getSize(); + Off = IS->OutSecOff + IS->template getSize<ELFT>(); if ((IS->Flags & SHF_EXECINSTR) == 0) break; } @@ -964,7 +962,8 @@ void createThunks(ArrayRef<OutputSectionBase *> OutputSections) { for (InputSection<ELFT> *IS : OS->Sections) { for (Relocation &Rel : IS->Relocations) { SymbolBody &Body = *Rel.Sym; - if (Target->needsThunk(Rel.Expr, Rel.Type, IS->getFile(), Body)) { + if (Target->needsThunk(Rel.Expr, Rel.Type, IS->template getFile<ELFT>(), + Body)) { Thunk<ELFT> *T; bool IsNew; std::tie(T, IsNew) = GetThunk(Body, Rel.Type); @@ -990,10 +989,10 @@ void createThunks(ArrayRef<OutputSectionBase *> OutputSections) { mergeThunks<ELFT>(KV.first, KV.second); } -template void scanRelocations<ELF32LE>(InputSectionBase<ELF32LE> &); -template void scanRelocations<ELF32BE>(InputSectionBase<ELF32BE> &); -template void scanRelocations<ELF64LE>(InputSectionBase<ELF64LE> &); -template void scanRelocations<ELF64BE>(InputSectionBase<ELF64BE> &); +template void scanRelocations<ELF32LE>(InputSectionBase &); +template void scanRelocations<ELF32BE>(InputSectionBase &); +template void scanRelocations<ELF64LE>(InputSectionBase &); +template void scanRelocations<ELF64BE>(InputSectionBase &); template void createThunks<ELF32LE>(ArrayRef<OutputSectionBase *>); template void createThunks<ELF32BE>(ArrayRef<OutputSectionBase *>); diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h index fedd56ba04b..1512a674480 100644 --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -17,7 +17,7 @@ namespace elf { class SymbolBody; class InputSectionData; template <class ELFT> class InputSection; -template <class ELFT> class InputSectionBase; +class InputSectionBase; class OutputSectionBase; // List of target-independent relocation types. Relocations read @@ -109,7 +109,7 @@ struct Relocation { SymbolBody *Sym; }; -template <class ELFT> void scanRelocations(InputSectionBase<ELFT> &); +template <class ELFT> void scanRelocations(InputSectionBase &); template <class ELFT> void createThunks(ArrayRef<OutputSectionBase *> OutputSections); diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 76e6e0e58f1..47dd62e8ccf 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -361,28 +361,26 @@ static void reportDuplicate(SymbolBody *Existing, InputFile *NewFile) { } template <class ELFT> -static void reportDuplicate(SymbolBody *Existing, - InputSectionBase<ELFT> *ErrSec, +static void reportDuplicate(SymbolBody *Existing, InputSectionBase *ErrSec, typename ELFT::uint ErrOffset) { DefinedRegular<ELFT> *D = dyn_cast<DefinedRegular<ELFT>>(Existing); if (!D || !D->Section || !ErrSec) { - reportDuplicate(Existing, ErrSec ? ErrSec->getFile() : nullptr); + reportDuplicate(Existing, ErrSec ? ErrSec->getFile<ELFT>() : nullptr); return; } - std::string OldLoc = D->Section->getLocation(D->Value); - std::string NewLoc = ErrSec->getLocation(ErrOffset); + std::string OldLoc = D->Section->template getLocation<ELFT>(D->Value); + std::string NewLoc = ErrSec->getLocation<ELFT>(ErrOffset); print(NewLoc + ": duplicate symbol '" + toString(*Existing) + "'"); print(OldLoc + ": previous definition was here"); } template <typename ELFT> -Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther, - uint8_t Type, uintX_t Value, uintX_t Size, - uint8_t Binding, - InputSectionBase<ELFT> *Section, - InputFile *File) { +Symbol * +SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther, uint8_t Type, + uintX_t Value, uintX_t Size, uint8_t Binding, + InputSectionBase *Section, InputFile *File) { Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther), @@ -393,7 +391,7 @@ Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther, replaceBody<DefinedRegular<ELFT>>(S, Name, /*IsLocal=*/false, StOther, Type, Value, Size, Section, File); else if (Cmp == 0) - reportDuplicate(S->body(), Section, Value); + reportDuplicate<ELFT>(S->body(), Section, Value); return S; } diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 371188179d2..2b8a7f982dc 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -60,7 +60,7 @@ public: Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type, uintX_t Value, uintX_t Size, uint8_t Binding, - InputSectionBase<ELFT> *Section, InputFile *File); + InputSectionBase *Section, InputFile *File); Symbol *addSynthetic(StringRef N, const OutputSectionBase *Section, uintX_t Value, uint8_t StOther); @@ -92,7 +92,7 @@ public: void trace(StringRef Name); void wrap(StringRef Name); - std::vector<InputSectionBase<ELFT> *> Sections; + std::vector<InputSectionBase *> Sections; private: std::vector<SymbolBody *> findByVersion(SymbolVersion Ver); diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index f3c2a0eaf91..4285211f92e 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -44,7 +44,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) { } case SymbolBody::DefinedRegularKind: { auto &D = cast<DefinedRegular<ELFT>>(Body); - InputSectionBase<ELFT> *IS = D.Section; + InputSectionBase *IS = D.Section; // According to the ELF spec reference to a local symbol from outside // the group are not allowed. Unfortunately .eh_frame breaks that rule @@ -62,8 +62,8 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) { Offset += Addend; Addend = 0; } - const OutputSectionBase *OutSec = IS->getOutputSection(); - uintX_t VA = (OutSec ? OutSec->Addr : 0) + IS->getOffset(Offset); + const OutputSectionBase *OutSec = IS->getOutputSection<ELFT>(); + uintX_t VA = (OutSec ? OutSec->Addr : 0) + IS->getOffset<ELFT>(Offset); if (D.isTls() && !Config->Relocatable) { if (!Out<ELFT>::TlsPhdr) fatal(toString(D.File) + @@ -219,7 +219,8 @@ template <class ELFT> bool DefinedRegular<ELFT>::isMipsPIC() const { if (!Section || !isFunc()) return false; return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC || - (Section->getFile()->getObj().getHeader()->e_flags & EF_MIPS_PIC); + (Section->getFile<ELFT>()->getObj().getHeader()->e_flags & + EF_MIPS_PIC); } Undefined::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 9be14d09a7c..0342f90b75b 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -180,7 +180,7 @@ template <class ELFT> class DefinedRegular : public Defined { public: DefinedRegular(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type, - uintX_t Value, uintX_t Size, InputSectionBase<ELFT> *Section, + uintX_t Value, uintX_t Size, InputSectionBase *Section, InputFile *File) : Defined(SymbolBody::DefinedRegularKind, Name, IsLocal, StOther, Type), Value(Value), Size(Size), @@ -204,14 +204,13 @@ public: // manipulates this Section pointers so that they point to the same // section. This is a bit tricky, so be careful to not be confused. // If this is null, the symbol is an absolute symbol. - InputSectionBase<ELFT> *&Section; + InputSectionBase *&Section; private: - static InputSectionBase<ELFT> *NullInputSection; + static InputSectionBase *NullInputSection; }; -template <class ELFT> -InputSectionBase<ELFT> *DefinedRegular<ELFT>::NullInputSection; +template <class ELFT> InputSectionBase *DefinedRegular<ELFT>::NullInputSection; // DefinedSynthetic is a class to represent linker-generated ELF symbols. // The difference from the regular symbol is that DefinedSynthetic symbols diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 19326bc741d..bec6240ff7c 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -130,13 +130,13 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() { Elf_Mips_ABIFlags Flags = {}; bool Create = false; - for (InputSectionBase<ELFT> *Sec : Symtab<ELFT>::X->Sections) { + for (InputSectionBase *Sec : Symtab<ELFT>::X->Sections) { if (!Sec->Live || Sec->Type != SHT_MIPS_ABIFLAGS) continue; Sec->Live = false; Create = true; - std::string Filename = toString(Sec->getFile()); + std::string Filename = toString(Sec->getFile<ELFT>()); const size_t Size = Sec->Data.size(); // Older version of BFD (such as the default FreeBSD linker) concatenate // .MIPS.abiflags instead of merging. To allow for this case (or potential @@ -197,13 +197,13 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() { Elf_Mips_RegInfo Reginfo = {}; bool Create = false; - for (InputSectionBase<ELFT> *Sec : Symtab<ELFT>::X->Sections) { + for (InputSectionBase *Sec : Symtab<ELFT>::X->Sections) { if (!Sec->Live || Sec->Type != SHT_MIPS_OPTIONS) continue; Sec->Live = false; Create = true; - std::string Filename = toString(Sec->getFile()); + std::string Filename = toString(Sec->getFile<ELFT>()); ArrayRef<uint8_t> D = Sec->Data; while (!D.empty()) { @@ -217,7 +217,7 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() { if (Config->Relocatable && Opt->getRegInfo().ri_gp_value) error(Filename + ": unsupported non-zero ri_gp_value"); Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask; - Sec->getFile()->MipsGp0 = Opt->getRegInfo().ri_gp_value; + Sec->getFile<ELFT>()->MipsGp0 = Opt->getRegInfo().ri_gp_value; break; } @@ -253,22 +253,24 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() { Elf_Mips_RegInfo Reginfo = {}; bool Create = false; - for (InputSectionBase<ELFT> *Sec : Symtab<ELFT>::X->Sections) { + for (InputSectionBase *Sec : Symtab<ELFT>::X->Sections) { if (!Sec->Live || Sec->Type != SHT_MIPS_REGINFO) continue; Sec->Live = false; Create = true; if (Sec->Data.size() != sizeof(Elf_Mips_RegInfo)) { - error(toString(Sec->getFile()) + ": invalid size of .reginfo section"); + error(toString(Sec->getFile<ELFT>()) + + ": invalid size of .reginfo section"); return nullptr; } auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data()); if (Config->Relocatable && R->ri_gp_value) - error(toString(Sec->getFile()) + ": unsupported non-zero ri_gp_value"); + error(toString(Sec->getFile<ELFT>()) + + ": unsupported non-zero ri_gp_value"); Reginfo.ri_gprmask |= R->ri_gprmask; - Sec->getFile()->MipsGp0 = R->ri_gp_value; + Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value; }; if (Create) @@ -288,10 +290,9 @@ template <class ELFT> InputSection<ELFT> *elf::createInterpSection() { } template <class ELFT> -SymbolBody *elf::addSyntheticLocal(StringRef Name, uint8_t Type, - typename ELFT::uint Value, - typename ELFT::uint Size, - InputSectionBase<ELFT> *Section) { +SymbolBody * +elf::addSyntheticLocal(StringRef Name, uint8_t Type, typename ELFT::uint Value, + typename ELFT::uint Size, InputSectionBase *Section) { auto *S = make<DefinedRegular<ELFT>>(Name, /*IsLocal*/ true, STV_DEFAULT, Type, Value, Size, Section, nullptr); if (In<ELFT>::SymTab) @@ -452,7 +453,7 @@ template <class ELFT> bool GotSection<ELFT>::empty() const { } template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) { - this->relocate(Buf, Buf + Size); + this->template relocate<ELFT>(Buf, Buf + Size); } template <class ELFT> @@ -494,7 +495,8 @@ void MipsGotSection<ELFT>::addEntry(SymbolBody &Sym, int64_t Addend, // method calculate number of "pages" required to cover all saved output // section and allocate appropriate number of GOT entries. auto *DefSym = cast<DefinedRegular<ELFT>>(&Sym); - PageIndexMap.insert({DefSym->Section->getOutputSection(), 0}); + PageIndexMap.insert( + {DefSym->Section->template getOutputSection<ELFT>(), 0}); return; } if (Sym.isTls()) { @@ -565,7 +567,8 @@ typename MipsGotSection<ELFT>::uintX_t MipsGotSection<ELFT>::getPageEntryOffset(const SymbolBody &B, int64_t Addend) const { const OutputSectionBase *OutSec = - cast<DefinedRegular<ELFT>>(&B)->Section->getOutputSection(); + cast<DefinedRegular<ELFT>>(&B) + ->Section->template getOutputSection<ELFT>(); uintX_t SecAddr = getMipsPageAddr(OutSec->Addr); uintX_t SymAddr = getMipsPageAddr(B.getVA<ELFT>(Addend)); uintX_t Index = PageIndexMap.lookup(OutSec) + (SymAddr - SecAddr) / 0xffff; @@ -976,7 +979,7 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { template <class ELFT> typename ELFT::uint DynamicReloc<ELFT>::getOffset() const { - return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec); + return InputSec->OutSec->Addr + InputSec->getOffset<ELFT>(OffsetInSec); } template <class ELFT> int64_t DynamicReloc<ELFT>::getAddend() const { @@ -1168,14 +1171,14 @@ void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) { for (auto I = Symbols.begin(); I != Symbols.begin() + NumLocals; ++I) { const DefinedRegular<ELFT> &Body = *cast<DefinedRegular<ELFT>>(I->Symbol); - InputSectionBase<ELFT> *Section = Body.Section; + InputSectionBase *Section = Body.Section; auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); if (!Section) { ESym->st_shndx = SHN_ABS; ESym->st_value = Body.Value; } else { - const OutputSectionBase *OutSec = Section->getOutputSection(); + const OutputSectionBase *OutSec = Section->getOutputSection<ELFT>(); ESym->st_shndx = OutSec->SectionIndex; ESym->st_value = OutSec->Addr + Section->getOffset(Body); } @@ -1241,7 +1244,7 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) { case SymbolBody::DefinedRegularKind: { auto &D = cast<DefinedRegular<ELFT>>(*Sym); if (D.Section) - return D.Section->getOutputSection(); + return D.Section->template getOutputSection<ELFT>(); break; } case SymbolBody::DefinedCommonKind: @@ -1512,7 +1515,7 @@ GdbIndexSection<ELFT>::GdbIndexSection() StringPool(llvm::StringTableBuilder::ELF) {} template <class ELFT> void GdbIndexSection<ELFT>::parseDebugSections() { - for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) + for (InputSectionBase *S : Symtab<ELFT>::X->Sections) if (InputSection<ELFT> *IS = dyn_cast<InputSection<ELFT>>(S)) if (IS->OutSec && IS->Name == ".debug_info") readDwarf(IS); @@ -1610,7 +1613,8 @@ template <class ELFT> void GdbIndexSection<ELFT>::writeTo(uint8_t *Buf) { // Write the address area. for (AddressEntry<ELFT> &E : AddressArea) { - uintX_t BaseAddr = E.Section->OutSec->Addr + E.Section->getOffset(0); + uintX_t BaseAddr = + E.Section->OutSec->Addr + E.Section->template getOffset<ELFT>(0); write64le(Buf, BaseAddr + E.LowAddress); write64le(Buf + 8, BaseAddr + E.HighAddress); write32le(Buf + 16, E.CuIndex); @@ -1969,8 +1973,10 @@ void ARMExidxSentinelSection<ELFT>::writeTo(uint8_t *Buf) { // Get the InputSection before us, we are by definition last auto RI = cast<OutputSection<ELFT>>(this->OutSec)->Sections.rbegin(); InputSection<ELFT> *LE = *(++RI); - InputSection<ELFT> *LC = cast<InputSection<ELFT>>(LE->getLinkOrderDep()); - uint64_t S = LC->OutSec->Addr + LC->getOffset(LC->getSize()); + InputSection<ELFT> *LC = + cast<InputSection<ELFT>>(LE->template getLinkOrderDep<ELFT>()); + uint64_t S = LC->OutSec->Addr + + LC->template getOffset<ELFT>(LC->template getSize<ELFT>()); uint64_t P = this->getVA(); Target->relocateOne(Buf, R_ARM_PREL31, S - P); write32le(Buf + 4, 0x1); @@ -2018,18 +2024,22 @@ template MergeInputSection<ELF32BE> *elf::createCommentSection(); template MergeInputSection<ELF64LE> *elf::createCommentSection(); template MergeInputSection<ELF64BE> *elf::createCommentSection(); -template SymbolBody * -elf::addSyntheticLocal<ELF32LE>(StringRef, uint8_t, ELF32LE::uint, - ELF32LE::uint, InputSectionBase<ELF32LE> *); -template SymbolBody * -elf::addSyntheticLocal<ELF32BE>(StringRef, uint8_t, ELF32BE::uint, - ELF32BE::uint, InputSectionBase<ELF32BE> *); -template SymbolBody * -elf::addSyntheticLocal<ELF64LE>(StringRef, uint8_t, ELF64LE::uint, - ELF64LE::uint, InputSectionBase<ELF64LE> *); -template SymbolBody * -elf::addSyntheticLocal<ELF64BE>(StringRef, uint8_t, ELF64BE::uint, - ELF64BE::uint, InputSectionBase<ELF64BE> *); +template SymbolBody *elf::addSyntheticLocal<ELF32LE>(StringRef, uint8_t, + ELF32LE::uint, + ELF32LE::uint, + InputSectionBase *); +template SymbolBody *elf::addSyntheticLocal<ELF32BE>(StringRef, uint8_t, + ELF32BE::uint, + ELF32BE::uint, + InputSectionBase *); +template SymbolBody *elf::addSyntheticLocal<ELF64LE>(StringRef, uint8_t, + ELF64LE::uint, + ELF64LE::uint, + InputSectionBase *); +template SymbolBody *elf::addSyntheticLocal<ELF64BE>(StringRef, uint8_t, + ELF64BE::uint, + ELF64BE::uint, + InputSectionBase *); template class elf::MipsAbiFlagsSection<ELF32LE>; template class elf::MipsAbiFlagsSection<ELF32BE>; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index a1190d2803f..7c6425f3ab4 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -277,7 +277,7 @@ template <class ELFT> class DynamicReloc { typedef typename ELFT::uint uintX_t; public: - DynamicReloc(uint32_t Type, const InputSectionBase<ELFT> *InputSec, + DynamicReloc(uint32_t Type, const InputSectionBase *InputSec, uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, int64_t Addend) : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), @@ -286,13 +286,13 @@ public: uintX_t getOffset() const; int64_t getAddend() const; uint32_t getSymIndex() const; - const InputSectionBase<ELFT> *getInputSec() const { return InputSec; } + const InputSectionBase *getInputSec() const { return InputSec; } uint32_t Type; private: SymbolBody *Sym; - const InputSectionBase<ELFT> *InputSec = nullptr; + const InputSectionBase *InputSec = nullptr; uintX_t OffsetInSec; bool UseSymVA; int64_t Addend; @@ -749,7 +749,7 @@ template <class ELFT> MergeInputSection<ELFT> *createCommentSection(); template <class ELFT> SymbolBody * addSyntheticLocal(StringRef Name, uint8_t Type, typename ELFT::uint Value, - typename ELFT::uint Size, InputSectionBase<ELFT> *Section); + typename ELFT::uint Size, InputSectionBase *Section); // Linker generated sections which can be used as inputs. template <class ELFT> struct In { diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 2b0381f06b3..7d2433072f4 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -66,8 +66,8 @@ template <class ELFT> static std::string getErrorLoc(uint8_t *Loc) { continue; uint8_t *ISLoc = cast<OutputSection<ELFT>>(IS->OutSec)->Loc + IS->OutSecOff; - if (ISLoc <= Loc && Loc < ISLoc + IS->getSize()) - return IS->getLocation(Loc - ISLoc) + ": "; + if (ISLoc <= Loc && Loc < ISLoc + IS->template getSize<ELFT>()) + return IS->template getLocation<ELFT>(Loc - ISLoc) + ": "; } return ""; } @@ -1760,8 +1760,8 @@ void ARMTargetInfo::writePltHeader(uint8_t *Buf) const { void ARMTargetInfo::addPltHeaderSymbols(InputSectionData *ISD) const { auto *IS = cast<InputSection<ELF32LE>>(ISD); - addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS); - addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS); + addSyntheticLocal<ELF32LE>("$a", STT_NOTYPE, 0, 0, IS); + addSyntheticLocal<ELF32LE>("$d", STT_NOTYPE, 16, 0, IS); } void ARMTargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr, @@ -1783,8 +1783,8 @@ void ARMTargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr, void ARMTargetInfo::addPltSymbols(InputSectionData *ISD, uint64_t Off) const { auto *IS = cast<InputSection<ELF32LE>>(ISD); - addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS); - addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS); + addSyntheticLocal<ELF32LE>("$a", STT_NOTYPE, Off, 0, IS); + addSyntheticLocal<ELF32LE>("$d", STT_NOTYPE, Off + 12, 0, IS); } bool ARMTargetInfo::needsThunk(RelExpr Expr, uint32_t RelocType, diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp index 6123a1a2234..651e11b4172 100644 --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -127,10 +127,10 @@ void ARMToThumbV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf, template <class ELFT> void ARMToThumbV7ABSLongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) { - this->ThunkSym = addSyntheticLocal( + this->ThunkSym = addSyntheticLocal<ELFT>( Saver.save("__ARMToThumbv7ABSLongThunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); - addSyntheticLocal("$a", STT_NOTYPE, this->Offset, 0, &IS); + addSyntheticLocal<ELFT>("$a", STT_NOTYPE, this->Offset, 0, &IS); } template <class ELFT> @@ -149,10 +149,10 @@ void ThumbToARMV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf, template <class ELFT> void ThumbToARMV7ABSLongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) { - this->ThunkSym = addSyntheticLocal( + this->ThunkSym = addSyntheticLocal<ELFT>( Saver.save("__ThumbToARMv7ABSLongThunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); - addSyntheticLocal("$t", STT_NOTYPE, this->Offset, 0, &IS); + addSyntheticLocal<ELFT>("$t", STT_NOTYPE, this->Offset, 0, &IS); } template <class ELFT> @@ -173,10 +173,10 @@ void ARMToThumbV7PILongThunk<ELFT>::writeTo(uint8_t *Buf, template <class ELFT> void ARMToThumbV7PILongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) { - this->ThunkSym = addSyntheticLocal( + this->ThunkSym = addSyntheticLocal<ELFT>( Saver.save("__ARMToThumbV7PILongThunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); - addSyntheticLocal("$a", STT_NOTYPE, this->Offset, 0, &IS); + addSyntheticLocal<ELFT>("$a", STT_NOTYPE, this->Offset, 0, &IS); } template <class ELFT> @@ -197,10 +197,10 @@ void ThumbToARMV7PILongThunk<ELFT>::writeTo(uint8_t *Buf, template <class ELFT> void ThumbToARMV7PILongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) { - this->ThunkSym = addSyntheticLocal( + this->ThunkSym = addSyntheticLocal<ELFT>( Saver.save("__ThumbToARMV7PILongThunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); - addSyntheticLocal("$t", STT_NOTYPE, this->Offset, 0, &IS); + addSyntheticLocal<ELFT>("$t", STT_NOTYPE, this->Offset, 0, &IS); } // Write MIPS LA25 thunk code to call PIC function from the non-PIC one. @@ -218,7 +218,7 @@ void MipsThunk<ELFT>::writeTo(uint8_t *Buf, ThunkSection<ELFT> &) const { } template <class ELFT> void MipsThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) { - this->ThunkSym = addSyntheticLocal( + this->ThunkSym = addSyntheticLocal<ELFT>( Saver.save("__LA25Thunk_" + this->Destination.getName()), STT_FUNC, this->Offset, size(), &IS); } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index abdf61a8e7a..f4568ebf26e 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -54,7 +54,7 @@ private: void addSectionSymbols(); void addReservedSymbols(); void createSections(); - void forEachRelSec(std::function<void(InputSectionBase<ELFT> &)> Fn); + void forEachRelSec(std::function<void(InputSectionBase &)> Fn); void sortSections(); void finalizeSections(); void addPredefinedSections(); @@ -152,7 +152,7 @@ template <class ELFT> void Writer<ELFT>::removeEmptyPTLoad() { } template <class ELFT> -static typename ELFT::uint getOutFlags(InputSectionBase<ELFT> *S) { +static typename ELFT::uint getOutFlags(InputSectionBase *S) { return S->Flags & ~(typename ELFT::uint)(SHF_GROUP | SHF_COMPRESSED); } @@ -164,7 +164,7 @@ template <class ELFT> static void combineMergableSections() { typedef typename ELFT::uint uintX_t; std::vector<MergeSyntheticSection<ELFT> *> MergeSections; - for (InputSectionBase<ELFT> *&S : Symtab<ELFT>::X->Sections) { + for (InputSectionBase *&S : Symtab<ELFT>::X->Sections) { MergeInputSection<ELFT> *MS = dyn_cast<MergeInputSection<ELFT>>(S); if (!MS) continue; @@ -175,7 +175,7 @@ template <class ELFT> static void combineMergableSections() { continue; StringRef OutsecName = getOutputSectionName(MS->Name); - uintX_t Flags = getOutFlags(MS); + uintX_t Flags = getOutFlags<ELFT>(MS); uintX_t Alignment = std::max<uintX_t>(MS->Alignment, MS->Entsize); auto I = @@ -195,7 +195,7 @@ template <class ELFT> static void combineMergableSections() { (*I)->addSection(MS); } - std::vector<InputSectionBase<ELFT> *> &V = Symtab<ELFT>::X->Sections; + std::vector<InputSectionBase *> &V = Symtab<ELFT>::X->Sections; V.erase(std::remove(V.begin(), V.end(), nullptr), V.end()); } @@ -307,7 +307,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { // you can call lld::elf::main more than once as a library. memset(&Out<ELFT>::First, 0, sizeof(Out<ELFT>)); - auto Add = [](InputSectionBase<ELFT> *Sec) { + auto Add = [](InputSectionBase *Sec) { Symtab<ELFT>::X->Sections.push_back(Sec); }; @@ -452,7 +452,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { } template <class ELFT> -static bool shouldKeepInSymtab(InputSectionBase<ELFT> *Sec, StringRef SymName, +static bool shouldKeepInSymtab(InputSectionBase *Sec, StringRef SymName, const SymbolBody &B) { if (B.isFile() || B.isSection()) return false; @@ -514,7 +514,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { if (!includeInSymtab<ELFT>(*B)) continue; - InputSectionBase<ELFT> *Sec = DR->Section; + InputSectionBase *Sec = DR->Section; if (!shouldKeepInSymtab<ELFT>(Sec, B->getName(), *B)) continue; In<ELFT>::SymTab->addLocal(B); @@ -747,7 +747,7 @@ addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec, } template <class ELFT> -static Symbol *addRegular(StringRef Name, InputSectionBase<ELFT> *Sec, +static Symbol *addRegular(StringRef Name, InputSectionBase *Sec, typename ELFT::uint Value) { // The linker generated symbols are added as STB_WEAK to allow user defined // ones to override them. @@ -757,14 +757,14 @@ static Symbol *addRegular(StringRef Name, InputSectionBase<ELFT> *Sec, } template <class ELFT> -static Symbol *addOptionalRegular(StringRef Name, InputSectionBase<ELFT> *IS, +static Symbol *addOptionalRegular(StringRef Name, InputSectionBase *IS, typename ELFT::uint Value) { SymbolBody *S = Symtab<ELFT>::X->find(Name); if (!S) return nullptr; if (S->isInCurrentDSO()) return S->symbol(); - return addRegular(Name, IS, Value); + return addRegular<ELFT>(Name, IS, Value); } // The beginning and the ending of .rel[a].plt section are marked @@ -903,9 +903,8 @@ static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *> OutputSections) { } template <class ELFT> -void Writer<ELFT>::forEachRelSec( - std::function<void(InputSectionBase<ELFT> &)> Fn) { - for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections) { +void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) { + for (InputSectionBase *IS : Symtab<ELFT>::X->Sections) { if (!IS->Live) continue; // Scan all relocations. Each relocation goes through a series @@ -921,7 +920,7 @@ void Writer<ELFT>::forEachRelSec( } template <class ELFT> void Writer<ELFT>::createSections() { - for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections) + for (InputSectionBase *IS : Symtab<ELFT>::X->Sections) if (IS) Factory.addInputSec(IS, getOutputSectionName(IS->Name)); @@ -1047,7 +1046,7 @@ static void removeUnusedSyntheticSections(std::vector<OutputSectionBase *> &V) { // All input synthetic sections that can be empty are placed after // all regular ones. We iterate over them all and exit at first // non-synthetic. - for (InputSectionBase<ELFT> *S : llvm::reverse(Symtab<ELFT>::X->Sections)) { + for (InputSectionBase *S : llvm::reverse(Symtab<ELFT>::X->Sections)) { SyntheticSection<ELFT> *SS = dyn_cast<SyntheticSection<ELFT>>(S); if (!SS) return; @@ -1084,7 +1083,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { // Even the author of gold doesn't remember why gold behaves that way. // https://sourceware.org/ml/binutils/2002-03/msg00360.html if (In<ELFT>::DynSymTab) - addRegular("_DYNAMIC", In<ELFT>::Dynamic, 0); + addRegular<ELFT>("_DYNAMIC", In<ELFT>::Dynamic, 0); // Define __rel[a]_iplt_{start,end} symbols if needed. addRelIpltSymbols(); diff --git a/lld/ELF/Writer.h b/lld/ELF/Writer.h index b5be425b043..93ea264d7c1 100644 --- a/lld/ELF/Writer.h +++ b/lld/ELF/Writer.h @@ -19,7 +19,7 @@ namespace lld { namespace elf { class InputFile; class OutputSectionBase; -template <class ELFT> class InputSectionBase; +class InputSectionBase; template <class ELFT> class ObjectFile; template <class ELFT> class SymbolTable; template <class ELFT> void writeResult(); |