ELFObjectWriter.h revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
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
19namespace mcld {
20
21class Module;
22class LinkerConfig;
23class GNULDBackend;
24class FragmentLinker;
25class Relocation;
26class LDSection;
27class SectionData;
28class RelocData;
29class Output;
30class MemoryRegion;
31class 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 */
38class ELFObjectWriter : public ObjectWriter
39{
40public:
41  typedef uint64_t FileOffset;
42
43public:
44  ELFObjectWriter(GNULDBackend& pBackend,
45                  const LinkerConfig& pConfig);
46
47  ~ELFObjectWriter();
48
49  llvm::error_code writeObject(Module& pModule, MemoryArea& pOutput);
50
51private:
52  void writeSection(MemoryArea& pOutput, LDSection *section);
53
54  GNULDBackend&       target()        { return m_Backend; }
55
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>
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
121private:
122  GNULDBackend& m_Backend;
123
124  const LinkerConfig& m_Config;
125};
126
127template<>
128uint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const;
129
130template<>
131uint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const;
132
133} // namespace of mcld
134
135#endif
136
137