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