[lld] r286950 - [ELF] Convert DynamicSection to input section.
Eugene Leviant via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 15 04:26:56 PST 2016
Author: evgeny777
Date: Tue Nov 15 06:26:55 2016
New Revision: 286950
URL: http://llvm.org/viewvc/llvm-project?rev=286950&view=rev
Log:
[ELF] Convert DynamicSection to input section.
This patch introduces the following changes:
- DynamicSection now inherits InputSection<ELFT> and was moved
to SyntheticSections.h/.cpp.
- Link and Entsize fields of DynamicSection are propagated to
its output section
- In<ELFT>::SyntheticSections was removed.
- Finalization of synthetic sections was removed from
OutputSection<ELFT>::finalize. Now finalizeSyntheticSections is
used instead.
Differential revision: https://reviews.llvm.org/D26603
Modified:
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Nov 15 06:26:55 2016
@@ -395,177 +395,6 @@ void GnuHashTableSection<ELFT>::addSymbo
static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }
template <class ELFT>
-DynamicSection<ELFT>::DynamicSection()
- : OutputSectionBase(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) {
- this->Addralign = sizeof(uintX_t);
- this->Entsize = ELFT::Is64Bits ? 16 : 8;
-
- // .dynamic section is not writable on MIPS.
- // See "Special Section" in Chapter 4 in the following document:
- // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- if (Config->EMachine == EM_MIPS)
- this->Flags = SHF_ALLOC;
-
- addEntries();
-}
-
-// There are some dynamic entries that don't depend on other sections.
-// Such entries can be set early.
-template <class ELFT> void DynamicSection<ELFT>::addEntries() {
- // Add strings to .dynstr early so that .dynstr's size will be
- // fixed early.
- for (StringRef S : Config->AuxiliaryList)
- Add({DT_AUXILIARY, In<ELFT>::DynStrTab->addString(S)});
- if (!Config->RPath.empty())
- Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
- In<ELFT>::DynStrTab->addString(Config->RPath)});
- for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles())
- if (F->isNeeded())
- Add({DT_NEEDED, In<ELFT>::DynStrTab->addString(F->getSoName())});
- if (!Config->SoName.empty())
- Add({DT_SONAME, In<ELFT>::DynStrTab->addString(Config->SoName)});
-
- // Set DT_FLAGS and DT_FLAGS_1.
- uint32_t DtFlags = 0;
- uint32_t DtFlags1 = 0;
- if (Config->Bsymbolic)
- DtFlags |= DF_SYMBOLIC;
- if (Config->ZNodelete)
- DtFlags1 |= DF_1_NODELETE;
- if (Config->ZNow) {
- DtFlags |= DF_BIND_NOW;
- DtFlags1 |= DF_1_NOW;
- }
- if (Config->ZOrigin) {
- DtFlags |= DF_ORIGIN;
- DtFlags1 |= DF_1_ORIGIN;
- }
-
- if (DtFlags)
- Add({DT_FLAGS, DtFlags});
- if (DtFlags1)
- Add({DT_FLAGS_1, DtFlags1});
-
- if (!Config->Entry.empty())
- Add({DT_DEBUG, (uint64_t)0});
-}
-
-// Add remaining entries to complete .dynamic contents.
-template <class ELFT> void DynamicSection<ELFT>::finalize() {
- if (this->Size)
- return; // Already finalized.
-
- this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
-
- if (Out<ELFT>::RelaDyn->hasRelocs()) {
- bool IsRela = Config->Rela;
- Add({IsRela ? DT_RELA : DT_REL, Out<ELFT>::RelaDyn});
- Add({IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->Size});
- Add({IsRela ? DT_RELAENT : DT_RELENT,
- uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
-
- // MIPS dynamic loader does not support RELCOUNT tag.
- // The problem is in the tight relation between dynamic
- // relocations and GOT. So do not emit this tag on MIPS.
- if (Config->EMachine != EM_MIPS) {
- size_t NumRelativeRels = Out<ELFT>::RelaDyn->getRelativeRelocCount();
- if (Config->ZCombreloc && NumRelativeRels)
- Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
- }
- }
- if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
- Add({DT_JMPREL, Out<ELFT>::RelaPlt});
- Add({DT_PLTRELSZ, Out<ELFT>::RelaPlt->Size});
- Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
- In<ELFT>::GotPlt});
- Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)});
- }
-
- Add({DT_SYMTAB, Out<ELFT>::DynSymTab});
- Add({DT_SYMENT, sizeof(Elf_Sym)});
- Add({DT_STRTAB, In<ELFT>::DynStrTab});
- Add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()});
- if (Out<ELFT>::GnuHashTab)
- Add({DT_GNU_HASH, Out<ELFT>::GnuHashTab});
- if (Out<ELFT>::HashTab)
- Add({DT_HASH, Out<ELFT>::HashTab});
-
- if (Out<ELFT>::PreinitArray) {
- Add({DT_PREINIT_ARRAY, Out<ELFT>::PreinitArray});
- Add({DT_PREINIT_ARRAYSZ, Out<ELFT>::PreinitArray, Entry::SecSize});
- }
- if (Out<ELFT>::InitArray) {
- Add({DT_INIT_ARRAY, Out<ELFT>::InitArray});
- Add({DT_INIT_ARRAYSZ, Out<ELFT>::InitArray, Entry::SecSize});
- }
- if (Out<ELFT>::FiniArray) {
- Add({DT_FINI_ARRAY, Out<ELFT>::FiniArray});
- Add({DT_FINI_ARRAYSZ, Out<ELFT>::FiniArray, Entry::SecSize});
- }
-
- if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Init))
- Add({DT_INIT, B});
- if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Fini))
- Add({DT_FINI, B});
-
- bool HasVerNeed = Out<ELFT>::VerNeed->getNeedNum() != 0;
- if (HasVerNeed || Out<ELFT>::VerDef)
- Add({DT_VERSYM, Out<ELFT>::VerSym});
- if (Out<ELFT>::VerDef) {
- Add({DT_VERDEF, Out<ELFT>::VerDef});
- Add({DT_VERDEFNUM, getVerDefNum()});
- }
- if (HasVerNeed) {
- Add({DT_VERNEED, Out<ELFT>::VerNeed});
- Add({DT_VERNEEDNUM, Out<ELFT>::VerNeed->getNeedNum()});
- }
-
- if (Config->EMachine == EM_MIPS) {
- Add({DT_MIPS_RLD_VERSION, 1});
- Add({DT_MIPS_FLAGS, RHF_NOTPOT});
- Add({DT_MIPS_BASE_ADDRESS, Config->ImageBase});
- Add({DT_MIPS_SYMTABNO, Out<ELFT>::DynSymTab->getNumSymbols()});
- Add({DT_MIPS_LOCAL_GOTNO, In<ELFT>::Got->getMipsLocalEntriesNum()});
- if (const SymbolBody *B = In<ELFT>::Got->getMipsFirstGlobalEntry())
- Add({DT_MIPS_GOTSYM, B->DynsymIndex});
- else
- Add({DT_MIPS_GOTSYM, Out<ELFT>::DynSymTab->getNumSymbols()});
- Add({DT_PLTGOT, In<ELFT>::Got});
- if (Out<ELFT>::MipsRldMap)
- Add({DT_MIPS_RLD_MAP, Out<ELFT>::MipsRldMap});
- }
-
- // +1 for DT_NULL
- this->Size = (Entries.size() + 1) * this->Entsize;
-}
-
-template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
- auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
-
- for (const Entry &E : Entries) {
- P->d_tag = E.Tag;
- switch (E.Kind) {
- case Entry::SecAddr:
- P->d_un.d_ptr = E.OutSec->Addr;
- break;
- case Entry::InSecAddr:
- P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff;
- break;
- case Entry::SecSize:
- P->d_un.d_val = E.OutSec->Size;
- break;
- case Entry::SymAddr:
- P->d_un.d_ptr = E.Sym->template getVA<ELFT>();
- break;
- case Entry::PlainInt:
- P->d_un.d_val = E.Val;
- break;
- }
- ++P;
- }
-}
-
-template <class ELFT>
EhFrameHeader<ELFT>::EhFrameHeader()
: OutputSectionBase(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {}
@@ -650,14 +479,6 @@ template <class ELFT> void OutputSection
}
}
- // Recalculate input section offsets if we own any synthetic section
- for (auto *SS : In<ELFT>::SyntheticSections)
- if (SS && this == SS->OutSec) {
- this->Size = 0;
- assignOffsets();
- break;
- }
-
if (Type != SHT_RELA && Type != SHT_REL)
return;
this->Link = Out<ELFT>::SymTab->SectionIndex;
@@ -1544,11 +1365,6 @@ template class HashTableSection<ELF32BE>
template class HashTableSection<ELF64LE>;
template class HashTableSection<ELF64BE>;
-template class DynamicSection<ELF32LE>;
-template class DynamicSection<ELF32BE>;
-template class DynamicSection<ELF64LE>;
-template class DynamicSection<ELF64BE>;
-
template class OutputSection<ELF32LE>;
template class OutputSection<ELF32BE>;
template class OutputSection<ELF64LE>;
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Nov 15 06:26:55 2016
@@ -45,7 +45,6 @@ class OutputSectionBase {
public:
enum Kind {
Base,
- Dynamic,
EHFrame,
EHFrameHdr,
GnuHashTable,
@@ -478,55 +477,6 @@ private:
unsigned Shift2;
};
-template <class ELFT> class DynamicSection final : public OutputSectionBase {
- 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
- // type and value fields. Value are one of plain integers, symbol
- // addresses, or section addresses. This struct represents the entry.
- struct Entry {
- int32_t Tag;
- union {
- OutputSectionBase *OutSec;
- InputSection<ELFT> *InSec;
- uint64_t Val;
- const SymbolBody *Sym;
- };
- enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;
- Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
- : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
- Entry(int32_t Tag, InputSection<ELFT> *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.
- std::vector<Entry> Entries;
-
-public:
- DynamicSection();
- void finalize() override;
- void writeTo(uint8_t *Buf) override;
- Kind getKind() const override { return Dynamic; }
- static bool classof(const OutputSectionBase *B) {
- return B->getKind() == Dynamic;
- }
-
-private:
- void addEntries();
- void Add(Entry E) { Entries.push_back(E); }
-};
-
// --eh-frame-hdr option tells linker to construct a header for all the
// .eh_frame sections. This header is placed to a section named .eh_frame_hdr
// and also to a PT_GNU_EH_FRAME segment.
@@ -566,7 +516,6 @@ template <class ELFT> struct Out {
typedef typename ELFT::Phdr Elf_Phdr;
static uint8_t First;
- static DynamicSection<ELFT> *Dynamic;
static EhFrameHeader<ELFT> *EhFrameHdr;
static EhOutputSection<ELFT> *EhFrame;
static GdbIndexSection<ELFT> *GdbIndex;
@@ -627,7 +576,6 @@ template <class ELFT> uint64_t getHeader
}
template <class ELFT> uint8_t Out<ELFT>::First;
-template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
template <class ELFT> GdbIndexSection<ELFT> *Out<ELFT>::GdbIndex;
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Nov 15 06:26:55 2016
@@ -673,6 +673,181 @@ template <class ELFT> void StringTableSe
}
}
+static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }
+
+template <class ELFT>
+DynamicSection<ELFT>::DynamicSection()
+ : SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC,
+ sizeof(uintX_t), ".dynamic") {
+ this->Entsize = ELFT::Is64Bits ? 16 : 8;
+ // .dynamic section is not writable on MIPS.
+ // See "Special Section" in Chapter 4 in the following document:
+ // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+ if (Config->EMachine == EM_MIPS)
+ this->Flags = SHF_ALLOC;
+
+ addEntries();
+}
+
+// There are some dynamic entries that don't depend on other sections.
+// Such entries can be set early.
+template <class ELFT> void DynamicSection<ELFT>::addEntries() {
+ // Add strings to .dynstr early so that .dynstr's size will be
+ // fixed early.
+ for (StringRef S : Config->AuxiliaryList)
+ Add({DT_AUXILIARY, In<ELFT>::DynStrTab->addString(S)});
+ if (!Config->RPath.empty())
+ Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
+ In<ELFT>::DynStrTab->addString(Config->RPath)});
+ for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles())
+ if (F->isNeeded())
+ Add({DT_NEEDED, In<ELFT>::DynStrTab->addString(F->getSoName())});
+ if (!Config->SoName.empty())
+ Add({DT_SONAME, In<ELFT>::DynStrTab->addString(Config->SoName)});
+
+ // Set DT_FLAGS and DT_FLAGS_1.
+ uint32_t DtFlags = 0;
+ uint32_t DtFlags1 = 0;
+ if (Config->Bsymbolic)
+ DtFlags |= DF_SYMBOLIC;
+ if (Config->ZNodelete)
+ DtFlags1 |= DF_1_NODELETE;
+ if (Config->ZNow) {
+ DtFlags |= DF_BIND_NOW;
+ DtFlags1 |= DF_1_NOW;
+ }
+ if (Config->ZOrigin) {
+ DtFlags |= DF_ORIGIN;
+ DtFlags1 |= DF_1_ORIGIN;
+ }
+
+ if (DtFlags)
+ Add({DT_FLAGS, DtFlags});
+ if (DtFlags1)
+ Add({DT_FLAGS_1, DtFlags1});
+
+ if (!Config->Entry.empty())
+ Add({DT_DEBUG, (uint64_t)0});
+}
+
+// Add remaining entries to complete .dynamic contents.
+template <class ELFT> void DynamicSection<ELFT>::finalize() {
+ if (this->Size)
+ return; // Already finalized.
+
+ this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
+
+ if (Out<ELFT>::RelaDyn->hasRelocs()) {
+ bool IsRela = Config->Rela;
+ Add({IsRela ? DT_RELA : DT_REL, Out<ELFT>::RelaDyn});
+ Add({IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->Size});
+ Add({IsRela ? DT_RELAENT : DT_RELENT,
+ uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
+
+ // MIPS dynamic loader does not support RELCOUNT tag.
+ // The problem is in the tight relation between dynamic
+ // relocations and GOT. So do not emit this tag on MIPS.
+ if (Config->EMachine != EM_MIPS) {
+ size_t NumRelativeRels = Out<ELFT>::RelaDyn->getRelativeRelocCount();
+ if (Config->ZCombreloc && NumRelativeRels)
+ Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
+ }
+ }
+ if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
+ Add({DT_JMPREL, Out<ELFT>::RelaPlt});
+ Add({DT_PLTRELSZ, Out<ELFT>::RelaPlt->Size});
+ Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
+ In<ELFT>::GotPlt});
+ Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)});
+ }
+
+ Add({DT_SYMTAB, Out<ELFT>::DynSymTab});
+ Add({DT_SYMENT, sizeof(Elf_Sym)});
+ Add({DT_STRTAB, In<ELFT>::DynStrTab});
+ Add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()});
+ if (Out<ELFT>::GnuHashTab)
+ Add({DT_GNU_HASH, Out<ELFT>::GnuHashTab});
+ if (Out<ELFT>::HashTab)
+ Add({DT_HASH, Out<ELFT>::HashTab});
+
+ if (Out<ELFT>::PreinitArray) {
+ Add({DT_PREINIT_ARRAY, Out<ELFT>::PreinitArray});
+ Add({DT_PREINIT_ARRAYSZ, Out<ELFT>::PreinitArray, Entry::SecSize});
+ }
+ if (Out<ELFT>::InitArray) {
+ Add({DT_INIT_ARRAY, Out<ELFT>::InitArray});
+ Add({DT_INIT_ARRAYSZ, Out<ELFT>::InitArray, Entry::SecSize});
+ }
+ if (Out<ELFT>::FiniArray) {
+ Add({DT_FINI_ARRAY, Out<ELFT>::FiniArray});
+ Add({DT_FINI_ARRAYSZ, Out<ELFT>::FiniArray, Entry::SecSize});
+ }
+
+ if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Init))
+ Add({DT_INIT, B});
+ if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Fini))
+ Add({DT_FINI, B});
+
+ bool HasVerNeed = Out<ELFT>::VerNeed->getNeedNum() != 0;
+ if (HasVerNeed || Out<ELFT>::VerDef)
+ Add({DT_VERSYM, Out<ELFT>::VerSym});
+ if (Out<ELFT>::VerDef) {
+ Add({DT_VERDEF, Out<ELFT>::VerDef});
+ Add({DT_VERDEFNUM, getVerDefNum()});
+ }
+ if (HasVerNeed) {
+ Add({DT_VERNEED, Out<ELFT>::VerNeed});
+ Add({DT_VERNEEDNUM, Out<ELFT>::VerNeed->getNeedNum()});
+ }
+
+ if (Config->EMachine == EM_MIPS) {
+ Add({DT_MIPS_RLD_VERSION, 1});
+ Add({DT_MIPS_FLAGS, RHF_NOTPOT});
+ Add({DT_MIPS_BASE_ADDRESS, Config->ImageBase});
+ Add({DT_MIPS_SYMTABNO, Out<ELFT>::DynSymTab->getNumSymbols()});
+ Add({DT_MIPS_LOCAL_GOTNO, In<ELFT>::Got->getMipsLocalEntriesNum()});
+ if (const SymbolBody *B = In<ELFT>::Got->getMipsFirstGlobalEntry())
+ Add({DT_MIPS_GOTSYM, B->DynsymIndex});
+ else
+ Add({DT_MIPS_GOTSYM, Out<ELFT>::DynSymTab->getNumSymbols()});
+ Add({DT_PLTGOT, In<ELFT>::Got});
+ if (Out<ELFT>::MipsRldMap)
+ Add({DT_MIPS_RLD_MAP, Out<ELFT>::MipsRldMap});
+ }
+
+ this->OutSec->Entsize = this->Entsize;
+ this->OutSec->Link = this->Link;
+
+ // +1 for DT_NULL
+ this->Size = (Entries.size() + 1) * this->Entsize;
+}
+
+template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
+ auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
+
+ for (const Entry &E : Entries) {
+ P->d_tag = E.Tag;
+ switch (E.Kind) {
+ case Entry::SecAddr:
+ P->d_un.d_ptr = E.OutSec->Addr;
+ break;
+ case Entry::InSecAddr:
+ P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff;
+ break;
+ case Entry::SecSize:
+ P->d_un.d_val = E.OutSec->Size;
+ break;
+ case Entry::SymAddr:
+ P->d_un.d_ptr = E.Sym->template getVA<ELFT>();
+ break;
+ case Entry::PlainInt:
+ P->d_un.d_val = E.Val;
+ break;
+ }
+ ++P;
+ }
+}
+
template InputSection<ELF32LE> *elf::createCommonSection();
template InputSection<ELF32BE> *elf::createCommonSection();
template InputSection<ELF64LE> *elf::createCommonSection();
@@ -747,3 +922,8 @@ template class elf::StringTableSection<E
template class elf::StringTableSection<ELF32BE>;
template class elf::StringTableSection<ELF64LE>;
template class elf::StringTableSection<ELF64BE>;
+
+template class elf::DynamicSection<ELF32LE>;
+template class elf::DynamicSection<ELF32BE>;
+template class elf::DynamicSection<ELF64LE>;
+template class elf::DynamicSection<ELF64BE>;
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Tue Nov 15 06:26:55 2016
@@ -72,6 +72,7 @@ public:
virtual void writeTo(uint8_t *Buf) = 0;
virtual size_t getSize() const { return this->Data.size(); }
+ virtual void finalize() {}
uintX_t getVA() const {
return this->OutSec ? this->OutSec->Addr + this->OutSecOff : 0;
}
@@ -144,7 +145,7 @@ public:
GotSection();
void writeTo(uint8_t *Buf) override;
size_t getSize() const override { return Size; }
- void finalize();
+ void finalize() override;
void addEntry(SymbolBody &Sym);
void addMipsEntry(SymbolBody &Sym, uintX_t Addend, RelExpr Expr);
bool addDynTlsEntry(SymbolBody &Sym);
@@ -238,6 +239,54 @@ private:
std::vector<StringRef> Strings;
};
+template <class ELFT>
+class DynamicSection final : public SyntheticSection<ELFT> {
+ 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
+ // type and value fields. Value are one of plain integers, symbol
+ // addresses, or section addresses. This struct represents the entry.
+ struct Entry {
+ int32_t Tag;
+ union {
+ OutputSectionBase *OutSec;
+ InputSection<ELFT> *InSec;
+ uint64_t Val;
+ const SymbolBody *Sym;
+ };
+ enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;
+ Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
+ : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
+ Entry(int32_t Tag, InputSection<ELFT> *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.
+ std::vector<Entry> Entries;
+
+public:
+ DynamicSection();
+ void finalize() 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;
+};
+
template <class ELFT> InputSection<ELFT> *createCommonSection();
template <class ELFT> InputSection<ELFT> *createInterpSection();
template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
@@ -246,6 +295,7 @@ template <class ELFT> MergeInputSection<
template <class ELFT> struct In {
static BuildIdSection<ELFT> *BuildId;
static InputSection<ELFT> *Common;
+ static DynamicSection<ELFT> *Dynamic;
static StringTableSection<ELFT> *DynStrTab;
static GotSection<ELFT> *Got;
static GotPltSection<ELFT> *GotPlt;
@@ -255,15 +305,11 @@ template <class ELFT> struct In {
static MipsReginfoSection<ELFT> *MipsReginfo;
static StringTableSection<ELFT> *ShStrTab;
static StringTableSection<ELFT> *StrTab;
-
- // Contains list of sections, which size is not known when
- // createSections() is called. This list is used when output
- // sections are being finalized to calculate their size correctly.
- static std::vector<SyntheticSection<ELFT> *> SyntheticSections;
};
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> GotSection<ELFT> *In<ELFT>::Got;
template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt;
@@ -273,9 +319,6 @@ template <class ELFT> MipsOptionsSection
template <class ELFT> MipsReginfoSection<ELFT> *In<ELFT>::MipsReginfo;
template <class ELFT> StringTableSection<ELFT> *In<ELFT>::ShStrTab;
template <class ELFT> StringTableSection<ELFT> *In<ELFT>::StrTab;
-template <class ELFT>
-std::vector<SyntheticSection<ELFT> *> In<ELFT>::SyntheticSections;
-
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Tue Nov 15 06:26:55 2016
@@ -356,7 +356,7 @@ RelExpr X86TargetInfo::adjustRelaxExpr(u
}
void X86TargetInfo::writeGotPltHeader(uint8_t *Buf) const {
- write32le(Buf, Out<ELF32LE>::Dynamic->Addr);
+ write32le(Buf, In<ELF32LE>::Dynamic->getVA());
}
void X86TargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &S) const {
@@ -596,7 +596,7 @@ void X86_64TargetInfo<ELFT>::writeGotPlt
// required, but it is documented in the psabi and the glibc dynamic linker
// seems to use it (note that this is relevant for linking ld.so, not any
// other program).
- write64le(Buf, Out<ELFT>::Dynamic->Addr);
+ write64le(Buf, In<ELFT>::Dynamic->getVA());
}
template <class ELFT>
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Nov 15 06:26:55 2016
@@ -210,7 +210,7 @@ template <class ELFT> void Writer<ELFT>:
Out<ELFT>::Bss =
make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
- Out<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
+ In<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>();
Out<ELFT>::Plt = make<PltSection<ELFT>>();
Out<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
@@ -314,13 +314,6 @@ template <class ELFT> void Writer<ELFT>:
In<ELFT>::Got = make<GotSection<ELFT>>();
In<ELFT>::GotPlt = make<GotPltSection<ELFT>>();
-
- // These sections are filled after createSections() is called.
- // We use this list to fixup size of output sections, when they
- // are finalized.
- In<ELFT>::SyntheticSections = {In<ELFT>::ShStrTab, In<ELFT>::StrTab,
- In<ELFT>::DynStrTab, In<ELFT>::Got,
- In<ELFT>::GotPlt};
}
template <class ELFT>
@@ -434,7 +427,7 @@ template <class ELFT> bool elf::isRelroS
return true;
if (Sec == In<ELFT>::GotPlt->OutSec)
return Config->ZNow;
- if (Sec == Out<ELFT>::Dynamic || Sec == In<ELFT>::Got->OutSec)
+ if (Sec == In<ELFT>::Dynamic->OutSec || Sec == In<ELFT>::Got->OutSec)
return true;
StringRef S = Sec->getName();
return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" ||
@@ -861,6 +854,17 @@ template <class ELFT> void Writer<ELFT>:
Script<ELFT>::X->adjustSectionsAfterSorting();
}
+template <class ELFT>
+static void
+finalizeSynthetic(const std::vector<SyntheticSection<ELFT> *> &Sections) {
+ for (SyntheticSection<ELFT> *SS : Sections)
+ if (SS && SS->OutSec) {
+ SS->finalize();
+ SS->OutSec->Size = 0;
+ SS->OutSec->assignOffsets();
+ }
+}
+
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::finalizeSections() {
Out<ELFT>::DebugInfo = findSection(".debug_info");
@@ -882,8 +886,7 @@ template <class ELFT> void Writer<ELFT>:
// Even the author of gold doesn't remember why gold behaves that way.
// https://sourceware.org/ml/binutils/2002-03/msg00360.html
if (Out<ELFT>::DynSymTab)
- Symtab<ELFT>::X->addSynthetic("_DYNAMIC", Out<ELFT>::Dynamic, 0,
- STV_HIDDEN);
+ addRegular("_DYNAMIC", In<ELFT>::Dynamic, 0);
// Define __rel[a]_iplt_{start,end} symbols if needed.
addRelIpltSymbols();
@@ -940,11 +943,11 @@ template <class ELFT> void Writer<ELFT>:
// at the end because some tags like RELSZ depend on result
// of finalizing other sections.
for (OutputSectionBase *Sec : OutputSections)
- if (Sec != Out<ELFT>::Dynamic)
- Sec->finalize();
+ Sec->finalize();
- if (Out<ELFT>::DynSymTab)
- Out<ELFT>::Dynamic->finalize();
+ finalizeSynthetic<ELFT>({In<ELFT>::ShStrTab, In<ELFT>::StrTab,
+ In<ELFT>::DynStrTab, In<ELFT>::Got, In<ELFT>::GotPlt,
+ In<ELFT>::Dynamic});
// Now that all output offsets are fixed. Finalize mergeable sections
// to fix their maps from input offsets to output offsets.
@@ -992,7 +995,7 @@ template <class ELFT> void Writer<ELFT>:
Add(Out<ELFT>::GnuHashTab);
Add(Out<ELFT>::HashTab);
- Add(Out<ELFT>::Dynamic);
+ addInputSec(In<ELFT>::Dynamic);
addInputSec(In<ELFT>::DynStrTab);
if (Out<ELFT>::RelaDyn->hasRelocs())
Add(Out<ELFT>::RelaDyn);
@@ -1006,10 +1009,8 @@ template <class ELFT> void Writer<ELFT>:
// We fill .got and .got.plt sections in scanRelocs(). This is the
// reason we don't add it earlier in createSections().
- if (needsGot()) {
- In<ELFT>::Got->finalize();
+ if (needsGot())
addInputSec(In<ELFT>::Got);
- }
if (!In<ELFT>::GotPlt->empty())
addInputSec(In<ELFT>::GotPlt);
@@ -1158,8 +1159,8 @@ template <class ELFT> std::vector<PhdrEn
// Add an entry for .dynamic.
if (Out<ELFT>::DynSymTab) {
- Phdr &H = *AddHdr(PT_DYNAMIC, Out<ELFT>::Dynamic->getPhdrFlags());
- H.add(Out<ELFT>::Dynamic);
+ Phdr &H = *AddHdr(PT_DYNAMIC, In<ELFT>::Dynamic->OutSec->getPhdrFlags());
+ H.add(In<ELFT>::Dynamic->OutSec);
}
// PT_GNU_RELRO includes all sections that should be marked as
More information about the llvm-commits
mailing list