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