1//===- IRBuilder.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// IRBuilder is a class used as a convenient way to create MCLinker sections
11// with a consistent and simplified interface.
12//
13//===----------------------------------------------------------------------===//
14#ifndef MCLD_IRBUILDER_H
15#define MCLD_IRBUILDER_H
16
17#include <mcld/MC/Input.h>
18#include <mcld/MC/InputBuilder.h>
19
20#include <mcld/LD/LDSection.h>
21#include <mcld/LD/EhFrame.h>
22#include <mcld/LD/LDSymbol.h>
23
24#include <mcld/Fragment/Fragment.h>
25#include <mcld/Fragment/Relocation.h>
26#include <mcld/Fragment/RegionFragment.h>
27#include <mcld/Fragment/FillFragment.h>
28#include <mcld/Fragment/FragmentRef.h>
29
30#include <mcld/Support/Path.h>
31#include <mcld/Support/FileHandle.h>
32
33namespace mcld {
34
35class Module;
36class LinkerConfig;
37class InputTree;
38
39/** \class IRBuilder
40 *  \brief IRBuilder provides an uniform API for creating sections and
41 *  inserting them into a input file.
42 *
43 *  Ahead-of-time virtual machines (VM) usually compiles an intermediate
44 *  language into a system-dependent binary.  IRBuilder helps such kind of VMs
45 *  to emit binaries in native object format, such as ELF or MachO.
46 */
47class IRBuilder
48{
49public:
50  enum ObjectFormat {
51    ELF,
52    MachO,
53    COFF
54  };
55
56  enum SymbolDefinePolicy {
57    Force,
58    AsReferred
59  };
60
61  enum SymbolResolvePolicy {
62    Unresolve,
63    Resolve
64  };
65
66public:
67  IRBuilder(Module& pModule, const LinkerConfig& pConfig);
68
69  ~IRBuilder();
70
71  const InputBuilder& getInputBuilder() const { return m_InputBuilder; }
72  InputBuilder&       getInputBuilder()       { return m_InputBuilder; }
73  const Module& getModule() const { return m_Module; }
74  Module&       getModule()       { return m_Module; }
75
76/// @}
77/// @name Input Files On The Command Line
78/// @{
79
80  /// CreateInput - To create an input file and append it to the input tree.
81  /// This function is like to add an input file in the command line.
82  ///
83  /// There are four types of the input files:
84  ///   - relocatable objects,
85  ///   - shared objects,
86  ///   - archives,
87  ///   - and user-defined objects.
88  ///
89  /// If Input::Unknown type is given, MCLinker will automatically
90  /// open and read the input file, and create sections of the input. Otherwise,
91  /// users need to manually create sections by IRBuilder.
92  ///
93  /// @see mcld::Input
94  ///
95  /// @param pName [in] The name of the input file.
96  /// @param pPath [in] The path of the input file.
97  /// @param pType [in] The type of the input file. MCLinker will parse the
98  ///                   input file to create sections only if pType is
99  ///                   Input::Unknown.
100  /// @return the created mcld::Input.
101  Input* CreateInput(const std::string& pName,
102                     const sys::fs::Path& pPath,
103                     Input::Type pType);
104
105  /// ReadInput - To read an input file and append it to the input tree.
106  /// This function is like to add an input file in the command line.
107  ///
108  /// This funciton is equal to call
109  ///   @ref IRBuilder::CreateInput(pName, pPath, Input::Unknown);
110  ///
111  /// MCLinker will automatically open and read the input file, and create
112  /// sections of the input.
113  ///
114  /// @see mcld::Input
115  ///
116  /// @param pName [in] The name of the input file.
117  /// @param pPath [in] The path of the input file.
118  /// @return the created mcld::Input.
119  Input* ReadInput(const std::string& pName, const sys::fs::Path& pPath);
120
121  /// ReadInput - To read an input file and append it to the input tree.
122  ///
123  /// This function is equal to -l option. This function tells MCLinker to
124  /// search for lib[pNameSpec].so or lib[pNameSpec].a in the search path.
125  ///
126  /// @param pNameSpec [in] The namespec of the input file.
127  /// @return the created mcld::Input.
128  Input* ReadInput(const std::string& pNameSpec);
129
130  /// ReadInput - To read an input file and append it to the input tree.
131  /// Another way to open file manually. Use MCLinker's mcld::FileHandle.
132  Input* ReadInput(FileHandle& pFileHandle);
133
134  /// ReadInput - To read an input file and append it to the input tree.
135  ///
136  /// This function is like to add an input in the command line.
137  ///
138  /// This function tells MCLinker to read pRawMemory as an image of an object
139  /// file. So far, MCLinekr only supports ELF object format, but it will
140  /// support various object formats in the future. MCLinker relies triple to
141  /// know the object format of pRawMemory.
142  /// @param [in] pName      The name of the input file
143  /// @param [in] pRawMemory An image of object file
144  /// @param [in] pSize      The size of the memory
145  /// @return The created mcld::Input
146  Input* ReadInput(const std::string& pName, void* pRawMemory, size_t pSize);
147
148  /// StartGroup - Add an opening tag of group.
149  ///
150  /// This function is equal to --start-group option. This function tells
151  /// MCLinker to create a new archive group and to add the following archives
152  /// in the created group. The archives in a group are searched repeatedly
153  /// until no new undefined references are created.
154  bool StartGroup();
155
156  /// EndGroup - Add a closing tag of group.
157  ///
158  /// This function is equal to --end-group option. This function tells
159  /// MCLinker to stop adding following archives in the created group.
160  bool EndGroup();
161
162/// @}
163/// @name Positional Options On The Command Line
164/// @{
165
166  /// WholeArchive - Append a --whole-archive option on the command line
167  ///
168  /// This function is equal to --whole-archive option. This function tells
169  /// MCLinker to include every object files in the following archives.
170  void WholeArchive();
171
172  /// NoWholeArchive - Append a --no-whole-archive option on the command line.
173  ///
174  /// This function is equal to --no-whole-archive option. This function tells
175  /// MCLinker to stop including every object files in the following archives.
176  /// Only used object files in the following archives are included.
177  void NoWholeArchive();
178
179  /// AsNeeded - Append a --as-needed option on the command line.
180  ///
181  /// This function is equal to --as-needed option. This function tells
182  /// MCLinker to not add a DT_NEEDED tag in .dynamic sections for the
183  /// following shared objects that are not really used. MCLinker will add tags
184  //  only for the following shared objects which is really used.
185  void AsNeeded();
186
187  /// NoAsNeeded - Append a --no-as-needed option on the command line.
188  ///
189  /// This function is equal to --no-as-needed option. This function tells
190  /// MCLinker to add a DT_NEEDED tag in .dynamic section for every shared
191  /// objects that is created after this option.
192  void NoAsNeeded();
193
194  /// CopyDTNeeded - Append a --add-needed option on the command line.
195  ///
196  /// This function is equal to --add-needed option. This function tells
197  /// NCLinker to copy all DT_NEEDED tags of every following shared objects
198  /// to the output file.
199  void CopyDTNeeded();
200
201  /// NoCopyDTNeeded - Append a --no-add-needed option on the command line.
202  ///
203  /// This function is equal to --no-add-needed option. This function tells
204  /// MCLinker to stop copying all DT_NEEDS tags in the following shared
205  /// objects to the output file.
206  void NoCopyDTNeeded();
207
208  /// AgainstShared - Append a -Bdynamic option on the command line.
209  ///
210  /// This function is equal to -Bdynamic option. This function tells MCLinker
211  /// to search shared objects before archives for the following namespec.
212  void AgainstShared();
213
214  /// AgainstStatic - Append a -static option on the command line.
215  ///
216  /// This function is equal to -static option. This function tells MCLinker to
217  /// search archives before shared objects for the following namespec.
218  void AgainstStatic();
219
220/// @}
221/// @name Input Methods
222/// @{
223
224  /// CreateELFHeader - To create and append a section header in the input file
225  ///
226  /// @param OF     [in]      The file format. @see ObjectFormat
227  /// @param pInput [in, out] The input file.
228  /// @param pName  [in]      The name of the section.
229  /// @param pType  [in]      The meaning of the content in the section. The
230  ///                         value is format-dependent. In ELF, the value is
231  ///                         SHT_* in normal.
232  /// @param pFlag  [in]      The format-dependent flag. In ELF, the value is
233  ///                         SHF_* in normal.
234  /// @param pAlign [in]      The alignment constraint of the section
235  /// @return The created section header.
236  static LDSection* CreateELFHeader(Input& pInput,
237                                    const std::string& pName,
238                                    uint32_t pType,
239                                    uint32_t pFlag,
240                                    uint32_t pAlign);
241
242  /// CreateSectionData - To create a section data for given pSection.
243  /// @param [in, out] pSection The given LDSection. It can be in either an
244  ///         input or the output.
245  ///         pSection.getSectionData() is set to a valid section data.
246  /// @return The created section data. If the pSection already has section
247  ///         data, or if the pSection's type should not have a section data
248  ///         (.eh_frame or relocation data), then an assertion occurs.
249  static SectionData* CreateSectionData(LDSection& pSection);
250
251  /// CreateRelocData - To create a relocation data for given pSection.
252  /// @param [in, out] pSection The given LDSection. It can be in either an
253  ///         input or the output.
254  ///         pSection.getRelocData() is set to a valid relocation data.
255  /// @return The created relocation data. If the pSection already has
256  ///         relocation data, or if the pSection's type is not
257  ///         LDFileFormat::Relocation, then an assertion occurs.
258  static RelocData* CreateRelocData(LDSection &pSection);
259
260  /// CreateEhFrame - To create a eh_frame for given pSection
261  /// @param [in, out] pSection The given LDSection. It can be in either an
262  ///         input or the output.
263  ///         pSection.getEhFrame() is set to a valid eh_frame.
264  /// @return The created eh_frame. If the pSection already has eh_frame data,
265  ///         or if the pSection's type is not LDFileFormat::EhFrame, then an
266  ///         assertion occurs.
267  static EhFrame* CreateEhFrame(LDSection& pSection);
268
269  /// CreateBSS - To create a bss section for given pSection
270  /// @param [in, out] pSection The given LDSection. It can be in either an
271  ///         input or the output.
272  ///         pSection.getSectionData() is set to a valid section data and
273  ///         contains a fillment fragment whose size is pSection.size().
274  /// @return The create section data. It the pSection already has a section
275  ///         data, or if the pSection's type is not LDFileFormat::BSS, then
276  ///         an assertion occurs.
277  static SectionData* CreateBSS(LDSection& pSection);
278
279  /// CreateRegion - To create a region fragment in the input file.
280  /// This function tells MCLinker to read a piece of data from the input
281  /// file, and to create a region fragment that carries the data. The data
282  /// will be deallocated automatically when pInput is destroyed.
283  ///
284  /// @param pInput  [in, out] The input file.
285  /// @param pOffset [in]      The starting file offset of the data
286  /// @param pLength [in]      The number of bytes of the data
287  /// @return If pLength is zero or failing to request a region, return a
288  ///         FillFragment.
289  static Fragment* CreateRegion(Input& pInput, size_t pOffset, size_t pLength);
290
291  /// CreateRegion - To create a region fragment wrapping the given memory.
292  /// This function tells MCLinker to create a region fragment by the data
293  /// directly. Since the data is given from outside, not read from the input
294  /// file, users should deallocated the data manually.
295  ///
296  /// @param pMemory [in] The start address of the given data
297  /// @param pLength [in] The number of bytes of the data
298  /// @return If pLength is zero or failing to request a region, return a
299  ///         FillFragment.
300  static Fragment* CreateRegion(void* pMemory, size_t pLength);
301
302  /// AppendFragment - To append pFrag to the given SectionData pSD.
303  /// This function tells MCLinker to append a fragment to section data, and
304  /// update size of the section header.
305  ///
306  /// @note In order to keep the alignment of pFrag, This function inserts an
307  /// AlignFragment before pFrag if the section header's alignment is larger
308  /// than 1.
309  /// @note This function does not update offset of section headers.
310  ///
311  /// @param pFrag [in, out] The appended fragment. Its offset is set as the
312  ///                        section offset in pSD.
313  /// @param pSD   [in, out] The section data. Size of the header is also
314  ///                        updated.
315  /// @return Total size of the inserted fragments.
316  static uint64_t AppendFragment(Fragment& pFrag, SectionData& pSD);
317
318  /// AppendRelocation - To append a relocation to a relocation data.
319  /// This function tells MCLinker to add a general relocation to the
320  /// relocation data. This function does not update offset and size of section
321  /// headers.
322  ///
323  /// @param pReloc [in]      The appended relocation.
324  /// @param pRD    [in, out] The relocation data being appended.
325  static void AppendRelocation(Relocation& pRelocation, RelocData& pRD);
326
327  /// AppendEhFrame - To append a fragment to a EhFrame.
328  /// @note In order to keep the alignment of pFrag, This function inserts an
329  /// AlignFragment before pFrag if the section header's alignment is larger
330  /// than 1.
331  /// @note This function also update size of the section header, but does not
332  /// update header's offset.
333  ///
334  /// @param pFrag    [in, out] The appended fragment.
335  /// @param pEhFrame [in, out] The EhFrame.
336  /// @return Total size of the inserted fragments.
337  static uint64_t AppendEhFrame(Fragment& pFrag, EhFrame& pEhFrame);
338
339  /// AppendEhFrame - To append a FDE to the given EhFrame pEhFram.
340  /// @note In order to keep the alignment of pFrag, This function inserts an
341  /// AlignFragment before pFrag if the section header's alignment is larger
342  /// than 1.
343  /// @note This function also update size of the section header, but does not
344  /// update header's offset.
345  ///
346  /// @param [in, out] pFDE The appended FDE entry.
347  /// @param [in, out] pEhFrame The eh_frame being appended.
348  /// @return Total size of the inserted fragments.
349  static uint64_t AppendEhFrame(EhFrame::FDE& pFDE, EhFrame& pEhFrame);
350
351  /// AppendEhFrame - To append a CIE to the given EhFrame pEhFram.
352  /// @note In order to keep the alignment of pFrag, This function inserts an
353  /// AlignFragment before pFrag if the section header's alignment is larger
354  /// than 1.
355  /// @note This function also update size of the section header, but does not
356  /// update header's offset.
357  ///
358  /// @param [in, out] pCIE The appended CIE entry.
359  /// @param [in, out] pEhFrame The eh_frame being appended.
360  /// @return Total size of the inserted fragments.
361  static uint64_t AppendEhFrame(EhFrame::CIE& pCIE, EhFrame& pEhFrame);
362
363  /// AddSymbol - To add a symbol to the input file.
364  /// This function create a new symbol and insert it into the input file. If
365  /// mcld::Module has another symbol with the same name, then this function
366  /// resolves these two symbols and keeps one in mcld::Module by their
367  /// attributes.
368  ///
369  /// This is a general method for all kinds of symbol.
370  ///
371  /// @param [in, out] pInput   The input file. Either a relocatable or dynamic
372  ///                           object
373  /// @param [in]      pName    The name of the symbol
374  /// @param [in]      pType    What the symbol refers to. May be a object,
375  ///                           function, no-type and so on. @see ResolveInfo
376  /// @param [in]      pDesc    { Undefined, Define, Common, Indirect }
377  /// @param [in]      pBind    { Global, Weak, Local, Absolute }
378  /// @param [in]      pSize    The size of the symbol. Bigger common symbols
379  ///                           overrides the smaller common symbols.
380  /// @param [in]      pValue   Common symbols' value are alignment constraints
381  ///                           Undefined symbols don't have value.
382  ///                           The rest symbols' value are relative section
383  ///                           offset.
384  /// @param [in]      pSection Absolute, undefined, common symbols do not have
385  ///                           pSection. Keep their pSection be NULL.
386  /// @oaram [in]      pVis     The visibility of the symbol
387  ///
388  /// @return The added symbol. If the insertion fails due to the resoluction,
389  /// return NULL.
390  LDSymbol* AddSymbol(Input& pInput,
391                      const std::string& pName,
392                      ResolveInfo::Type pType,
393                      ResolveInfo::Desc pDesc,
394                      ResolveInfo::Binding pBind,
395                      ResolveInfo::SizeType pSize,
396                      LDSymbol::ValueType pValue = 0x0,
397                      LDSection* pSection = NULL,
398                      ResolveInfo::Visibility pVis = ResolveInfo::Default);
399
400  /// AddSymbol - To add a symbol in mcld::Module
401  /// This function create a new symbol and insert it into mcld::Module.
402  ///
403  /// @tparam POLICY idicate the condition to define or not to define the
404  /// symbol.
405  ///   - AsRefered
406  ///     - Define a symbol only if mcld::Module contains a symbol with
407  ///       identical name. If mcld::Module does not have any symbol with
408  ///       the same name, this function returns NULL.
409  ///
410  ///   - Force
411  ///     - Define a symbol no matter mcld::Module has a symbol with identical
412  ///       name or not.
413  ///
414  /// @tparam RESOLVE indicate the method to define a symbol. If we must define
415  /// a symbol in mcld::Module, then how to define it.
416  ///
417  ///   - Resolve
418  ///      - Follow the symbol resolution rule to bind the symbol references.
419  ///        Resolution of the symbols with idential name depends on their
420  ///        attributes.
421  ///
422  ///   - Unresolve
423  ///      - Forcefully override the symbol in mcld::Module.  With this
424  ///        argument, AddSymbol function turns a blind eye to symbol
425  ///        resolution rules.
426  ///
427  /// @param [in] pName    The name of the symbol
428  /// @param [in] pType    The type of the symbol
429  /// @param [in] pDesc    The description of the symbol, Could be one of
430  ///                      { Undefined, Define, Common, Indirect }
431  /// @param [in] pBinding The binding of the symbol. Could be one of
432  ///                      { Global, Weak, Local, Absolute }
433  ///
434  /// @return The symbol kept in mcld::Module.
435  template<SymbolDefinePolicy POLICY, SymbolResolvePolicy RESOLVE>
436  LDSymbol* AddSymbol(const llvm::StringRef& pName,
437                      ResolveInfo::Type pType,
438                      ResolveInfo::Desc pDesc,
439                      ResolveInfo::Binding pBinding,
440                      ResolveInfo::SizeType pSize = 0,
441                      LDSymbol::ValueType pValue = 0x0,
442                      FragmentRef* pFragmentRef = FragmentRef::Null(),
443                      ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
444
445  /// AddRelocation - To add a relocation entry
446  ///
447  /// @param [in] pSection The relocation section. pSection's link should point to
448  ///                      the target section.
449  /// @param [in] pType    The type of the relocation (target dependent)
450  /// @param [in] pSym     The symbol should be the symbol in the input file.
451  /// @param [in] pOffset  The offset of target section.
452  /// @param [in] pAddend  Tthe addend value for applying relocation
453  static Relocation* AddRelocation(LDSection& pSection,
454                                   Relocation::Type pType,
455                                   LDSymbol& pSym,
456                                   uint32_t pOffset,
457                                   Relocation::Address pAddend = 0);
458
459  /// shouldForceLocal - The helper function for AddSymbol to check if the
460  /// symbols should be force to local symbols
461  bool shouldForceLocal(const ResolveInfo& pInfo, const LinkerConfig& pConfig);
462
463private:
464  LDSymbol* addSymbolFromObject(const std::string& pName,
465                                ResolveInfo::Type pType,
466                                ResolveInfo::Desc pDesc,
467                                ResolveInfo::Binding pBinding,
468                                ResolveInfo::SizeType pSize,
469                                LDSymbol::ValueType pValue,
470                                FragmentRef* pFragmentRef,
471                                ResolveInfo::Visibility pVisibility);
472
473  LDSymbol* addSymbolFromDynObj(Input& pInput,
474                                const std::string& pName,
475                                ResolveInfo::Type pType,
476                                ResolveInfo::Desc pDesc,
477                                ResolveInfo::Binding pBinding,
478                                ResolveInfo::SizeType pSize,
479                                LDSymbol::ValueType pValue,
480                                ResolveInfo::Visibility pVisibility);
481
482private:
483  Module& m_Module;
484  const LinkerConfig& m_Config;
485
486  InputBuilder m_InputBuilder;
487};
488
489template<> LDSymbol*
490IRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
491                         const llvm::StringRef& pName,
492                         ResolveInfo::Type pType,
493                         ResolveInfo::Desc pDesc,
494                         ResolveInfo::Binding pBinding,
495                         ResolveInfo::SizeType pSize,
496                         LDSymbol::ValueType pValue,
497                         FragmentRef* pFragmentRef,
498                         ResolveInfo::Visibility pVisibility);
499
500template<> LDSymbol*
501IRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
502                         const llvm::StringRef& pName,
503                         ResolveInfo::Type pType,
504                         ResolveInfo::Desc pDesc,
505                         ResolveInfo::Binding pBinding,
506                         ResolveInfo::SizeType pSize,
507                         LDSymbol::ValueType pValue,
508                         FragmentRef* pFragmentRef,
509                         ResolveInfo::Visibility pVisibility);
510
511template<> LDSymbol*
512IRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
513                         const llvm::StringRef& pName,
514                         ResolveInfo::Type pType,
515                         ResolveInfo::Desc pDesc,
516                         ResolveInfo::Binding pBinding,
517                         ResolveInfo::SizeType pSize,
518                         LDSymbol::ValueType pValue,
519                         FragmentRef* pFragmentRef,
520                         ResolveInfo::Visibility pVisibility);
521
522template<> LDSymbol*
523IRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
524                         const llvm::StringRef& pName,
525                         ResolveInfo::Type pType,
526                         ResolveInfo::Desc pDesc,
527                         ResolveInfo::Binding pBinding,
528                         ResolveInfo::SizeType pSize,
529                         LDSymbol::ValueType pValue,
530                         FragmentRef* pFragmentRef,
531                         ResolveInfo::Visibility pVisibility);
532
533} // end of namespace mcld
534
535#endif
536