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