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. mergeSymbolTable(Input & pInput)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 ----- // getLayout()168 Layout& getLayout() 169 { return m_Layout; } 170 getLayout()171 const Layout& getLayout() const 172 { return m_Layout; } 173 174 bool layout(); 175 176 // ----- output symbols ----- // getOutputSymbols()177 SymbolCategory& getOutputSymbols() 178 { return m_OutputSymbols; } 179 getOutputSymbols()180 const SymbolCategory& getOutputSymbols() const 181 { return m_OutputSymbols; } 182 183 // ----- capacity ----- // getLDInfo()184 MCLDInfo& getLDInfo() 185 { return m_Info; } 186 getLDInfo()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