X86LDBackend.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
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#include "X86.h" 10#include "X86ELFDynamic.h" 11#include "X86LDBackend.h" 12#include "X86Relocator.h" 13#include "X86GNUInfo.h" 14 15#include <llvm/ADT/Triple.h> 16#include <llvm/Support/Casting.h> 17 18#include <mcld/LinkerConfig.h> 19#include <mcld/IRBuilder.h> 20#include <mcld/Fragment/FillFragment.h> 21#include <mcld/Fragment/RegionFragment.h> 22#include <mcld/Fragment/FragmentLinker.h> 23#include <mcld/Support/MemoryRegion.h> 24#include <mcld/Support/MsgHandling.h> 25#include <mcld/Support/TargetRegistry.h> 26#include <mcld/Object/ObjectBuilder.h> 27 28#include <cstring> 29 30using namespace mcld; 31 32//===----------------------------------------------------------------------===// 33// X86GNULDBackend 34//===----------------------------------------------------------------------===// 35X86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig, 36 GNUInfo* pInfo, 37 Relocation::Type pCopyRel) 38 : GNULDBackend(pConfig, pInfo), 39 m_pRelocator(NULL), 40 m_pPLT(NULL), 41 m_pRelDyn(NULL), 42 m_pRelPLT(NULL), 43 m_pDynamic(NULL), 44 m_pGOTSymbol(NULL), 45 m_CopyRel(pCopyRel) 46{ 47 Triple::ArchType arch = pConfig.targets().triple().getArch(); 48 assert (arch == Triple::x86 || arch == Triple::x86_64); 49 if (arch == Triple::x86 || 50 pConfig.targets().triple().getEnvironment() == Triple::GNUX32) { 51 m_RelEntrySize = 8; 52 m_RelaEntrySize = 12; 53 if (arch == Triple::x86) 54 m_PointerRel = llvm::ELF::R_386_32; 55 else 56 m_PointerRel = llvm::ELF::R_X86_64_32; 57 } 58 else { 59 m_RelEntrySize = 16; 60 m_RelaEntrySize = 24; 61 m_PointerRel = llvm::ELF::R_X86_64_64; 62 } 63} 64 65X86GNULDBackend::~X86GNULDBackend() 66{ 67 delete m_pRelocator; 68 delete m_pPLT; 69 delete m_pRelDyn; 70 delete m_pRelPLT; 71 delete m_pDynamic; 72} 73 74Relocator* X86GNULDBackend::getRelocator() 75{ 76 assert(NULL != m_pRelocator); 77 return m_pRelocator; 78} 79 80void X86GNULDBackend::doPreLayout(IRBuilder& pBuilder) 81{ 82 // initialize .dynamic data 83 if (!config().isCodeStatic() && NULL == m_pDynamic) 84 m_pDynamic = new X86ELFDynamic(*this, config()); 85 86 // set .got.plt and .got sizes 87 // when building shared object, the .got section is must 88 if (LinkerConfig::Object != config().codeGenType()) { 89 setGOTSectionSize(pBuilder); 90 91 // set .plt size 92 if (m_pPLT->hasPLT1()) 93 m_pPLT->finalizeSectionSize(); 94 95 // set .rel.dyn/.rela.dyn size 96 if (!m_pRelDyn->empty()) { 97 assert(!config().isCodeStatic() && 98 "static linkage should not result in a dynamic relocation section"); 99 setRelDynSize(); 100 } 101 // set .rel.plt/.rela.plt size 102 if (!m_pRelPLT->empty()) { 103 assert(!config().isCodeStatic() && 104 "static linkage should not result in a dynamic relocation section"); 105 setRelPLTSize(); 106 } 107 } 108} 109 110void X86GNULDBackend::doPostLayout(Module& pModule, 111 IRBuilder& pBuilder) 112{ 113} 114 115/// dynamic - the dynamic section of the target machine. 116/// Use co-variant return type to return its own dynamic section. 117X86ELFDynamic& X86GNULDBackend::dynamic() 118{ 119 assert(NULL != m_pDynamic); 120 return *m_pDynamic; 121} 122 123/// dynamic - the dynamic section of the target machine. 124/// Use co-variant return type to return its own dynamic section. 125const X86ELFDynamic& X86GNULDBackend::dynamic() const 126{ 127 assert(NULL != m_pDynamic); 128 return *m_pDynamic; 129} 130 131void X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder, 132 Fragment& pFrag) 133{ 134 // define symbol _GLOBAL_OFFSET_TABLE_ 135 if (m_pGOTSymbol != NULL) { 136 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 137 "_GLOBAL_OFFSET_TABLE_", 138 ResolveInfo::Object, 139 ResolveInfo::Define, 140 ResolveInfo::Local, 141 0x0, // size 142 0x0, // value 143 FragmentRef::Create(pFrag, 0x0), 144 ResolveInfo::Hidden); 145 } 146 else { 147 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 148 "_GLOBAL_OFFSET_TABLE_", 149 ResolveInfo::Object, 150 ResolveInfo::Define, 151 ResolveInfo::Local, 152 0x0, // size 153 0x0, // value 154 FragmentRef::Create(pFrag, 0x0), 155 ResolveInfo::Hidden); 156 } 157} 158 159void X86GNULDBackend::addCopyReloc(ResolveInfo& pSym) 160{ 161 Relocation& rel_entry = *m_pRelDyn->consumeEntry(); 162 rel_entry.setType(m_CopyRel); 163 assert(pSym.outSymbol()->hasFragRef()); 164 rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef()); 165 rel_entry.setSymInfo(&pSym); 166} 167 168/// defineSymbolforCopyReloc 169/// For a symbol needing copy relocation, define a copy symbol in the BSS 170/// section and all other reference to this symbol should refer to this 171/// copy. 172/// @note This is executed at `scan relocation' stage. 173LDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(IRBuilder& pBuilder, 174 const ResolveInfo& pSym) 175{ 176 // get or create corresponding BSS LDSection 177 LDSection* bss_sect_hdr = NULL; 178 ELFFileFormat* file_format = getOutputFormat(); 179 if (ResolveInfo::ThreadLocal == pSym.type()) 180 bss_sect_hdr = &file_format->getTBSS(); 181 else 182 bss_sect_hdr = &file_format->getBSS(); 183 184 // get or create corresponding BSS SectionData 185 assert(NULL != bss_sect_hdr); 186 SectionData* bss_section = NULL; 187 if (bss_sect_hdr->hasSectionData()) 188 bss_section = bss_sect_hdr->getSectionData(); 189 else 190 bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr); 191 192 // Determine the alignment by the symbol value 193 // FIXME: here we use the largest alignment 194 uint32_t addralign = config().targets().bitclass() / 8; 195 196 // allocate space in BSS for the copy symbol 197 Fragment* frag = new FillFragment(0x0, 1, pSym.size()); 198 uint64_t size = ObjectBuilder::AppendFragment(*frag, 199 *bss_section, 200 addralign); 201 bss_sect_hdr->setSize(bss_sect_hdr->size() + size); 202 203 // change symbol binding to Global if it's a weak symbol 204 ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding(); 205 if (binding == ResolveInfo::Weak) 206 binding = ResolveInfo::Global; 207 208 // Define the copy symbol in the bss section and resolve it 209 LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 210 pSym.name(), 211 (ResolveInfo::Type)pSym.type(), 212 ResolveInfo::Define, 213 binding, 214 pSym.size(), // size 215 0x0, // value 216 FragmentRef::Create(*frag, 0x0), 217 (ResolveInfo::Visibility)pSym.other()); 218 219 return *cpy_sym; 220} 221 222void X86GNULDBackend::scanRelocation(Relocation& pReloc, 223 IRBuilder& pLinker, 224 Module& pModule, 225 LDSection& pSection) 226{ 227 if (LinkerConfig::Object == config().codeGenType()) 228 return; 229 // rsym - The relocation target symbol 230 ResolveInfo* rsym = pReloc.symInfo(); 231 assert(NULL != rsym && 232 "ResolveInfo of relocation not set while scanRelocation"); 233 234 pReloc.updateAddend(); 235 assert(NULL != pSection.getLink()); 236 if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) 237 return; 238 239 // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation 240 // entries should be created. 241 if (rsym->isLocal()) // rsym is local 242 scanLocalReloc(pReloc, pLinker, pModule, pSection); 243 else // rsym is external 244 scanGlobalReloc(pReloc, pLinker, pModule, pSection); 245 246 // check if we should issue undefined reference for the relocation target 247 // symbol 248 if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull()) 249 fatal(diag::undefined_reference) << rsym->name(); 250} 251 252uint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection, 253 MemoryRegion& pRegion) const 254{ 255 assert(pRegion.size() && "Size of MemoryRegion is zero!"); 256 257 const ELFFileFormat* FileFormat = getOutputFormat(); 258 assert(FileFormat && 259 "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 260 261 unsigned int EntrySize = 0; 262 uint64_t RegionSize = 0; 263 264 if (&pSection == &(FileFormat->getPLT())) { 265 assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); 266 267 unsigned char* buffer = pRegion.getBuffer(); 268 269 m_pPLT->applyPLT0(); 270 m_pPLT->applyPLT1(); 271 X86PLT::iterator it = m_pPLT->begin(); 272 unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); 273 274 memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); 275 RegionSize += plt0_size; 276 ++it; 277 278 PLTEntryBase* plt1 = 0; 279 X86PLT::iterator ie = m_pPLT->end(); 280 while (it != ie) { 281 plt1 = &(llvm::cast<PLTEntryBase>(*it)); 282 EntrySize = plt1->size(); 283 memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); 284 RegionSize += EntrySize; 285 ++it; 286 } 287 } 288 289 else if (&pSection == &(FileFormat->getGOT())) { 290 RegionSize += emitGOTSectionData(pRegion); 291 } 292 293 else if (&pSection == &(FileFormat->getGOTPLT())) { 294 RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); 295 } 296 297 else { 298 fatal(diag::unrecognized_output_sectoin) 299 << pSection.name() 300 << "mclinker@googlegroups.com"; 301 } 302 return RegionSize; 303} 304 305X86PLT& X86GNULDBackend::getPLT() 306{ 307 assert(NULL != m_pPLT && "PLT section not exist"); 308 return *m_pPLT; 309} 310 311const X86PLT& X86GNULDBackend::getPLT() const 312{ 313 assert(NULL != m_pPLT && "PLT section not exist"); 314 return *m_pPLT; 315} 316 317OutputRelocSection& X86GNULDBackend::getRelDyn() 318{ 319 assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist"); 320 return *m_pRelDyn; 321} 322 323const OutputRelocSection& X86GNULDBackend::getRelDyn() const 324{ 325 assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist"); 326 return *m_pRelDyn; 327} 328 329OutputRelocSection& X86GNULDBackend::getRelPLT() 330{ 331 assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist"); 332 return *m_pRelPLT; 333} 334 335const OutputRelocSection& X86GNULDBackend::getRelPLT() const 336{ 337 assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist"); 338 return *m_pRelPLT; 339} 340 341unsigned int 342X86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 343{ 344 const ELFFileFormat* file_format = getOutputFormat(); 345 346 if (&pSectHdr == &file_format->getGOT()) { 347 if (config().options().hasNow()) 348 return SHO_RELRO; 349 return SHO_RELRO_LAST; 350 } 351 352 if (&pSectHdr == &file_format->getGOTPLT()) { 353 if (config().options().hasNow()) 354 return SHO_RELRO; 355 return SHO_NON_RELRO_FIRST; 356 } 357 358 if (&pSectHdr == &file_format->getPLT()) 359 return SHO_PLT; 360 361 return SHO_UNDEFINED; 362} 363 364void X86GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 365{ 366 if (LinkerConfig::Object != config().codeGenType()) { 367 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 368 // same name in input 369 m_pGOTSymbol = 370 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 371 "_GLOBAL_OFFSET_TABLE_", 372 ResolveInfo::Object, 373 ResolveInfo::Define, 374 ResolveInfo::Local, 375 0x0, // size 376 0x0, // value 377 FragmentRef::Null(), // FragRef 378 ResolveInfo::Hidden); 379 } 380} 381 382/// finalizeSymbol - finalize the symbol value 383bool X86GNULDBackend::finalizeTargetSymbols() 384{ 385 return true; 386} 387 388/// doCreateProgramHdrs - backend can implement this function to create the 389/// target-dependent segments 390void X86GNULDBackend::doCreateProgramHdrs(Module& pModule) 391{ 392 // TODO 393} 394 395X86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig, 396 GNUInfo* pInfo) 397 : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY), 398 m_pGOT (NULL), 399 m_pGOTPLT (NULL) { 400} 401 402X86_32GNULDBackend::~X86_32GNULDBackend() 403{ 404 delete m_pGOT; 405 delete m_pGOTPLT; 406} 407 408bool X86_32GNULDBackend::initRelocator() 409{ 410 if (NULL == m_pRelocator) { 411 m_pRelocator = new X86_32Relocator(*this); 412 } 413 return true; 414} 415 416void X86_32GNULDBackend::scanLocalReloc(Relocation& pReloc, 417 IRBuilder& pBuilder, 418 Module& pModule, 419 LDSection& pSection) 420{ 421 // rsym - The relocation target symbol 422 ResolveInfo* rsym = pReloc.symInfo(); 423 424 switch(pReloc.type()){ 425 426 case llvm::ELF::R_386_32: 427 case llvm::ELF::R_386_16: 428 case llvm::ELF::R_386_8: 429 // If buiding PIC object (shared library or PIC executable), 430 // a dynamic relocations with RELATIVE type to this location is needed. 431 // Reserve an entry in .rel.dyn 432 if (config().isCodeIndep()) { 433 m_pRelDyn->reserveEntry(); 434 // set Rel bit 435 rsym->setReserved(rsym->reserved() | ReserveRel); 436 checkAndSetHasTextRel(*pSection.getLink()); 437 } 438 return; 439 440 case llvm::ELF::R_386_GOTOFF: 441 case llvm::ELF::R_386_GOTPC: 442 // FIXME: A GOT section is needed 443 return; 444 445 case llvm::ELF::R_386_GOT32: 446 // Symbol needs GOT entry, reserve entry in .got 447 // return if we already create GOT for this symbol 448 if (rsym->reserved() & (ReserveGOT | GOTRel)) 449 return; 450 // FIXME: check STT_GNU_IFUNC symbol 451 m_pGOT->reserve(); 452 453 // If the GOT is used in statically linked binaries, 454 // the GOT entry is enough and no relocation is needed. 455 if (config().isCodeStatic()) { 456 rsym->setReserved(rsym->reserved() | ReserveGOT); 457 return; 458 } 459 // If building shared object or the symbol is undefined, a dynamic 460 // relocation is needed to relocate this GOT entry. Reserve an 461 // entry in .rel.dyn 462 if (LinkerConfig::DynObj == 463 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) { 464 m_pRelDyn->reserveEntry(); 465 // set GOTRel bit 466 rsym->setReserved(rsym->reserved() | GOTRel); 467 return; 468 } 469 // set GOT bit 470 rsym->setReserved(rsym->reserved() | ReserveGOT); 471 return; 472 473 case llvm::ELF::R_386_PC32: 474 case llvm::ELF::R_386_PC16: 475 case llvm::ELF::R_386_PC8: 476 return; 477 478 case llvm::ELF::R_386_TLS_GD: { 479 // FIXME: no linker optimization for TLS relocation 480 if (rsym->reserved() & GOTRel) 481 return; 482 m_pGOT->reserve(2); 483 // reserve an rel entry 484 m_pRelDyn->reserveEntry(); 485 // set GOTRel bit 486 rsym->setReserved(rsym->reserved() | GOTRel); 487 // define the section symbol for .tdata or .tbss 488 // the target symbol of the created dynamic relocation should be the 489 // section symbol of the section which this symbol defined. so we 490 // need to define that section symbol here 491 ELFFileFormat* file_format = getOutputFormat(); 492 const LDSection* sym_sect = 493 &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection(); 494 if (&file_format->getTData() == sym_sect) { 495 if (NULL == f_pTDATA) 496 f_pTDATA = pModule.getSectionSymbolSet().get(*sym_sect); 497 } 498 else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) { 499 if (NULL == f_pTBSS) 500 f_pTBSS = pModule.getSectionSymbolSet().get(*sym_sect); 501 } 502 else 503 error(diag::invalid_tls) << rsym->name() << sym_sect->name(); 504 return; 505 } 506 507 case llvm::ELF::R_386_TLS_LDM: 508 getTLSModuleID(); 509 return; 510 511 case llvm::ELF::R_386_TLS_LDO_32: 512 return; 513 514 case llvm::ELF::R_386_TLS_IE: 515 setHasStaticTLS(); 516 // if buildint shared object, a RELATIVE dynamic relocation is needed 517 if (LinkerConfig::DynObj == config().codeGenType()) { 518 m_pRelDyn->reserveEntry(); 519 rsym->setReserved(rsym->reserved() | ReserveRel); 520 checkAndSetHasTextRel(*pSection.getLink()); 521 } else { 522 // for local sym, we can convert ie to le if not building shared object 523 convertTLSIEtoLE(pReloc, pSection); 524 return; 525 } 526 if (rsym->reserved() & GOTRel) 527 return; 528 // reserve got and dyn relocation entries for tp-relative offset 529 m_pGOT->reserve(); 530 m_pRelDyn->reserveEntry(); 531 // set GOTRel bit 532 rsym->setReserved(rsym->reserved() | GOTRel); 533 m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol()); 534 return; 535 536 case llvm::ELF::R_386_TLS_GOTIE: 537 setHasStaticTLS(); 538 if (rsym->reserved() & GOTRel) 539 return; 540 // reserve got and dyn relocation entries for tp-relative offset 541 m_pGOT->reserve(); 542 m_pRelDyn->reserveEntry(); 543 // set GOTRel bit 544 rsym->setReserved(rsym->reserved() | GOTRel); 545 m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol()); 546 return; 547 548 case llvm::ELF::R_386_TLS_LE: 549 case llvm::ELF::R_386_TLS_LE_32: 550 setHasStaticTLS(); 551 // if buildint shared object, a dynamic relocation is needed 552 if (LinkerConfig::DynObj == config().codeGenType()) { 553 m_pRelDyn->reserveEntry(); 554 rsym->setReserved(rsym->reserved() | ReserveRel); 555 checkAndSetHasTextRel(*pSection.getLink()); 556 // the target symbol of the dynamic relocation is rsym, so we need to 557 // emit it into .dynsym 558 assert(NULL != rsym->outSymbol()); 559 m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol()); 560 } 561 return; 562 563 default: 564 fatal(diag::unsupported_relocation) << (int)pReloc.type() 565 << "mclinker@googlegroups.com"; 566 break; 567 } // end switch 568} 569 570void X86_32GNULDBackend::scanGlobalReloc(Relocation& pReloc, 571 IRBuilder& pBuilder, 572 Module& pModule, 573 LDSection& pSection) 574{ 575 // rsym - The relocation target symbol 576 ResolveInfo* rsym = pReloc.symInfo(); 577 578 switch(pReloc.type()) { 579 case llvm::ELF::R_386_32: 580 case llvm::ELF::R_386_16: 581 case llvm::ELF::R_386_8: 582 // Absolute relocation type, symbol may needs PLT entry or 583 // dynamic relocation entry 584 if (symbolNeedsPLT(*rsym)) { 585 // create plt for this symbol if it does not have one 586 if (!(rsym->reserved() & ReservePLT)){ 587 // Symbol needs PLT entry, we need to reserve a PLT entry 588 // and the corresponding GOT and dynamic relocation entry 589 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 590 // when calling X86PLT->reserveEntry()) 591 m_pPLT->reserveEntry(); 592 m_pGOTPLT->reserve(); 593 m_pRelPLT->reserveEntry(); 594 // set PLT bit 595 rsym->setReserved(rsym->reserved() | ReservePLT); 596 } 597 } 598 599 if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) { 600 // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 601 m_pRelDyn->reserveEntry(); 602 if (symbolNeedsCopyReloc(pReloc, *rsym)) { 603 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym); 604 addCopyReloc(*cpy_sym.resolveInfo()); 605 } 606 else { 607 // set Rel bit 608 rsym->setReserved(rsym->reserved() | ReserveRel); 609 checkAndSetHasTextRel(pSection); 610 } 611 } 612 return; 613 614 case llvm::ELF::R_386_GOTOFF: 615 case llvm::ELF::R_386_GOTPC: { 616 // FIXME: A GOT section is needed 617 return; 618 } 619 620 case llvm::ELF::R_386_PLT32: 621 // A PLT entry is needed when building shared library 622 623 // return if we already create plt for this symbol 624 if (rsym->reserved() & ReservePLT) 625 return; 626 627 // if the symbol's value can be decided at link time, then no need plt 628 if (symbolFinalValueIsKnown(*rsym)) 629 return; 630 631 // if symbol is defined in the ouput file and it's not 632 // preemptible, no need plt 633 if (rsym->isDefine() && !rsym->isDyn() && 634 !isSymbolPreemptible(*rsym)) { 635 return; 636 } 637 638 // Symbol needs PLT entry, we need to reserve a PLT entry 639 // and the corresponding GOT and dynamic relocation entry 640 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 641 // when calling X86PLT->reserveEntry()) 642 m_pPLT->reserveEntry(); 643 m_pGOTPLT->reserve(); 644 m_pRelPLT->reserveEntry(); 645 // set PLT bit 646 rsym->setReserved(rsym->reserved() | ReservePLT); 647 return; 648 649 case llvm::ELF::R_386_GOT32: 650 // Symbol needs GOT entry, reserve entry in .got 651 // return if we already create GOT for this symbol 652 if (rsym->reserved() & (ReserveGOT | GOTRel)) 653 return; 654 m_pGOT->reserve(); 655 656 // If the GOT is used in statically linked binaries, 657 // the GOT entry is enough and no relocation is needed. 658 if (config().isCodeStatic()) { 659 rsym->setReserved(rsym->reserved() | ReserveGOT); 660 return; 661 } 662 // If building shared object or the symbol is undefined, a dynamic 663 // relocation is needed to relocate this GOT entry. Reserve an 664 // entry in .rel.dyn 665 if (LinkerConfig::DynObj == 666 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) { 667 m_pRelDyn->reserveEntry(); 668 // set GOTRel bit 669 rsym->setReserved(rsym->reserved() | GOTRel); 670 return; 671 } 672 // set GOT bit 673 rsym->setReserved(rsym->reserved() | ReserveGOT); 674 return; 675 676 case llvm::ELF::R_386_PC32: 677 case llvm::ELF::R_386_PC16: 678 case llvm::ELF::R_386_PC8: 679 680 if (symbolNeedsPLT(*rsym) && 681 LinkerConfig::DynObj != config().codeGenType()) { 682 // create plt for this symbol if it does not have one 683 if (!(rsym->reserved() & ReservePLT)){ 684 // Symbol needs PLT entry, we need to reserve a PLT entry 685 // and the corresponding GOT and dynamic relocation entry 686 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 687 // when calling X86PLT->reserveEntry()) 688 m_pPLT->reserveEntry(); 689 m_pGOTPLT->reserve(); 690 m_pRelPLT->reserveEntry(); 691 // set PLT bit 692 rsym->setReserved(rsym->reserved() | ReservePLT); 693 } 694 } 695 696 if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false)) { 697 // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 698 m_pRelDyn->reserveEntry(); 699 if (symbolNeedsCopyReloc(pReloc, *rsym)) { 700 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym); 701 addCopyReloc(*cpy_sym.resolveInfo()); 702 } 703 else { 704 // set Rel bit 705 rsym->setReserved(rsym->reserved() | ReserveRel); 706 checkAndSetHasTextRel(pSection); 707 } 708 } 709 return; 710 711 case llvm::ELF::R_386_TLS_GD: { 712 // FIXME: no linker optimization for TLS relocation 713 if (rsym->reserved() & GOTRel) 714 return; 715 // reserve two pairs of got entry and dynamic relocation 716 m_pGOT->reserve(2); 717 m_pRelDyn->reserveEntry(2); 718 // set GOTRel bit 719 rsym->setReserved(rsym->reserved() | GOTRel); 720 return; 721 } 722 723 case llvm::ELF::R_386_TLS_LDM: 724 getTLSModuleID(); 725 return; 726 727 case llvm::ELF::R_386_TLS_LDO_32: 728 return; 729 730 case llvm::ELF::R_386_TLS_IE: 731 setHasStaticTLS(); 732 // if buildint shared object, a RELATIVE dynamic relocation is needed 733 if (LinkerConfig::DynObj == config().codeGenType()) { 734 m_pRelDyn->reserveEntry(); 735 rsym->setReserved(rsym->reserved() | ReserveRel); 736 checkAndSetHasTextRel(*pSection.getLink()); 737 } else { 738 // for global sym, we can convert ie to le if its final value is known 739 if (symbolFinalValueIsKnown(*rsym)) { 740 convertTLSIEtoLE(pReloc, pSection); 741 return; 742 } 743 } 744 if (rsym->reserved() & GOTRel) 745 return; 746 // reserve got and dyn relocation entries for tp-relative offset 747 m_pGOT->reserve(); 748 m_pRelDyn->reserveEntry(); 749 // set GOTRel bit 750 rsym->setReserved(rsym->reserved() | GOTRel); 751 return; 752 753 case llvm::ELF::R_386_TLS_GOTIE: 754 setHasStaticTLS(); 755 if (rsym->reserved() & GOTRel) 756 return; 757 // reserve got and dyn relocation entries for tp-relative offset 758 m_pGOT->reserve(); 759 m_pRelDyn->reserveEntry(); 760 // set GOTRel bit 761 rsym->setReserved(rsym->reserved() | GOTRel); 762 return; 763 764 case llvm::ELF::R_386_TLS_LE: 765 case llvm::ELF::R_386_TLS_LE_32: 766 setHasStaticTLS(); 767 // if buildint shared object, a dynamic relocation is needed 768 if (LinkerConfig::DynObj == config().codeGenType()) { 769 m_pRelDyn->reserveEntry(); 770 rsym->setReserved(rsym->reserved() | ReserveRel); 771 checkAndSetHasTextRel(*pSection.getLink()); 772 } 773 return; 774 775 default: { 776 fatal(diag::unsupported_relocation) << (int)pReloc.type() 777 << "mclinker@googlegroups.com"; 778 break; 779 } 780 } // end switch 781} 782 783void X86_32GNULDBackend::initTargetSections(Module& pModule, 784 ObjectBuilder& pBuilder) 785{ 786 if (LinkerConfig::Object != config().codeGenType()) { 787 ELFFileFormat* file_format = getOutputFormat(); 788 // initialize .got 789 LDSection& got = file_format->getGOT(); 790 m_pGOT = new X86_32GOT(got); 791 792 // initialize .got.plt 793 LDSection& gotplt = file_format->getGOTPLT(); 794 m_pGOTPLT = new X86_32GOTPLT(gotplt); 795 796 // initialize .plt 797 LDSection& plt = file_format->getPLT(); 798 m_pPLT = new X86_32PLT(plt, 799 *m_pGOTPLT, 800 config()); 801 802 // initialize .rel.plt 803 LDSection& relplt = file_format->getRelPlt(); 804 relplt.setLink(&plt); 805 m_pRelPLT = new OutputRelocSection(pModule, relplt); 806 807 // initialize .rel.dyn 808 LDSection& reldyn = file_format->getRelDyn(); 809 m_pRelDyn = new OutputRelocSection(pModule, reldyn); 810 811 } 812} 813 814X86_32GOT& X86_32GNULDBackend::getGOT() 815{ 816 assert(NULL != m_pGOT); 817 return *m_pGOT; 818} 819 820const X86_32GOT& X86_32GNULDBackend::getGOT() const 821{ 822 assert(NULL != m_pGOT); 823 return *m_pGOT; 824} 825 826X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() 827{ 828 assert(NULL != m_pGOTPLT); 829 return *m_pGOTPLT; 830} 831 832const X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() const 833{ 834 assert(NULL != m_pGOTPLT); 835 return *m_pGOTPLT; 836} 837 838void X86_32GNULDBackend::setRelDynSize() 839{ 840 ELFFileFormat* file_format = getOutputFormat(); 841 file_format->getRelDyn().setSize 842 (m_pRelDyn->numOfRelocs() * getRelEntrySize()); 843} 844 845void X86_32GNULDBackend::setRelPLTSize() 846{ 847 ELFFileFormat* file_format = getOutputFormat(); 848 file_format->getRelPlt().setSize 849 (m_pRelPLT->numOfRelocs() * getRelEntrySize()); 850} 851 852void X86_32GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder) 853{ 854 // set .got.plt size 855 if (LinkerConfig::DynObj == config().codeGenType() || 856 m_pGOTPLT->hasGOT1() || 857 NULL != m_pGOTSymbol) { 858 m_pGOTPLT->finalizeSectionSize(); 859 defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 860 } 861 862 // set .got size 863 if (!m_pGOT->empty()) 864 m_pGOT->finalizeSectionSize(); 865} 866 867uint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const 868{ 869 assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 870 871 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 872 873 X86_32GOTEntry* got = 0; 874 unsigned int EntrySize = X86_32GOTEntry::EntrySize; 875 uint64_t RegionSize = 0; 876 877 for (X86_32GOT::iterator it = m_pGOT->begin(), 878 ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 879 got = &(llvm::cast<X86_32GOTEntry>((*it))); 880 *buffer = static_cast<uint32_t>(got->getValue()); 881 RegionSize += EntrySize; 882 } 883 884 return RegionSize; 885} 886 887uint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, 888 const ELFFileFormat* FileFormat) const 889{ 890 assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 891 m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 892 m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 893 894 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 895 896 X86_32GOTEntry* got = 0; 897 unsigned int EntrySize = X86_32GOTEntry::EntrySize; 898 uint64_t RegionSize = 0; 899 900 for (X86_32GOTPLT::iterator it = m_pGOTPLT->begin(), 901 ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 902 got = &(llvm::cast<X86_32GOTEntry>((*it))); 903 *buffer = static_cast<uint32_t>(got->getValue()); 904 RegionSize += EntrySize; 905 } 906 907 return RegionSize; 908} 909 910/// convert R_386_TLS_IE to R_386_TLS_LE 911void X86_32GNULDBackend::convertTLSIEtoLE(Relocation& pReloc, 912 LDSection& pSection) 913{ 914 assert(pReloc.type() == llvm::ELF::R_386_TLS_IE); 915 assert(NULL != pReloc.targetRef().frag()); 916 917 // 1. create the fragment references and new relocs 918 uint64_t off = pReloc.targetRef().offset(); 919 if (off >= 4) 920 off -= 4; 921 else 922 off = 0; 923 924 FragmentRef* fragref = FragmentRef::Create(*pReloc.targetRef().frag(), off); 925 // TODO: add symbols for R_386_TLS_OPT relocs 926 Relocation* reloc = Relocation::Create(X86_32Relocator::R_386_TLS_OPT, 927 *fragref, 928 0x0); 929 930 // 2. modify the opcodes to the appropriate ones 931 uint8_t* op = (reinterpret_cast<uint8_t*>(&reloc->target())); 932 off = pReloc.targetRef().offset() - reloc->targetRef().offset() - 1; 933 if (op[off] == 0xa1) { 934 op[off] = 0xb8; 935 } else { 936 switch (op[off - 1]) { 937 case 0x8b: 938 assert((op[off] & 0xc7) == 0x05); 939 op[off - 1] = 0xc7; 940 op[off] = 0xc0 | ((op[off] >> 3) & 7); 941 break; 942 case 0x03: 943 assert((op[off] & 0xc7) == 0x05); 944 op[off - 1] = 0x81; 945 op[off] = 0xc0 | ((op[off] >> 3) & 7); 946 break; 947 default: 948 assert(0); 949 break; 950 } 951 } 952 953 // 3. insert the new relocs "BEFORE" the original reloc. 954 pSection.getRelocData()->getRelocationList().insert( 955 RelocData::iterator(pReloc), reloc); 956 957 // 4. change the type of the original reloc 958 pReloc.setType(llvm::ELF::R_386_TLS_LE); 959} 960 961// Create a GOT entry for the TLS module index 962X86_32GOTEntry& X86_32GNULDBackend::getTLSModuleID() 963{ 964 static X86_32GOTEntry* got_entry = NULL; 965 if (NULL != got_entry) 966 return *got_entry; 967 968 // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM 969 m_pGOT->reserve(2); 970 got_entry = m_pGOT->consume(); 971 m_pGOT->consume()->setValue(0x0); 972 973 m_pRelDyn->reserveEntry(); 974 Relocation* rel_entry = m_pRelDyn->consumeEntry(); 975 rel_entry->setType(llvm::ELF::R_386_TLS_DTPMOD32); 976 rel_entry->targetRef().assign(*got_entry, 0x0); 977 rel_entry->setSymInfo(NULL); 978 979 return *got_entry; 980} 981 982X86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig, 983 GNUInfo* pInfo) 984 : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY), 985 m_pGOT (NULL), 986 m_pGOTPLT (NULL) { 987} 988 989X86_64GNULDBackend::~X86_64GNULDBackend() 990{ 991 delete m_pGOT; 992 delete m_pGOTPLT; 993} 994 995bool X86_64GNULDBackend::initRelocator() 996{ 997 if (NULL == m_pRelocator) { 998 m_pRelocator = new X86_64Relocator(*this); 999 } 1000 return true; 1001} 1002 1003X86_64GOT& X86_64GNULDBackend::getGOT() 1004{ 1005 assert(NULL != m_pGOT); 1006 return *m_pGOT; 1007} 1008 1009const X86_64GOT& X86_64GNULDBackend::getGOT() const 1010{ 1011 assert(NULL != m_pGOT); 1012 return *m_pGOT; 1013} 1014 1015X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() 1016{ 1017 assert(NULL != m_pGOTPLT); 1018 return *m_pGOTPLT; 1019} 1020 1021const X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() const 1022{ 1023 assert(NULL != m_pGOTPLT); 1024 return *m_pGOTPLT; 1025} 1026 1027void X86_64GNULDBackend::setRelDynSize() 1028{ 1029 ELFFileFormat* file_format = getOutputFormat(); 1030 file_format->getRelaDyn().setSize 1031 (m_pRelDyn->numOfRelocs() * getRelaEntrySize()); 1032} 1033 1034void X86_64GNULDBackend::setRelPLTSize() 1035{ 1036 ELFFileFormat* file_format = getOutputFormat(); 1037 file_format->getRelaPlt().setSize 1038 (m_pRelPLT->numOfRelocs() * getRelaEntrySize()); 1039} 1040 1041void X86_64GNULDBackend::scanLocalReloc(Relocation& pReloc, 1042 IRBuilder& pBuilder, 1043 Module& pModule, 1044 LDSection& pSection) 1045{ 1046 // rsym - The relocation target symbol 1047 ResolveInfo* rsym = pReloc.symInfo(); 1048 1049 switch(pReloc.type()){ 1050 case llvm::ELF::R_X86_64_64: 1051 case llvm::ELF::R_X86_64_32: 1052 case llvm::ELF::R_X86_64_16: 1053 case llvm::ELF::R_X86_64_8: 1054 case llvm::ELF::R_X86_64_32S: 1055 // If buiding PIC object (shared library or PIC executable), 1056 // a dynamic relocations with RELATIVE type to this location is needed. 1057 // Reserve an entry in .rela.dyn 1058 if (config().isCodeIndep()) { 1059 m_pRelDyn->reserveEntry(); 1060 // set Rel bit 1061 rsym->setReserved(rsym->reserved() | ReserveRel); 1062 checkAndSetHasTextRel(*pSection.getLink()); 1063 } 1064 return; 1065 1066 case llvm::ELF::R_X86_64_PC32: 1067 case llvm::ELF::R_X86_64_PC16: 1068 case llvm::ELF::R_X86_64_PC8: 1069 return; 1070 1071 case llvm::ELF::R_X86_64_GOTPCREL: 1072 // Symbol needs GOT entry, reserve entry in .got 1073 // return if we already create GOT for this symbol 1074 if (rsym->reserved() & (ReserveGOT | GOTRel)) 1075 return; 1076 m_pGOT->reserve(); 1077 1078 // If the GOT is used in statically linked binaries, 1079 // the GOT entry is enough and no relocation is needed. 1080 if (config().isCodeStatic()) { 1081 rsym->setReserved(rsym->reserved() | ReserveGOT); 1082 return; 1083 } 1084 // If building shared object or the symbol is undefined, a dynamic 1085 // relocation is needed to relocate this GOT entry. Reserve an 1086 // entry in .rela.dyn 1087 if (LinkerConfig::DynObj == 1088 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) { 1089 m_pRelDyn->reserveEntry(); 1090 // set GOTRel bit 1091 rsym->setReserved(rsym->reserved() | GOTRel); 1092 return; 1093 } 1094 // set GOT bit 1095 rsym->setReserved(rsym->reserved() | ReserveGOT); 1096 return; 1097 1098 default: 1099 fatal(diag::unsupported_relocation) << (int)pReloc.type() 1100 << "mclinker@googlegroups.com"; 1101 break; 1102 } // end switch 1103} 1104 1105void X86_64GNULDBackend::scanGlobalReloc(Relocation& pReloc, 1106 IRBuilder& pBuilder, 1107 Module& pModule, 1108 LDSection& pSection) 1109{ 1110 // rsym - The relocation target symbol 1111 ResolveInfo* rsym = pReloc.symInfo(); 1112 1113 switch(pReloc.type()) { 1114 case llvm::ELF::R_X86_64_64: 1115 case llvm::ELF::R_X86_64_32: 1116 case llvm::ELF::R_X86_64_16: 1117 case llvm::ELF::R_X86_64_8: 1118 case llvm::ELF::R_X86_64_32S: 1119 // Absolute relocation type, symbol may needs PLT entry or 1120 // dynamic relocation entry 1121 if (symbolNeedsPLT(*rsym)) { 1122 // create plt for this symbol if it does not have one 1123 if (!(rsym->reserved() & ReservePLT)){ 1124 // Symbol needs PLT entry, we need to reserve a PLT entry 1125 // and the corresponding GOT and dynamic relocation entry 1126 // in .got and .rela.plt. (GOT entry will be reserved simultaneously 1127 // when calling X86PLT->reserveEntry()) 1128 m_pPLT->reserveEntry(); 1129 m_pGOTPLT->reserve(); 1130 m_pRelPLT->reserveEntry(); 1131 // set PLT bit 1132 rsym->setReserved(rsym->reserved() | ReservePLT); 1133 } 1134 } 1135 1136 if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) { 1137 // symbol needs dynamic relocation entry, reserve an entry in .rela.dyn 1138 m_pRelDyn->reserveEntry(); 1139 if (symbolNeedsCopyReloc(pReloc, *rsym)) { 1140 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym); 1141 addCopyReloc(*cpy_sym.resolveInfo()); 1142 } 1143 else { 1144 // set Rel bit 1145 rsym->setReserved(rsym->reserved() | ReserveRel); 1146 checkAndSetHasTextRel(*pSection.getLink()); 1147 } 1148 } 1149 return; 1150 1151 case llvm::ELF::R_X86_64_GOTPCREL: 1152 // Symbol needs GOT entry, reserve entry in .got 1153 // return if we already create GOT for this symbol 1154 if (rsym->reserved() & (ReserveGOT | GOTRel)) 1155 return; 1156 m_pGOT->reserve(); 1157 1158 // If the GOT is used in statically linked binaries, 1159 // the GOT entry is enough and no relocation is needed. 1160 if (config().isCodeStatic()) { 1161 rsym->setReserved(rsym->reserved() | ReserveGOT); 1162 return; 1163 } 1164 // If building shared object or the symbol is undefined, a dynamic 1165 // relocation is needed to relocate this GOT entry. Reserve an 1166 // entry in .rela.dyn 1167 if (LinkerConfig::DynObj == 1168 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) { 1169 m_pRelDyn->reserveEntry(); 1170 // set GOTRel bit 1171 rsym->setReserved(rsym->reserved() | GOTRel); 1172 return; 1173 } 1174 // set GOT bit 1175 rsym->setReserved(rsym->reserved() | ReserveGOT); 1176 return; 1177 1178 case llvm::ELF::R_X86_64_PLT32: 1179 // A PLT entry is needed when building shared library 1180 1181 // return if we already create plt for this symbol 1182 if (rsym->reserved() & ReservePLT) 1183 return; 1184 1185 // if the symbol's value can be decided at link time, then no need plt 1186 if (symbolFinalValueIsKnown(*rsym)) 1187 return; 1188 1189 // if symbol is defined in the ouput file and it's not 1190 // preemptible, no need plt 1191 if (rsym->isDefine() && !rsym->isDyn() && 1192 !isSymbolPreemptible(*rsym)) { 1193 return; 1194 } 1195 1196 // Symbol needs PLT entry, we need to reserve a PLT entry 1197 // and the corresponding GOT and dynamic relocation entry 1198 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 1199 // when calling X86PLT->reserveEntry()) 1200 m_pPLT->reserveEntry(); 1201 m_pGOTPLT->reserve(); 1202 m_pRelPLT->reserveEntry(); 1203 // set PLT bit 1204 rsym->setReserved(rsym->reserved() | ReservePLT); 1205 return; 1206 1207 case llvm::ELF::R_X86_64_PC32: 1208 case llvm::ELF::R_X86_64_PC16: 1209 case llvm::ELF::R_X86_64_PC8: 1210 if (symbolNeedsPLT(*rsym) && 1211 LinkerConfig::DynObj != config().codeGenType()) { 1212 // create plt for this symbol if it does not have one 1213 if (!(rsym->reserved() & ReservePLT)){ 1214 // Symbol needs PLT entry, we need to reserve a PLT entry 1215 // and the corresponding GOT and dynamic relocation entry 1216 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 1217 // when calling X86PLT->reserveEntry()) 1218 m_pPLT->reserveEntry(); 1219 m_pGOTPLT->reserve(); 1220 m_pRelPLT->reserveEntry(); 1221 // set PLT bit 1222 rsym->setReserved(rsym->reserved() | ReservePLT); 1223 } 1224 } 1225 1226 // Only PC relative relocation against dynamic symbol needs a 1227 // dynamic relocation. Only dynamic copy relocation is allowed 1228 // and PC relative relocation will be resolved to the local copy. 1229 // All other dynamic relocations may lead to run-time relocation 1230 // overflow. 1231 if (isDynamicSymbol(*rsym) && 1232 symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false) && 1233 symbolNeedsCopyReloc(pReloc, *rsym)) { 1234 m_pRelDyn->reserveEntry(); 1235 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym); 1236 addCopyReloc(*cpy_sym.resolveInfo()); 1237 } 1238 return; 1239 1240 default: 1241 fatal(diag::unsupported_relocation) << (int)pReloc.type() 1242 << "mclinker@googlegroups.com"; 1243 break; 1244 } // end switch 1245} 1246 1247void X86_64GNULDBackend::initTargetSections(Module& pModule, 1248 ObjectBuilder& pBuilder) 1249{ 1250 if (LinkerConfig::Object != config().codeGenType()) { 1251 ELFFileFormat* file_format = getOutputFormat(); 1252 // initialize .got 1253 LDSection& got = file_format->getGOT(); 1254 m_pGOT = new X86_64GOT(got); 1255 1256 // initialize .got.plt 1257 LDSection& gotplt = file_format->getGOTPLT(); 1258 m_pGOTPLT = new X86_64GOTPLT(gotplt); 1259 1260 // initialize .plt 1261 LDSection& plt = file_format->getPLT(); 1262 m_pPLT = new X86_64PLT(plt, 1263 *m_pGOTPLT, 1264 config()); 1265 1266 // initialize .rela.plt 1267 LDSection& relplt = file_format->getRelaPlt(); 1268 relplt.setLink(&plt); 1269 m_pRelPLT = new OutputRelocSection(pModule, relplt); 1270 1271 // initialize .rela.dyn 1272 LDSection& reldyn = file_format->getRelaDyn(); 1273 m_pRelDyn = new OutputRelocSection(pModule, reldyn); 1274 1275 } 1276} 1277 1278void X86_64GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder) 1279{ 1280 // set .got.plt size 1281 if (LinkerConfig::DynObj == config().codeGenType() || 1282 m_pGOTPLT->hasGOT1() || 1283 NULL != m_pGOTSymbol) { 1284 m_pGOTPLT->finalizeSectionSize(); 1285 defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 1286 } 1287 1288 // set .got size 1289 if (!m_pGOT->empty()) 1290 m_pGOT->finalizeSectionSize(); 1291} 1292 1293uint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const 1294{ 1295 assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 1296 1297 uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer()); 1298 1299 X86_64GOTEntry* got = 0; 1300 unsigned int EntrySize = X86_64GOTEntry::EntrySize; 1301 uint64_t RegionSize = 0; 1302 1303 for (X86_64GOT::iterator it = m_pGOT->begin(), 1304 ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 1305 got = &(llvm::cast<X86_64GOTEntry>((*it))); 1306 *buffer = static_cast<uint64_t>(got->getValue()); 1307 RegionSize += EntrySize; 1308 } 1309 1310 return RegionSize; 1311} 1312 1313uint64_t X86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, 1314 const ELFFileFormat* FileFormat) const 1315{ 1316 assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 1317 m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 1318 m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 1319 1320 uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer()); 1321 1322 X86_64GOTEntry* got = 0; 1323 unsigned int EntrySize = X86_64GOTEntry::EntrySize; 1324 uint64_t RegionSize = 0; 1325 1326 for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(), 1327 ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 1328 got = &(llvm::cast<X86_64GOTEntry>((*it))); 1329 *buffer = static_cast<uint64_t>(got->getValue()); 1330 RegionSize += EntrySize; 1331 } 1332 1333 return RegionSize; 1334} 1335 1336namespace mcld { 1337 1338//===----------------------------------------------------------------------===// 1339/// createX86LDBackend - the help funtion to create corresponding X86LDBackend 1340/// 1341TargetLDBackend* createX86LDBackend(const llvm::Target& pTarget, 1342 const LinkerConfig& pConfig) 1343{ 1344 if (pConfig.targets().triple().isOSDarwin()) { 1345 assert(0 && "MachO linker is not supported yet"); 1346 /** 1347 return new X86MachOLDBackend(createX86MachOArchiveReader, 1348 createX86MachOObjectReader, 1349 createX86MachOObjectWriter); 1350 **/ 1351 } 1352 if (pConfig.targets().triple().isOSWindows()) { 1353 assert(0 && "COFF linker is not supported yet"); 1354 /** 1355 return new X86COFFLDBackend(createX86COFFArchiveReader, 1356 createX86COFFObjectReader, 1357 createX86COFFObjectWriter); 1358 **/ 1359 } 1360 Triple::ArchType arch = pConfig.targets().triple().getArch(); 1361 if (arch == Triple::x86) 1362 return new X86_32GNULDBackend(pConfig, 1363 new X86_32GNUInfo(pConfig.targets().triple())); 1364 assert (arch == Triple::x86_64); 1365 return new X86_64GNULDBackend(pConfig, 1366 new X86_64GNUInfo(pConfig.targets().triple())); 1367} 1368 1369} // namespace of mcld 1370 1371//===----------------------------------------------------------------------===// 1372// Force static initialization. 1373//===----------------------------------------------------------------------===// 1374extern "C" void MCLDInitializeX86LDBackend() { 1375 // Register the linker backend 1376 mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_32Target, createX86LDBackend); 1377 mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_64Target, createX86LDBackend); 1378} 1379