summaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/ELF/ExecutableWriter.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ReaderWriter/ELF/ExecutableWriter.h')
-rw-r--r--lib/ReaderWriter/ELF/ExecutableWriter.h135
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;
}
}