X86LDBackend.h revision 37b74a387bb3993387029859c2d9d051c41c724e
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 TARGET_X86_X86LDBACKEND_H_
10#define TARGET_X86_X86LDBACKEND_H_
11
12#include "X86ELFDynamic.h"
13#include "X86GOT.h"
14#include "X86GOTPLT.h"
15#include "X86PLT.h"
16
17#include "mcld/LD/LDSection.h"
18#include "mcld/Target/GNULDBackend.h"
19#include "mcld/Target/OutputRelocSection.h"
20
21namespace mcld {
22
23class LinkerConfig;
24class GNUInfo;
25
26//===----------------------------------------------------------------------===//
27/// X86GNULDBackend - linker backend of X86 target of GNU ELF format
28///
29class X86GNULDBackend : public GNULDBackend {
30 public:
31  X86GNULDBackend(const LinkerConfig& pConfig,
32                  GNUInfo* pInfo,
33                  Relocation::Type pCopyRel);
34
35  ~X86GNULDBackend();
36
37  uint32_t machine() const;
38
39  X86PLT& getPLT();
40
41  const X86PLT& getPLT() const;
42
43  /// preLayout - Backend can do any needed modification before layout
44  void doPreLayout(IRBuilder& pBuilder);
45
46  /// postLayout -Backend can do any needed modification after layout
47  void doPostLayout(Module& pModule, IRBuilder& pBuilder);
48
49  /// dynamic - the dynamic section of the target machine.
50  /// Use co-variant return type to return its own dynamic section.
51  X86ELFDynamic& dynamic();
52
53  /// dynamic - the dynamic section of the target machine.
54  /// Use co-variant return type to return its own dynamic section.
55  const X86ELFDynamic& dynamic() const;
56
57  /// emitSectionData - write out the section data into the memory region.
58  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
59  /// call back target backend to emit the data.
60  ///
61  /// Backends handle the target-special tables (plt, gp,...) by themselves.
62  /// Backend can put the data of the tables in MCSectionData directly
63  ///  - LDSection.getSectionData can get the section data.
64  /// Or, backend can put the data into special data structure
65  ///  - backend can maintain its own map<LDSection, table> to get the table
66  /// from given LDSection.
67  ///
68  /// @param pSection - the given LDSection
69  /// @param pLayout - for comouting the size of fragment
70  /// @param pRegion - the region to write out data
71  /// @return the size of the table in the file.
72  uint64_t emitSectionData(const LDSection& pSection,
73                           MemoryRegion& pRegion) const;
74
75  /// initRelocator - create and initialize Relocator.
76  virtual bool initRelocator() = 0;
77
78  /// getRelocator - return relocator.
79  const Relocator* getRelocator() const;
80  Relocator* getRelocator();
81
82  virtual void initTargetSections(Module& pModule, ObjectBuilder& pBuilder) = 0;
83
84  void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
85
86  OutputRelocSection& getRelDyn();
87  const OutputRelocSection& getRelDyn() const;
88
89  OutputRelocSection& getRelPLT();
90  const OutputRelocSection& getRelPLT() const;
91
92  LDSymbol* getGOTSymbol() { return m_pGOTSymbol; }
93  const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; }
94
95  /// getTargetSectionOrder - compute the layout order of X86 target sections
96  unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
97
98  /// finalizeTargetSymbols - finalize the symbol value
99  bool finalizeTargetSymbols();
100
101  /// getPointerRel - get pointer relocation type.
102  Relocation::Type getPointerRel() { return m_PointerRel; }
103
104  Relocation::Type getCopyRelType() const { return m_CopyRel; }
105  Relocation::Type getPointerRelType() const { return m_PointerRel; }
106
107 protected:
108  void defineGOTSymbol(IRBuilder& pBuilder, Fragment&);
109
110  /// getRelEntrySize - the size in BYTE of rel type relocation
111  size_t getRelEntrySize() { return m_RelEntrySize; }
112
113  /// getRelEntrySize - the size in BYTE of rela type relocation
114  size_t getRelaEntrySize() { return m_RelaEntrySize; }
115
116 private:
117  /// doCreateProgramHdrs - backend can implement this function to create the
118  /// target-dependent segments
119  void doCreateProgramHdrs(Module& pModule);
120
121  virtual void setGOTSectionSize(IRBuilder& pBuilder) = 0;
122
123  virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const = 0;
124
125  virtual uint64_t emitGOTPLTSectionData(
126      MemoryRegion& pRegion,
127      const ELFFileFormat* FileFormat) const = 0;
128
129  virtual void setRelDynSize() = 0;
130  virtual void setRelPLTSize() = 0;
131
132  void addEhFrameForPLT(Module& pModule);
133  virtual llvm::StringRef createCIERegionForPLT() = 0;
134  virtual llvm::StringRef createFDERegionForPLT() = 0;
135
136 protected:
137  Relocator* m_pRelocator;
138  X86PLT* m_pPLT;
139  /// m_RelDyn - dynamic relocation table of .rel.dyn
140  OutputRelocSection* m_pRelDyn;
141  /// m_RelPLT - dynamic relocation table of .rel.plt
142  OutputRelocSection* m_pRelPLT;
143
144  X86ELFDynamic* m_pDynamic;
145  LDSymbol* m_pGOTSymbol;
146
147  size_t m_RelEntrySize;
148  size_t m_RelaEntrySize;
149
150  Relocation::Type m_CopyRel;
151  Relocation::Type m_PointerRel;
152};
153
154//
155//===----------------------------------------------------------------------===//
156/// X86_32GNULDBackend - linker backend of X86-32 target of GNU ELF format
157///
158class X86_32GNULDBackend : public X86GNULDBackend {
159 public:
160  X86_32GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
161
162  ~X86_32GNULDBackend();
163
164  void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
165
166  X86_32GOT& getGOT();
167
168  const X86_32GOT& getGOT() const;
169
170  X86_32GOTPLT& getGOTPLT();
171
172  const X86_32GOTPLT& getGOTPLT() const;
173
174 private:
175  /// initRelocator - create and initialize Relocator.
176  bool initRelocator();
177
178  void setGOTSectionSize(IRBuilder& pBuilder);
179
180  uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
181
182  uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
183                                 const ELFFileFormat* FileFormat) const;
184
185  void setRelDynSize();
186  void setRelPLTSize();
187
188  llvm::StringRef createCIERegionForPLT();
189  llvm::StringRef createFDERegionForPLT();
190
191 private:
192  X86_32GOT* m_pGOT;
193  X86_32GOTPLT* m_pGOTPLT;
194};
195
196//
197//===----------------------------------------------------------------------===//
198/// X86_64GNULDBackend - linker backend of X86-64 target of GNU ELF format
199///
200class X86_64GNULDBackend : public X86GNULDBackend {
201 public:
202  X86_64GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
203
204  ~X86_64GNULDBackend();
205
206  void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
207
208  X86_64GOT& getGOT();
209
210  const X86_64GOT& getGOT() const;
211
212  X86_64GOTPLT& getGOTPLT();
213
214  const X86_64GOTPLT& getGOTPLT() const;
215
216 private:
217  /// initRelocator - create and initialize Relocator.
218  bool initRelocator();
219
220  void setGOTSectionSize(IRBuilder& pBuilder);
221
222  uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
223
224  uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
225                                 const ELFFileFormat* FileFormat) const;
226
227  void setRelDynSize();
228  void setRelPLTSize();
229
230  llvm::StringRef createCIERegionForPLT();
231  llvm::StringRef createFDERegionForPLT();
232
233 private:
234  X86_64GOT* m_pGOT;
235  X86_64GOTPLT* m_pGOTPLT;
236};
237
238}  // namespace mcld
239
240#endif  // TARGET_X86_X86LDBACKEND_H_
241