• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 namespace mcld {
20 
21 //===----------------------------------------------------------------------===//
22 /// X86GNULDBackend - linker backend of X86 target of GNU ELF format
23 ///
24 class X86GNULDBackend : public GNULDBackend
25 {
26 public:
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 
isLittleEndian()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
OSABI()132   uint8_t OSABI() const
133   { return llvm::ELF::ELFOSABI_NONE; }
134 
135   /// ABIVersion - the value of e_ident[EI_ABIVRESION]
136   /// FIXME
ABIVersion()137   uint8_t ABIVersion() const
138   { return 0x0; }
139 
140   /// flags - the value of ElfXX_Ehdr::e_flags
141   /// FIXME
flags()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 
188 public:
189   bool isSymbolPreemptible(const ResolveInfo& pSym,
190                            const MCLDInfo& pLDInfo,
191                            const Output& pOutput) const;
192 
193 private:
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 
224 private:
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 /**
241 class X86MachOLDBackend : public DarwinX86LDBackend
242 {
243 public:
244   X86MachOLDBackend();
245   ~X86MachOLDBackend();
246 
247 private:
248   MCMachOTargetArchiveReader *createTargetArchiveReader() const;
249   MCMachOTargetObjectReader *createTargetObjectReader() const;
250   MCMachOTargetObjectWriter *createTargetObjectWriter() const;
251 
252 };
253 **/
254 } // namespace of mcld
255 
256 #endif
257