diff options
Diffstat (limited to 'lib/ReaderWriter/ELF/DynamicLibraryWriter.h')
-rw-r--r-- | lib/ReaderWriter/ELF/DynamicLibraryWriter.h | 96 |
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 |