Home | History | Annotate | Download | only in MC
      1 //===- MCLinker.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 // This file provides a number of APIs used by SectLinker.
     11 // These APIs do the things which a linker should do.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 #ifndef MCLD_MCLINKER_H
     15 #define MCLD_MCLINKER_H
     16 #ifdef ENABLE_UNITTEST
     17 #include <gtest.h>
     18 #endif
     19 
     20 #include <llvm/ADT/ilist.h>
     21 #include <llvm/MC/MCAssembler.h>
     22 #include <mcld/LD/StrSymPool.h>
     23 #include <mcld/LD/StaticResolver.h>
     24 #include <mcld/LD/LDSectionFactory.h>
     25 #include <mcld/LD/LDFileFormat.h>
     26 #include <mcld/LD/LDContext.h>
     27 #include <mcld/LD/Relocation.h>
     28 #include <mcld/LD/SectionMerger.h>
     29 #include <mcld/LD/Layout.h>
     30 #include <mcld/MC/MCLDInput.h>
     31 #include <mcld/MC/SymbolCategory.h>
     32 #include <mcld/Support/GCFactory.h>
     33 #include <mcld/Support/GCFactoryListTraits.h>
     34 #include <set>
     35 #include <string>
     36 
     37 namespace mcld {
     38 
     39 class TargetLDBackend;
     40 class MCLDInfo;
     41 class LDSection;
     42 class LDSectionFactory;
     43 class SectionMap;
     44 class Output;
     45 
     46 /** \class MCLinker
     47  *  \brief MCLinker provides a pass to link object files.
     48  */
     49 class MCLinker
     50 {
     51 public:
     52   enum DefinePolicy
     53   {
     54     Force,
     55     AsRefered
     56   };
     57 
     58   enum ResolvePolicy
     59   {
     60     Unresolve,
     61     Resolve
     62   };
     63 
     64 public:
     65   MCLinker(TargetLDBackend& pBackend,
     66            MCLDInfo& pLDInfo,
     67            LDContext& pContext,
     68            SectionMap& pSectionMap,
     69            const Resolver& pResolver = StaticResolver());
     70   ~MCLinker();
     71 
     72   // ----- about symbols  ----- //
     73   /// addDynSymbol - add a symbol and resolve it immediately
     74   template<Input::Type FROM>
     75   LDSymbol* addSymbol(const llvm::StringRef& pName,
     76                       ResolveInfo::Type pType,
     77                       ResolveInfo::Desc pDesc,
     78                       ResolveInfo::Binding pBinding,
     79                       ResolveInfo::SizeType pSize,
     80                       LDSymbol::ValueType pValue,
     81                       MCFragmentRef* pFragmentRef,
     82                       ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
     83 
     84   /// defineSymbol - add a symbol
     85   /// defineSymbol define a output symbol
     86   ///
     87   /// @tparam POLICY idicate how to define the symbol.
     88   ///   - Force
     89   ///     - Define the symbol forcefully. If the symbol has existed, override
     90   ///       it. Otherwise, define it.
     91   ///   - AsRefered
     92   ///     - If the symbol has existed, override it. Otherwise, return NULL
     93   ///       immediately.
     94   ///
     95   /// @tparam RESOLVE indicate whether to resolve the symbol or not.
     96   ///   - Unresolve
     97   ///      - Do not resolve the symbol, and override the symbol immediately.
     98   ///   - Resolve
     99   ///      - Resolve the defined symbol.
    100   ///
    101   /// @return If the output symbol has existed, return it. Otherwise, create
    102   ///         a new symbol and return the new one.
    103   template<DefinePolicy POLICY, ResolvePolicy RESOLVE>
    104   LDSymbol* defineSymbol(const llvm::StringRef& pName,
    105                          bool pIsDyn,
    106                          ResolveInfo::Type pType,
    107                          ResolveInfo::Desc pDesc,
    108                          ResolveInfo::Binding pBinding,
    109                          ResolveInfo::SizeType pSize,
    110                          LDSymbol::ValueType pValue,
    111                          MCFragmentRef* pFragmentRef,
    112                          ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
    113 
    114   /// mergeSymbolTable - merge the symbol table and resolve symbols.
    115   ///   Since in current design, MCLinker resolves symbols when reading symbol
    116   ///   tables, this function do nothing.
    117   bool mergeSymbolTable(Input& pInput)
    118   { return true; }
    119 
    120   bool finalizeSymbols();
    121 
    122   // -----  sections  ----- //
    123   /// getSectionMap - getSectionMap to change the behavior of SectionMerger
    124   /// SectionMap& getSectionMap()
    125   /// { return m_SectionMap; }
    126 
    127   /// createSectHdr - for reader and standard/target format to create a section
    128   /// header. This function will create a new LDSection and return it. If the
    129   /// output has no related LDSection, this function will also create one and
    130   /// push into the output.
    131   LDSection& createSectHdr(const std::string& pName,
    132                            LDFileFormat::Kind pKind,
    133                            uint32_t pType,
    134                            uint32_t pFlag);
    135 
    136   /// getOrCreateOutputSectHdr - for reader and standard/target format to get
    137   /// or create the output's section header
    138   LDSection& getOrCreateOutputSectHdr(const std::string& pName,
    139                                       LDFileFormat::Kind pKind,
    140                                       uint32_t pType,
    141                                       uint32_t pFlag,
    142                                       uint32_t pAlign = 0x0);
    143 
    144   /// getOrCreateSectData - for reader to map and perform section merging immediately
    145   llvm::MCSectionData& getOrCreateSectData(LDSection& pSection);
    146 
    147   // -----  relocations ----- //
    148   /// addRelocation - add a relocation entry in MCLinker (only for object file)
    149   /// @param pType - the type of the relocation
    150   /// @param pResolveInfo - the symbol should be the symbol in the input file. MCLinker
    151   ///                  computes the real applied address by the output symbol.
    152   /// @param pFragmentRef - the fragment reference of the applied address.
    153   /// @param pAddend - the addend value for applying relocation
    154   Relocation* addRelocation(Relocation::Type pType,
    155                             const LDSymbol& pSym,
    156                             ResolveInfo& pResolveInfo,
    157                             MCFragmentRef& pFragmentRef,
    158                             Relocation::Address pAddend = 0);
    159 
    160   /// applyRelocations - apply all relocation enties.
    161   bool applyRelocations();
    162 
    163   /// syncRelocationResult - After applying relocation, write back relocation target
    164   /// data to output file.
    165   void syncRelocationResult();
    166 
    167   // -----  layout  ----- //
    168   Layout& getLayout()
    169   { return m_Layout; }
    170 
    171   const Layout& getLayout() const
    172   { return m_Layout; }
    173 
    174   bool layout();
    175 
    176   // -----  output symbols  ----- //
    177   SymbolCategory& getOutputSymbols()
    178   { return m_OutputSymbols; }
    179 
    180   const SymbolCategory& getOutputSymbols() const
    181   { return m_OutputSymbols; }
    182 
    183   // -----  capacity  ----- //
    184   MCLDInfo& getLDInfo()
    185   { return m_Info; }
    186 
    187   const MCLDInfo& getLDInfo() const
    188   { return m_Info; }
    189 
    190 private:
    191   LDSymbol* defineSymbolForcefully(const llvm::StringRef& pName,
    192                                    bool pIsDyn,
    193                                    ResolveInfo::Type pType,
    194                                    ResolveInfo::Desc pDesc,
    195                                    ResolveInfo::Binding pBinding,
    196                                    ResolveInfo::SizeType pSize,
    197                                    LDSymbol::ValueType pValue,
    198                                    MCFragmentRef* pFragmentRef,
    199                                    ResolveInfo::Visibility pVisibility);
    200 
    201   LDSymbol* defineAndResolveSymbolForcefully(const llvm::StringRef& pName,
    202                                              bool pIsDyn,
    203                                              ResolveInfo::Type pType,
    204                                              ResolveInfo::Desc pDesc,
    205                                              ResolveInfo::Binding pBinding,
    206                                              ResolveInfo::SizeType pSize,
    207                                              LDSymbol::ValueType pValue,
    208                                              MCFragmentRef* pFragmentRef,
    209                                              ResolveInfo::Visibility pVisibility);
    210 
    211   LDSymbol* defineSymbolAsRefered(const llvm::StringRef& pName,
    212                                   bool pIsDyn,
    213                                   ResolveInfo::Type pType,
    214                                   ResolveInfo::Desc pDesc,
    215                                   ResolveInfo::Binding pBinding,
    216                                   ResolveInfo::SizeType pSize,
    217                                   LDSymbol::ValueType pValue,
    218                                   MCFragmentRef* pFragmentRef,
    219                                   ResolveInfo::Visibility pVisibility);
    220 
    221   LDSymbol* defineAndResolveSymbolAsRefered(const llvm::StringRef& pName,
    222                                             bool pIsDyn,
    223                                             ResolveInfo::Type pType,
    224                                             ResolveInfo::Desc pDesc,
    225                                             ResolveInfo::Binding pBinding,
    226                                             ResolveInfo::SizeType pSize,
    227                                             LDSymbol::ValueType pValue,
    228                                             MCFragmentRef* pFragmentRef,
    229                                             ResolveInfo::Visibility pVisibility);
    230 
    231   bool shouldForceLocal(const ResolveInfo& pInfo) const;
    232 
    233   LDSymbol* addSymbolFromDynObj(const llvm::StringRef& pName,
    234                                 ResolveInfo::Type pType,
    235                                 ResolveInfo::Desc pDesc,
    236                                 ResolveInfo::Binding pBinding,
    237                                 ResolveInfo::SizeType pSize,
    238                                 LDSymbol::ValueType pValue,
    239                                 MCFragmentRef* pFragmentRef,
    240                                 ResolveInfo::Visibility pVisibility);
    241 
    242   LDSymbol* addSymbolFromObject(const llvm::StringRef& pName,
    243                                 ResolveInfo::Type pType,
    244                                 ResolveInfo::Desc pDesc,
    245                                 ResolveInfo::Binding pBinding,
    246                                 ResolveInfo::SizeType pSize,
    247                                 LDSymbol::ValueType pValue,
    248                                 MCFragmentRef* pFragmentRef,
    249                                 ResolveInfo::Visibility pVisibility);
    250 private:
    251   typedef GCFactory<LDSymbol, 0> LDSymbolFactory;
    252   typedef GCFactory<llvm::MCSectionData, 0> LDSectionDataFactory;
    253   typedef llvm::iplist<llvm::MCFragment,
    254                        GCFactoryListTraits<llvm::MCFragment> > RelocationListType;
    255   typedef std::set<LDSymbol*> ForceLocalSymbolTable;
    256   typedef std::vector<LDSymbol*> OutputSymbolTable;
    257 
    258 private:
    259   TargetLDBackend& m_Backend;
    260   MCLDInfo& m_Info;
    261   LDContext& m_Output;
    262   SectionMap& m_SectionMap;
    263   LDSymbolFactory m_LDSymbolFactory;
    264   LDSectionFactory m_LDSectHdrFactory;
    265   LDSectionDataFactory m_LDSectDataFactory;
    266   SectionMerger m_SectionMerger;
    267   StrSymPool m_StrSymPool;
    268   Layout m_Layout;
    269   RelocationListType m_RelocationList;
    270   SymbolCategory m_OutputSymbols;
    271 
    272 };
    273 
    274 #include "MCLinker.tcc"
    275 
    276 } // namespace of mcld
    277 
    278 #endif
    279 
    280