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 TARGET_ARM_ARMLDBACKEND_H_
10 #define TARGET_ARM_ARMLDBACKEND_H_
11 
12 #include "ARMELFDynamic.h"
13 #include "ARMException.h"
14 #include "ARMGOT.h"
15 #include "ARMPLT.h"
16 #include "mcld/LD/LDSection.h"
17 #include "mcld/Target/GNULDBackend.h"
18 #include "mcld/Target/OutputRelocSection.h"
19 
20 namespace mcld {
21 
22 class ARMELFAttributeData;
23 class GNUInfo;
24 class LinkerConfig;
25 
26 //===----------------------------------------------------------------------===//
27 /// ARMGNULDBackend - linker backend of ARM target of GNU ELF format
28 ///
29 class ARMGNULDBackend : public GNULDBackend {
30  public:
31   // max branch offsets for ARM, THUMB, and THUMB2
32   static const int32_t ARM_MAX_FWD_BRANCH_OFFSET = ((((1 << 23) - 1) << 2) + 8);
33   static const int32_t ARM_MAX_BWD_BRANCH_OFFSET = ((-((1 << 23) << 2)) + 8);
34   static const int32_t THM_MAX_FWD_BRANCH_OFFSET = ((1 << 22) - 2 + 4);
35   static const int32_t THM_MAX_BWD_BRANCH_OFFSET = (-(1 << 22) + 4);
36   static const int32_t THM2_MAX_FWD_BRANCH_OFFSET = (((1 << 24) - 2) + 4);
37   static const int32_t THM2_MAX_BWD_BRANCH_OFFSET = (-(1 << 24) + 4);
38 
39  public:
40   ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
41   ~ARMGNULDBackend();
42 
43  public:
44   typedef std::vector<llvm::ELF::Elf32_Dyn*> ELF32DynList;
45 
46  public:
47   /// initTargetSections - initialize target dependent sections in output.
48   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
49 
50   /// initTargetSymbols - initialize target dependent symbols in output.
51   void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
52 
53   /// initRelocator - create and initialize Relocator.
54   bool initRelocator();
55 
56   /// getRelocator - return relocator.
57   const Relocator* getRelocator() const;
58   Relocator* getRelocator();
59 
60   /// doPreLayout - Backend can do any needed modification before layout
61   void doPreLayout(IRBuilder& pBuilder);
62 
63   /// doPostLayout -Backend can do any needed modification after layout
64   void doPostLayout(Module& pModule, IRBuilder& pBuilder);
65 
66   /// dynamic - the dynamic section of the target machine.
67   /// Use co-variant return type to return its own dynamic section.
68   ARMELFDynamic& dynamic();
69 
70   /// dynamic - the dynamic section of the target machine.
71   /// Use co-variant return type to return its own dynamic section.
72   const ARMELFDynamic& dynamic() const;
73 
74   /// emitSectionData - write out the section data into the memory region.
75   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
76   /// call back target backend to emit the data.
77   ///
78   /// Backends handle the target-special tables (plt, gp,...) by themselves.
79   /// Backend can put the data of the tables in SectionData directly
80   ///  - LDSection.getSectionData can get the section data.
81   /// Or, backend can put the data into special data structure
82   ///  - backend can maintain its own map<LDSection, table> to get the table
83   /// from given LDSection.
84   ///
85   /// @param pSection - the given LDSection
86   /// @param pConfig - all options in the command line.
87   /// @param pRegion - the region to write out data
88   /// @return the size of the table in the file.
89   uint64_t emitSectionData(const LDSection& pSection,
90                            MemoryRegion& pRegion) const;
91 
92   ARMGOT& getGOT();
93   const ARMGOT& getGOT() const;
94 
95   ARMPLT& getPLT();
96   const ARMPLT& getPLT() const;
97 
98   OutputRelocSection& getRelDyn();
99   const OutputRelocSection& getRelDyn() const;
100 
101   OutputRelocSection& getRelPLT();
102   const OutputRelocSection& getRelPLT() const;
103 
104   ARMELFAttributeData& getAttributeData();
105   const ARMELFAttributeData& getAttributeData() const;
106 
getGOTSymbol()107   LDSymbol* getGOTSymbol() { return m_pGOTSymbol; }
getGOTSymbol()108   const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; }
109 
110   /// getTargetSectionOrder - compute the layout order of ARM target sections
111   unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
112 
113   /// finalizeTargetSymbols - finalize the symbol value
114   bool finalizeTargetSymbols();
115 
116   /// preMergeSections - hooks to be executed before merging sections
117   virtual void preMergeSections(Module& pModule);
118 
119   /// postMergeSections - hooks to be executed after merging sections
120   virtual void postMergeSections(Module& pModule);
121 
122   /// mergeSection - merge target dependent sections
123   bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection);
124 
125   /// setUpReachedSectionsForGC - set the reference from section XXX to
126   /// .ARM.exidx.XXX to make sure GC correctly handle section exidx
127   void setUpReachedSectionsForGC(
128       const Module& pModule,
129       GarbageCollection::SectionReachedListMap& pSectReachedListMap) const;
130 
131   /// readSection - read target dependent sections
132   bool readSection(Input& pInput, SectionData& pSD);
133 
134   /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
135   /// function pointer access
136   bool mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) const;
137 
138  private:
139   void defineGOTSymbol(IRBuilder& pBuilder);
140 
141   /// maxFwdBranchOffset
142   int64_t maxFwdBranchOffset();
143   /// maxBwdBranchOffset
144   int64_t maxBwdBranchOffset();
145 
146   /// mayRelax - Backends should override this function if they need relaxation
mayRelax()147   bool mayRelax() { return true; }
148 
149   /// relax - the relaxation pass
150   virtual bool relax(Module& pModule, IRBuilder& pBuilder);
151 
152   /// doRelax - Backend can orevride this function to add its relaxation
153   /// implementation. Return true if the output (e.g., .text) is "relaxed"
154   /// (i.e. layout is changed), and set pFinished to true if everything is fit,
155   /// otherwise set it to false.
156   bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
157 
158   /// initTargetStubs
159   bool initTargetStubs();
160 
161   /// getRelEntrySize - the size in BYTE of rel type relocation
getRelEntrySize()162   size_t getRelEntrySize() { return 8; }
163 
164   /// getRelEntrySize - the size in BYTE of rela type relocation
getRelaEntrySize()165   size_t getRelaEntrySize() {
166     assert(0 && "ARM backend with Rela type relocation\n");
167     return 12;
168   }
169 
170   /// doCreateProgramHdrs - backend can implement this function to create the
171   /// target-dependent segments
172   virtual void doCreateProgramHdrs(Module& pModule);
173 
174   /// scanInputExceptionSections - scan exception-related input sections in
175   /// the Module, build the ARMExData, and reclaim GC'ed sections
176   void scanInputExceptionSections(Module& pModule);
177 
178   /// scanInputExceptionSections - scan exception-related input sections in
179   /// the Input, build the ARMInputExMap, and reclaim GC'ed sections
180   void scanInputExceptionSections(Module& pModule, Input& pInput);
181 
182   /// rewriteExceptionSection - rewrite the output .ARM.exidx section.
183   void rewriteARMExIdxSection(Module& pModule);
184 
185  private:
186   Relocator* m_pRelocator;
187 
188   ARMGOT* m_pGOT;
189   ARMPLT* m_pPLT;
190   /// m_RelDyn - dynamic relocation table of .rel.dyn
191   OutputRelocSection* m_pRelDyn;
192   /// m_RelPLT - dynamic relocation table of .rel.plt
193   OutputRelocSection* m_pRelPLT;
194 
195   /// m_pAttrData - attribute data in public ("aeabi") attribute subsection
196   ARMELFAttributeData* m_pAttrData;
197 
198   ARMELFDynamic* m_pDynamic;
199   LDSymbol* m_pGOTSymbol;
200   LDSymbol* m_pEXIDXStart;
201   LDSymbol* m_pEXIDXEnd;
202 
203   //     variable name           :  ELF
204   LDSection* m_pEXIDX;       // .ARM.exidx
205   LDSection* m_pEXTAB;       // .ARM.extab
206   LDSection* m_pAttributes;  // .ARM.attributes
207   //  LDSection* m_pPreemptMap;      // .ARM.preemptmap
208   //  LDSection* m_pDebugOverlay;    // .ARM.debug_overlay
209   //  LDSection* m_pOverlayTable;    // .ARM.overlay_table
210 
211   // m_ExData - exception handling section data structures
212   ARMExData m_ExData;
213 };
214 }  // namespace mcld
215 
216 #endif  // TARGET_ARM_ARMLDBACKEND_H_
217