1 //===- X86LDBackend.cpp ---------------------------------------------------===// 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 #include "X86.h" 11 #include "X86ELFDynamic.h" 12 #include "X86LDBackend.h" 13 #include "X86RelocationFactory.h" 14 15 #include <llvm/ADT/Triple.h> 16 #include <mcld/Support/MemoryRegion.h> 17 #include <mcld/Support/TargetRegistry.h> 18 #include <mcld/MC/MCLDInfo.h> 19 #include <mcld/MC/MCLDOutput.h> 20 #include <mcld/MC/MCLinker.h> 21 #include <mcld/LD/SectionMap.h> 22 #include <mcld/MC/MCRegionFragment.h> 23 24 #include <cstring> 25 26 using namespace mcld; 27 28 X86GNULDBackend::X86GNULDBackend() 29 : m_pRelocFactory(NULL), 30 m_pGOT(NULL), 31 m_pPLT(NULL), 32 m_pRelDyn(NULL), 33 m_pRelPLT(NULL), 34 m_pDynamic(NULL) { 35 } 36 37 X86GNULDBackend::~X86GNULDBackend() 38 { 39 if (NULL != m_pRelocFactory) 40 delete m_pRelocFactory; 41 if (NULL != m_pGOT) 42 delete m_pGOT; 43 if (NULL != m_pPLT) 44 delete m_pPLT; 45 if (NULL !=m_pRelDyn) 46 delete m_pRelDyn; 47 if (NULL != m_pRelPLT) 48 delete m_pRelPLT; 49 if (NULL != m_pDynamic) 50 delete m_pDynamic; 51 } 52 53 RelocationFactory* X86GNULDBackend::getRelocFactory() 54 { 55 assert(NULL != m_pRelocFactory); 56 return m_pRelocFactory; 57 } 58 59 bool X86GNULDBackend::initRelocFactory(const MCLinker& pLinker) 60 { 61 if (NULL == m_pRelocFactory) { 62 m_pRelocFactory = new X86RelocationFactory(1024, *this); 63 m_pRelocFactory->setLayout(pLinker.getLayout()); 64 } 65 return true; 66 } 67 68 void X86GNULDBackend::doPreLayout(const Output& pOutput, 69 const MCLDInfo& pInfo, 70 MCLinker& pLinker) 71 { 72 // when building shared object, the .got section is needed 73 if(pOutput.type() == Output::DynObj && (NULL == m_pGOT)) 74 createX86GOT(pLinker, pOutput); 75 } 76 77 void X86GNULDBackend::doPostLayout(const Output& pOutput, 78 const MCLDInfo& pInfo, 79 MCLinker& pLinker) 80 { 81 // emit program headers 82 if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) 83 emitProgramHdrs(pLinker.getLDInfo().output()); 84 } 85 86 /// dynamic - the dynamic section of the target machine. 87 /// Use co-variant return type to return its own dynamic section. 88 X86ELFDynamic& X86GNULDBackend::dynamic() 89 { 90 if (NULL == m_pDynamic) 91 m_pDynamic = new X86ELFDynamic(*this); 92 93 return *m_pDynamic; 94 } 95 96 /// dynamic - the dynamic section of the target machine. 97 /// Use co-variant return type to return its own dynamic section. 98 const X86ELFDynamic& X86GNULDBackend::dynamic() const 99 { 100 assert( NULL != m_pDynamic); 101 return *m_pDynamic; 102 } 103 104 void X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput) 105 { 106 // get .got LDSection and create MCSectionData 107 ELFFileFormat* file_format = getOutputFormat(pOutput); 108 109 LDSection& got = file_format->getGOT(); 110 m_pGOT = new X86GOT(got, pLinker.getOrCreateSectData(got)); 111 112 // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 113 if( m_pGOTSymbol != NULL ) { 114 pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>( 115 "_GLOBAL_OFFSET_TABLE_", 116 false, 117 ResolveInfo::Object, 118 ResolveInfo::Define, 119 ResolveInfo::Local, 120 0x0, // size 121 0x0, // value 122 pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 123 ResolveInfo::Hidden); 124 } 125 else { 126 m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 127 "_GLOBAL_OFFSET_TABLE_", 128 false, 129 ResolveInfo::Object, 130 ResolveInfo::Define, 131 ResolveInfo::Local, 132 0x0, // size 133 0x0, // value 134 pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 135 ResolveInfo::Hidden); 136 } 137 } 138 139 void X86GNULDBackend::createX86PLTandRelPLT(MCLinker& pLinker, 140 const Output& pOutput) 141 { 142 ELFFileFormat* file_format = getOutputFormat(pOutput); 143 144 LDSection& plt = file_format->getPLT(); 145 LDSection& relplt = file_format->getRelPlt(); 146 // create MCSectionData and X86PLT 147 m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOT, pOutput); 148 149 // set info of .rel.plt to .plt 150 relplt.setLink(&plt); 151 // create MCSectionData and X86RelDynSection 152 m_pRelPLT = new OutputRelocSection(relplt, 153 pLinker.getOrCreateSectData(relplt), 154 8); 155 } 156 157 void X86GNULDBackend::createX86RelDyn(MCLinker& pLinker, 158 const Output& pOutput) 159 { 160 // get .rel.dyn LDSection and create MCSectionData 161 ELFFileFormat* file_format = getOutputFormat(pOutput); 162 163 LDSection& reldyn = file_format->getRelDyn(); 164 // create MCSectionData and X86RelDynSection 165 m_pRelDyn = new OutputRelocSection(reldyn, 166 pLinker.getOrCreateSectData(reldyn), 167 8); 168 } 169 170 ELFFileFormat* X86GNULDBackend::getOutputFormat(const Output& pOutput) const 171 { 172 switch (pOutput.type()) { 173 case Output::DynObj: 174 return getDynObjFileFormat(); 175 case Output::Exec: 176 return getExecFileFormat(); 177 // FIXME: We do not support building .o now 178 case Output::Object: 179 default: 180 llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") + 181 llvm::Twine(pOutput.type())); 182 return NULL; 183 } 184 } 185 186 bool X86GNULDBackend::isSymbolNeedsPLT(const ResolveInfo& pSym, 187 const MCLDInfo& pLDInfo, 188 const Output& pOutput) const 189 { 190 return((Output::DynObj == pOutput.type()) 191 &&(ResolveInfo::Function == pSym.type()) 192 &&(pSym.isDyn() || pSym.isUndef() || 193 isSymbolPreemptible(pSym, pLDInfo, pOutput)) 194 ); 195 } 196 197 bool X86GNULDBackend::isSymbolNeedsDynRel(const ResolveInfo& pSym, 198 const Output& pOutput, 199 bool isAbsReloc) const 200 { 201 if(pSym.isUndef() && (pOutput.type()==Output::Exec)) 202 return false; 203 if(pSym.isAbsolute()) 204 return false; 205 if(pOutput.type()==Output::DynObj && isAbsReloc) 206 return true; 207 if(pSym.isDyn() || pSym.isUndef()) 208 return true; 209 210 return false; 211 } 212 213 bool X86GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym, 214 const MCLDInfo& pLDInfo, 215 const Output& pOutput) const 216 { 217 if(pSym.other() != ResolveInfo::Default) 218 return false; 219 220 if(pOutput.type() != Output::DynObj) 221 return false; 222 223 if(pLDInfo.options().Bsymbolic()) 224 return false; 225 226 return true; 227 } 228 229 void X86GNULDBackend::updateAddend(Relocation& pReloc, 230 const LDSymbol& pInputSym, 231 const Layout& pLayout) const 232 { 233 // Update value keep in addend if we meet a section symbol 234 if(pReloc.symInfo()->type() == ResolveInfo::Section) { 235 pReloc.setAddend(pLayout.getOutputOffset( 236 *pInputSym.fragRef()) + pReloc.addend()); 237 } 238 } 239 240 void X86GNULDBackend::scanLocalReloc(Relocation& pReloc, 241 const LDSymbol& pInputSym, 242 MCLinker& pLinker, 243 const MCLDInfo& pLDInfo, 244 const Output& pOutput) 245 { 246 // rsym - The relocation target symbol 247 ResolveInfo* rsym = pReloc.symInfo(); 248 249 updateAddend(pReloc, pInputSym, pLinker.getLayout()); 250 251 switch(pReloc.type()){ 252 253 case llvm::ELF::R_386_32: 254 // If buiding PIC object (shared library or PIC executable), 255 // a dynamic relocations with RELATIVE type to this location is needed. 256 // Reserve an entry in .rel.dyn 257 if(Output::DynObj == pOutput.type()) { 258 // create .rel.dyn section if not exist 259 if(NULL == m_pRelDyn) 260 createX86RelDyn(pLinker, pOutput); 261 m_pRelDyn->reserveEntry(*m_pRelocFactory); 262 // set Rel bit 263 rsym->setReserved(rsym->reserved() | ReserveRel); 264 } 265 return; 266 267 case llvm::ELF::R_386_GOTOFF: 268 case llvm::ELF::R_386_GOTPC: 269 // A GOT section is needed 270 if(NULL == m_pGOT) 271 createX86GOT(pLinker, pOutput); 272 return; 273 274 case llvm::ELF::R_386_PC32: 275 return; 276 277 default: 278 llvm::report_fatal_error(llvm::Twine("unexpected reloc ") + 279 llvm::Twine((int) pReloc.type()) + 280 llvm::Twine(" in object file")); 281 break; 282 } // end switch 283 } 284 285 void X86GNULDBackend::scanGlobalReloc(Relocation& pReloc, 286 const LDSymbol& pInputSym, 287 MCLinker& pLinker, 288 const MCLDInfo& pLDInfo, 289 const Output& pOutput) 290 { 291 // rsym - The relocation target symbol 292 ResolveInfo* rsym = pReloc.symInfo(); 293 294 switch(pReloc.type()) { 295 case llvm::ELF::R_386_32: 296 // Absolute relocation type, symbol may needs PLT entry or 297 // dynamic relocation entry 298 if(isSymbolNeedsPLT(*rsym, pLDInfo, pOutput)) { 299 // create plt for this symbol if it does not have one 300 if(!(rsym->reserved() & ReservePLT)){ 301 // Create .got section if it dosen't exist 302 if(NULL == m_pGOT) 303 createX86GOT(pLinker, pOutput); 304 // create .plt and .rel.plt if not exist 305 if(NULL == m_pPLT) 306 createX86PLTandRelPLT(pLinker, pOutput); 307 // Symbol needs PLT entry, we need to reserve a PLT entry 308 // and the corresponding GOT and dynamic relocation entry 309 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 310 // when calling X86PLT->reserveEntry()) 311 m_pPLT->reserveEntry(); 312 m_pRelPLT->reserveEntry(*m_pRelocFactory); 313 // set PLT bit 314 rsym->setReserved(rsym->reserved() | ReservePLT); 315 } 316 } 317 318 if(isSymbolNeedsDynRel(*rsym, pOutput, true)) { 319 // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 320 // create .rel.dyn section if not exist 321 if(NULL == m_pRelDyn) 322 createX86RelDyn(pLinker, pOutput); 323 m_pRelDyn->reserveEntry(*m_pRelocFactory); 324 // set Rel bit 325 rsym->setReserved(rsym->reserved() | ReserveRel); 326 } 327 return; 328 329 case llvm::ELF::R_386_GOTOFF: 330 case llvm::ELF::R_386_GOTPC: { 331 // A GOT section is needed 332 if(NULL == m_pGOT) 333 createX86GOT(pLinker, pOutput); 334 return; 335 } 336 337 case llvm::ELF::R_386_PLT32: 338 // A PLT entry is needed when building shared library 339 340 // return if we already create plt for this symbol 341 if(rsym->reserved() & ReservePLT) 342 return; 343 344 // if symbol is defined in the ouput file and it's not 345 // preemptible, no need plt 346 if(rsym->isDefine() && !rsym->isDyn() && 347 !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) { 348 return; 349 } 350 351 // Create .got section if it dosen't exist 352 if(NULL == m_pGOT) 353 createX86GOT(pLinker, pOutput); 354 // create .plt and .rel.plt if not exist 355 if(NULL == m_pPLT) 356 createX86PLTandRelPLT(pLinker, pOutput); 357 // Symbol needs PLT entry, we need to reserve a PLT entry 358 // and the corresponding GOT and dynamic relocation entry 359 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 360 // when calling X86PLT->reserveEntry()) 361 m_pPLT->reserveEntry(); 362 m_pRelPLT->reserveEntry(*m_pRelocFactory); 363 // set PLT bit 364 rsym->setReserved(rsym->reserved() | ReservePLT); 365 return; 366 367 case llvm::ELF::R_386_GOT32: 368 // Symbol needs GOT entry, reserve entry in .got 369 // return if we already create GOT for this symbol 370 if(rsym->reserved() & (ReserveGOT | GOTRel)) 371 return; 372 if(NULL == m_pGOT) 373 createX86GOT(pLinker, pOutput); 374 m_pGOT->reserveEntry(); 375 // If building shared object or the symbol is undefined, a dynamic 376 // relocation is needed to relocate this GOT entry. Reserve an 377 // entry in .rel.dyn 378 if(Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) { 379 // create .rel.dyn section if not exist 380 if(NULL == m_pRelDyn) 381 createX86RelDyn(pLinker, pOutput); 382 m_pRelDyn->reserveEntry(*m_pRelocFactory); 383 // set GOTRel bit 384 rsym->setReserved(rsym->reserved() | GOTRel); 385 return; 386 } 387 // set GOT bit 388 rsym->setReserved(rsym->reserved() | ReserveGOT); 389 return; 390 391 case llvm::ELF::R_386_PC32: 392 // We allow R_386_PC32 only if it isn't preemptible. Otherwise 393 // we will generate writable text section in output. 394 if (!isSymbolPreemptible(*rsym, pLDInfo, pOutput)) 395 return; 396 397 default: { 398 llvm::report_fatal_error(llvm::Twine("Unexpected reloc ") + 399 llvm::Twine((int) pReloc.type()) + 400 llvm::Twine(" in object file")); 401 break; 402 } 403 } // end switch 404 } 405 406 void X86GNULDBackend::scanRelocation(Relocation& pReloc, 407 const LDSymbol& pInputSym, 408 MCLinker& pLinker, 409 const MCLDInfo& pLDInfo, 410 const Output& pOutput) 411 { 412 // rsym - The relocation target symbol 413 ResolveInfo* rsym = pReloc.symInfo(); 414 assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 415 416 // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation 417 // entries should be created. 418 // FIXME: Below judgements concern only .so is generated as output 419 // FIXME: Below judgements concren nothing about TLS related relocation 420 421 // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got section 422 // is needed 423 if(NULL == m_pGOT && NULL != m_pGOTSymbol) { 424 if(rsym == m_pGOTSymbol->resolveInfo()) { 425 createX86GOT(pLinker, pOutput); 426 } 427 } 428 429 // rsym is local 430 if(rsym->isLocal()) 431 scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 432 433 // rsym is external 434 else 435 scanGlobalReloc(pReloc, pInputSym ,pLinker, pLDInfo, pOutput); 436 437 } 438 439 uint64_t X86GNULDBackend::emitSectionData(const Output& pOutput, 440 const LDSection& pSection, 441 const MCLDInfo& pInfo, 442 MemoryRegion& pRegion) const 443 { 444 assert(pRegion.size() && "Size of MemoryRegion is zero!"); 445 446 ELFFileFormat* FileFormat = getOutputFormat(pOutput); 447 assert(FileFormat && 448 "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 449 450 unsigned int EntrySize = 0; 451 uint64_t RegionSize = 0; 452 453 if (&pSection == &(FileFormat->getPLT())) { 454 assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); 455 456 unsigned char* buffer = pRegion.getBuffer(); 457 458 m_pPLT->applyPLT0(); 459 m_pPLT->applyPLT1(); 460 461 X86PLT::iterator it = m_pPLT->begin(); 462 unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize(); 463 464 memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size); 465 RegionSize += plt0_size; 466 ++it; 467 468 X86PLT1* plt1 = 0; 469 X86PLT::iterator ie = m_pPLT->end(); 470 while (it != ie) { 471 plt1 = &(llvm::cast<X86PLT1>(*it)); 472 EntrySize = plt1->getEntrySize(); 473 memcpy(buffer + RegionSize, plt1->getContent(), EntrySize); 474 RegionSize += EntrySize; 475 ++it; 476 } 477 } 478 479 else if (&pSection == &(FileFormat->getGOT())) { 480 assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 481 482 m_pGOT->applyGOT0(FileFormat->getDynamic().addr()); 483 484 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 485 486 GOTEntry* got = 0; 487 EntrySize = m_pGOT->getEntrySize(); 488 489 for (X86GOT::iterator it = m_pGOT->begin(), 490 ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 491 got = &(llvm::cast<GOTEntry>((*it))); 492 *buffer = static_cast<uint32_t>(got->getContent()); 493 RegionSize += EntrySize; 494 } 495 } 496 497 else 498 llvm::report_fatal_error("unsupported section name " 499 + pSection.name() + " !"); 500 501 return RegionSize; 502 } 503 uint32_t X86GNULDBackend::machine() const 504 { 505 return llvm::ELF::EM_386; 506 } 507 508 X86GOT& X86GNULDBackend::getGOT() 509 { 510 assert(NULL != m_pGOT); 511 return *m_pGOT; 512 } 513 514 const X86GOT& X86GNULDBackend::getGOT() const 515 { 516 assert(NULL != m_pGOT); 517 return *m_pGOT; 518 } 519 520 X86PLT& X86GNULDBackend::getPLT() 521 { 522 assert(NULL != m_pPLT && "PLT section not exist"); 523 return *m_pPLT; 524 } 525 526 const X86PLT& X86GNULDBackend::getPLT() const 527 { 528 assert(NULL != m_pPLT && "PLT section not exist"); 529 return *m_pPLT; 530 } 531 532 OutputRelocSection& X86GNULDBackend::getRelDyn() 533 { 534 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 535 return *m_pRelDyn; 536 } 537 538 const OutputRelocSection& X86GNULDBackend::getRelDyn() const 539 { 540 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 541 return *m_pRelDyn; 542 } 543 544 OutputRelocSection& X86GNULDBackend::getRelPLT() 545 { 546 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 547 return *m_pRelPLT; 548 } 549 550 const OutputRelocSection& X86GNULDBackend::getRelPLT() const 551 { 552 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 553 return *m_pRelPLT; 554 } 555 556 unsigned int 557 X86GNULDBackend::getTargetSectionOrder(const Output& pOutput, 558 const LDSection& pSectHdr) const 559 { 560 ELFFileFormat* file_format = getOutputFormat(pOutput); 561 562 // FIXME: if command line option, "-z now", is given, we can let the order of 563 // .got and .got.plt be the same as RELRO sections 564 if (&pSectHdr == &file_format->getGOT()) 565 return SHO_RELRO_LAST; 566 567 if (&pSectHdr == &file_format->getGOTPLT()) 568 return SHO_NON_RELRO_FIRST; 569 570 if (&pSectHdr == &file_format->getPLT()) 571 return SHO_PLT; 572 573 return SHO_UNDEFINED; 574 } 575 576 unsigned int X86GNULDBackend::bitclass() const 577 { 578 return 32; 579 } 580 581 bool X86GNULDBackend::initTargetSectionMap(SectionMap& pSectionMap) 582 { 583 return true; 584 } 585 586 void X86GNULDBackend::initTargetSections(MCLinker& pLinker) 587 { 588 } 589 590 void X86GNULDBackend::initTargetSymbols(MCLinker& pLinker) 591 { 592 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 593 // same name in input 594 m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 595 "_GLOBAL_OFFSET_TABLE_", 596 false, 597 ResolveInfo::Object, 598 ResolveInfo::Define, 599 ResolveInfo::Local, 600 0x0, // size 601 0x0, // value 602 NULL, // FragRef 603 ResolveInfo::Hidden); 604 } 605 606 /// finalizeSymbol - finalize the symbol value 607 /// If the symbol's reserved field is not zero, MCLinker will call back this 608 /// function to ask the final value of the symbol 609 bool X86GNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const 610 { 611 return false; 612 } 613 614 /// allocateCommonSymbols - allocate common symbols in the corresponding 615 /// sections. 616 /// @refer Google gold linker: common.cc: 214 617 bool 618 X86GNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const 619 { 620 // SymbolCategory contains all symbols that must emit to the output files. 621 // We are not like Google gold linker, we don't remember symbols before symbol 622 // resolution. All symbols in SymbolCategory are already resolved. Therefore, we 623 // don't need to care about some symbols may be changed its category due to symbol 624 // resolution. 625 SymbolCategory& symbol_list = pLinker.getOutputSymbols(); 626 627 if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) 628 return true; 629 630 // addralign := max value of all common symbols 631 uint64_t addralign = 0x0; 632 633 // Due to the visibility, some common symbols may be forcefully local. 634 SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd(); 635 for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 636 if (ResolveInfo::Common == (*com_sym)->desc()) { 637 if ((*com_sym)->value() > addralign) 638 addralign = (*com_sym)->value(); 639 } 640 } 641 642 // global common symbols. 643 com_end = symbol_list.commonEnd(); 644 for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 645 if ((*com_sym)->value() > addralign) 646 addralign = (*com_sym)->value(); 647 } 648 649 // FIXME: If the order of common symbols is defined, then sort common symbols 650 // com_sym = symbol_list.commonBegin(); 651 // std::sort(com_sym, com_end, some kind of order); 652 653 // get or create corresponding BSS LDSection 654 LDSection* bss_sect_hdr = NULL; 655 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 656 bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr( 657 ".tbss", 658 LDFileFormat::BSS, 659 llvm::ELF::SHT_NOBITS, 660 llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 661 } 662 else { 663 bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss", 664 LDFileFormat::BSS, 665 llvm::ELF::SHT_NOBITS, 666 llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 667 } 668 669 // get or create corresponding BSS MCSectionData 670 assert(NULL != bss_sect_hdr); 671 llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr); 672 673 // allocate all common symbols 674 uint64_t offset = bss_sect_hdr->size(); 675 676 // allocate all local common symbols 677 com_end = symbol_list.localEnd(); 678 for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 679 if (ResolveInfo::Common == (*com_sym)->desc()) { 680 // We have to reset the description of the symbol here. When doing 681 // incremental linking, the output relocatable object may have common 682 // symbols. Therefore, we can not treat common symbols as normal symbols 683 // when emitting the regular name pools. We must change the symbols' 684 // description here. 685 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 686 llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size()); 687 (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0)); 688 uint64_t size = pLinker.getLayout().appendFragment(*frag, 689 bss_section, 690 (*com_sym)->value()); 691 offset += size; 692 } 693 } 694 695 // allocate all global common symbols 696 com_end = symbol_list.commonEnd(); 697 for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 698 // We have to reset the description of the symbol here. When doing 699 // incremental linking, the output relocatable object may have common 700 // symbols. Therefore, we can not treat common symbols as normal symbols 701 // when emitting the regular name pools. We must change the symbols' 702 // description here. 703 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 704 llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size()); 705 (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0)); 706 uint64_t size = pLinker.getLayout().appendFragment(*frag, 707 bss_section, 708 (*com_sym)->value()); 709 offset += size; 710 } 711 712 bss_sect_hdr->setSize(offset); 713 symbol_list.changeCommonsToGlobal(); 714 return true; 715 } 716 717 namespace mcld { 718 719 //===----------------------------------------------------------------------===// 720 /// createX86LDBackend - the help funtion to create corresponding X86LDBackend 721 /// 722 TargetLDBackend* createX86LDBackend(const llvm::Target& pTarget, 723 const std::string& pTriple) 724 { 725 Triple theTriple(pTriple); 726 if (theTriple.isOSDarwin()) { 727 assert(0 && "MachO linker is not supported yet"); 728 /** 729 return new X86MachOLDBackend(createX86MachOArchiveReader, 730 createX86MachOObjectReader, 731 createX86MachOObjectWriter); 732 **/ 733 } 734 if (theTriple.isOSWindows()) { 735 assert(0 && "COFF linker is not supported yet"); 736 /** 737 return new X86COFFLDBackend(createX86COFFArchiveReader, 738 createX86COFFObjectReader, 739 createX86COFFObjectWriter); 740 **/ 741 } 742 return new X86GNULDBackend(); 743 } 744 745 } // namespace of mcld 746 747 //============================= 748 // Force static initialization. 749 extern "C" void LLVMInitializeX86LDBackend() { 750 // Register the linker backend 751 mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend); 752 } 753