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