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