summaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ReaderWriter/ELF/DynamicLibraryWriter.h')
-rw-r--r--lib/ReaderWriter/ELF/DynamicLibraryWriter.h96
1 files changed, 96 insertions, 0 deletions
diff --git a/lib/ReaderWriter/ELF/DynamicLibraryWriter.h b/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
new file mode 100644
index 000000000000..f97514b525c0
--- /dev/null
+++ b/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
@@ -0,0 +1,96 @@
+//===- lib/ReaderWriter/ELF/DynamicLibraryWriter.h ------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLD_READER_WRITER_ELF_DYNAMIC_LIBRARY_WRITER_H
+#define LLD_READER_WRITER_ELF_DYNAMIC_LIBRARY_WRITER_H
+
+#include "OutputELFWriter.h"
+
+namespace lld {
+namespace elf {
+using namespace llvm;
+using namespace llvm::object;
+
+template<class ELFT>
+class DynamicLibraryWriter;
+
+//===----------------------------------------------------------------------===//
+// DynamicLibraryWriter Class
+//===----------------------------------------------------------------------===//
+template<class ELFT>
+class DynamicLibraryWriter : public OutputELFWriter<ELFT> {
+public:
+ DynamicLibraryWriter(ELFLinkingContext &context, TargetLayout<ELFT> &layout)
+ : OutputELFWriter<ELFT>(context, layout),
+ _runtimeFile(new RuntimeFile<ELFT>(context, "C runtime")) {}
+
+protected:
+ virtual void buildDynamicSymbolTable(const File &file);
+ virtual void addDefaultAtoms();
+ virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
+ virtual void finalizeDefaultAtomValues();
+
+protected:
+ std::unique_ptr<RuntimeFile<ELFT> > _runtimeFile;
+};
+
+//===----------------------------------------------------------------------===//
+// DynamicLibraryWriter
+//===----------------------------------------------------------------------===//
+template <class ELFT>
+void DynamicLibraryWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
+ // Add all the defined symbols to the dynamic symbol table
+ // we need hooks into the Atom to find out which atoms need
+ // to be exported
+ for (auto sec : this->_layout.sections())
+ if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
+ for (const auto &atom : section->atoms()) {
+ const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
+ if (da && (da->scope() == DefinedAtom::scopeGlobal))
+ this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
+ atom->_virtualAddr, atom);
+ }
+
+ for (const UndefinedAtom *a : file.undefined())
+ this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF);
+
+ OutputELFWriter<ELFT>::buildDynamicSymbolTable(file);
+}
+
+template <class ELFT> void DynamicLibraryWriter<ELFT>::addDefaultAtoms() {
+ _runtimeFile->addAbsoluteAtom("_end");
+}
+
+/// \brief Hook in lld to add CRuntime file
+template <class ELFT>
+bool DynamicLibraryWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File> > &result) {
+ // Add the default atoms as defined by executables
+ DynamicLibraryWriter<ELFT>::addDefaultAtoms();
+ OutputELFWriter<ELFT>::createImplicitFiles(result);
+ result.push_back(std::move(_runtimeFile));
+ return true;
+}
+
+template <class ELFT>
+void DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
+ auto underScoreEndAtomIter = this->_layout.findAbsoluteAtom("_end");
+
+ if (auto bssSection = this->_layout.findOutputSection(".bss")) {
+ (*underScoreEndAtomIter)->_virtualAddr =
+ bssSection->virtualAddr() + bssSection->memSize();
+ } else if (auto dataSection = this->_layout.findOutputSection(".data")) {
+ (*underScoreEndAtomIter)->_virtualAddr =
+ dataSection->virtualAddr() + dataSection->memSize();
+ }
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // LLD_READER_WRITER_ELF_DYNAMIC_LIBRARY_WRITER_H