//===- 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 DynamicLibraryWriter; //===----------------------------------------------------------------------===// // DynamicLibraryWriter Class //===----------------------------------------------------------------------===// template class DynamicLibraryWriter : public OutputELFWriter { public: DynamicLibraryWriter(ELFLinkingContext &context, TargetLayout &layout) : OutputELFWriter(context, layout), _runtimeFile(new RuntimeFile(context, "C runtime")) {} protected: virtual void buildDynamicSymbolTable(const File &file); virtual void addDefaultAtoms(); virtual bool createImplicitFiles(std::vector > &); virtual void finalizeDefaultAtomValues(); protected: std::unique_ptr > _runtimeFile; }; //===----------------------------------------------------------------------===// // DynamicLibraryWriter //===----------------------------------------------------------------------===// template void DynamicLibraryWriter::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>(sec)) for (const auto &atom : section->atoms()) { const DefinedAtom *da = dyn_cast(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::buildDynamicSymbolTable(file); } template void DynamicLibraryWriter::addDefaultAtoms() { _runtimeFile->addAbsoluteAtom("_end"); } /// \brief Hook in lld to add CRuntime file template bool DynamicLibraryWriter::createImplicitFiles( std::vector > &result) { // Add the default atoms as defined by executables DynamicLibraryWriter::addDefaultAtoms(); OutputELFWriter::createImplicitFiles(result); result.push_back(std::move(_runtimeFile)); return true; } template void DynamicLibraryWriter::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