• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- MCLinker.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 //
10 // This file provides a number of APIs used by SectLinker.
11 // These APIs do the things which a linker should do.
12 //
13 //===----------------------------------------------------------------------===//
14 #ifndef MCLD_MCLINKER_H
15 #define MCLD_MCLINKER_H
16 #ifdef ENABLE_UNITTEST
17 #include <gtest.h>
18 #endif
19 
20 #include <set>
21 #include <string>
22 
23 #include <llvm/ADT/ilist.h>
24 
25 #include <mcld/LD/StaticResolver.h>
26 #include <mcld/LD/LDSectionFactory.h>
27 #include <mcld/LD/LDFileFormat.h>
28 #include <mcld/LD/LDContext.h>
29 #include <mcld/LD/Relocation.h>
30 #include <mcld/LD/SectionMerger.h>
31 #include <mcld/LD/Layout.h>
32 #include <mcld/MC/MCLDInput.h>
33 #include <mcld/MC/SymbolCategory.h>
34 #include <mcld/Support/GCFactory.h>
35 #include <mcld/Support/GCFactoryListTraits.h>
36 
37 namespace mcld {
38 
39 class TargetLDBackend;
40 class MCLDInfo;
41 class LDSection;
42 class LDSectionFactory;
43 class SectionData;
44 class SectionMap;
45 class Output;
46 class EhFrame;
47 class EhFrameHdr;
48 
49 /** \class MCLinker
50  *  \brief MCLinker provides a pass to link object files.
51  */
52 class MCLinker
53 {
54 public:
55   enum DefinePolicy
56   {
57     Force,
58     AsRefered
59   };
60 
61   enum ResolvePolicy
62   {
63     Unresolve,
64     Resolve
65   };
66 
67 public:
68   MCLinker(TargetLDBackend& pBackend,
69            MCLDInfo& pLDInfo,
70            SectionMap& pSectionMap);
71 
72   ~MCLinker();
73 
74   // ----- about symbols  ----- //
75   /// addDynSymbol - add a symbol and resolve it immediately
76   template<Input::Type FROM>
77   LDSymbol* addSymbol(const llvm::StringRef& pName,
78                       ResolveInfo::Type pType,
79                       ResolveInfo::Desc pDesc,
80                       ResolveInfo::Binding pBinding,
81                       ResolveInfo::SizeType pSize,
82                       LDSymbol::ValueType pValue,
83                       FragmentRef* pFragmentRef,
84                       ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
85 
86   /// defineSymbol - add a symbol
87   /// defineSymbol define a output symbol
88   ///
89   /// @tparam POLICY idicate how to define the symbol.
90   ///   - Force
91   ///     - Define the symbol forcefully. If the symbol has existed, override
92   ///       it. Otherwise, define it.
93   ///   - AsRefered
94   ///     - If the symbol has existed, override it. Otherwise, return NULL
95   ///       immediately.
96   ///
97   /// @tparam RESOLVE indicate whether to resolve the symbol or not.
98   ///   - Unresolve
99   ///      - Do not resolve the symbol, and override the symbol immediately.
100   ///   - Resolve
101   ///      - Resolve the defined symbol.
102   ///
103   /// @return If the output symbol has existed, return it. Otherwise, create
104   ///         a new symbol and return the new one.
105   template<DefinePolicy POLICY, ResolvePolicy RESOLVE>
106   LDSymbol* defineSymbol(const llvm::StringRef& pName,
107                          bool pIsDyn,
108                          ResolveInfo::Type pType,
109                          ResolveInfo::Desc pDesc,
110                          ResolveInfo::Binding pBinding,
111                          ResolveInfo::SizeType pSize,
112                          LDSymbol::ValueType pValue,
113                          FragmentRef* pFragmentRef,
114                          ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
115 
116   bool finalizeSymbols();
117 
118   // -----  sections  ----- //
119   /// getSectionMap - getSectionMap to change the behavior of SectionMerger
120   /// SectionMap& getSectionMap()
121   /// { return m_SectionMap; }
122 
123   /// createSectHdr - for reader and standard/target format to create a section
124   /// header. This function will create a new LDSection and return it. If the
125   /// output has no related LDSection, this function will also create one and
126   /// push into the output.
127   LDSection& createSectHdr(const std::string& pName,
128                            LDFileFormat::Kind pKind,
129                            uint32_t pType,
130                            uint32_t pFlag);
131 
132   /// getOrCreateOutputSectHdr - for reader and standard/target format to get
133   /// or create the output's section header
134   LDSection& getOrCreateOutputSectHdr(const std::string& pName,
135                                       LDFileFormat::Kind pKind,
136                                       uint32_t pType,
137                                       uint32_t pFlag,
138                                       uint32_t pAlign = 0x0);
139 
140   /// getOrCreateSectData - for reader to map and perform section merging immediately
141   SectionData& getOrCreateSectData(LDSection& pSection);
142 
143   // -----  eh_frame sections  ----- //
144   /// addEhFrame - add an exception handling section
145   /// @param pInput - the Input contains this section
146   /// @param pSection - the input section
147   /// @param pArea - the memory area which pSection is within.
148   uint64_t addEhFrame(const Input& pInput,
149                       LDSection& pSection,
150                       MemoryArea& pArea);
151 
152   // -----  relocations  ----- //
153   /// addRelocation - add a relocation entry in MCLinker (only for object file)
154   /// @param pType - the type of the relocation
155   /// @param pResolveInfo - the symbol should be the symbol in the input file. MCLinker
156   ///                  computes the real applied address by the output symbol.
157   /// @param pFragmentRef - the fragment reference of the applied address.
158   /// @param pAddend - the addend value for applying relocation
159   Relocation* addRelocation(Relocation::Type pType,
160                             const LDSymbol& pSym,
161                             ResolveInfo& pResolveInfo,
162                             FragmentRef& pFragmentRef,
163                             const LDSection& pSection,
164                             Relocation::Address pAddend = 0);
165 
166   /// applyRelocations - apply all relocation enties.
167   bool applyRelocations();
168 
169   /// syncRelocationResult - After applying relocation, write back relocation target
170   /// data to output file.
171   void syncRelocationResult();
172 
173   // -----  layout  ----- //
174   void initSectionMap();
175 
getLayout()176   Layout& getLayout()
177   { return m_Layout; }
178 
getLayout()179   const Layout& getLayout() const
180   { return m_Layout; }
181 
182   bool layout();
183 
184   // -----  output symbols  ----- //
getOutputSymbols()185   SymbolCategory& getOutputSymbols()
186   { return m_OutputSymbols; }
187 
getOutputSymbols()188   const SymbolCategory& getOutputSymbols() const
189   { return m_OutputSymbols; }
190 
191   // -----  capacity  ----- //
getLDInfo()192   MCLDInfo& getLDInfo()
193   { return m_LDInfo; }
194 
getLDInfo()195   const MCLDInfo& getLDInfo() const
196   { return m_LDInfo; }
197 
198 private:
199   LDSymbol* defineSymbolForcefully(const llvm::StringRef& pName,
200                                    bool pIsDyn,
201                                    ResolveInfo::Type pType,
202                                    ResolveInfo::Desc pDesc,
203                                    ResolveInfo::Binding pBinding,
204                                    ResolveInfo::SizeType pSize,
205                                    LDSymbol::ValueType pValue,
206                                    FragmentRef* pFragmentRef,
207                                    ResolveInfo::Visibility pVisibility);
208 
209   LDSymbol* defineAndResolveSymbolForcefully(const llvm::StringRef& pName,
210                                              bool pIsDyn,
211                                              ResolveInfo::Type pType,
212                                              ResolveInfo::Desc pDesc,
213                                              ResolveInfo::Binding pBinding,
214                                              ResolveInfo::SizeType pSize,
215                                              LDSymbol::ValueType pValue,
216                                              FragmentRef* pFragmentRef,
217                                              ResolveInfo::Visibility pVisibility);
218 
219   LDSymbol* defineSymbolAsRefered(const llvm::StringRef& pName,
220                                   bool pIsDyn,
221                                   ResolveInfo::Type pType,
222                                   ResolveInfo::Desc pDesc,
223                                   ResolveInfo::Binding pBinding,
224                                   ResolveInfo::SizeType pSize,
225                                   LDSymbol::ValueType pValue,
226                                   FragmentRef* pFragmentRef,
227                                   ResolveInfo::Visibility pVisibility);
228 
229   LDSymbol* defineAndResolveSymbolAsRefered(const llvm::StringRef& pName,
230                                             bool pIsDyn,
231                                             ResolveInfo::Type pType,
232                                             ResolveInfo::Desc pDesc,
233                                             ResolveInfo::Binding pBinding,
234                                             ResolveInfo::SizeType pSize,
235                                             LDSymbol::ValueType pValue,
236                                             FragmentRef* pFragmentRef,
237                                             ResolveInfo::Visibility pVisibility);
238 
239   bool shouldForceLocal(const ResolveInfo& pInfo) const;
240 
241   LDSymbol* addSymbolFromDynObj(const llvm::StringRef& pName,
242                                 ResolveInfo::Type pType,
243                                 ResolveInfo::Desc pDesc,
244                                 ResolveInfo::Binding pBinding,
245                                 ResolveInfo::SizeType pSize,
246                                 LDSymbol::ValueType pValue,
247                                 FragmentRef* pFragmentRef,
248                                 ResolveInfo::Visibility pVisibility);
249 
250   LDSymbol* addSymbolFromObject(const llvm::StringRef& pName,
251                                 ResolveInfo::Type pType,
252                                 ResolveInfo::Desc pDesc,
253                                 ResolveInfo::Binding pBinding,
254                                 ResolveInfo::SizeType pSize,
255                                 LDSymbol::ValueType pValue,
256                                 FragmentRef* pFragmentRef,
257                                 ResolveInfo::Visibility pVisibility);
258 private:
259   typedef GCFactory<LDSymbol, 0> LDSymbolFactory;
260   typedef GCFactory<SectionData, 0> LDSectionDataFactory;
261   typedef llvm::iplist<Fragment,
262                        GCFactoryListTraits<Fragment> > RelocationListType;
263   typedef std::set<LDSymbol*> ForceLocalSymbolTable;
264   typedef std::vector<LDSymbol*> OutputSymbolTable;
265 
266 private:
267   TargetLDBackend& m_Backend;
268   MCLDInfo& m_LDInfo;
269   SectionMap& m_SectionMap;
270   LDSymbolFactory m_LDSymbolFactory;
271   LDSectionFactory m_LDSectHdrFactory;
272   LDSectionDataFactory m_LDSectDataFactory;
273   SectionMerger* m_pSectionMerger;
274   Layout m_Layout;
275   RelocationListType m_RelocationList;
276   SymbolCategory m_OutputSymbols;
277 };
278 
279 #include "MCLinker.tcc"
280 
281 } // namespace of mcld
282 
283 #endif
284 
285