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