• 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, const Output& pOutput);
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                       const LDSection& pSection);
109 
machine()110   uint32_t machine() const
111   { return llvm::ELF::EM_ARM; }
112 
113   /// OSABI - the value of e_ident[EI_OSABI]
OSABI()114   virtual uint8_t OSABI() const
115   { return llvm::ELF::ELFOSABI_NONE; }
116 
117   /// ABIVersion - the value of e_ident[EI_ABIVRESION]
ABIVersion()118   virtual uint8_t ABIVersion() const
119   { return 0x0; }
120 
121   /// flags - the value of ElfXX_Ehdr::e_flags
flags()122   virtual uint64_t flags() const
123   { return (llvm::ELF::EF_ARM_EABIMASK & 0x05000000); }
124 
isLittleEndian()125   bool isLittleEndian() const
126   { return true; }
127 
bitclass()128   unsigned int bitclass() const
129   { return 32; }
130 
defaultTextSegmentAddr()131   uint64_t defaultTextSegmentAddr() const
132   { return 0x8000; }
133 
134   /// doPreLayout - Backend can do any needed modification before layout
135   void doPreLayout(const Output& pOutput,
136                    const MCLDInfo& pInfo,
137                    MCLinker& pLinker);
138 
139   /// doPostLayout -Backend can do any needed modification after layout
140   void doPostLayout(const Output& pOutput,
141                     const MCLDInfo& pInfo,
142                     MCLinker& pLinker);
143 
144   /// dynamic - the dynamic section of the target machine.
145   /// Use co-variant return type to return its own dynamic section.
146   ARMELFDynamic& dynamic();
147 
148   /// dynamic - the dynamic section of the target machine.
149   /// Use co-variant return type to return its own dynamic section.
150   const ARMELFDynamic& dynamic() const;
151 
152 
153   /// emitSectionData - write out the section data into the memory region.
154   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
155   /// call back target backend to emit the data.
156   ///
157   /// Backends handle the target-special tables (plt, gp,...) by themselves.
158   /// Backend can put the data of the tables in SectionData directly
159   ///  - LDSection.getSectionData can get the section data.
160   /// Or, backend can put the data into special data structure
161   ///  - backend can maintain its own map<LDSection, table> to get the table
162   /// from given LDSection.
163   ///
164   /// @param pOutput - the output file
165   /// @param pSection - the given LDSection
166   /// @param pInfo - all options in the command line.
167   /// @param pLayout - for comouting the size of fragment
168   /// @param pRegion - the region to write out data
169   /// @return the size of the table in the file.
170   uint64_t emitSectionData(const Output& pOutput,
171                            const LDSection& pSection,
172                            const MCLDInfo& pInfo,
173                            const Layout& pLayout,
174                            MemoryRegion& pRegion) const;
175 
176   ARMGOT& getGOT();
177 
178   const ARMGOT& getGOT() const;
179 
180   ARMPLT& getPLT();
181 
182   const ARMPLT& getPLT() const;
183 
184   OutputRelocSection& getRelDyn();
185 
186   const OutputRelocSection& getRelDyn() const;
187 
188   OutputRelocSection& getRelPLT();
189 
190   const OutputRelocSection& getRelPLT() const;
191 
192   /// getTargetSectionOrder - compute the layout order of ARM target sections
193   unsigned int getTargetSectionOrder(const Output& pOutput,
194                                      const LDSection& pSectHdr,
195                                      const MCLDInfo& pInfo) const;
196 
197   /// finalizeTargetSymbols - finalize the symbol value
198   bool finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput);
199 
200   /// readSection - read target dependent sections
201   bool readSection(Input& pInput,
202                    MCLinker& pLinker,
203                    LDSection& pInputSectHdr);
204 
205 private:
206   void scanLocalReloc(Relocation& pReloc,
207                       const LDSymbol& pInputSym,
208                       MCLinker& pLinker,
209                       const MCLDInfo& pLDInfo,
210                       const Output& pOutput);
211 
212   void scanGlobalReloc(Relocation& pReloc,
213                        const LDSymbol& pInputSym,
214                        MCLinker& pLinker,
215                        const MCLDInfo& pLDInfo,
216                        const Output& pOutput);
217 
218   void checkValidReloc(Relocation& pReloc,
219                        const MCLDInfo& pLDInfo,
220                        const Output& pOutput) const;
221 
222   /// addCopyReloc - add a copy relocation into .rel.dyn for pSym
223   /// @param pSym - A resolved copy symbol that defined in BSS section
224   void addCopyReloc(ResolveInfo& pSym);
225 
226   /// defineSymbolforCopyReloc - allocate a space in BSS section and
227   /// and force define the copy of pSym to BSS section
228   /// @return the output LDSymbol of the copy symbol
229   LDSymbol& defineSymbolforCopyReloc(MCLinker& pLinker,
230                                      const ResolveInfo& pSym);
231 
232   /// updateAddend - update addend value of the relocation if the
233   /// the target symbol is a section symbol. Addend is the offset
234   /// in the section. This value should be updated after section
235   /// merged.
236   void updateAddend(Relocation& pReloc,
237                     const LDSymbol& pInputSym,
238                     const Layout& pLayout) const;
239 
240   void createARMGOT(MCLinker& pLinker, const Output& pOutput);
241 
242   /// createARMPLTandRelPLT - create PLT and RELPLT sections.
243   /// Because in ELF sh_info in .rel.plt is the shndx of .plt, these two
244   /// sections should be create together.
245   void createARMPLTandRelPLT(MCLinker& pLinker, const Output& pOutput);
246 
247   void createARMRelDyn(MCLinker& pLinker, const Output& pOutput);
248 
249 private:
250   RelocationFactory* m_pRelocFactory;
251   ARMGOT* m_pGOT;
252   ARMPLT* m_pPLT;
253   /// m_RelDyn - dynamic relocation table of .rel.dyn
254   OutputRelocSection* m_pRelDyn;
255   /// m_RelPLT - dynamic relocation table of .rel.plt
256   OutputRelocSection* m_pRelPLT;
257 
258   ARMELFDynamic* m_pDynamic;
259   LDSymbol* m_pGOTSymbol;
260 
261   //     variable name           :  ELF
262   LDSection* m_pEXIDX;           // .ARM.exidx
263   LDSection* m_pEXTAB;           // .ARM.extab
264   LDSection* m_pAttributes;      // .ARM.attributes
265 //  LDSection* m_pPreemptMap;      // .ARM.preemptmap
266 //  LDSection* m_pDebugOverlay;    // .ARM.debug_overlay
267 //  LDSection* m_pOverlayTable;    // .ARM.overlay_table
268 };
269 
270 //===----------------------------------------------------------------------===//
271 /// ARMMachOLDBackend - linker backend of ARM target of MachO format
272 ///
273 /**
274 class ARMMachOLDBackend : public DarwinARMLDBackend
275 {
276 public:
277   ARMMachOLDBackend();
278   ~ARMMachOLDBackend();
279 
280 private:
281   MCMachOTargetArchiveReader *createTargetArchiveReader() const;
282   MCMachOTargetObjectReader *createTargetObjectReader() const;
283   MCMachOTargetObjectWriter *createTargetObjectWriter() const;
284 
285 };
286 **/
287 } // namespace of mcld
288 
289 #endif
290 
291