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