//===- lib/ReaderWriter/ELF/OutputELFWriter.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_OUTPUT_WRITER_H #define LLD_READER_WRITER_ELF_OUTPUT_WRITER_H #include "ELFFile.h" #include "TargetLayout.h" #include "lld/Core/Writer.h" #include "llvm/ADT/StringSet.h" namespace lld { class ELFLinkingContext; namespace elf { using namespace llvm; using namespace llvm::object; // OutputELFWriter Class // /// \brief This acts as the base class for all the ELF writers that are output /// for emitting an ELF output file. This class also acts as a common class for /// creating static and dynamic executables. All the function in this class /// can be overridden and an appropriate writer be created template class OutputELFWriter : public ELFWriter { public: typedef Elf_Shdr_Impl Elf_Shdr; typedef Elf_Sym_Impl Elf_Sym; typedef Elf_Dyn_Impl Elf_Dyn; OutputELFWriter(ELFLinkingContext &ctx, TargetLayout &layout); protected: // build the sections that need to be created virtual void createDefaultSections(); // Build all the output sections void buildChunks(const File &file) override; // Build the output file virtual std::error_code buildOutput(const File &file); // Setup the ELF header. virtual std::error_code setELFHeader(); // Write the file to the path specified std::error_code writeFile(const File &File, StringRef path) override; // Write to the output file. virtual std::error_code writeOutput(const File &file, StringRef path); // Get the size of the output file that the linker would emit. virtual uint64_t outputFileSize() const; // Build the atom to address map, this has to be called // before applying relocations virtual void buildAtomToAddressMap(const File &file); // Build the symbol table for static linking virtual void buildStaticSymbolTable(const File &file); // Build the dynamic symbol table for dynamic linking virtual void buildDynamicSymbolTable(const File &file); // Build the section header table virtual void buildSectionHeaderTable(); // Assign sections that have no segments such as the symbol table, // section header table, string table etc virtual void assignSectionsWithNoSegments(); // Add any runtime files and their atoms to the output void createImplicitFiles(std::vector> &) override; // Finalize the default atom values virtual void finalizeDefaultAtomValues(); // This is called by the write section to apply relocations uint64_t addressOfAtom(const Atom *atom) override { auto addr = _atomToAddressMap.find(atom); return addr == _atomToAddressMap.end() ? 0 : addr->second; } // This is a hook for creating default dynamic entries virtual void createDefaultDynamicEntries() {} /// \brief Create symbol table. virtual unique_bump_ptr> createSymbolTable(); /// \brief create dynamic table. virtual unique_bump_ptr> createDynamicTable(); /// \brief create dynamic symbol table. virtual unique_bump_ptr> createDynamicSymbolTable(); /// \brief Create entry in the dynamic symbols table for this atom. virtual bool isDynSymEntryRequired(const SharedLibraryAtom *sla) const { return _layout.isReferencedByDefinedAtom(sla); } /// \brief Create DT_NEEDED dynamic tage for the shared library. virtual bool isNeededTagRequired(const SharedLibraryAtom *sla) const { return false; } /// \brief Process undefined symbols that left after resolution step. virtual void processUndefinedSymbol(StringRef symName, RuntimeFile &file) const; /// \brief Assign addresses to atoms marking section's start and end. void updateScopeAtomValues(StringRef sym, StringRef sec); llvm::BumpPtrAllocator _alloc; ELFLinkingContext &_ctx; TargetHandler &_targetHandler; typedef llvm::DenseMap AtomToAddress; AtomToAddress _atomToAddressMap; TargetLayout &_layout; unique_bump_ptr> _elfHeader; unique_bump_ptr> _programHeader; unique_bump_ptr> _symtab; unique_bump_ptr> _strtab; unique_bump_ptr> _shstrtab; unique_bump_ptr> _shdrtab; unique_bump_ptr> _ehFrameHeader; /// \name Dynamic sections. /// @{ unique_bump_ptr> _dynamicTable; unique_bump_ptr> _dynamicSymbolTable; unique_bump_ptr> _dynamicStringTable; unique_bump_ptr> _hashTable; llvm::StringSet<> _soNeeded; /// @} private: static StringRef maybeGetSOName(Node *node); void updateScopeAtomValues(StringRef start, StringRef end, StringRef sec); }; } // namespace elf } // namespace lld #endif // LLD_READER_WRITER_ELF_OUTPUT_WRITER_H