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