Home | History | Annotate | Download | only in mcld
      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 
     72   const InputBuilder& getInputBuilder() const { return m_InputBuilder; }
     73   InputBuilder&       getInputBuilder()       { return m_InputBuilder; }
     74   const Module& getModule() const { return m_Module; }
     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