diff options
Diffstat (limited to 'contrib/llvm/tools/lld/ELF/SyntheticSections.h')
-rw-r--r-- | contrib/llvm/tools/lld/ELF/SyntheticSections.h | 464 |
1 files changed, 257 insertions, 207 deletions
diff --git a/contrib/llvm/tools/lld/ELF/SyntheticSections.h b/contrib/llvm/tools/lld/ELF/SyntheticSections.h index df67e079ad0e..1098c58a3baf 100644 --- a/contrib/llvm/tools/lld/ELF/SyntheticSections.h +++ b/contrib/llvm/tools/lld/ELF/SyntheticSections.h @@ -6,10 +6,22 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// Synthetic sections represent chunks of linker-created data. If you +// need to create a chunk of data that to be included in some section +// in the result, you probably want to create that as a synthetic section. +// +// Synthetic sections are designed as input sections as opposed to +// output sections because we want to allow them to be manipulated +// using linker scripts just like other input sections from regular +// files. +// +//===----------------------------------------------------------------------===// #ifndef LLD_ELF_SYNTHETIC_SECTION_H #define LLD_ELF_SYNTHETIC_SECTION_H +#include "EhFrame.h" #include "GdbIndex.h" #include "InputSection.h" #include "llvm/ADT/MapVector.h" @@ -18,49 +30,95 @@ namespace lld { namespace elf { -template <class ELFT> class SyntheticSection : public InputSection<ELFT> { - typedef typename ELFT::uint uintX_t; - +class SyntheticSection : public InputSection { public: - SyntheticSection(uintX_t Flags, uint32_t Type, uintX_t Addralign, + SyntheticSection(uint64_t Flags, uint32_t Type, uint32_t Alignment, StringRef Name) - : InputSection<ELFT>(Flags, Type, Addralign, ArrayRef<uint8_t>(), Name, - InputSectionData::Synthetic) { + : InputSection(Flags, Type, Alignment, {}, Name, + InputSectionBase::Synthetic) { this->Live = true; } virtual ~SyntheticSection() = default; virtual void writeTo(uint8_t *Buf) = 0; virtual size_t getSize() const = 0; - virtual void finalize() {} + virtual void finalizeContents() {} + // If the section has the SHF_ALLOC flag and the size may be changed if + // thunks are added, update the section size. + virtual void updateAllocSize() {} + // If any additional finalization of contents are needed post thunk creation. + virtual void postThunkContents() {} virtual bool empty() const { return false; } + uint64_t getVA() const; - uintX_t getVA() const { - return this->OutSec ? this->OutSec->Addr + this->OutSecOff : 0; + static bool classof(const InputSectionBase *D) { + return D->kind() == InputSectionBase::Synthetic; } +}; - static bool classof(const InputSectionData *D) { - return D->kind() == InputSectionData::Synthetic; - } +struct CieRecord { + EhSectionPiece *Piece = nullptr; + std::vector<EhSectionPiece *> FdePieces; }; -template <class ELFT> class GotSection final : public SyntheticSection<ELFT> { - typedef typename ELFT::uint uintX_t; +// Section for .eh_frame. +template <class ELFT> class EhFrameSection final : public SyntheticSection { + typedef typename ELFT::Shdr Elf_Shdr; + typedef typename ELFT::Rel Elf_Rel; + typedef typename ELFT::Rela Elf_Rela; + + void updateAlignment(uint64_t Val) { + if (Val > this->Alignment) + this->Alignment = Val; + } + +public: + EhFrameSection(); + void writeTo(uint8_t *Buf) override; + void finalizeContents() override; + bool empty() const override { return Sections.empty(); } + size_t getSize() const override { return Size; } + + void addSection(InputSectionBase *S); + + size_t NumFdes = 0; + + std::vector<EhInputSection *> Sections; + +private: + uint64_t Size = 0; + template <class RelTy> + void addSectionAux(EhInputSection *S, llvm::ArrayRef<RelTy> Rels); + + template <class RelTy> + CieRecord *addCie(EhSectionPiece &Piece, ArrayRef<RelTy> Rels); + + template <class RelTy> + bool isFdeLive(EhSectionPiece &Piece, ArrayRef<RelTy> Rels); + + uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc); + std::vector<CieRecord *> Cies; + + // CIE records are uniquified by their contents and personality functions. + llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap; +}; + +template <class ELFT> class GotSection final : public SyntheticSection { public: GotSection(); void writeTo(uint8_t *Buf) override; size_t getSize() const override { return Size; } - void finalize() override; + void finalizeContents() override; bool empty() const override; void addEntry(SymbolBody &Sym); bool addDynTlsEntry(SymbolBody &Sym); bool addTlsIndex(); - uintX_t getGlobalDynAddr(const SymbolBody &B) const; - uintX_t getGlobalDynOffset(const SymbolBody &B) const; + uint64_t getGlobalDynAddr(const SymbolBody &B) const; + uint64_t getGlobalDynOffset(const SymbolBody &B) const; - uintX_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; } + uint64_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; } uint32_t getTlsIndexOff() const { return TlsIndexOff; } // Flag to force GOT to be in output if we have relocations @@ -70,11 +128,11 @@ public: private: size_t NumEntries = 0; uint32_t TlsIndexOff = -1; - uintX_t Size = 0; + uint64_t Size = 0; }; // .note.gnu.build-id section. -template <class ELFT> class BuildIdSection : public SyntheticSection<ELFT> { +class BuildIdSection : public SyntheticSection { // First 16 bytes are a header. static const unsigned HeaderSize = 16; @@ -92,22 +150,36 @@ private: uint8_t *HashBuf; }; -template <class ELFT> -class MipsGotSection final : public SyntheticSection<ELFT> { - typedef typename ELFT::uint uintX_t; +// BssSection is used to reserve space for copy relocations and common symbols. +// We create three instances of this class for .bss, .bss.rel.ro and "COMMON", +// that are used for writable symbols, read-only symbols and common symbols, +// respectively. +class BssSection final : public SyntheticSection { +public: + BssSection(StringRef Name); + void writeTo(uint8_t *) override {} + bool empty() const override { return getSize() == 0; } + size_t reserveSpace(uint64_t Size, uint32_t Alignment); + size_t getSize() const override { return Size; } +private: + uint64_t Size = 0; +}; + +class MipsGotSection final : public SyntheticSection { public: MipsGotSection(); void writeTo(uint8_t *Buf) override; size_t getSize() const override { return Size; } - void finalize() override; + void updateAllocSize() override; + void finalizeContents() override; bool empty() const override; - void addEntry(SymbolBody &Sym, uintX_t Addend, RelExpr Expr); + void addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr); bool addDynTlsEntry(SymbolBody &Sym); bool addTlsIndex(); - uintX_t getPageEntryOffset(const SymbolBody &B, uintX_t Addend) const; - uintX_t getBodyEntryOffset(const SymbolBody &B, uintX_t Addend) const; - uintX_t getGlobalDynOffset(const SymbolBody &B) const; + uint64_t getPageEntryOffset(const SymbolBody &B, int64_t Addend) const; + uint64_t getBodyEntryOffset(const SymbolBody &B, int64_t Addend) const; + uint64_t getGlobalDynOffset(const SymbolBody &B) const; // Returns the symbol which corresponds to the first entry of the global part // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic @@ -121,11 +193,11 @@ public: // Returns offset of TLS part of the MIPS GOT table. This part goes // after 'local' and 'global' entries. - uintX_t getTlsOffset() const; + uint64_t getTlsOffset() const; uint32_t getTlsIndexOff() const { return TlsIndexOff; } - uintX_t getGp() const; + uint64_t getGp() const; private: // MIPS GOT consists of three parts: local, global and tls. Each part @@ -171,9 +243,9 @@ private: uint32_t PageEntriesNum = 0; // Map output sections referenced by MIPS GOT relocations // to the first index of "Page" entries allocated for this section. - llvm::SmallMapVector<const OutputSectionBase *, size_t, 16> PageIndexMap; + llvm::SmallMapVector<const OutputSection *, size_t, 16> PageIndexMap; - typedef std::pair<const SymbolBody *, uintX_t> GotEntry; + typedef std::pair<const SymbolBody *, uint64_t> GotEntry; typedef std::vector<GotEntry> GotEntries; // Map from Symbol-Addend pair to the GOT index. llvm::DenseMap<GotEntry, size_t> EntryIndexMap; @@ -189,13 +261,10 @@ private: std::vector<const SymbolBody *> TlsEntries; uint32_t TlsIndexOff = -1; - uintX_t Size = 0; + uint64_t Size = 0; }; -template <class ELFT> -class GotPltSection final : public SyntheticSection<ELFT> { - typedef typename ELFT::uint uintX_t; - +class GotPltSection final : public SyntheticSection { public: GotPltSection(); void addEntry(SymbolBody &Sym); @@ -207,14 +276,11 @@ private: std::vector<const SymbolBody *> Entries; }; -// The IgotPltSection is a Got associated with the IpltSection for GNU Ifunc +// The IgotPltSection is a Got associated with the PltSection for GNU Ifunc // Symbols that will be relocated by Target->IRelativeRel. // On most Targets the IgotPltSection will immediately follow the GotPltSection // on ARM the IgotPltSection will immediately follow the GotSection. -template <class ELFT> -class IgotPltSection final : public SyntheticSection<ELFT> { - typedef typename ELFT::uint uintX_t; - +class IgotPltSection final : public SyntheticSection { public: IgotPltSection(); void addEntry(SymbolBody &Sym); @@ -226,10 +292,8 @@ private: std::vector<const SymbolBody *> Entries; }; -template <class ELFT> -class StringTableSection final : public SyntheticSection<ELFT> { +class StringTableSection final : public SyntheticSection { public: - typedef typename ELFT::uint uintX_t; StringTableSection(StringRef Name, bool Dynamic); unsigned addString(StringRef S, bool HashIt = true); void writeTo(uint8_t *Buf) override; @@ -239,54 +303,41 @@ public: private: const bool Dynamic; - // ELF string tables start with a NUL byte, so 1. - uintX_t Size = 1; + uint64_t Size = 0; llvm::DenseMap<StringRef, unsigned> StringMap; std::vector<StringRef> Strings; }; -template <class ELFT> class DynamicReloc { - typedef typename ELFT::uint uintX_t; - +class DynamicReloc { public: - DynamicReloc(uint32_t Type, const InputSectionBase<ELFT> *InputSec, - uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, - uintX_t Addend) + DynamicReloc(uint32_t Type, const InputSectionBase *InputSec, + uint64_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, + int64_t Addend) : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {} - DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec, - uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, - uintX_t Addend) - : Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec), - UseSymVA(UseSymVA), Addend(Addend) {} - - uintX_t getOffset() const; - uintX_t getAddend() const; + uint64_t getOffset() const; + int64_t getAddend() const; uint32_t getSymIndex() const; - const OutputSectionBase *getOutputSec() const { return OutputSec; } - 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 OutputSectionBase *OutputSec = nullptr; - uintX_t OffsetInSec; + const InputSectionBase *InputSec = nullptr; + uint64_t OffsetInSec; bool UseSymVA; - uintX_t Addend; + int64_t Addend; }; -template <class ELFT> -class DynamicSection final : public SyntheticSection<ELFT> { +template <class ELFT> class DynamicSection final : public SyntheticSection { typedef typename ELFT::Dyn Elf_Dyn; 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; // The .dynamic section contains information for the dynamic linker. // The section consists of fixed size entries, which consist of @@ -295,49 +346,45 @@ class DynamicSection final : public SyntheticSection<ELFT> { struct Entry { int32_t Tag; union { - OutputSectionBase *OutSec; - InputSection<ELFT> *InSec; + OutputSection *OutSec; + InputSection *InSec; uint64_t Val; const SymbolBody *Sym; }; enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind; - Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr) + Entry(int32_t Tag, OutputSection *OutSec, KindT Kind = SecAddr) : Tag(Tag), OutSec(OutSec), Kind(Kind) {} - Entry(int32_t Tag, InputSection<ELFT> *Sec) + Entry(int32_t Tag, InputSection *Sec) : Tag(Tag), InSec(Sec), Kind(InSecAddr) {} Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {} Entry(int32_t Tag, const SymbolBody *Sym) : Tag(Tag), Sym(Sym), Kind(SymAddr) {} }; - // finalize() fills this vector with the section contents. finalize() - // cannot directly create final section contents because when the - // function is called, symbol or section addresses are not fixed yet. + // finalizeContents() fills this vector with the section contents. std::vector<Entry> Entries; public: DynamicSection(); - void finalize() override; + void finalizeContents() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override { return Size; } private: void addEntries(); void add(Entry E) { Entries.push_back(E); } - uintX_t Size = 0; + uint64_t Size = 0; }; -template <class ELFT> -class RelocationSection final : public SyntheticSection<ELFT> { +template <class ELFT> class RelocationSection final : public SyntheticSection { typedef typename ELFT::Rel Elf_Rel; typedef typename ELFT::Rela Elf_Rela; - typedef typename ELFT::uint uintX_t; public: RelocationSection(StringRef Name, bool Sort); - void addReloc(const DynamicReloc<ELFT> &Reloc); + void addReloc(const DynamicReloc &Reloc); unsigned getRelocOffset(); - void finalize() override; + void finalizeContents() override; void writeTo(uint8_t *Buf) override; bool empty() const override { return Relocs.empty(); } size_t getSize() const override { return Relocs.size() * this->Entsize; } @@ -346,7 +393,7 @@ public: private: bool Sort; size_t NumRelativeRelocs = 0; - std::vector<DynamicReloc<ELFT>> Relocs; + std::vector<DynamicReloc> Relocs; }; struct SymbolTableEntry { @@ -354,125 +401,95 @@ struct SymbolTableEntry { size_t StrTabOffset; }; -template <class ELFT> -class SymbolTableSection final : public SyntheticSection<ELFT> { +template <class ELFT> class SymbolTableSection final : public SyntheticSection { public: - typedef typename ELFT::Shdr Elf_Shdr; typedef typename ELFT::Sym Elf_Sym; - typedef typename ELFT::SymRange Elf_Sym_Range; - typedef typename ELFT::uint uintX_t; - SymbolTableSection(StringTableSection<ELFT> &StrTabSec); - void finalize() override; + SymbolTableSection(StringTableSection &StrTabSec); + + void finalizeContents() override; + void postThunkContents() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override { return getNumSymbols() * sizeof(Elf_Sym); } - void addGlobal(SymbolBody *Body); - void addLocal(SymbolBody *Body); - StringTableSection<ELFT> &getStrTabSec() const { return StrTabSec; } + void addSymbol(SymbolBody *Body); unsigned getNumSymbols() const { return Symbols.size() + 1; } size_t getSymbolIndex(SymbolBody *Body); - ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; } - static const OutputSectionBase *getOutputSection(SymbolBody *Sym); - private: - void writeLocalSymbols(uint8_t *&Buf); - void writeGlobalSymbols(uint8_t *Buf); - // A vector of symbols and their string table offsets. std::vector<SymbolTableEntry> Symbols; - StringTableSection<ELFT> &StrTabSec; - - unsigned NumLocals = 0; + StringTableSection &StrTabSec; }; // Outputs GNU Hash section. For detailed explanation see: // https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections template <class ELFT> -class GnuHashTableSection final : public SyntheticSection<ELFT> { - typedef typename ELFT::Off Elf_Off; - typedef typename ELFT::Word Elf_Word; - typedef typename ELFT::uint uintX_t; - +class GnuHashTableSection final : public SyntheticSection { public: GnuHashTableSection(); - void finalize() override; + void finalizeContents() override; void writeTo(uint8_t *Buf) override; - size_t getSize() const override { return this->Size; } + size_t getSize() const override { return Size; } // Adds symbols to the hash table. // Sorts the input to satisfy GNU hash section requirements. void addSymbols(std::vector<SymbolTableEntry> &Symbols); private: - static unsigned calcNBuckets(unsigned NumHashed); - static unsigned calcMaskWords(unsigned NumHashed); + size_t getShift2() const { return Config->Is64 ? 6 : 5; } - void writeHeader(uint8_t *&Buf); - void writeBloomFilter(uint8_t *&Buf); + void writeBloomFilter(uint8_t *Buf); void writeHashTable(uint8_t *Buf); - struct SymbolData { + struct Entry { SymbolBody *Body; - size_t STName; + size_t StrTabOffset; uint32_t Hash; }; - std::vector<SymbolData> Symbols; - - unsigned MaskWords; - unsigned NBuckets; - unsigned Shift2; - uintX_t Size = 0; + std::vector<Entry> Symbols; + size_t MaskWords; + size_t NBuckets = 0; + size_t Size = 0; }; -template <class ELFT> -class HashTableSection final : public SyntheticSection<ELFT> { - typedef typename ELFT::Word Elf_Word; - +template <class ELFT> class HashTableSection final : public SyntheticSection { public: HashTableSection(); - void finalize() override; + void finalizeContents() override; void writeTo(uint8_t *Buf) override; - size_t getSize() const override { return this->Size; } + size_t getSize() const override { return Size; } private: size_t Size = 0; }; -template <class ELFT> class PltSection final : public SyntheticSection<ELFT> { +// The PltSection is used for both the Plt and Iplt. The former always has a +// header as its first entry that is used at run-time to resolve lazy binding. +// The latter is used for GNU Ifunc symbols, that will be subject to a +// Target->IRelativeRel. +class PltSection : public SyntheticSection { public: - PltSection(); + PltSection(size_t HeaderSize); void writeTo(uint8_t *Buf) override; size_t getSize() const override; - void addEntry(SymbolBody &Sym); bool empty() const override { return Entries.empty(); } + void addSymbols(); -private: - std::vector<std::pair<const SymbolBody *, unsigned>> Entries; -}; - -// The IpltSection is a variant of Plt for recording entries for GNU Ifunc -// symbols that will be subject to a Target->IRelativeRel -// The IpltSection immediately follows the Plt section in the Output Section -template <class ELFT> class IpltSection final : public SyntheticSection<ELFT> { -public: - IpltSection(); - void writeTo(uint8_t *Buf) override; - size_t getSize() const override; - void addEntry(SymbolBody &Sym); - bool empty() const override { return Entries.empty(); } + template <class ELFT> void addEntry(SymbolBody &Sym); private: + void writeHeader(uint8_t *Buf){}; + void addHeaderSymbols(){}; + unsigned getPltRelocOff() const; std::vector<std::pair<const SymbolBody *, unsigned>> Entries; + // Iplt always has HeaderSize of 0, the Plt HeaderSize is always non-zero + size_t HeaderSize; }; -template <class ELFT> -class GdbIndexSection final : public SyntheticSection<ELFT> { - typedef typename ELFT::uint uintX_t; - +class GdbIndexSection final : public SyntheticSection { const unsigned OffsetTypeSize = 4; const unsigned CuListOffset = 6 * OffsetTypeSize; const unsigned CompilationUnitSize = 16; @@ -481,13 +498,13 @@ class GdbIndexSection final : public SyntheticSection<ELFT> { public: GdbIndexSection(); - void finalize() override; + void finalizeContents() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override; bool empty() const override; // Pairs of [CU Offset, CU length]. - std::vector<std::pair<uintX_t, uintX_t>> CompilationUnits; + std::vector<std::pair<uint64_t, uint64_t>> CompilationUnits; llvm::StringTableBuilder StringPool; @@ -496,11 +513,10 @@ public: // The CU vector portion of the constant pool. std::vector<std::vector<std::pair<uint32_t, uint8_t>>> CuVectors; - std::vector<AddressEntry<ELFT>> AddressArea; + std::vector<AddressEntry> AddressArea; private: - void parseDebugSections(); - void readDwarf(InputSection<ELFT> *I); + void readDwarf(InputSection *Sec); uint32_t CuTypesOffset; uint32_t SymTabOffset; @@ -522,10 +538,7 @@ private: // Detailed info about internals can be found in Ian Lance Taylor's blog: // http://www.airs.com/blog/archives/460 (".eh_frame") // http://www.airs.com/blog/archives/462 (".eh_frame_hdr") -template <class ELFT> -class EhFrameHeader final : public SyntheticSection<ELFT> { - typedef typename ELFT::uint uintX_t; - +template <class ELFT> class EhFrameHeader final : public SyntheticSection { public: EhFrameHeader(); void writeTo(uint8_t *Buf) override; @@ -551,13 +564,13 @@ private: // The section shall contain an array of Elf_Verdef structures, optionally // followed by an array of Elf_Verdaux structures. template <class ELFT> -class VersionDefinitionSection final : public SyntheticSection<ELFT> { +class VersionDefinitionSection final : public SyntheticSection { typedef typename ELFT::Verdef Elf_Verdef; typedef typename ELFT::Verdaux Elf_Verdaux; public: VersionDefinitionSection(); - void finalize() override; + void finalizeContents() override; size_t getSize() const override; void writeTo(uint8_t *Buf) override; @@ -574,12 +587,12 @@ private: // The values 0 and 1 are reserved. All other values are used for versions in // the own object or in any of the dependencies. template <class ELFT> -class VersionTableSection final : public SyntheticSection<ELFT> { +class VersionTableSection final : public SyntheticSection { typedef typename ELFT::Versym Elf_Versym; public: VersionTableSection(); - void finalize() override; + void finalizeContents() override; size_t getSize() const override; void writeTo(uint8_t *Buf) override; bool empty() const override; @@ -590,8 +603,7 @@ public: // Elf_Verneed specifies the version requirements for a single DSO, and contains // a reference to a linked list of Elf_Vernaux data structures which define the // mapping from version identifiers to version names. -template <class ELFT> -class VersionNeedSection final : public SyntheticSection<ELFT> { +template <class ELFT> class VersionNeedSection final : public SyntheticSection { typedef typename ELFT::Verneed Elf_Verneed; typedef typename ELFT::Vernaux Elf_Vernaux; @@ -604,17 +616,40 @@ class VersionNeedSection final : public SyntheticSection<ELFT> { public: VersionNeedSection(); - void addSymbol(SharedSymbol<ELFT> *SS); - void finalize() override; + void addSymbol(SharedSymbol *SS); + void finalizeContents() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override; size_t getNeedNum() const { return Needed.size(); } bool empty() const override; }; +// MergeSyntheticSection is a class that allows us to put mergeable sections +// with different attributes in a single output sections. To do that +// we put them into MergeSyntheticSection synthetic input sections which are +// attached to regular output sections. +class MergeSyntheticSection final : public SyntheticSection { +public: + MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags, + uint32_t Alignment); + void addSection(MergeInputSection *MS); + void writeTo(uint8_t *Buf) override; + void finalizeContents() override; + bool shouldTailMerge() const; + size_t getSize() const override; + +private: + void finalizeTailMerge(); + void finalizeNoTailMerge(); + + bool Finalized = false; + llvm::StringTableBuilder Builder; + std::vector<MergeInputSection *> Sections; +}; + // .MIPS.abiflags section. template <class ELFT> -class MipsAbiFlagsSection final : public SyntheticSection<ELFT> { +class MipsAbiFlagsSection final : public SyntheticSection { typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags; public: @@ -629,8 +664,7 @@ private: }; // .MIPS.options section. -template <class ELFT> -class MipsOptionsSection final : public SyntheticSection<ELFT> { +template <class ELFT> class MipsOptionsSection final : public SyntheticSection { typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options; typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo; @@ -649,8 +683,7 @@ private: }; // MIPS .reginfo section. -template <class ELFT> -class MipsReginfoSection final : public SyntheticSection<ELFT> { +template <class ELFT> class MipsReginfoSection final : public SyntheticSection { typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo; public: @@ -668,78 +701,95 @@ private: // of executable file which is pointed to by the DT_MIPS_RLD_MAP entry. // See "Dynamic section" in Chapter 5 in the following document: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf -template <class ELFT> class MipsRldMapSection : public SyntheticSection<ELFT> { +class MipsRldMapSection : public SyntheticSection { public: MipsRldMapSection(); - size_t getSize() const override { return sizeof(typename ELFT::uint); } + size_t getSize() const override { return Config->Wordsize; } void writeTo(uint8_t *Buf) override; }; -template <class ELFT> class ARMExidxSentinelSection : public SyntheticSection<ELFT> { +class ARMExidxSentinelSection : public SyntheticSection { public: ARMExidxSentinelSection(); size_t getSize() const override { return 8; } void writeTo(uint8_t *Buf) override; }; -template <class ELFT> InputSection<ELFT> *createCommonSection(); -template <class ELFT> InputSection<ELFT> *createInterpSection(); -template <class ELFT> MergeInputSection<ELFT> *createCommentSection(); +// A container for one or more linker generated thunks. Instances of these +// thunks including ARM interworking and Mips LA25 PI to non-PI thunks. +class ThunkSection : public SyntheticSection { +public: + // ThunkSection in OS, with desired OutSecOff of Off + ThunkSection(OutputSection *OS, uint64_t Off); + + // Add a newly created Thunk to this container: + // 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); + size_t getSize() const override { return Size; } + void writeTo(uint8_t *Buf) override; + InputSection *getTargetInputSection() const; + +private: + std::vector<const Thunk *> Thunks; + size_t Size = 0; +}; + +template <class ELFT> InputSection *createCommonSection(); +InputSection *createInterpSection(); +template <class ELFT> MergeInputSection *createCommentSection(); +template <class ELFT> +SymbolBody *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, + uint64_t Size, InputSectionBase *Section); // Linker generated sections which can be used as inputs. -template <class ELFT> struct In { - static InputSection<ELFT> *ARMAttributes; - static BuildIdSection<ELFT> *BuildId; - static InputSection<ELFT> *Common; +struct InX { + static InputSection *ARMAttributes; + static BssSection *Bss; + static BssSection *BssRelRo; + static BuildIdSection *BuildId; + static InputSection *Common; + static StringTableSection *DynStrTab; + static InputSection *Interp; + static GdbIndexSection *GdbIndex; + static GotPltSection *GotPlt; + static IgotPltSection *IgotPlt; + static MipsGotSection *MipsGot; + static MipsRldMapSection *MipsRldMap; + static PltSection *Plt; + static PltSection *Iplt; + static StringTableSection *ShStrTab; + static StringTableSection *StrTab; +}; + +template <class ELFT> struct In : public InX { static DynamicSection<ELFT> *Dynamic; - static StringTableSection<ELFT> *DynStrTab; static SymbolTableSection<ELFT> *DynSymTab; static EhFrameHeader<ELFT> *EhFrameHdr; static GnuHashTableSection<ELFT> *GnuHashTab; - static GdbIndexSection<ELFT> *GdbIndex; static GotSection<ELFT> *Got; - static MipsGotSection<ELFT> *MipsGot; - static GotPltSection<ELFT> *GotPlt; - static IgotPltSection<ELFT> *IgotPlt; + static EhFrameSection<ELFT> *EhFrame; static HashTableSection<ELFT> *HashTab; - static InputSection<ELFT> *Interp; - static MipsRldMapSection<ELFT> *MipsRldMap; - static PltSection<ELFT> *Plt; - static IpltSection<ELFT> *Iplt; static RelocationSection<ELFT> *RelaDyn; static RelocationSection<ELFT> *RelaPlt; static RelocationSection<ELFT> *RelaIplt; - static StringTableSection<ELFT> *ShStrTab; - static StringTableSection<ELFT> *StrTab; static SymbolTableSection<ELFT> *SymTab; static VersionDefinitionSection<ELFT> *VerDef; static VersionTableSection<ELFT> *VerSym; static VersionNeedSection<ELFT> *VerNeed; }; -template <class ELFT> InputSection<ELFT> *In<ELFT>::ARMAttributes; -template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId; -template <class ELFT> InputSection<ELFT> *In<ELFT>::Common; template <class ELFT> DynamicSection<ELFT> *In<ELFT>::Dynamic; -template <class ELFT> StringTableSection<ELFT> *In<ELFT>::DynStrTab; template <class ELFT> SymbolTableSection<ELFT> *In<ELFT>::DynSymTab; template <class ELFT> EhFrameHeader<ELFT> *In<ELFT>::EhFrameHdr; -template <class ELFT> GdbIndexSection<ELFT> *In<ELFT>::GdbIndex; template <class ELFT> GnuHashTableSection<ELFT> *In<ELFT>::GnuHashTab; template <class ELFT> GotSection<ELFT> *In<ELFT>::Got; -template <class ELFT> MipsGotSection<ELFT> *In<ELFT>::MipsGot; -template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt; -template <class ELFT> IgotPltSection<ELFT> *In<ELFT>::IgotPlt; +template <class ELFT> EhFrameSection<ELFT> *In<ELFT>::EhFrame; template <class ELFT> HashTableSection<ELFT> *In<ELFT>::HashTab; -template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp; -template <class ELFT> MipsRldMapSection<ELFT> *In<ELFT>::MipsRldMap; -template <class ELFT> PltSection<ELFT> *In<ELFT>::Plt; -template <class ELFT> IpltSection<ELFT> *In<ELFT>::Iplt; template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn; template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt; template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaIplt; -template <class ELFT> StringTableSection<ELFT> *In<ELFT>::ShStrTab; -template <class ELFT> StringTableSection<ELFT> *In<ELFT>::StrTab; template <class ELFT> SymbolTableSection<ELFT> *In<ELFT>::SymTab; template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef; template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym; |