1 //===- HexagonLDBackend.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_HEXAGON_HEXAGONLDBACKEND_H_
10 #define TARGET_HEXAGON_HEXAGONLDBACKEND_H_
11 
12 #include "HexagonELFDynamic.h"
13 #include "HexagonGOT.h"
14 #include "HexagonPLT.h"
15 #include "HexagonGOTPLT.h"
16 #include "mcld/IRBuilder.h"
17 #include "mcld/LinkerConfig.h"
18 #include "mcld/LD/LDSection.h"
19 #include "mcld/Object/ObjectBuilder.h"
20 #include "mcld/Target/GNULDBackend.h"
21 #include "mcld/Target/OutputRelocSection.h"
22 
23 namespace mcld {
24 
25 class HexagonGNUInfo;
26 class LinkerConfig;
27 
28 //===----------------------------------------------------------------------===//
29 /// HexagonLDBackend - linker backend of Hexagon target of GNU ELF format
30 ///
31 class HexagonLDBackend : public GNULDBackend {
32  public:
33   HexagonLDBackend(const LinkerConfig& pConfig, HexagonGNUInfo* pInfo);
34 
35   ~HexagonLDBackend();
36 
37   uint32_t machine() const;
38 
39   HexagonGOT& getGOT();
40 
41   const HexagonGOT& getGOT() const;
42 
43   HexagonPLT& getPLT();
44 
45   const HexagonPLT& getPLT() const;
46 
47   /// preLayout - Backend can do any needed modification before layout
48   void doPreLayout(IRBuilder& pBuilder);
49 
50   bool allocateCommonSymbols(Module& pModule);
51 
52   /// postLayout - Backend can do any needed modification after layout
53   void doPostLayout(Module& pModule, IRBuilder& pBuilder);
54 
55   /// dynamic - the dynamic section of the target machine.
56   /// Use co-variant return type to return its own dynamic section.
57   HexagonELFDynamic& dynamic();
58 
59   /// dynamic - the dynamic section of the target machine.
60   /// Use co-variant return type to return its own dynamic section.
61   const HexagonELFDynamic& dynamic() const;
62 
63   /// emitSectionData - write out the section data into the memory region.
64   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
65   /// call back target backend to emit the data.
66   ///
67   /// Backends handle the target-special tables (plt, gp,...) by themselves.
68   /// Backend can put the data of the tables in MCSectionData directly
69   ///  - LDSection.getSectionData can get the section data.
70   /// Or, backend can put the data into special data structure
71   ///  - backend can maintain its own map<LDSection, table> to get the table
72   /// from given LDSection.
73   ///
74   /// @param pSection - the given LDSection
75   /// @param pLayout - for comouting the size of fragment
76   /// @param pRegion - the region to write out data
77   /// @return the size of the table in the file.
78   uint64_t emitSectionData(const LDSection& pSection,
79                            MemoryRegion& pRegion) const;
80 
81   /// initRelocator - create and initialize Relocator.
82   bool initRelocator();
83 
84   /// getRelocator - return relocator.
85   const Relocator* getRelocator() const;
86   Relocator* getRelocator();
87 
getSymDesc(uint16_t shndx)88   ResolveInfo::Desc getSymDesc(uint16_t shndx) const {
89     if (shndx >= llvm::ELF::SHN_HEXAGON_SCOMMON &&
90         shndx <= llvm::ELF::SHN_HEXAGON_SCOMMON_8)
91       return ResolveInfo::Common;
92     return ResolveInfo::NoneDesc;
93   }
94 
95   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
96 
97   void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
98 
99   bool initBRIslandFactory();
100 
101   bool initStubFactory();
102 
mayRelax()103   bool mayRelax() { return true; }
104 
105   bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
106 
107   bool initTargetStubs();
108 
109   OutputRelocSection& getRelaDyn();
110 
111   const OutputRelocSection& getRelaDyn() const;
112 
113   HexagonGOTPLT& getGOTPLT();
114 
115   const HexagonGOTPLT& getGOTPLT() const;
116 
117   OutputRelocSection& getRelaPLT();
118 
119   const OutputRelocSection& getRelaPLT() const;
120 
121   /// getTargetSectionOrder - compute the layout order of Hexagon target section
122   unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
123 
124   /// finalizeTargetSymbols - finalize the symbol value
125   bool finalizeTargetSymbols();
126 
127   /// mergeSection - merge target dependent sections
128   bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection);
129 
130   /// readSection - read target dependent sections
131   bool readSection(Input& pInput, SectionData& pSD);
132 
133   bool MoveCommonData(SectionData& pFrom, SectionData& pTo);
134 
135   bool MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo);
136 
137   bool SetSDataSection();
138 
getGP()139   uint32_t getGP() { return m_psdata->addr(); }
140 
getCopyRelType()141   Relocation::Type getCopyRelType() const { return m_CopyRel; }
142 
getGOTSymbolAddr()143   virtual uint32_t getGOTSymbolAddr() { return m_pGOTSymbol->value(); }
144 
145  protected:
146   void defineGOTSymbol(IRBuilder& pBuilder, Fragment&);
147 
148  private:
149   /// getRelEntrySize - the size in BYTE of rela type relocation
getRelEntrySize()150   size_t getRelEntrySize() { return 0; }
151 
152   /// getRelaEntrySize - the size in BYTE of rela type relocation
getRelaEntrySize()153   size_t getRelaEntrySize() { return 12; }
154 
155   /// doCreateProgramHdrs - backend can implement this function to create the
156   /// target-dependent segments
157   void doCreateProgramHdrs(Module& pModule);
158 
159   /// maxFwdBranchOffset
maxFwdBranchOffset()160   int64_t maxFwdBranchOffset() const { return ~(~0U << 6); }
161 
162   virtual void setGOTSectionSize(IRBuilder& pBuilder);
163 
164   virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
165 
166   virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
167                                          const ELFFileFormat* FileFormat) const;
168 
169   virtual void setRelaDynSize();
170   virtual void setRelaPLTSize();
171 
172  private:
173   Relocator* m_pRelocator;
174   HexagonGOT* m_pGOT;
175   HexagonGOTPLT* m_pGOTPLT;
176   HexagonPLT* m_pPLT;
177   /// m_RelaDyn - dynamic relocation table of .rela.dyn
178   OutputRelocSection* m_pRelaDyn;
179   /// m_RelaPLT - dynamic relocation table of .rela.plt
180   OutputRelocSection* m_pRelaPLT;
181 
182   HexagonELFDynamic* m_pDynamic;
183 
184   LDSection* m_psdata;
185   LDSection* m_pscommon_1;
186   LDSection* m_pscommon_2;
187   LDSection* m_pscommon_4;
188   LDSection* m_pscommon_8;
189   LDSection* m_pstart;
190   LDSymbol* m_psdabase;
191 
192   LDSymbol* m_pGOTSymbol;
193   LDSymbol* m_pBSSEnd;
194   Relocation::Type m_CopyRel;
195 };
196 
197 }  // namespace mcld
198 
199 #endif  // TARGET_HEXAGON_HEXAGONLDBACKEND_H_
200