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
37namespace mcld {
38
39class TargetLDBackend;
40class MCLDInfo;
41class LDSection;
42class LDSectionFactory;
43class SectionData;
44class SectionMap;
45class Output;
46class EhFrame;
47class EhFrameHdr;
48
49/** \class MCLinker
50 *  \brief MCLinker provides a pass to link object files.
51 */
52class MCLinker
53{
54public:
55  enum DefinePolicy
56  {
57    Force,
58    AsRefered
59  };
60
61  enum ResolvePolicy
62  {
63    Unresolve,
64    Resolve
65  };
66
67public:
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
176  Layout& getLayout()
177  { return m_Layout; }
178
179  const Layout& getLayout() const
180  { return m_Layout; }
181
182  bool layout();
183
184  // -----  output symbols  ----- //
185  SymbolCategory& getOutputSymbols()
186  { return m_OutputSymbols; }
187
188  const SymbolCategory& getOutputSymbols() const
189  { return m_OutputSymbols; }
190
191  // -----  capacity  ----- //
192  MCLDInfo& getLDInfo()
193  { return m_LDInfo; }
194
195  const MCLDInfo& getLDInfo() const
196  { return m_LDInfo; }
197
198private:
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);
258private:
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
266private:
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