ARMLDBackend.h revision a6c24dff8b7fa2551a3a885e77a2e814f5b764a2
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
20namespace mcld {
21
22class ARMELFAttributeData;
23class GNUInfo;
24class LinkerConfig;
25
26//===----------------------------------------------------------------------===//
27/// ARMGNULDBackend - linker backend of ARM target of GNU ELF format
28///
29class 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
107  LDSymbol* getGOTSymbol() { return m_pGOTSymbol; }
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
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
162  size_t getRelEntrySize() { return 8; }
163
164  /// getRelEntrySize - the size in BYTE of rela type relocation
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