//===- ELFObjectWriter.h --------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_ELF_OBJECT_WRITER_H #define MCLD_ELF_OBJECT_WRITER_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif #include <mcld/LD/ObjectWriter.h> #include <cassert> #include <llvm/Support/system_error.h> namespace mcld { class Module; class LinkerConfig; class GNULDBackend; class FragmentLinker; class Relocation; class LDSection; class SectionData; class RelocData; class Output; class MemoryRegion; class MemoryArea; /** \class ELFObjectWriter * \brief ELFObjectWriter writes the target-independent parts of object files. * ELFObjectWriter reads a MCLDFile and writes into raw_ostream * */ class ELFObjectWriter : public ObjectWriter { public: ELFObjectWriter(GNULDBackend& pBackend, const LinkerConfig& pConfig); ~ELFObjectWriter(); llvm::error_code writeObject(Module& pModule, MemoryArea& pOutput); private: void writeSection(MemoryArea& pOutput, LDSection *section); GNULDBackend& target() { return m_Backend; } const GNULDBackend& target() const { return m_Backend; } // writeELFHeader - emit ElfXX_Ehdr template<size_t SIZE> void writeELFHeader(const LinkerConfig& pConfig, const Module& pModule, MemoryArea& pOutput) const; uint64_t getEntryPoint(const LinkerConfig& pConfig, const Module& pModule) const; // emitSectionHeader - emit ElfXX_Shdr template<size_t SIZE> void emitSectionHeader(const Module& pModule, const LinkerConfig& pConfig, MemoryArea& pOutput) const; // emitProgramHeader - emit ElfXX_Phdr template<size_t SIZE> void emitProgramHeader(MemoryArea& pOutput) const; // emitShStrTab - emit .shstrtab void emitShStrTab(const LDSection& pShStrTab, const Module& pModule, MemoryArea& pOutput); void emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const; void emitRelocation(const LinkerConfig& pConfig, const LDSection& pSection, MemoryRegion& pRegion) const; // emitRel - emit ElfXX_Rel template<size_t SIZE> void emitRel(const LinkerConfig& pConfig, const RelocData& pRelocData, MemoryRegion& pRegion) const; // emitRela - emit ElfXX_Rela template<size_t SIZE> void emitRela(const LinkerConfig& pConfig, const RelocData& pRelocData, MemoryRegion& pRegion) const; // getSectEntrySize - compute ElfXX_Shdr::sh_entsize template<size_t SIZE> uint64_t getSectEntrySize(const LDSection& pSection) const; // getSectLink - compute ElfXX_Shdr::sh_link uint64_t getSectLink(const LDSection& pSection, const LinkerConfig& pConfig) const; // getSectInfo - compute ElfXX_Shdr::sh_info uint64_t getSectInfo(const LDSection& pSection) const; template<size_t SIZE> uint64_t getLastStartOffset(const Module& pModule) const { assert(0 && "Call invalid ELFObjectWriter::getLastStartOffset"); return 0; } void emitSectionData(const SectionData& pSD, MemoryRegion& pRegion) const; private: GNULDBackend& m_Backend; const LinkerConfig& m_Config; }; template<> uint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const; template<> uint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const; } // namespace of mcld #endif