From b1f2b51a896e561397aa4ef2620b37ed02c03a58 Mon Sep 17 00:00:00 2001 From: Igor Kudrin Date: Mon, 5 Oct 2015 10:29:46 +0000 Subject: [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 --- lld/ELF/OutputSections.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'lld/ELF/OutputSections.cpp') diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 7e7ad4990ca..c9a353b666e 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -170,13 +170,14 @@ template void HashTableSection::addSymbol(SymbolBody *S) { template DynamicSection::DynamicSection(SymbolTable &SymTab, HashTableSection &HashSec, - RelocationSection &RelaDynSec) + RelocationSection &RelaDynSec, + const OutputSection &BssSec) : OutputSectionBase(".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 void DynamicSection::finalize() { DynStrSec.add(File->getSoName()); NumEntries += SharedFiles.size(); + if (Symbol *S = SymTab.getSymbols().lookup(Config->Init)) + InitSym = dyn_cast>(S->Body); + if (Symbol *S = SymTab.getSymbols().lookup(Config->Fini)) + FiniSym = dyn_cast>(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 void DynamicSection::writeTo(uint8_t *Buf) { for (const std::unique_ptr &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); } -- cgit v1.2.3