aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorIgor Kudrin <ikudrin.dev@gmail.com>2015-10-05 10:29:46 +0000
committerIgor Kudrin <ikudrin.dev@gmail.com>2015-10-05 10:29:46 +0000
commitb1f2b51a896e561397aa4ef2620b37ed02c03a58 (patch)
tree67a956eeee946c230793ce83f92e6fbae68a87cc /lld/ELF/OutputSections.cpp
parent9ed154f9213acaa34fd79aa4a274e9162bf3bf77 (diff)
downloadllvm-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.cpp20
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);
}