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