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