diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:57:38 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:57:38 +0000 |
| commit | 5a5c549fe9a3fef595297bd21d36bed8409dc37d (patch) | |
| tree | a964c8f5ac85b7b641cac022c5f9bf4eed3d2b9b /lib/ReaderWriter/ELF/ExecutableWriter.h | |
| parent | fb911942f1434f3d1750f83f25f5e42c80e60638 (diff) | |
Notes
Diffstat (limited to 'lib/ReaderWriter/ELF/ExecutableWriter.h')
| -rw-r--r-- | lib/ReaderWriter/ELF/ExecutableWriter.h | 135 |
1 files changed, 55 insertions, 80 deletions
diff --git a/lib/ReaderWriter/ELF/ExecutableWriter.h b/lib/ReaderWriter/ELF/ExecutableWriter.h index 477e3920abae..9d9f4d9ce0a5 100644 --- a/lib/ReaderWriter/ELF/ExecutableWriter.h +++ b/lib/ReaderWriter/ELF/ExecutableWriter.h @@ -16,32 +16,29 @@ namespace elf { using namespace llvm; using namespace llvm::object; -template<class ELFT> -class ExecutableWriter; - //===----------------------------------------------------------------------===// // ExecutableWriter Class //===----------------------------------------------------------------------===// template<class ELFT> class ExecutableWriter : public OutputELFWriter<ELFT> { public: - ExecutableWriter(ELFLinkingContext &context, TargetLayout<ELFT> &layout) - : OutputELFWriter<ELFT>(context, layout), - _runtimeFile(new RuntimeFile<ELFT>(context, "C runtime")) {} + ExecutableWriter(ELFLinkingContext &ctx, TargetLayout<ELFT> &layout) + : OutputELFWriter<ELFT>(ctx, layout) {} protected: - virtual void buildDynamicSymbolTable(const File &file); - virtual void addDefaultAtoms(); - virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &); - virtual void finalizeDefaultAtomValues(); - virtual void createDefaultSections(); + void buildDynamicSymbolTable(const File &file) override; + void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override; + void finalizeDefaultAtomValues() override; + void createDefaultSections() override; - virtual bool isNeededTagRequired(const SharedLibraryAtom *sla) const { + bool isNeededTagRequired(const SharedLibraryAtom *sla) const override { return this->_layout.isCopied(sla); } unique_bump_ptr<InterpSection<ELFT>> _interpSection; - std::unique_ptr<RuntimeFile<ELFT> > _runtimeFile; + +private: + std::unique_ptr<RuntimeFile<ELFT>> createRuntimeFile(); }; //===----------------------------------------------------------------------===// @@ -56,8 +53,8 @@ void ExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) { if (!da) continue; if (da->dynamicExport() != DefinedAtom::dynamicExportAlways && - !this->_context.isDynamicallyExportedSymbol(da->name()) && - !(this->_context.shouldExportDynamic() && + !this->_ctx.isDynamicallyExportedSymbol(da->name()) && + !(this->_ctx.shouldExportDynamic() && da->scope() == Atom::Scope::scopeGlobal)) continue; this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), @@ -65,7 +62,7 @@ void ExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) { } // Put weak symbols in the dynamic symbol table. - if (this->_context.isDynamic()) { + if (this->_ctx.isDynamic()) { for (const UndefinedAtom *a : file.undefined()) { if (this->_layout.isReferencedByDefinedAtom(a) && a->canBeNull() != UndefinedAtom::canBeNullNever) @@ -76,48 +73,44 @@ void ExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) { OutputELFWriter<ELFT>::buildDynamicSymbolTable(file); } -/// \brief Add absolute symbols by default. These are linker added -/// absolute symbols template<class ELFT> -void ExecutableWriter<ELFT>::addDefaultAtoms() { - OutputELFWriter<ELFT>::addDefaultAtoms(); - _runtimeFile->addUndefinedAtom(this->_context.entrySymbolName()); - _runtimeFile->addAbsoluteAtom("__bss_start"); - _runtimeFile->addAbsoluteAtom("__bss_end"); - _runtimeFile->addAbsoluteAtom("_end"); - _runtimeFile->addAbsoluteAtom("end"); - _runtimeFile->addAbsoluteAtom("__preinit_array_start"); - _runtimeFile->addAbsoluteAtom("__preinit_array_end"); - _runtimeFile->addAbsoluteAtom("__init_array_start"); - _runtimeFile->addAbsoluteAtom("__init_array_end"); - if (this->_context.isRelaOutputFormat()) { - _runtimeFile->addAbsoluteAtom("__rela_iplt_start"); - _runtimeFile->addAbsoluteAtom("__rela_iplt_end"); +std::unique_ptr<RuntimeFile<ELFT>> ExecutableWriter<ELFT>::createRuntimeFile() { + auto file = llvm::make_unique<RuntimeFile<ELFT>>(this->_ctx, "C runtime"); + file->addUndefinedAtom(this->_ctx.entrySymbolName()); + file->addAbsoluteAtom("__bss_start"); + file->addAbsoluteAtom("__bss_end"); + file->addAbsoluteAtom("_end"); + file->addAbsoluteAtom("end"); + file->addAbsoluteAtom("__preinit_array_start", true); + file->addAbsoluteAtom("__preinit_array_end", true); + file->addAbsoluteAtom("__init_array_start", true); + file->addAbsoluteAtom("__init_array_end", true); + if (this->_ctx.isRelaOutputFormat()) { + file->addAbsoluteAtom("__rela_iplt_start"); + file->addAbsoluteAtom("__rela_iplt_end"); } else { - _runtimeFile->addAbsoluteAtom("__rel_iplt_start"); - _runtimeFile->addAbsoluteAtom("__rel_iplt_end"); + file->addAbsoluteAtom("__rel_iplt_start"); + file->addAbsoluteAtom("__rel_iplt_end"); } - _runtimeFile->addAbsoluteAtom("__fini_array_start"); - _runtimeFile->addAbsoluteAtom("__fini_array_end"); + file->addAbsoluteAtom("__fini_array_start", true); + file->addAbsoluteAtom("__fini_array_end", true); + return file; } /// \brief Hook in lld to add CRuntime file template <class ELFT> -bool ExecutableWriter<ELFT>::createImplicitFiles( +void ExecutableWriter<ELFT>::createImplicitFiles( std::vector<std::unique_ptr<File> > &result) { - // Add the default atoms as defined by executables - ExecutableWriter<ELFT>::addDefaultAtoms(); OutputELFWriter<ELFT>::createImplicitFiles(result); - result.push_back(std::move(_runtimeFile)); - return true; + result.push_back(createRuntimeFile()); } template <class ELFT> void ExecutableWriter<ELFT>::createDefaultSections() { OutputELFWriter<ELFT>::createDefaultSections(); - if (this->_context.isDynamic()) { + if (this->_ctx.isDynamic()) { _interpSection.reset(new (this->_alloc) InterpSection<ELFT>( - this->_context, ".interp", DefaultLayout<ELFT>::ORDER_INTERP, - this->_context.getInterpreter())); + this->_ctx, ".interp", TargetLayout<ELFT>::ORDER_INTERP, + this->_ctx.getInterpreter())); this->_layout.addSection(_interpSection.get()); } } @@ -126,53 +119,35 @@ template <class ELFT> void ExecutableWriter<ELFT>::createDefaultSections() { /// created template <class ELFT> void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() { OutputELFWriter<ELFT>::finalizeDefaultAtomValues(); - auto bssStartAtomIter = this->_layout.findAbsoluteAtom("__bss_start"); - auto bssEndAtomIter = this->_layout.findAbsoluteAtom("__bss_end"); - auto underScoreEndAtomIter = this->_layout.findAbsoluteAtom("_end"); - auto endAtomIter = this->_layout.findAbsoluteAtom("end"); + AtomLayout *bssStartAtom = this->_layout.findAbsoluteAtom("__bss_start"); + AtomLayout *bssEndAtom = this->_layout.findAbsoluteAtom("__bss_end"); + AtomLayout *underScoreEndAtom = this->_layout.findAbsoluteAtom("_end"); + AtomLayout *endAtom = this->_layout.findAbsoluteAtom("end"); - auto startEnd = [&](StringRef sym, StringRef sec) -> void { - std::string start = ("__" + sym + "_start").str(); - std::string end = ("__" + sym + "_end").str(); - auto s = this->_layout.findAbsoluteAtom(start); - auto e = this->_layout.findAbsoluteAtom(end); - auto section = this->_layout.findOutputSection(sec); - if (section) { - (*s)->_virtualAddr = section->virtualAddr(); - (*e)->_virtualAddr = section->virtualAddr() + section->memSize(); - } else { - (*s)->_virtualAddr = 0; - (*e)->_virtualAddr = 0; - } - }; + assert((bssStartAtom || bssEndAtom || underScoreEndAtom || endAtom) && + "Unable to find the absolute atoms that have been added by lld"); - startEnd("preinit_array", ".preinit_array"); - startEnd("init_array", ".init_array"); - if (this->_context.isRelaOutputFormat()) - startEnd("rela_iplt", ".rela.plt"); + this->updateScopeAtomValues("preinit_array", ".preinit_array"); + this->updateScopeAtomValues("init_array", ".init_array"); + if (this->_ctx.isRelaOutputFormat()) + this->updateScopeAtomValues("rela_iplt", ".rela.plt"); else - startEnd("rel_iplt", ".rel.plt"); - startEnd("fini_array", ".fini_array"); - - assert(!(bssStartAtomIter == this->_layout.absoluteAtoms().end() || - bssEndAtomIter == this->_layout.absoluteAtoms().end() || - underScoreEndAtomIter == this->_layout.absoluteAtoms().end() || - endAtomIter == this->_layout.absoluteAtoms().end()) && - "Unable to find the absolute atoms that have been added by lld"); + this->updateScopeAtomValues("rel_iplt", ".rel.plt"); + this->updateScopeAtomValues("fini_array", ".fini_array"); auto bssSection = this->_layout.findOutputSection(".bss"); // If we don't find a bss section, then don't set these values if (bssSection) { - (*bssStartAtomIter)->_virtualAddr = bssSection->virtualAddr(); - (*bssEndAtomIter)->_virtualAddr = + bssStartAtom->_virtualAddr = bssSection->virtualAddr(); + bssEndAtom->_virtualAddr = bssSection->virtualAddr() + bssSection->memSize(); - (*underScoreEndAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr; - (*endAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr; + underScoreEndAtom->_virtualAddr = bssEndAtom->_virtualAddr; + endAtom->_virtualAddr = bssEndAtom->_virtualAddr; } else if (auto dataSection = this->_layout.findOutputSection(".data")) { - (*underScoreEndAtomIter)->_virtualAddr = + underScoreEndAtom->_virtualAddr = dataSection->virtualAddr() + dataSection->memSize(); - (*endAtomIter)->_virtualAddr = (*underScoreEndAtomIter)->_virtualAddr; + endAtom->_virtualAddr = underScoreEndAtom->_virtualAddr; } } |
