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 getInputBuilder()71 const InputBuilder& getInputBuilder() const { return m_InputBuilder; } getInputBuilder()72 InputBuilder& getInputBuilder() { return m_InputBuilder; } getModule()73 const Module& getModule() const { return m_Module; } getModule()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