• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ARMLDBackend.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_ARM_LDBACKEND_H
10 #define MCLD_ARM_LDBACKEND_H
11 
12 #include "ARMELFDynamic.h"
13 #include "ARMGOT.h"
14 #include "ARMPLT.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 class MCLDInfo;
22 class MCLinker;
23 class Output;
24 class SectionMap;
25 
26 
27 //===----------------------------------------------------------------------===//
28 /// ARMGNULDBackend - linker backend of ARM target of GNU ELF format
29 ///
30 class ARMGNULDBackend : public GNULDBackend
31 {
32 public:
33   ARMGNULDBackend();
34   ~ARMGNULDBackend();
35 public:
36   typedef std::vector<llvm::ELF::Elf32_Dyn*> ELF32DynList;
37 
38   /** \enum ReservedEntryType
39    *  \brief The reserved entry type of reserved space in ResolveInfo.
40    *
41    *  This is used for sacnRelocation to record what kinds of entries are
42    *  reserved for this resolved symbol
43    *
44    *  In ARM, there are three kinds of entries, GOT, PLT, and dynamic reloction.
45    *  GOT may needs a corresponding relocation to relocate itself, so we
46    *  separate GOT to two situations: GOT and GOTRel. Besides, for the same
47    *  symbol, there might be two kinds of entries reserved for different location.
48    *  For example, reference to the same symbol, one may use GOT and the other may
49    *  use dynamic relocation.
50    *
51    *  bit:  3       2      1     0
52    *   | PLT | GOTRel | GOT | Rel |
53    *
54    *  value    Name         - Description
55    *
56    *  0000     None         - no reserved entry
57    *  0001     ReserveRel   - reserve an dynamic relocation entry
58    *  0010     ReserveGOT   - reserve an GOT entry
59    *  0011     GOTandRel    - For different relocation, we've reserved GOT and
60    *                          Rel for different location.
61    *  0100     GOTRel       - reserve an GOT entry and the corresponding Dyncamic
62    *                          relocation entry which relocate this GOT entry
63    *  0101     GOTRelandRel - For different relocation, we've reserved GOTRel
64    *                          and relocation entry for different location.
65    *  1000     ReservePLT   - reserve an PLT entry and the corresponding GOT,
66    *                          Dynamic relocation entries
67    *  1001     PLTandRel    - For different relocation, we've reserved PLT and
68    *                          Rel for different location.
69    */
70   enum ReservedEntryType {
71     None         = 0,
72     ReserveRel   = 1,
73     ReserveGOT   = 2,
74     GOTandRel    = 3,
75     GOTRel       = 4,
76     GOTRelandRel = 5,
77     ReservePLT   = 8,
78     PLTandRel    = 9
79   };
80 
81 public:
82   /// initTargetSectionMap - initialize target dependent section mapping
83   bool initTargetSectionMap(SectionMap& pSectionMap);
84 
85   /// initTargetSections - initialize target dependent sections in output.
86   void initTargetSections(MCLinker& pLinker);
87 
88   /// initTargetSymbols - initialize target dependent symbols in output.
89   void initTargetSymbols(MCLinker& pLinker);
90 
91   /// initRelocFactory - create and initialize RelocationFactory
92   bool initRelocFactory(const MCLinker& pLinker);
93 
94   /// getRelocFactory
95   RelocationFactory* getRelocFactory();
96 
97   /// scanRelocation - determine the empty entries are needed or not and create
98   /// the empty entries if needed.
99   /// For ARM, following entries are check to create:
100   /// - GOT entry (for .got section)
101   /// - PLT entry (for .plt section)
102   /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections)
103   void scanRelocation(Relocation& pReloc,
104                       const LDSymbol& pInputSym,
105                       MCLinker& pLinker,
106                       const MCLDInfo& pLDInfo,
107                       const Output& pOutput);
108 
machine()109   uint32_t machine() const
110   { return llvm::ELF::EM_ARM; }
111 
112   /// OSABI - the value of e_ident[EI_OSABI]
OSABI()113   virtual uint8_t OSABI() const
114   { return llvm::ELF::ELFOSABI_NONE; }
115 
116   /// ABIVersion - the value of e_ident[EI_ABIVRESION]
ABIVersion()117   virtual uint8_t ABIVersion() const
118   { return 0x0; }
119 
120   /// flags - the value of ElfXX_Ehdr::e_flags
flags()121   virtual uint64_t flags() const
122   { return (llvm::ELF::EF_ARM_EABIMASK & 0x05000000); }
123 
isLittleEndian()124   bool isLittleEndian() const
125   { return true; }
126 
bitclass()127   unsigned int bitclass() const
128   { return 32; }
129 
130   /// doPreLayout - Backend can do any needed modification before layout
131   void doPreLayout(const Output& pOutput,
132                    const MCLDInfo& pInfo,
133                    MCLinker& pLinker);
134 
135   /// doPostLayout -Backend can do any needed modification after layout
136   void doPostLayout(const Output& pOutput,
137                     const MCLDInfo& pInfo,
138                     MCLinker& pLinker);
139 
140   /// dynamic - the dynamic section of the target machine.
141   /// Use co-variant return type to return its own dynamic section.
142   ARMELFDynamic& dynamic();
143 
144   /// dynamic - the dynamic section of the target machine.
145   /// Use co-variant return type to return its own dynamic section.
146   const ARMELFDynamic& dynamic() const;
147 
148 
149   /// emitSectionData - write out the section data into the memory region.
150   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
151   /// call back target backend to emit the data.
152   ///
153   /// Backends handle the target-special tables (plt, gp,...) by themselves.
154   /// Backend can put the data of the tables in MCSectionData directly
155   ///  - LDSection.getSectionData can get the section data.
156   /// Or, backend can put the data into special data structure
157   ///  - backend can maintain its own map<LDSection, table> to get the table
158   /// from given LDSection.
159   ///
160   /// @param pOutput - the output file
161   /// @param pSection - the given LDSection
162   /// @param pInfo - all options in the command line.
163   /// @param pRegion - the region to write out data
164   /// @return the size of the table in the file.
165   uint64_t emitSectionData(const Output& pOutput,
166                            const LDSection& pSection,
167                            const MCLDInfo& pInfo,
168                            MemoryRegion& pRegion) const;
169 
170   ARMGOT& getGOT();
171 
172   const ARMGOT& getGOT() const;
173 
174   ARMPLT& getPLT();
175 
176   const ARMPLT& getPLT() const;
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 ARM target sections
187   unsigned int getTargetSectionOrder(const Output& pOutput,
188                                      const LDSection& pSectHdr) const;
189 
190   /// finalizeSymbol - finalize the symbol value
191   /// If the symbol's reserved field is not zero, MCLinker will call back this
192   /// function to ask the final value of the symbol
193   bool finalizeSymbol(LDSymbol& pSymbol) const;
194 
195   /// allocateCommonSymbols - allocate common symbols in the corresponding
196   /// sections.
197   bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
198 
199   /// readSection - read target dependent sections
200   bool readSection(Input& pInput,
201                    MCLinker& pLinker,
202                    LDSection& pInputSectHdr);
203 
204 public:
205   bool isSymbolPreemptible(const ResolveInfo& pSym,
206                            const MCLDInfo& pLDInfo,
207                            const Output& pOutput) const;
208 
209   bool isPIC(const MCLDInfo& pLDInfo, const Output& pOutput) const;
210 
211 private:
212   void scanLocalReloc(Relocation& pReloc,
213                       const LDSymbol& pInputSym,
214                       MCLinker& pLinker,
215                       const MCLDInfo& pLDInfo,
216                       const Output& pOutput);
217 
218   void scanGlobalReloc(Relocation& pReloc,
219                        const LDSymbol& pInputSym,
220                        MCLinker& pLinker,
221                        const MCLDInfo& pLDInfo,
222                        const Output& pOutput);
223 
224   bool isSymbolNeedsPLT(const ResolveInfo& pSym,
225                         const MCLDInfo& pLDInfo,
226                         const Output& pOutput) const;
227 
228   bool isSymbolNeedsDynRel(const ResolveInfo& pSym,
229                            const Output& pOutput,
230                            bool isAbsReloc) const;
231 
232 
233   void checkValidReloc(Relocation& pReloc,
234                        const MCLDInfo& pLDInfo,
235                        const Output& pOutput) const;
236 
237   /// updateAddend - update addend value of the relocation if the
238   /// the target symbol is a section symbol. Addend is the offset
239   /// in the section. This value should be updated after section
240   /// merged.
241   void updateAddend(Relocation& pReloc,
242                     const LDSymbol& pInputSym,
243                     const Layout& pLayout) const;
244 
245   void createARMGOT(MCLinker& pLinker, const Output& pOutput);
246 
247   /// createARMPLTandRelPLT - create PLT and RELPLT sections.
248   /// Because in ELF sh_info in .rel.plt is the shndx of .plt, these two
249   /// sections should be create together.
250   void createARMPLTandRelPLT(MCLinker& pLinker, const Output& pOutput);
251 
252   void createARMRelDyn(MCLinker& pLinker, const Output& pOutput);
253 
254   ELFFileFormat* getOutputFormat(const Output& pOutput) const;
255 
256 private:
257   RelocationFactory* m_pRelocFactory;
258   ARMGOT* m_pGOT;
259   ARMPLT* m_pPLT;
260   /// m_RelDyn - dynamic relocation table of .rel.dyn
261   OutputRelocSection* m_pRelDyn;
262   /// m_RelPLT - dynamic relocation table of .rel.plt
263   OutputRelocSection* m_pRelPLT;
264 
265   ARMELFDynamic* m_pDynamic;
266   LDSymbol* m_pGOTSymbol;
267 
268   //     variable name           :  ELF
269   LDSection* m_pEXIDX;           // .ARM.exidx
270   LDSection* m_pEXTAB;           // .ARM.extab
271   LDSection* m_pAttributes;      // .ARM.attributes
272 //  LDSection* m_pPreemptMap;      // .ARM.preemptmap
273 //  LDSection* m_pDebugOverlay;    // .ARM.debug_overlay
274 //  LDSection* m_pOverlayTable;    // .ARM.overlay_table
275 };
276 
277 //===----------------------------------------------------------------------===//
278 /// ARMMachOLDBackend - linker backend of ARM target of MachO format
279 ///
280 /**
281 class ARMMachOLDBackend : public DarwinARMLDBackend
282 {
283 public:
284   ARMMachOLDBackend();
285   ~ARMMachOLDBackend();
286 
287 private:
288   MCMachOTargetArchiveReader *createTargetArchiveReader() const;
289   MCMachOTargetObjectReader *createTargetObjectReader() const;
290   MCMachOTargetObjectWriter *createTargetObjectWriter() const;
291 
292 };
293 **/
294 } // namespace of mcld
295 
296 #endif
297