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