aboutsummaryrefslogtreecommitdiff
path: root/ELF/SyntheticSections.h
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/SyntheticSections.h')
-rw-r--r--ELF/SyntheticSections.h137
1 files changed, 80 insertions, 57 deletions
diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h
index a780c6631374..6fc40d355d5e 100644
--- a/ELF/SyntheticSections.h
+++ b/ELF/SyntheticSections.h
@@ -21,8 +21,8 @@
#ifndef LLD_ELF_SYNTHETIC_SECTION_H
#define LLD_ELF_SYNTHETIC_SECTION_H
+#include "DWARF.h"
#include "EhFrame.h"
-#include "GdbIndex.h"
#include "InputSection.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/MC/StringTableBuilder.h"
@@ -50,8 +50,6 @@ public:
// If the section has the SHF_ALLOC flag and the size may be changed if
// thunks are added, update the section size.
virtual bool updateAllocSize() { return false; }
- // If any additional finalization of contents are needed post thunk creation.
- virtual void postThunkContents() {}
virtual bool empty() const { return false; }
static bool classof(const SectionBase *D) {
@@ -137,6 +135,15 @@ protected:
uint64_t Size = 0;
};
+// .note.GNU-stack section.
+class GnuStackSection : public SyntheticSection {
+public:
+ GnuStackSection()
+ : SyntheticSection(0, llvm::ELF::SHT_PROGBITS, 1, ".note.GNU-stack") {}
+ void writeTo(uint8_t *Buf) override {}
+ size_t getSize() const override { return 0; }
+};
+
// .note.gnu.build-id section.
class BuildIdSection : public SyntheticSection {
// First 16 bytes are a header.
@@ -163,7 +170,9 @@ private:
class BssSection final : public SyntheticSection {
public:
BssSection(StringRef Name, uint64_t Size, uint32_t Alignment);
- void writeTo(uint8_t *) override {}
+ void writeTo(uint8_t *) override {
+ llvm_unreachable("unexpected writeTo() call for SHT_NOBITS section");
+ }
bool empty() const override { return getSize() == 0; }
size_t getSize() const override { return Size; }
@@ -300,8 +309,6 @@ private:
uint64_t Size = 0;
- size_t LocalEntriesNum = 0;
-
// Symbol and addend.
typedef std::pair<Symbol *, int64_t> GotEntry;
@@ -333,8 +340,6 @@ private:
size_t getPageEntriesNum() const;
// Number of entries require 16-bit index to access.
size_t getIndexedEntriesNum() const;
-
- bool isOverflow() const;
};
// Container of GOT created for each input file.
@@ -529,6 +534,7 @@ struct RelativeReloc {
class RelrBaseSection : public SyntheticSection {
public:
RelrBaseSection();
+ bool empty() const override { return Relocs.empty(); }
std::vector<RelativeReloc> Relocs;
};
@@ -561,7 +567,6 @@ class SymbolTableBaseSection : public SyntheticSection {
public:
SymbolTableBaseSection(StringTableSection &StrTabSec);
void finalizeContents() override;
- void postThunkContents() override;
size_t getSize() const override { return getNumSymbols() * Entsize; }
void addSymbol(Symbol *Sym);
unsigned getNumSymbols() const { return Symbols.size() + 1; }
@@ -569,6 +574,8 @@ public:
ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
protected:
+ void sortSymTabSymbols();
+
// A vector of symbols and their string table offsets.
std::vector<SymbolTableEntry> Symbols;
@@ -612,7 +619,8 @@ public:
void addSymbols(std::vector<SymbolTableEntry> &Symbols);
private:
- enum { Shift2 = 6 };
+ // See the comment in writeBloomFilter.
+ enum { Shift2 = 26 };
void writeBloomFilter(uint8_t *Buf);
void writeHashTable(uint8_t *Buf);
@@ -652,13 +660,13 @@ public:
size_t getSize() const override;
bool empty() const override { return Entries.empty(); }
void addSymbols();
-
template <class ELFT> void addEntry(Symbol &Sym);
+ size_t HeaderSize;
+
private:
unsigned getPltRelocOff() const;
std::vector<std::pair<const Symbol *, unsigned>> Entries;
- size_t HeaderSize;
bool IsIplt;
};
@@ -676,9 +684,9 @@ public:
uint64_t CuLength;
};
- struct NameTypeEntry {
+ struct NameAttrEntry {
llvm::CachedHashStringRef Name;
- uint32_t Type;
+ uint32_t CuIndexAndAttrs;
};
struct GdbChunk {
@@ -748,11 +756,7 @@ public:
// shall be contained in the DT_VERDEFNUM entry of the .dynamic section.
// 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 {
- typedef typename ELFT::Verdef Elf_Verdef;
- typedef typename ELFT::Verdaux Elf_Verdaux;
-
public:
VersionDefinitionSection();
void finalizeContents() override;
@@ -760,6 +764,7 @@ public:
void writeTo(uint8_t *Buf) override;
private:
+ enum { EntrySize = 28 };
void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
unsigned FileDefNameOff;
@@ -773,8 +778,6 @@ private:
// the own object or in any of the dependencies.
template <class ELFT>
class VersionTableSection final : public SyntheticSection {
- typedef typename ELFT::Versym Elf_Versym;
-
public:
VersionTableSection();
void finalizeContents() override;
@@ -964,9 +967,27 @@ private:
size_t Size = 0;
};
+// This section is used to store the addresses of functions that are called
+// in range-extending thunks on PowerPC64. When producing position dependant
+// code the addresses are link-time constants and the table is written out to
+// the binary. When producing position-dependant code the table is allocated and
+// filled in by the dynamic linker.
+class PPC64LongBranchTargetSection final : public SyntheticSection {
+public:
+ PPC64LongBranchTargetSection();
+ void addEntry(Symbol &Sym);
+ size_t getSize() const override;
+ void writeTo(uint8_t *Buf) override;
+ bool empty() const override;
+ void finalizeContents() override { Finalized = true; }
+
+private:
+ std::vector<const Symbol *> Entries;
+ bool Finalized = false;
+};
+
InputSection *createInterpSection();
MergeInputSection *createCommentSection();
-void decompressSections();
template <class ELFT> void splitSections();
void mergeSections();
@@ -974,46 +995,48 @@ Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
uint64_t Size, InputSectionBase &Section);
// Linker generated sections which can be used as inputs.
-struct InX {
- static InputSection *ARMAttributes;
- static BssSection *Bss;
- static BssSection *BssRelRo;
- static BuildIdSection *BuildId;
- static EhFrameHeader *EhFrameHdr;
- static EhFrameSection *EhFrame;
- static SyntheticSection *Dynamic;
- static StringTableSection *DynStrTab;
- static SymbolTableBaseSection *DynSymTab;
- static GnuHashTableSection *GnuHashTab;
- static HashTableSection *HashTab;
- static InputSection *Interp;
- static GdbIndexSection *GdbIndex;
- static GotSection *Got;
- static GotPltSection *GotPlt;
- static IgotPltSection *IgotPlt;
- static MipsGotSection *MipsGot;
- static MipsRldMapSection *MipsRldMap;
- static PltSection *Plt;
- static PltSection *Iplt;
- static RelocationBaseSection *RelaDyn;
- static RelrBaseSection *RelrDyn;
- static RelocationBaseSection *RelaPlt;
- static RelocationBaseSection *RelaIplt;
- static StringTableSection *ShStrTab;
- static StringTableSection *StrTab;
- static SymbolTableBaseSection *SymTab;
- static SymtabShndxSection* SymTabShndx;
-};
-
-template <class ELFT> struct In {
- static VersionDefinitionSection<ELFT> *VerDef;
+struct InStruct {
+ InputSection *ARMAttributes;
+ BssSection *Bss;
+ BssSection *BssRelRo;
+ BuildIdSection *BuildId;
+ EhFrameHeader *EhFrameHdr;
+ EhFrameSection *EhFrame;
+ SyntheticSection *Dynamic;
+ StringTableSection *DynStrTab;
+ SymbolTableBaseSection *DynSymTab;
+ GnuHashTableSection *GnuHashTab;
+ HashTableSection *HashTab;
+ InputSection *Interp;
+ GdbIndexSection *GdbIndex;
+ GotSection *Got;
+ GotPltSection *GotPlt;
+ IgotPltSection *IgotPlt;
+ PPC64LongBranchTargetSection *PPC64LongBranchTarget;
+ MipsGotSection *MipsGot;
+ MipsRldMapSection *MipsRldMap;
+ PltSection *Plt;
+ PltSection *Iplt;
+ RelocationBaseSection *RelaDyn;
+ RelrBaseSection *RelrDyn;
+ RelocationBaseSection *RelaPlt;
+ RelocationBaseSection *RelaIplt;
+ StringTableSection *ShStrTab;
+ StringTableSection *StrTab;
+ SymbolTableBaseSection *SymTab;
+ SymtabShndxSection *SymTabShndx;
+ VersionDefinitionSection *VerDef;
+};
+
+extern InStruct In;
+
+template <class ELFT> struct InX {
static VersionTableSection<ELFT> *VerSym;
static VersionNeedSection<ELFT> *VerNeed;
};
-template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef;
-template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym;
-template <class ELFT> VersionNeedSection<ELFT> *In<ELFT>::VerNeed;
+template <class ELFT> VersionTableSection<ELFT> *InX<ELFT>::VerSym;
+template <class ELFT> VersionNeedSection<ELFT> *InX<ELFT>::VerNeed;
} // namespace elf
} // namespace lld