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