aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/lld/ELF/SyntheticSections.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/lld/ELF/SyntheticSections.h')
-rw-r--r--contrib/llvm/tools/lld/ELF/SyntheticSections.h464
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;