• 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/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 
33 namespace mcld {
34 
35 class Module;
36 class LinkerConfig;
37 class 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  */
47 class IRBuilder
48 {
49 public:
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 
66 public:
67   IRBuilder(Module& pModule, const LinkerConfig& pConfig);
68 
69   ~IRBuilder();
70 
getInputBuilder()71   const InputBuilder& getInputBuilder() const { return m_InputBuilder; }
getInputBuilder()72   InputBuilder&       getInputBuilder()       { return m_InputBuilder; }
getModule()73   const Module& getModule() const { return m_Module; }
getModule()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 
463 private:
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 
482 private:
483   Module& m_Module;
484   const LinkerConfig& m_Config;
485 
486   InputBuilder m_InputBuilder;
487 };
488 
489 template<> LDSymbol*
490 IRBuilder::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 
500 template<> LDSymbol*
501 IRBuilder::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 
511 template<> LDSymbol*
512 IRBuilder::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 
522 template<> LDSymbol*
523 IRBuilder::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