diff options
author | Igor Kudrin <ikudrin.dev@gmail.com> | 2015-10-05 10:29:46 +0000 |
---|---|---|
committer | Igor Kudrin <ikudrin.dev@gmail.com> | 2015-10-05 10:29:46 +0000 |
commit | b1f2b51a896e561397aa4ef2620b37ed02c03a58 (patch) | |
tree | 67a956eeee946c230793ce83f92e6fbae68a87cc /lld/ELF/OutputSections.cpp | |
parent | 9ed154f9213acaa34fd79aa4a274e9162bf3bf77 (diff) | |
download | llvm-b1f2b51a896e561397aa4ef2620b37ed02c03a58.zip llvm-b1f2b51a896e561397aa4ef2620b37ed02c03a58.tar.gz llvm-b1f2b51a896e561397aa4ef2620b37ed02c03a58.tar.bz2 |
[ELF2] Add DT_INIT and DT_FINI dynamic table entries
The entries are added if there are "_init" or "_fini" entries in
the symbol table respectively. According to the behavior of ld,
entries are inserted even for undefined symbols.
Symbol names can be overridden by using -init and -fini command
line switches. If used, these switches neither add new symbol table
entries nor require those symbols to be resolved.
Differential Revision: http://reviews.llvm.org/D13385
llvm-svn: 249297
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r-- | lld/ELF/OutputSections.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 7e7ad49..c9a353b 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -170,13 +170,14 @@ template <class ELFT> void HashTableSection<ELFT>::addSymbol(SymbolBody *S) { template <class ELFT> DynamicSection<ELFT>::DynamicSection(SymbolTable &SymTab, HashTableSection<ELFT> &HashSec, - RelocationSection<ELFT> &RelaDynSec) + RelocationSection<ELFT> &RelaDynSec, + const OutputSection<ELFT> &BssSec) : OutputSectionBase<ELFT::Is64Bits>(".dynamic", llvm::ELF::SHT_DYNAMIC, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE), HashSec(HashSec), DynSymSec(HashSec.getDynSymSec()), DynStrSec(DynSymSec.getStrTabSec()), RelaDynSec(RelaDynSec), - SymTab(SymTab) { + BssSec(BssSec), SymTab(SymTab) { typename Base::HeaderT &Header = this->Header; Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; Header.sh_entsize = ELFT::Is64Bits ? 16 : 8; @@ -224,6 +225,16 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { DynStrSec.add(File->getSoName()); NumEntries += SharedFiles.size(); + if (Symbol *S = SymTab.getSymbols().lookup(Config->Init)) + InitSym = dyn_cast<ELFSymbolBody<ELFT>>(S->Body); + if (Symbol *S = SymTab.getSymbols().lookup(Config->Fini)) + FiniSym = dyn_cast<ELFSymbolBody<ELFT>>(S->Body); + + if (InitSym) + ++NumEntries; // DT_INIT + if (FiniSym) + ++NumEntries; // DT_FINI + ++NumEntries; // DT_NULL Header.sh_size = NumEntries * Header.sh_entsize; @@ -280,6 +291,11 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { for (const std::unique_ptr<SharedFileBase> &File : SharedFiles) WriteVal(DT_NEEDED, DynStrSec.getFileOff(File->getSoName())); + if (InitSym) + WritePtr(DT_INIT, getSymVA(*InitSym, BssSec)); + if (FiniSym) + WritePtr(DT_FINI, getSymVA(*FiniSym, BssSec)); + WriteVal(DT_NULL, 0); } |