Index: include/lld/ReaderWriter/ELFLinkingContext.h =================================================================== --- include/lld/ReaderWriter/ELFLinkingContext.h +++ include/lld/ReaderWriter/ELFLinkingContext.h @@ -204,26 +204,24 @@ /// Get the entry symbol name StringRef entrySymbolName() const override; - /// add to the list of initializer functions - void addInitFunction(StringRef name) { _initFunctions.push_back(name); } + /// Set new initializer function + void setInitFunction(StringRef name) { _initFunction = name; } - /// add to the list of finalizer functions - void addFiniFunction(StringRef name) { _finiFunctions.push_back(name); } + /// Set new finalizer function + void setFiniFunction(StringRef name) { _finiFunction = name; } /// Add an absolute symbol. Used for --defsym. void addInitialAbsoluteSymbol(StringRef name, uint64_t addr) { _absoluteSymbols[name] = addr; } - /// Return the list of initializer symbols that are specified in the - /// linker command line, using the -init option. - range initFunctions() const { - return _initFunctions; - } + /// Return an initializer function name, either default "_init" or + /// configured by the -init command line option. + StringRef initFunction() const { return _initFunction; } - /// Return the list of finalizer symbols that are specified in the - /// linker command line, using the -fini option. - range finiFunctions() const { return _finiFunctions; } + /// Return a finalizer function name , either default "_fini" or + /// configured by the -fini command line option. + StringRef finiFunction() const { return _finiFunction; } void setSharedObjectName(StringRef soname) { _soname = soname; @@ -324,8 +322,8 @@ StringRefVector _inputSearchPaths; std::unique_ptr _writer; StringRef _dynamicLinkerPath; - StringRefVector _initFunctions; - StringRefVector _finiFunctions; + StringRef _initFunction; + StringRef _finiFunction; StringRef _sysrootPath; StringRef _soname; StringRefVector _rpathList; Index: lib/Driver/GnuLdDriver.cpp =================================================================== --- lib/Driver/GnuLdDriver.cpp +++ lib/Driver/GnuLdDriver.cpp @@ -427,11 +427,11 @@ break; case OPT_init: - ctx->addInitFunction(inputArg->getValue()); + ctx->setInitFunction(inputArg->getValue()); break; case OPT_fini: - ctx->addFiniFunction(inputArg->getValue()); + ctx->setFiniFunction(inputArg->getValue()); break; case OPT_output_filetype: Index: lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h +++ lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h @@ -92,9 +92,6 @@ return false; } } - - /// \brief Create Internal files for Init/Fini - void createInternalFiles(std::vector> &) const override; }; } // end namespace elf } // end namespace lld Index: lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp @@ -9,85 +9,8 @@ #include "AArch64LinkingContext.h" #include "AArch64RelocationPass.h" -#include "Atoms.h" -#include "lld/Core/File.h" -#include "lld/Core/Instrumentation.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringSwitch.h" using namespace lld; -using namespace lld::elf; - -using llvm::makeArrayRef; - -namespace { -using namespace llvm::ELF; - -const uint8_t AArch64InitFiniAtomContent[8] = {0}; - -// AArch64InitFini Atom -class AArch64InitAtom : public InitFiniAtom { -public: - AArch64InitAtom(const File &f, StringRef function) - : InitFiniAtom(f, ".init_array") { -#ifndef NDEBUG - _name = "__init_fn_"; - _name += function; -#endif - } - ArrayRef rawContent() const override { - return makeArrayRef(AArch64InitFiniAtomContent); - } - Alignment alignment() const override { return Alignment(3); } -}; - -class AArch64FiniAtom : public InitFiniAtom { -public: - AArch64FiniAtom(const File &f, StringRef function) - : InitFiniAtom(f, ".fini_array") { -#ifndef NDEBUG - _name = "__fini_fn_"; - _name += function; -#endif - } - ArrayRef rawContent() const override { - return makeArrayRef(AArch64InitFiniAtomContent); - } - - Alignment alignment() const override { return Alignment(3); } -}; - -class AArch64InitFiniFile : public SimpleFile { -public: - AArch64InitFiniFile(const ELFLinkingContext &context) - : SimpleFile("command line option -init/-fini"), _ordinal(0) {} - - void addInitFunction(StringRef name) { - Atom *initFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name); - AArch64InitAtom *initAtom = (new (_allocator) AArch64InitAtom(*this, name)); - initAtom->addReferenceELF_AArch64(llvm::ELF::R_AARCH64_ABS64, 0, - initFunctionAtom, 0); - initAtom->setOrdinal(_ordinal++); - addAtom(*initFunctionAtom); - addAtom(*initAtom); - } - - void addFiniFunction(StringRef name) { - Atom *finiFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name); - AArch64FiniAtom *finiAtom = (new (_allocator) AArch64FiniAtom(*this, name)); - finiAtom->addReferenceELF_AArch64(llvm::ELF::R_AARCH64_ABS64, 0, - finiFunctionAtom, 0); - finiAtom->setOrdinal(_ordinal++); - addAtom(*finiFunctionAtom); - addAtom(*finiAtom); - } - -private: - llvm::BumpPtrAllocator _allocator; - uint64_t _ordinal; -}; - -} // end anon namespace void elf::AArch64LinkingContext::addPasses(PassManager &pm) { auto pass = createAArch64RelocationPass(*this); @@ -95,15 +18,3 @@ pm.add(std::move(pass)); ELFLinkingContext::addPasses(pm); } - -void elf::AArch64LinkingContext::createInternalFiles( - std::vector> &result) const { - ELFLinkingContext::createInternalFiles(result); - std::unique_ptr initFiniFile( - new AArch64InitFiniFile(*this)); - for (auto ai : initFunctions()) - initFiniFile->addInitFunction(ai); - for (auto ai : finiFunctions()) - initFiniFile->addFiniFunction(ai); - result.push_back(std::move(initFiniFile)); -} Index: lib/ReaderWriter/ELF/ELFLinkingContext.cpp =================================================================== --- lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -63,7 +63,7 @@ _useShlibUndefines(true), _dynamicLinkerArg(false), _noAllowDynamicLibraries(false), _mergeRODataToTextSegment(true), _demangle(true), _alignSegments(true), _outputMagic(OutputMagic::DEFAULT), - _sysrootPath("") {} + _initFunction("_init"), _finiFunction("_fini"), _sysrootPath("") {} void ELFLinkingContext::addPasses(PassManager &pm) { if (_runLayoutPass) Index: lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h +++ lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h @@ -61,10 +61,6 @@ return false; } } - - /// \brief Create Internal files for Init/Fini - void createInternalFiles( - std::vector> &result) const override; }; } // elf Index: lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp +++ lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp @@ -7,100 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "Atoms.h" #include "HexagonLinkingContext.h" #include "HexagonTargetHandler.h" -#include "lld/Core/File.h" -#include "lld/Core/Pass.h" -#include "lld/Core/PassManager.h" -#include "lld/Core/Simple.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringSwitch.h" -using namespace lld; using namespace lld::elf; -namespace { - -const uint8_t hexagonInitFiniAtomContent[4] = { 0 }; - -// HexagonInitFini Atom -class HexagonInitAtom : public InitFiniAtom { -public: - HexagonInitAtom(const File &f, StringRef function) - : InitFiniAtom(f, ".init_array") { -#ifndef NDEBUG - _name = "__init_fn_"; - _name += function; -#endif - } - ArrayRef rawContent() const override { - return ArrayRef(hexagonInitFiniAtomContent, 4); - } - - Alignment alignment() const override { return Alignment(2); } -}; - -class HexagonFiniAtom : public InitFiniAtom { -public: - HexagonFiniAtom(const File &f, StringRef function) - : InitFiniAtom(f, ".fini_array") { -#ifndef NDEBUG - _name = "__fini_fn_"; - _name += function; -#endif - } - ArrayRef rawContent() const override { - return ArrayRef(hexagonInitFiniAtomContent, 4); - } - Alignment alignment() const override { return Alignment(2); } -}; - -class HexagonInitFiniFile : public SimpleFile { -public: - HexagonInitFiniFile(const ELFLinkingContext &context) - : SimpleFile("command line option -init/-fini"), _ordinal(0) {} - - void addInitFunction(StringRef name) { - Atom *initFuncAtom = new (_allocator) SimpleUndefinedAtom(*this, name); - HexagonInitAtom *initAtom = - (new (_allocator) HexagonInitAtom(*this, name)); - initAtom->addReferenceELF_Hexagon(llvm::ELF::R_HEX_32, 0, initFuncAtom, 0); - initAtom->setOrdinal(_ordinal++); - addAtom(*initFuncAtom); - addAtom(*initAtom); - } - - void addFiniFunction(StringRef name) { - Atom *finiFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name); - HexagonFiniAtom *finiAtom = - (new (_allocator) HexagonFiniAtom(*this, name)); - finiAtom->addReferenceELF_Hexagon(llvm::ELF::R_HEX_32, 0, finiFunctionAtom, - 0); - finiAtom->setOrdinal(_ordinal++); - addAtom(*finiFunctionAtom); - addAtom(*finiAtom); - } - -private: - llvm::BumpPtrAllocator _allocator; - uint64_t _ordinal; -}; -} - -void elf::HexagonLinkingContext::createInternalFiles( - std::vector > &result) const { - ELFLinkingContext::createInternalFiles(result); - std::unique_ptr initFiniFile( - new HexagonInitFiniFile(*this)); - for (auto ai : initFunctions()) - initFiniFile->addInitFunction(ai); - for (auto ai:finiFunctions()) - initFiniFile->addFiniFunction(ai); - result.push_back(std::move(initFiniFile)); -} - HexagonLinkingContext::HexagonLinkingContext(llvm::Triple triple) : ELFLinkingContext(triple, std::unique_ptr( new HexagonTargetHandler(*this))) {} Index: lib/ReaderWriter/ELF/SectionChunks.h =================================================================== --- lib/ReaderWriter/ELF/SectionChunks.h +++ lib/ReaderWriter/ELF/SectionChunks.h @@ -1134,6 +1134,14 @@ dyn.d_tag = DT_FINI_ARRAYSZ; _dt_fini_arraysz = addEntry(dyn); } + if (getInitAtomLayout()) { + dyn.d_tag = DT_INIT; + _dt_init = addEntry(dyn); + } + if (getFiniAtomLayout()) { + dyn.d_tag = DT_FINI; + _dt_fini = addEntry(dyn); + } } /// \brief Dynamic table tag for .got.plt section referencing. @@ -1179,6 +1187,10 @@ _entries[_dt_fini_array].d_un.d_val = finiArray->virtualAddr(); _entries[_dt_fini_arraysz].d_un.d_val = finiArray->memSize(); } + if (const auto *al = getInitAtomLayout()) + _entries[_dt_init].d_un.d_val = al->_virtualAddr; + if (const auto *al = getFiniAtomLayout()) + _entries[_dt_fini].d_un.d_val = al->_virtualAddr; if (_layout.hasDynamicRelocationTable()) { auto relaTbl = _layout.getDynamicRelocationTable(); _entries[_dt_rela].d_un.d_val = relaTbl->virtualAddr(); @@ -1215,9 +1227,25 @@ std::size_t _dt_fini_array; std::size_t _dt_fini_arraysz; std::size_t _dt_textrel; + std::size_t _dt_init; + std::size_t _dt_fini; TargetLayout &_layout; DynamicSymbolTable *_dynamicSymbolTable; HashSection *_hashTable; + + const AtomLayout *getInitAtomLayout() { + auto al = _layout.findAtomLayoutByName(this->_context.initFunction()); + if (al && isa(al->_atom)) + return al; + return nullptr; + } + + const AtomLayout *getFiniAtomLayout() { + auto al = _layout.findAtomLayoutByName(this->_context.finiFunction()); + if (al && isa(al->_atom)) + return al; + return nullptr; + } }; template class InterpSection : public Section { Index: lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h +++ lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h @@ -94,9 +94,6 @@ return false; } } - - /// \brief Create Internal files for Init/Fini - void createInternalFiles(std::vector> &) const override; }; } // end namespace elf } // end namespace lld Index: lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp +++ lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp @@ -8,88 +8,9 @@ //===----------------------------------------------------------------------===// #include "X86_64LinkingContext.h" -#include "Atoms.h" #include "X86_64RelocationPass.h" -#include "lld/Core/File.h" -#include "lld/Core/Instrumentation.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringSwitch.h" using namespace lld; -using namespace lld::elf; - -using llvm::makeArrayRef; - -namespace { -using namespace llvm::ELF; - -const uint8_t x86_64InitFiniAtomContent[8] = { 0 }; - -// X86_64InitFini Atom -class X86_64InitAtom : public InitFiniAtom { -public: - X86_64InitAtom(const File &f, StringRef function) - : InitFiniAtom(f, ".init_array") { -#ifndef NDEBUG - _name = "__init_fn_"; - _name += function; -#endif - } - ArrayRef rawContent() const override { - return makeArrayRef(x86_64InitFiniAtomContent); - } - Alignment alignment() const override { return Alignment(3); } -}; - -class X86_64FiniAtom : public InitFiniAtom { -public: - X86_64FiniAtom(const File &f, StringRef function) - : InitFiniAtom(f, ".fini_array") { -#ifndef NDEBUG - _name = "__fini_fn_"; - _name += function; -#endif - } - ArrayRef rawContent() const override { - return makeArrayRef(x86_64InitFiniAtomContent); - } - - Alignment alignment() const override { return Alignment(3); } -}; - -class X86_64InitFiniFile : public SimpleFile { -public: - X86_64InitFiniFile(const ELFLinkingContext &context) - : SimpleFile("command line option -init/-fini"), _ordinal(0) {} - - void addInitFunction(StringRef name) { - Atom *initFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name); - X86_64InitAtom *initAtom = - (new (_allocator) X86_64InitAtom(*this, name)); - initAtom->addReferenceELF_x86_64(llvm::ELF::R_X86_64_64, 0, - initFunctionAtom, 0); - initAtom->setOrdinal(_ordinal++); - addAtom(*initFunctionAtom); - addAtom(*initAtom); - } - - void addFiniFunction(StringRef name) { - Atom *finiFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name); - X86_64FiniAtom *finiAtom = - (new (_allocator) X86_64FiniAtom(*this, name)); - finiAtom->addReferenceELF_x86_64(llvm::ELF::R_X86_64_64, 0, - finiFunctionAtom, 0); - finiAtom->setOrdinal(_ordinal++); - addAtom(*finiFunctionAtom); - addAtom(*finiAtom); - } - -private: - llvm::BumpPtrAllocator _allocator; - uint64_t _ordinal; -}; - -} // end anon namespace void elf::X86_64LinkingContext::addPasses(PassManager &pm) { auto pass = createX86_64RelocationPass(*this); @@ -97,16 +18,3 @@ pm.add(std::move(pass)); ELFLinkingContext::addPasses(pm); } - -void elf::X86_64LinkingContext::createInternalFiles( - std::vector > &result) const { - ELFLinkingContext::createInternalFiles(result); - std::unique_ptr initFiniFile( - new X86_64InitFiniFile(*this)); - for (auto ai : initFunctions()) - initFiniFile->addInitFunction(ai); - for (auto ai:finiFunctions()) - initFiniFile->addFiniFunction(ai); - result.push_back(std::move(initFiniFile)); -} - Index: test/elf/AArch64/initfini-alignment.test =================================================================== --- test/elf/AArch64/initfini-alignment.test +++ /dev/null @@ -1,12 +0,0 @@ -# This tests the functionality that lld is able to create -# init_array/fini_array sections in the output ELF with the -# right alignment - -RUN: lld -flavor gnu -target aarch64--linux-gnu %p/Inputs/initfini-option.o \ -RUN: -init init -fini fini --noinhibit-exec -o %t -RUN: llvm-readobj -s %t | FileCheck %s - -CHECK: Name: .init_array -CHECK: AddressAlignment: 8 -CHECK: Name: .fini_array -CHECK: AddressAlignment: 8 Index: test/elf/AArch64/initfini-option.test =================================================================== --- test/elf/AArch64/initfini-option.test +++ /dev/null @@ -1,21 +0,0 @@ -# This tests the functionality that lld is able to create -# init_array/fini_array sections in the output ELF. This -# corresponds to the the .init_array/.fini_array sections -# in the output ELF. - -RUN: lld -flavor gnu -target aarch64--linux-gnu %p/Inputs/initfini-option.o \ -RUN: -init init -fini fini --noinhibit-exec --output-filetype=yaml -static -o %t -RUN: FileCheck %s < %t - -CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] -CHECK: section-name: .init_array -CHECK: references: -CHECK: - kind: R_AARCH64_ABS64 -CHECK: offset: 0 -CHECK: target: init -CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] -CHECK: section-name: .fini_array -CHECK: references: -CHECK: - kind: R_AARCH64_ABS64 -CHECK: offset: 0 -CHECK: target: fini Index: test/elf/Hexagon/Inputs/initfini-option.c =================================================================== --- test/elf/Hexagon/Inputs/initfini-option.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -void init() { - printf("%s\n", __FUNCTION__); -} - -void fini() { - printf("%s\n", __FUNCTION__); -} - -int main() { -} - Index: test/elf/Hexagon/initfini-option.test =================================================================== --- test/elf/Hexagon/initfini-option.test +++ /dev/null @@ -1,21 +0,0 @@ -# This tests the functionality that lld is able to create -# init_array/fini_array sections in the output ELF. This -# corresponds to the the .init_array/.fini_array sections -# in the output ELF. - -RUN: lld -flavor gnu -target hexagon %p/Inputs/initfini-option.o \ -RUN: -init init -fini fini --noinhibit-exec --output-filetype=yaml -static -o %t -RUN: FileCheck %s < %t - -CHECK: content: [ 00, 00, 00, 00 ] -CHECK: section-name: .init_array -CHECK: references: -CHECK: - kind: R_HEX_32 -CHECK: offset: 0 -CHECK: target: init -CHECK: content: [ 00, 00, 00, 00 ] -CHECK: section-name: .fini_array -CHECK: references: -CHECK: - kind: R_HEX_32 -CHECK: offset: 0 -CHECK: target: fini Index: test/elf/X86_64/initfini-alignment.test =================================================================== --- test/elf/X86_64/initfini-alignment.test +++ /dev/null @@ -1,12 +0,0 @@ -# This tests the functionality that lld is able to create -# init_array/fini_array sections in the output ELF with the -# right alignment - -RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/initfini-option.o \ -RUN: -init init -fini fini --noinhibit-exec -o %t -RUN: llvm-readobj -s %t | FileCheck %s - -CHECK: Name: .init_array -CHECK: AddressAlignment: 8 -CHECK: Name: .fini_array -CHECK: AddressAlignment: 8 Index: test/elf/X86_64/initfini-option.test =================================================================== --- test/elf/X86_64/initfini-option.test +++ /dev/null @@ -1,21 +0,0 @@ -# This tests the functionality that lld is able to create -# init_array/fini_array sections in the output ELF. This -# corresponds to the the .init_array/.fini_array sections -# in the output ELF. - -RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/initfini-option.o \ -RUN: -init init -fini fini --noinhibit-exec --output-filetype=yaml -o %t -RUN: FileCheck %s < %t - -CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] -CHECK: section-name: .init_array -CHECK: references: -CHECK: - kind: R_X86_64_64 -CHECK: offset: 0 -CHECK: target: init -CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] -CHECK: section-name: .fini_array -CHECK: references: -CHECK: - kind: R_X86_64_64 -CHECK: offset: 0 -CHECK: target: fini Index: test/elf/initfini-options.test =================================================================== --- /dev/null +++ test/elf/initfini-options.test @@ -0,0 +1,141 @@ +# Check the three following cases related to the DT_INIT/DT_FINI dynamic +# table tags and -init/-fini command line options handling: +# a) If there are no -init/-fini options and _init/_fini symbols are undefined +# linker does not emit DT_INIT/DT_FINI tags. +# b) If _init/_fini symbols are defined linker emit DT_INIT/DT_FINI tags +# point to these symbols. +# c) If there are -init/-fini options, they override default function names +# and linker uses the corresponding symbol values for the DT_INIT/DT_FINI. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t.no-init.o +# RUN: lld -flavor gnu -target x86_64 -shared --noinhibit-exec \ +# RUN: -o %t.no-init.so %t.no-init.o +# RUN: llvm-readobj -dynamic-table %t.no-init.so \ +# RUN: | FileCheck -check-prefix=NO-INIT %s + +# NO-INIT-NOT: 0x000000000000000C INIT 0x{{[0-9A-F]+}} +# NO-INIT-NOT: 0x000000000000000D FINI 0x{{[0-9A-F]+}} + +# RUN: yaml2obj -format=elf -docnum 2 %s > %t.def-init.o +# RUN: lld -flavor gnu -target x86_64 -shared -o %t.def-init.so %t.def-init.o +# RUN: llvm-readobj -symbols -dynamic-table %t.def-init.so \ +# RUN: | FileCheck -check-prefix=DEF-INIT %s + +# DEF-INIT: Name: _init (8) +# DEF-INIT-NEXT: Value: 0x4001E4 +# DEF-INIT: Name: _fini (14) +# DEF-INIT-NEXT: Value: 0x4001EB +# +# DEF-INIT: 0x000000000000000C INIT 0x4001E4 +# DEF-INIT: 0x000000000000000D FINI 0x4001EB + +# RUN: yaml2obj -format=elf -docnum 3 %s > %t.custom-init.o +# RUN: lld -flavor gnu -target x86_64 -shared \ +# RUN: -init _init -init _start -fini _fini -fini _stop \ +# RUN: -o %t.custom-init.so %t.custom-init.o +# RUN: llvm-readobj -symbols -dynamic-table %t.custom-init.so \ +# RUN: | FileCheck -check-prefix=CUSTOM-INIT %s + +# CUSTOM-INIT: Name: _start (1) +# CUSTOM-INIT-NEXT: Value: 0x4001FC +# CUSTOM-INIT: Name: _stop (8) +# CUSTOM-INIT-NEXT: Value: 0x400204 +# +# CUSTOM-INIT: 0x000000000000000C INIT 0x4001FC +# CUSTOM-INIT: 0x000000000000000D FINI 0x400204 + +# no-init.o +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x08 + +Symbols: + Global: + - Name: _start + Type: STT_FUNC + Section: .text + Size: 0x08 + - Name: _init + - Name: _fini + +# def-init.o +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x18 + +Symbols: + Global: + - Name: _start + Type: STT_FUNC + Section: .text + Value: 0x0 + Size: 0x8 + - Name: _init + Type: STT_FUNC + Section: .text + Value: 0x8 + Size: 0x8 + - Name: _fini + Type: STT_FUNC + Section: .text + Value: 0xF + Size: 0x8 + +# custom-init.o +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Size: 0x20 + +Symbols: + Global: + - Name: _start + Type: STT_FUNC + Section: .text + Value: 0x0 + Size: 0x8 + - Name: _stop + Type: STT_FUNC + Section: .text + Value: 0x8 + Size: 0x8 + - Name: _init + Type: STT_FUNC + Section: .text + Value: 0xF + Size: 0x8 + - Name: _fini + Type: STT_FUNC + Section: .text + Value: 0x18 + Size: 0x8 +... Index: unittests/DriverTests/GnuLdDriverTest.cpp =================================================================== --- unittests/DriverTests/GnuLdDriverTest.cpp +++ unittests/DriverTests/GnuLdDriverTest.cpp @@ -80,16 +80,13 @@ TEST_F(GnuLdParserTest, Init) { EXPECT_TRUE(parse("ld", "--start-group", "--end-group", "-init", "foo", "-init", "bar", nullptr)); - EXPECT_EQ(2, _context->initFunctions().size()); - EXPECT_EQ("foo", _context->initFunctions()[0]); - EXPECT_EQ("bar", _context->initFunctions()[1]); + EXPECT_EQ("bar", _context->initFunction()); } TEST_F(GnuLdParserTest, InitJoined) { EXPECT_TRUE(parse("ld", "--start-group", "--end-group", "-init=foo", nullptr)); - EXPECT_EQ(1, _context->initFunctions().size()); - EXPECT_EQ("foo", _context->initFunctions()[0]); + EXPECT_EQ("foo", _context->initFunction()); } // --soname