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
16namespace mcld {
17
18class EhFrame;
19class GNULDBackend;
20class LDSection;
21class LinkerConfig;
22class Module;
23class RelocData;
24class 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 */
31class 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
46  const GNULDBackend& target() const { return m_Backend; }
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>
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
120template <>
121uint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const;
122
123template <>
124uint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const;
125
126}  // namespace mcld
127
128#endif  // MCLD_LD_ELFOBJECTWRITER_H_
129