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_LD_ELFOBJECTWRITER_H_
10 #define MCLD_LD_ELFOBJECTWRITER_H_
11 #include "mcld/LD/ObjectWriter.h"
12 #include "mcld/Support/FileOutputBuffer.h"
13 
14 #include <cassert>
15 
16 namespace mcld {
17 
18 class EhFrame;
19 class GNULDBackend;
20 class LDSection;
21 class LinkerConfig;
22 class Module;
23 class RelocData;
24 class SectionData;
25 
26 /** \class ELFObjectWriter
27  *  \brief ELFObjectWriter writes the target-independent parts of object files.
28  *  ELFObjectWriter reads a MCLDFile and writes into raw_ostream
29  *
30  */
31 class ELFObjectWriter : public ObjectWriter {
32  public:
33   ELFObjectWriter(GNULDBackend& pBackend, const LinkerConfig& pConfig);
34 
35   ~ELFObjectWriter();
36 
37   std::error_code writeObject(Module& pModule, FileOutputBuffer& pOutput);
38 
39   size_t getOutputSize(const Module& pModule) const;
40 
41  private:
42   void writeSection(Module& pModule,
43                     FileOutputBuffer& pOutput,
44                     LDSection* section);
45 
target()46   const GNULDBackend& target() const { return m_Backend; }
target()47   GNULDBackend& target() { return m_Backend; }
48 
49   // writeELFHeader - emit ElfXX_Ehdr
50   template <size_t SIZE>
51   void writeELFHeader(const LinkerConfig& pConfig,
52                       const Module& pModule,
53                       FileOutputBuffer& pOutput) const;
54 
55   uint64_t getEntryPoint(const LinkerConfig& pConfig,
56                          const Module& pModule) const;
57 
58   // emitSectionHeader - emit ElfXX_Shdr
59   template <size_t SIZE>
60   void emitSectionHeader(const Module& pModule,
61                          const LinkerConfig& pConfig,
62                          FileOutputBuffer& pOutput) const;
63 
64   // emitProgramHeader - emit ElfXX_Phdr
65   template <size_t SIZE>
66   void emitProgramHeader(FileOutputBuffer& pOutput) const;
67 
68   // emitShStrTab - emit .shstrtab
69   void emitShStrTab(const LDSection& pShStrTab,
70                     const Module& pModule,
71                     FileOutputBuffer& pOutput);
72 
73   void emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const;
74 
75   void emitEhFrame(Module& pModule,
76                    EhFrame& pFrame,
77                    MemoryRegion& pRegion) const;
78 
79   void emitRelocation(const LinkerConfig& pConfig,
80                       const LDSection& pSection,
81                       MemoryRegion& pRegion) const;
82 
83   // emitRel - emit ElfXX_Rel
84   template <size_t SIZE>
85   void emitRel(const LinkerConfig& pConfig,
86                const RelocData& pRelocData,
87                MemoryRegion& pRegion) const;
88 
89   // emitRela - emit ElfXX_Rela
90   template <size_t SIZE>
91   void emitRela(const LinkerConfig& pConfig,
92                 const RelocData& pRelocData,
93                 MemoryRegion& pRegion) const;
94 
95   // getSectEntrySize - compute ElfXX_Shdr::sh_entsize
96   template <size_t SIZE>
97   uint64_t getSectEntrySize(const LDSection& pSection) const;
98 
99   // getSectLink - compute ElfXX_Shdr::sh_link
100   uint64_t getSectLink(const LDSection& pSection,
101                        const LinkerConfig& pConfig) const;
102 
103   // getSectInfo - compute ElfXX_Shdr::sh_info
104   uint64_t getSectInfo(const LDSection& pSection) const;
105 
106   template <size_t SIZE>
getLastStartOffset(const Module & pModule)107   uint64_t getLastStartOffset(const Module& pModule) const {
108     assert(0 && "Call invalid ELFObjectWriter::getLastStartOffset");
109     return 0;
110   }
111 
112   void emitSectionData(const SectionData& pSD, MemoryRegion& pRegion) const;
113 
114  private:
115   GNULDBackend& m_Backend;
116 
117   const LinkerConfig& m_Config;
118 };
119 
120 template <>
121 uint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const;
122 
123 template <>
124 uint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const;
125 
126 }  // namespace mcld
127 
128 #endif  // MCLD_LD_ELFOBJECTWRITER_H_
129