1 //===- ELFObjectWriter.h --------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #ifndef MCLD_ELF_OBJECT_WRITER_H 10 #define MCLD_ELF_OBJECT_WRITER_H 11 #ifdef ENABLE_UNITTEST 12 #include <gtest.h> 13 #endif 14 #include <mcld/LD/ObjectWriter.h> 15 #include <cassert> 16 17 #include <llvm/Support/system_error.h> 18 19 namespace mcld { 20 21 class Module; 22 class LinkerConfig; 23 class GNULDBackend; 24 class FragmentLinker; 25 class Relocation; 26 class LDSection; 27 class SectionData; 28 class RelocData; 29 class Output; 30 class MemoryRegion; 31 class MemoryArea; 32 33 /** \class ELFObjectWriter 34 * \brief ELFObjectWriter writes the target-independent parts of object files. 35 * ELFObjectWriter reads a MCLDFile and writes into raw_ostream 36 * 37 */ 38 class ELFObjectWriter : public ObjectWriter 39 { 40 public: 41 typedef uint64_t FileOffset; 42 43 public: 44 ELFObjectWriter(GNULDBackend& pBackend, 45 const LinkerConfig& pConfig); 46 47 ~ELFObjectWriter(); 48 49 llvm::error_code writeObject(Module& pModule, MemoryArea& pOutput); 50 51 private: 52 void writeSection(MemoryArea& pOutput, LDSection *section); 53 target()54 GNULDBackend& target() { return m_Backend; } 55 target()56 const GNULDBackend& target() const { return m_Backend; } 57 58 // writeELFHeader - emit ElfXX_Ehdr 59 template<size_t SIZE> 60 void writeELFHeader(const LinkerConfig& pConfig, 61 const Module& pModule, 62 MemoryArea& pOutput) const; 63 64 uint64_t getEntryPoint(const LinkerConfig& pConfig, 65 const Module& pModule) const; 66 67 // emitSectionHeader - emit ElfXX_Shdr 68 template<size_t SIZE> 69 void emitSectionHeader(const Module& pModule, 70 const LinkerConfig& pConfig, 71 MemoryArea& pOutput) const; 72 73 // emitProgramHeader - emit ElfXX_Phdr 74 template<size_t SIZE> 75 void emitProgramHeader(MemoryArea& pOutput) const; 76 77 // emitShStrTab - emit .shstrtab 78 void emitShStrTab(const LDSection& pShStrTab, 79 const Module& pModule, 80 MemoryArea& pOutput); 81 82 void emitSectionData(const LDSection& pSection, 83 MemoryRegion& pRegion) const; 84 85 void emitRelocation(const LinkerConfig& pConfig, 86 const LDSection& pSection, 87 MemoryRegion& pRegion) const; 88 89 // emitRel - emit ElfXX_Rel 90 template<size_t SIZE> 91 void emitRel(const LinkerConfig& pConfig, 92 const RelocData& pRelocData, 93 MemoryRegion& pRegion) const; 94 95 // emitRela - emit ElfXX_Rela 96 template<size_t SIZE> 97 void emitRela(const LinkerConfig& pConfig, 98 const RelocData& pRelocData, 99 MemoryRegion& pRegion) const; 100 101 // getSectEntrySize - compute ElfXX_Shdr::sh_entsize 102 template<size_t SIZE> 103 uint64_t getSectEntrySize(const LDSection& pSection) const; 104 105 // getSectLink - compute ElfXX_Shdr::sh_link 106 uint64_t getSectLink(const LDSection& pSection, 107 const LinkerConfig& pConfig) const; 108 109 // getSectInfo - compute ElfXX_Shdr::sh_info 110 uint64_t getSectInfo(const LDSection& pSection) const; 111 112 template<size_t SIZE> getLastStartOffset(const Module & pModule)113 uint64_t getLastStartOffset(const Module& pModule) const 114 { 115 assert(0 && "Call invalid ELFObjectWriter::getLastStartOffset"); 116 return 0; 117 } 118 119 void emitSectionData(const SectionData& pSD, MemoryRegion& pRegion) const; 120 121 private: 122 GNULDBackend& m_Backend; 123 124 const LinkerConfig& m_Config; 125 }; 126 127 template<> 128 uint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const; 129 130 template<> 131 uint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const; 132 133 } // namespace of mcld 134 135 #endif 136 137