1//===- X86LDBackend.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 X86_LDBACKEND_H
10#define X86_LDBACKEND_H
11
12#include "X86ELFDynamic.h"
13#include "X86GOT.h"
14#include "X86GOTPLT.h"
15#include "X86PLT.h"
16#include <mcld/LD/LDSection.h>
17#include <mcld/Target/GNULDBackend.h>
18#include <mcld/Target/OutputRelocSection.h>
19
20namespace mcld {
21
22//===----------------------------------------------------------------------===//
23/// X86GNULDBackend - linker backend of X86 target of GNU ELF format
24///
25class X86GNULDBackend : public GNULDBackend
26{
27public:
28  /** \enum ReservedEntryType
29   *  \brief The reserved entry type of reserved space in ResolveInfo.
30   *
31   *  This is used for sacnRelocation to record what kinds of entries are
32   *  reserved for this resolved symbol
33   *
34   *  In X86, there are three kinds of entries, GOT, PLT, and dynamic reloction.
35   *  GOT may needs a corresponding relocation to relocate itself, so we
36   *  separate GOT to two situations: GOT and GOTRel. Besides, for the same
37   *  symbol, there might be two kinds of entries reserved for different location.
38   *  For example, reference to the same symbol, one may use GOT and the other may
39   *  use dynamic relocation.
40   *
41   *  bit:  3       2      1     0
42   *   | PLT | GOTRel | GOT | Rel |
43   *
44   *  value    Name         - Description
45   *
46   *  0000     None         - no reserved entry
47   *  0001     ReserveRel   - reserve an dynamic relocation entry
48   *  0010     ReserveGOT   - reserve an GOT entry
49   *  0011     GOTandRel    - For different relocation, we've reserved GOT and
50   *                          Rel for different location.
51   *  0100     GOTRel       - reserve an GOT entry and the corresponding Dyncamic
52   *                          relocation entry which relocate this GOT entry
53   *  0101     GOTRelandRel - For different relocation, we've reserved GOTRel
54   *                          and relocation entry for different location.
55   *  1000     ReservePLT   - reserve an PLT entry and the corresponding GOT,
56   *                          Dynamic relocation entries
57   *  1001     PLTandRel    - For different relocation, we've reserved PLT and
58   *                          Rel for different location.
59   */
60  enum ReservedEntryType {
61    None         = 0,
62    ReserveRel   = 1,
63    ReserveGOT   = 2,
64    GOTandRel    = 3,
65    GOTRel       = 4,
66    GOTRelandRel = 5,
67    ReservePLT   = 8,
68    PLTandRel    = 9
69  };
70
71  X86GNULDBackend();
72
73  ~X86GNULDBackend();
74
75  RelocationFactory* getRelocFactory();
76
77  uint32_t machine() const;
78
79  bool isLittleEndian() const
80  { return true; }
81
82  X86GOT& getGOT();
83
84  const X86GOT& getGOT() const;
85
86  X86GOTPLT& getGOTPLT();
87
88  const X86GOTPLT& getGOTPLT() const;
89
90  X86PLT& getPLT();
91
92  const X86PLT& getPLT() const;
93
94  unsigned int bitclass() const;
95
96  /// preLayout - Backend can do any needed modification before layout
97  void doPreLayout(const Output& pOutput,
98                   const MCLDInfo& pInfo,
99                   MCLinker& pLinker);
100
101  /// postLayout -Backend can do any needed modification after layout
102  void doPostLayout(const Output& pOutput,
103                    const MCLDInfo& pInfo,
104                    MCLinker& pLinker);
105
106  /// dynamic - the dynamic section of the target machine.
107  /// Use co-variant return type to return its own dynamic section.
108  X86ELFDynamic& dynamic();
109
110  /// dynamic - the dynamic section of the target machine.
111  /// Use co-variant return type to return its own dynamic section.
112  const X86ELFDynamic& dynamic() const;
113
114  /// emitSectionData - write out the section data into the memory region.
115  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
116  /// call back target backend to emit the data.
117  ///
118  /// Backends handle the target-special tables (plt, gp,...) by themselves.
119  /// Backend can put the data of the tables in MCSectionData directly
120  ///  - LDSection.getSectionData can get the section data.
121  /// Or, backend can put the data into special data structure
122  ///  - backend can maintain its own map<LDSection, table> to get the table
123  /// from given LDSection.
124  ///
125  /// @param pOutput - the output file
126  /// @param pSection - the given LDSection
127  /// @param pInfo - all options in the command line.
128  /// @param pLayout - for comouting the size of fragment
129  /// @param pRegion - the region to write out data
130  /// @return the size of the table in the file.
131  uint64_t emitSectionData(const Output& pOutput,
132                           const LDSection& pSection,
133                           const MCLDInfo& pInfo,
134                           const Layout& pLayout,
135                           MemoryRegion& pRegion) const;
136
137  /// OSABI - the value of e_ident[EI_OSABI]
138  /// FIXME
139  uint8_t OSABI() const
140  { return llvm::ELF::ELFOSABI_NONE; }
141
142  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
143  /// FIXME
144  uint8_t ABIVersion() const
145  { return 0x0; }
146
147  /// flags - the value of ElfXX_Ehdr::e_flags
148  /// FIXME
149  uint64_t flags() const
150  { return 0x0; }
151
152  uint64_t defaultTextSegmentAddr() const
153  { return 0x08048000; }
154
155  /// initTargetSectionMap - initialize target dependent section mapping
156  bool initTargetSectionMap(SectionMap& pSectionMap);
157
158  // initRelocFactory - create and initialize RelocationFactory
159  bool initRelocFactory(const MCLinker& pLinker);
160
161  void initTargetSections(MCLinker& pLinker);
162
163  void initTargetSymbols(MCLinker& pLinker, const Output& pOutput);
164
165  /// scanRelocation - determine the empty entries are needed or not and create
166  /// the empty entries if needed.
167  /// For X86, following entries are check to create:
168  /// - GOT entry (for .got and .got.plt sections)
169  /// - PLT entry (for .plt section)
170  /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections)
171  void scanRelocation(Relocation& pReloc,
172                      const LDSymbol& pInputSym,
173                      MCLinker& pLinker,
174                      const MCLDInfo& pLDInfo,
175                      const Output& pOutput,
176                      const LDSection& pSection);
177
178  OutputRelocSection& getRelDyn();
179
180  const OutputRelocSection& getRelDyn() const;
181
182  OutputRelocSection& getRelPLT();
183
184  const OutputRelocSection& getRelPLT() const;
185
186  /// getTargetSectionOrder - compute the layout order of X86 target sections
187  unsigned int getTargetSectionOrder(const Output& pOutput,
188                                     const LDSection& pSectHdr,
189                                     const MCLDInfo& pInfo) const;
190
191  /// finalizeTargetSymbols - finalize the symbol value
192  bool finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput);
193
194private:
195  void scanLocalReloc(Relocation& pReloc,
196                      const LDSymbol& pInputSym,
197                      MCLinker& pLinker,
198                      const MCLDInfo& pLDInfo,
199                      const Output& pOutput);
200
201  void scanGlobalReloc(Relocation& pReloc,
202                       const LDSymbol& pInputSym,
203                       MCLinker& pLinker,
204                       const MCLDInfo& pLDInfo,
205                       const Output& pOutput);
206
207  /// addCopyReloc - add a copy relocation into .rel.dyn for pSym
208  /// @param pSym - A resolved copy symbol that defined in BSS section
209  void addCopyReloc(ResolveInfo& pSym);
210
211  /// defineSymbolforCopyReloc - allocate a space in BSS section and
212  /// and force define the copy of pSym to BSS section
213  /// @return the output LDSymbol of the copy symbol
214  LDSymbol& defineSymbolforCopyReloc(MCLinker& pLinker,
215                                     const ResolveInfo& pSym);
216
217  void updateAddend(Relocation& pReloc,
218                    const LDSymbol& pInputSym,
219                    const Layout& pLayout) const;
220
221  void createX86GOT(MCLinker& pLinker, const Output& pOutput);
222  void createX86GOTPLT(MCLinker& pLinker, const Output& pOutput);
223  void createX86PLTandRelPLT(MCLinker& pLinker, const Output& pOutput);
224  void createX86RelDyn(MCLinker& pLinker, const Output& pOutput);
225
226private:
227  RelocationFactory* m_pRelocFactory;
228  X86GOT* m_pGOT;
229  X86PLT* m_pPLT;
230  X86GOTPLT* m_pGOTPLT;
231  /// m_RelDyn - dynamic relocation table of .rel.dyn
232  OutputRelocSection* m_pRelDyn;
233  /// m_RelPLT - dynamic relocation table of .rel.plt
234  OutputRelocSection* m_pRelPLT;
235
236  X86ELFDynamic* m_pDynamic;
237  LDSymbol* m_pGOTSymbol;
238};
239
240//===----------------------------------------------------------------------===//
241/// X86MachOLDBackend - linker backend of X86 target of MachO format
242///
243/**
244class X86MachOLDBackend : public DarwinX86LDBackend
245{
246public:
247  X86MachOLDBackend();
248  ~X86MachOLDBackend();
249
250private:
251  MCMachOTargetArchiveReader *createTargetArchiveReader() const;
252  MCMachOTargetObjectReader *createTargetObjectReader() const;
253  MCMachOTargetObjectWriter *createTargetObjectWriter() const;
254
255};
256**/
257} // namespace of mcld
258
259#endif
260
261