X86LDBackend.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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 "X86RelocationFactory.h" 13 14#include <llvm/ADT/Triple.h> 15#include <llvm/Support/Casting.h> 16 17#include <mcld/LinkerConfig.h> 18#include <mcld/IRBuilder.h> 19#include <mcld/Fragment/FillFragment.h> 20#include <mcld/Fragment/RegionFragment.h> 21#include <mcld/Fragment/FragmentLinker.h> 22#include <mcld/Support/MemoryRegion.h> 23#include <mcld/Support/MsgHandling.h> 24#include <mcld/Support/TargetRegistry.h> 25#include <mcld/Object/ObjectBuilder.h> 26 27#include <cstring> 28 29using namespace mcld; 30 31//===----------------------------------------------------------------------===// 32// X86GNULDBackend 33//===----------------------------------------------------------------------===// 34X86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig) 35 : GNULDBackend(pConfig), 36 m_pRelocFactory(NULL), 37 m_pGOT(NULL), 38 m_pPLT(NULL), 39 m_pGOTPLT(NULL), 40 m_pRelDyn(NULL), 41 m_pRelPLT(NULL), 42 m_pDynamic(NULL), 43 m_pGOTSymbol(NULL) { 44} 45 46X86GNULDBackend::~X86GNULDBackend() 47{ 48 delete m_pRelocFactory; 49 delete m_pGOT; 50 delete m_pPLT; 51 delete m_pGOTPLT; 52 delete m_pRelDyn; 53 delete m_pRelPLT; 54 delete m_pDynamic; 55} 56 57RelocationFactory* X86GNULDBackend::getRelocFactory() 58{ 59 assert(NULL != m_pRelocFactory); 60 return m_pRelocFactory; 61} 62 63bool X86GNULDBackend::initRelocFactory(const FragmentLinker& pLinker) 64{ 65 if (NULL == m_pRelocFactory) { 66 m_pRelocFactory = new X86RelocationFactory(1024, *this); 67 m_pRelocFactory->setFragmentLinker(pLinker); 68 } 69 return true; 70} 71 72void X86GNULDBackend::doPreLayout(FragmentLinker& pLinker) 73{ 74 // set .got.plt size 75 // when building shared object, the .got section is must 76 if (LinkerConfig::Object != config().codeGenType()) { 77 if (LinkerConfig::DynObj == config().codeGenType() || 78 m_pGOTPLT->hasGOT1() || 79 NULL != m_pGOTSymbol) { 80 m_pGOTPLT->finalizeSectionSize(); 81 defineGOTSymbol(pLinker); 82 } 83 84 // set .got size 85 if (!m_pGOT->empty()) 86 m_pGOT->finalizeSectionSize(); 87 88 // set .plt size 89 if (m_pPLT->hasPLT1()) 90 m_pPLT->finalizeSectionSize(); 91 92 // set .rel.dyn size 93 if (!m_pRelDyn->empty()) 94 m_pRelDyn->finalizeSectionSize(); 95 96 // set .rel.plt size 97 if (!m_pRelPLT->empty()) 98 m_pRelPLT->finalizeSectionSize(); 99 } 100} 101 102void X86GNULDBackend::doPostLayout(Module& pModule, 103 FragmentLinker& pLinker) 104{ 105} 106 107/// dynamic - the dynamic section of the target machine. 108/// Use co-variant return type to return its own dynamic section. 109X86ELFDynamic& X86GNULDBackend::dynamic() 110{ 111 if (NULL == m_pDynamic) 112 m_pDynamic = new X86ELFDynamic(*this); 113 114 return *m_pDynamic; 115} 116 117/// dynamic - the dynamic section of the target machine. 118/// Use co-variant return type to return its own dynamic section. 119const X86ELFDynamic& X86GNULDBackend::dynamic() const 120{ 121 assert( NULL != m_pDynamic); 122 return *m_pDynamic; 123} 124 125void X86GNULDBackend::defineGOTSymbol(FragmentLinker& pLinker) 126{ 127 // define symbol _GLOBAL_OFFSET_TABLE_ 128 if (m_pGOTSymbol != NULL) { 129 pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Unresolve>( 130 "_GLOBAL_OFFSET_TABLE_", 131 false, 132 ResolveInfo::Object, 133 ResolveInfo::Define, 134 ResolveInfo::Local, 135 0x0, // size 136 0x0, // value 137 FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0), 138 ResolveInfo::Hidden); 139 } 140 else { 141 m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>( 142 "_GLOBAL_OFFSET_TABLE_", 143 false, 144 ResolveInfo::Object, 145 ResolveInfo::Define, 146 ResolveInfo::Local, 147 0x0, // size 148 0x0, // value 149 FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0), 150 ResolveInfo::Hidden); 151 } 152} 153 154void X86GNULDBackend::addCopyReloc(ResolveInfo& pSym) 155{ 156 Relocation& rel_entry = *m_pRelDyn->consumeEntry(); 157 rel_entry.setType(llvm::ELF::R_386_COPY); 158 assert(pSym.outSymbol()->hasFragRef()); 159 rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef()); 160 rel_entry.setSymInfo(&pSym); 161} 162 163/// defineSymbolforCopyReloc 164/// For a symbol needing copy relocation, define a copy symbol in the BSS 165/// section and all other reference to this symbol should refer to this 166/// copy. 167/// @note This is executed at `scan relocation' stage. 168LDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(FragmentLinker& pLinker, 169 const ResolveInfo& pSym) 170{ 171 // get or create corresponding BSS LDSection 172 LDSection* bss_sect_hdr = NULL; 173 ELFFileFormat* file_format = getOutputFormat(); 174 if (ResolveInfo::ThreadLocal == pSym.type()) 175 bss_sect_hdr = &file_format->getTBSS(); 176 else 177 bss_sect_hdr = &file_format->getBSS(); 178 179 // get or create corresponding BSS SectionData 180 assert(NULL != bss_sect_hdr); 181 SectionData* bss_section = NULL; 182 if (bss_sect_hdr->hasSectionData()) 183 bss_section = bss_sect_hdr->getSectionData(); 184 else 185 bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr); 186 187 // Determine the alignment by the symbol value 188 // FIXME: here we use the largest alignment 189 uint32_t addralign = bitclass() / 8; 190 191 // allocate space in BSS for the copy symbol 192 Fragment* frag = new FillFragment(0x0, 1, pSym.size()); 193 uint64_t size = ObjectBuilder::AppendFragment(*frag, 194 *bss_section, 195 addralign); 196 bss_sect_hdr->setSize(bss_sect_hdr->size() + size); 197 198 // change symbol binding to Global if it's a weak symbol 199 ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding(); 200 if (binding == ResolveInfo::Weak) 201 binding = ResolveInfo::Global; 202 203 // Define the copy symbol in the bss section and resolve it 204 LDSymbol* cpy_sym = 205 pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>( 206 pSym.name(), 207 false, 208 (ResolveInfo::Type)pSym.type(), 209 ResolveInfo::Define, 210 binding, 211 pSym.size(), // size 212 0x0, // value 213 FragmentRef::Create(*frag, 0x0), 214 (ResolveInfo::Visibility)pSym.other()); 215 216 return *cpy_sym; 217} 218 219void X86GNULDBackend::scanLocalReloc(Relocation& pReloc, 220 FragmentLinker& pLinker, 221 Module& pModule, 222 const LDSection& pSection) 223{ 224 // rsym - The relocation target symbol 225 ResolveInfo* rsym = pReloc.symInfo(); 226 227 switch(pReloc.type()){ 228 229 case llvm::ELF::R_386_32: 230 case llvm::ELF::R_386_16: 231 case llvm::ELF::R_386_8: 232 // If buiding PIC object (shared library or PIC executable), 233 // a dynamic relocations with RELATIVE type to this location is needed. 234 // Reserve an entry in .rel.dyn 235 if (pLinker.isOutputPIC()) { 236 m_pRelDyn->reserveEntry(*m_pRelocFactory); 237 // set Rel bit 238 rsym->setReserved(rsym->reserved() | ReserveRel); 239 } 240 return; 241 242 case llvm::ELF::R_386_GOTOFF: 243 case llvm::ELF::R_386_GOTPC: 244 // FIXME: A GOT section is needed 245 return; 246 247 case llvm::ELF::R_386_GOT32: 248 // Symbol needs GOT entry, reserve entry in .got 249 // return if we already create GOT for this symbol 250 if (rsym->reserved() & (ReserveGOT | GOTRel)) 251 return; 252 // FIXME: check STT_GNU_IFUNC symbol 253 m_pGOT->reserve(); 254 // If building shared object or the symbol is undefined, a dynamic 255 // relocation is needed to relocate this GOT entry. Reserve an 256 // entry in .rel.dyn 257 if (LinkerConfig::DynObj == 258 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) { 259 m_pRelDyn->reserveEntry(*m_pRelocFactory); 260 // set GOTRel bit 261 rsym->setReserved(rsym->reserved() | GOTRel); 262 return; 263 } 264 // set GOT bit 265 rsym->setReserved(rsym->reserved() | ReserveGOT); 266 return; 267 268 case llvm::ELF::R_386_PC32: 269 case llvm::ELF::R_386_PC16: 270 case llvm::ELF::R_386_PC8: 271 return; 272 273 case llvm::ELF::R_386_TLS_GD: { 274 // FIXME: no linker optimization for TLS relocation 275 if (rsym->reserved() & GOTRel) 276 return; 277 m_pGOT->reserve(2); 278 // reserve an rel entry 279 m_pRelDyn->reserveEntry(*m_pRelocFactory); 280 // set GOTRel bit 281 rsym->setReserved(rsym->reserved() | GOTRel); 282 // define the section symbol for .tdata or .tbss 283 // the target symbol of the created dynamic relocation should be the 284 // section symbol of the section which this symbol defined. so we 285 // need to define that section symbol here 286 ELFFileFormat* file_format = getOutputFormat(); 287 const LDSection* sym_sect = 288 &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection(); 289 if (&file_format->getTData() == sym_sect) { 290 if (NULL == f_pTDATA) 291 f_pTDATA = pModule.getSectionSymbolSet().get(*sym_sect); 292 } 293 else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) { 294 if (NULL == f_pTBSS) 295 f_pTBSS = pModule.getSectionSymbolSet().get(*sym_sect); 296 } 297 else 298 error(diag::invalid_tls) << rsym->name() << sym_sect->name(); 299 return; 300 } 301 302 case llvm::ELF::R_386_TLS_LDM: 303 getTLSModuleID(); 304 return; 305 306 case llvm::ELF::R_386_TLS_LDO_32: 307 return; 308 309 case llvm::ELF::R_386_TLS_IE: 310 setHasStaticTLS(); 311 // if buildint shared object, a RELATIVE dynamic relocation is needed 312 if (LinkerConfig::DynObj == config().codeGenType()) { 313 m_pRelDyn->reserveEntry(*m_pRelocFactory); 314 rsym->setReserved(rsym->reserved() | ReserveRel); 315 } 316 if (rsym->reserved() & GOTRel) 317 return; 318 // reserve got and dyn relocation entries for tp-relative offset 319 m_pGOT->reserve(); 320 m_pRelDyn->reserveEntry(*m_pRelocFactory); 321 // set GOTRel bit 322 rsym->setReserved(rsym->reserved() | GOTRel); 323 m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol()); 324 return; 325 326 case llvm::ELF::R_386_TLS_GOTIE: 327 setHasStaticTLS(); 328 if (rsym->reserved() & GOTRel) 329 return; 330 // reserve got and dyn relocation entries for tp-relative offset 331 m_pGOT->reserve(); 332 m_pRelDyn->reserveEntry(*m_pRelocFactory); 333 // set GOTRel bit 334 rsym->setReserved(rsym->reserved() | GOTRel); 335 m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol()); 336 return; 337 338 case llvm::ELF::R_386_TLS_LE: 339 case llvm::ELF::R_386_TLS_LE_32: 340 setHasStaticTLS(); 341 // if buildint shared object, a dynamic relocation is needed 342 if (LinkerConfig::DynObj == config().codeGenType()) { 343 m_pRelDyn->reserveEntry(*m_pRelocFactory); 344 rsym->setReserved(rsym->reserved() | ReserveRel); 345 // the target symbol of the dynamic relocation is rsym, so we need to 346 // emit it into .dynsym 347 assert(NULL != rsym->outSymbol()); 348 m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol()); 349 } 350 return; 351 352 default: 353 fatal(diag::unsupported_relocation) << (int)pReloc.type() 354 << "mclinker@googlegroups.com"; 355 break; 356 } // end switch 357} 358 359void X86GNULDBackend::scanGlobalReloc(Relocation& pReloc, 360 FragmentLinker& pLinker, 361 Module& pModule, 362 const LDSection& pSection) 363{ 364 // rsym - The relocation target symbol 365 ResolveInfo* rsym = pReloc.symInfo(); 366 367 switch(pReloc.type()) { 368 case llvm::ELF::R_386_32: 369 case llvm::ELF::R_386_16: 370 case llvm::ELF::R_386_8: 371 // Absolute relocation type, symbol may needs PLT entry or 372 // dynamic relocation entry 373 if (symbolNeedsPLT(pLinker, *rsym)) { 374 // create plt for this symbol if it does not have one 375 if (!(rsym->reserved() & ReservePLT)){ 376 // Symbol needs PLT entry, we need to reserve a PLT entry 377 // and the corresponding GOT and dynamic relocation entry 378 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 379 // when calling X86PLT->reserveEntry()) 380 m_pPLT->reserveEntry(); 381 m_pGOTPLT->reserve(); 382 m_pRelPLT->reserveEntry(*m_pRelocFactory); 383 // set PLT bit 384 rsym->setReserved(rsym->reserved() | ReservePLT); 385 } 386 } 387 388 if (symbolNeedsDynRel(pLinker, *rsym, (rsym->reserved() & ReservePLT), 389 true)) { 390 // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 391 m_pRelDyn->reserveEntry(*m_pRelocFactory); 392 if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) { 393 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym); 394 addCopyReloc(*cpy_sym.resolveInfo()); 395 } 396 else { 397 // set Rel bit 398 rsym->setReserved(rsym->reserved() | ReserveRel); 399 } 400 } 401 return; 402 403 case llvm::ELF::R_386_GOTOFF: 404 case llvm::ELF::R_386_GOTPC: { 405 // FIXME: A GOT section is needed 406 return; 407 } 408 409 case llvm::ELF::R_386_PLT32: 410 // A PLT entry is needed when building shared library 411 412 // return if we already create plt for this symbol 413 if (rsym->reserved() & ReservePLT) 414 return; 415 416 // if the symbol's value can be decided at link time, then no need plt 417 if (symbolFinalValueIsKnown(pLinker, *rsym)) 418 return; 419 420 // if symbol is defined in the ouput file and it's not 421 // preemptible, no need plt 422 if (rsym->isDefine() && !rsym->isDyn() && 423 !isSymbolPreemptible(*rsym)) { 424 return; 425 } 426 427 // Symbol needs PLT entry, we need to reserve a PLT entry 428 // and the corresponding GOT and dynamic relocation entry 429 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 430 // when calling X86PLT->reserveEntry()) 431 m_pPLT->reserveEntry(); 432 m_pGOTPLT->reserve(); 433 m_pRelPLT->reserveEntry(*m_pRelocFactory); 434 // set PLT bit 435 rsym->setReserved(rsym->reserved() | ReservePLT); 436 return; 437 438 case llvm::ELF::R_386_GOT32: 439 // Symbol needs GOT entry, reserve entry in .got 440 // return if we already create GOT for this symbol 441 if (rsym->reserved() & (ReserveGOT | GOTRel)) 442 return; 443 m_pGOT->reserve(); 444 // If building shared object or the symbol is undefined, a dynamic 445 // relocation is needed to relocate this GOT entry. Reserve an 446 // entry in .rel.dyn 447 if (LinkerConfig::DynObj == 448 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) { 449 m_pRelDyn->reserveEntry(*m_pRelocFactory); 450 // set GOTRel bit 451 rsym->setReserved(rsym->reserved() | GOTRel); 452 return; 453 } 454 // set GOT bit 455 rsym->setReserved(rsym->reserved() | ReserveGOT); 456 return; 457 458 case llvm::ELF::R_386_PC32: 459 case llvm::ELF::R_386_PC16: 460 case llvm::ELF::R_386_PC8: 461 462 if (symbolNeedsPLT(pLinker, *rsym) && 463 LinkerConfig::DynObj != config().codeGenType()) { 464 // create plt for this symbol if it does not have one 465 if (!(rsym->reserved() & ReservePLT)){ 466 // Symbol needs PLT entry, we need to reserve a PLT entry 467 // and the corresponding GOT and dynamic relocation entry 468 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 469 // when calling X86PLT->reserveEntry()) 470 m_pPLT->reserveEntry(); 471 m_pGOTPLT->reserve(); 472 m_pRelPLT->reserveEntry(*m_pRelocFactory); 473 // set PLT bit 474 rsym->setReserved(rsym->reserved() | ReservePLT); 475 } 476 } 477 478 if (symbolNeedsDynRel(pLinker, *rsym, (rsym->reserved() & ReservePLT), 479 false)) { 480 // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 481 m_pRelDyn->reserveEntry(*m_pRelocFactory); 482 if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) { 483 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym); 484 addCopyReloc(*cpy_sym.resolveInfo()); 485 } 486 else { 487 // set Rel bit 488 rsym->setReserved(rsym->reserved() | ReserveRel); 489 } 490 } 491 return; 492 493 case llvm::ELF::R_386_TLS_GD: { 494 // FIXME: no linker optimization for TLS relocation 495 if (rsym->reserved() & GOTRel) 496 return; 497 // reserve two pairs of got entry and dynamic relocation 498 m_pGOT->reserve(2); 499 m_pRelDyn->reserveEntry(*m_pRelocFactory, 2); 500 // set GOTRel bit 501 rsym->setReserved(rsym->reserved() | GOTRel); 502 return; 503 } 504 505 case llvm::ELF::R_386_TLS_LDM: 506 getTLSModuleID(); 507 return; 508 509 case llvm::ELF::R_386_TLS_LDO_32: 510 return; 511 512 case llvm::ELF::R_386_TLS_IE: 513 setHasStaticTLS(); 514 // if buildint shared object, a RELATIVE dynamic relocation is needed 515 if (LinkerConfig::DynObj == config().codeGenType()) { 516 m_pRelDyn->reserveEntry(*m_pRelocFactory); 517 rsym->setReserved(rsym->reserved() | ReserveRel); 518 } 519 if (rsym->reserved() & GOTRel) 520 return; 521 // reserve got and dyn relocation entries for tp-relative offset 522 m_pGOT->reserve(); 523 m_pRelDyn->reserveEntry(*m_pRelocFactory); 524 // set GOTRel bit 525 rsym->setReserved(rsym->reserved() | GOTRel); 526 return; 527 528 case llvm::ELF::R_386_TLS_GOTIE: 529 setHasStaticTLS(); 530 if (rsym->reserved() & GOTRel) 531 return; 532 // reserve got and dyn relocation entries for tp-relative offset 533 m_pGOT->reserve(); 534 m_pRelDyn->reserveEntry(*m_pRelocFactory); 535 // set GOTRel bit 536 rsym->setReserved(rsym->reserved() | GOTRel); 537 return; 538 539 case llvm::ELF::R_386_TLS_LE: 540 case llvm::ELF::R_386_TLS_LE_32: 541 setHasStaticTLS(); 542 // if buildint shared object, a dynamic relocation is needed 543 if (LinkerConfig::DynObj == config().codeGenType()) { 544 m_pRelDyn->reserveEntry(*m_pRelocFactory); 545 rsym->setReserved(rsym->reserved() | ReserveRel); 546 } 547 return; 548 549 default: { 550 fatal(diag::unsupported_relocation) << (int)pReloc.type() 551 << "mclinker@googlegroups.com"; 552 break; 553 } 554 } // end switch 555} 556 557void X86GNULDBackend::scanRelocation(Relocation& pReloc, 558 FragmentLinker& pLinker, 559 Module& pModule, 560 const LDSection& pSection) 561{ 562 if (LinkerConfig::Object == config().codeGenType()) 563 return; 564 // rsym - The relocation target symbol 565 ResolveInfo* rsym = pReloc.symInfo(); 566 assert(NULL != rsym && 567 "ResolveInfo of relocation not set while scanRelocation"); 568 569 pReloc.updateAddend(); 570 if (0 == (pSection.flag() & llvm::ELF::SHF_ALLOC)) 571 return; 572 573 // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation 574 // entries should be created. 575 if (rsym->isLocal()) // rsym is local 576 scanLocalReloc(pReloc, pLinker, pModule, pSection); 577 else // rsym is external 578 scanGlobalReloc(pReloc, pLinker, pModule, pSection); 579 580 // check if we shoule issue undefined reference for the relocation target 581 // symbol 582 if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak()) 583 fatal(diag::undefined_reference) << rsym->name(); 584 585 if ((rsym->reserved() & ReserveRel) != 0x0) { 586 // set hasTextRelSection if needed 587 checkAndSetHasTextRel(pSection); 588 } 589} 590 591uint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection, 592 MemoryRegion& pRegion) const 593{ 594 assert(pRegion.size() && "Size of MemoryRegion is zero!"); 595 596 const ELFFileFormat* FileFormat = getOutputFormat(); 597 assert(FileFormat && 598 "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 599 600 unsigned int EntrySize = 0; 601 uint64_t RegionSize = 0; 602 603 if (&pSection == &(FileFormat->getPLT())) { 604 assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); 605 606 unsigned char* buffer = pRegion.getBuffer(); 607 608 m_pPLT->applyPLT0(); 609 m_pPLT->applyPLT1(); 610 X86PLT::iterator it = m_pPLT->begin(); 611 unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize(); 612 613 memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size); 614 RegionSize += plt0_size; 615 ++it; 616 617 X86PLT1* plt1 = 0; 618 X86PLT::iterator ie = m_pPLT->end(); 619 while (it != ie) { 620 plt1 = &(llvm::cast<X86PLT1>(*it)); 621 EntrySize = plt1->getEntrySize(); 622 memcpy(buffer + RegionSize, plt1->getContent(), EntrySize); 623 RegionSize += EntrySize; 624 ++it; 625 } 626 } 627 628 else if (&pSection == &(FileFormat->getGOT())) { 629 assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 630 631 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 632 633 GOT::Entry* got = 0; 634 EntrySize = m_pGOT->getEntrySize(); 635 636 for (X86GOT::iterator it = m_pGOT->begin(), 637 ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 638 got = &(llvm::cast<GOT::Entry>((*it))); 639 *buffer = static_cast<uint32_t>(got->getContent()); 640 RegionSize += EntrySize; 641 } 642 } 643 644 else if (&pSection == &(FileFormat->getGOTPLT())) { 645 assert(m_pGOTPLT && "emitSectionData failed, m_pGOTPLT is NULL!"); 646 m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 647 m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 648 649 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 650 651 GOT::Entry* got = 0; 652 EntrySize = m_pGOTPLT->getEntrySize(); 653 654 for (X86GOTPLT::iterator it = m_pGOTPLT->begin(), 655 ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 656 got = &(llvm::cast<GOT::Entry>((*it))); 657 *buffer = static_cast<uint32_t>(got->getContent()); 658 RegionSize += EntrySize; 659 } 660 } 661 662 else { 663 fatal(diag::unrecognized_output_sectoin) 664 << pSection.name() 665 << "mclinker@googlegroups.com"; 666 } 667 return RegionSize; 668} 669 670uint32_t X86GNULDBackend::machine() const 671{ 672 return llvm::ELF::EM_386; 673} 674 675X86GOT& X86GNULDBackend::getGOT() 676{ 677 assert(NULL != m_pGOT); 678 return *m_pGOT; 679} 680 681const X86GOT& X86GNULDBackend::getGOT() const 682{ 683 assert(NULL != m_pGOT); 684 return *m_pGOT; 685} 686 687X86GOTPLT& X86GNULDBackend::getGOTPLT() 688{ 689 assert(NULL != m_pGOTPLT); 690 return *m_pGOTPLT; 691} 692 693const X86GOTPLT& X86GNULDBackend::getGOTPLT() const 694{ 695 assert(NULL != m_pGOTPLT); 696 return *m_pGOTPLT; 697} 698 699X86PLT& X86GNULDBackend::getPLT() 700{ 701 assert(NULL != m_pPLT && "PLT section not exist"); 702 return *m_pPLT; 703} 704 705const X86PLT& X86GNULDBackend::getPLT() const 706{ 707 assert(NULL != m_pPLT && "PLT section not exist"); 708 return *m_pPLT; 709} 710 711OutputRelocSection& X86GNULDBackend::getRelDyn() 712{ 713 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 714 return *m_pRelDyn; 715} 716 717const OutputRelocSection& X86GNULDBackend::getRelDyn() const 718{ 719 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 720 return *m_pRelDyn; 721} 722 723// Create a GOT entry for the TLS module index 724GOT::Entry& X86GNULDBackend::getTLSModuleID() 725{ 726 static GOT::Entry* got_entry = NULL; 727 if (NULL != got_entry) 728 return *got_entry; 729 730 // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM 731 m_pGOT->reserve(2); 732 got_entry = m_pGOT->consume(); 733 m_pGOT->consume()->setContent(0x0); 734 735 m_pRelDyn->reserveEntry(*m_pRelocFactory); 736 Relocation* rel_entry = m_pRelDyn->consumeEntry(); 737 rel_entry->setType(llvm::ELF::R_386_TLS_DTPMOD32); 738 rel_entry->targetRef().assign(*got_entry, 0x0); 739 rel_entry->setSymInfo(NULL); 740 741 return *got_entry; 742} 743 744OutputRelocSection& X86GNULDBackend::getRelPLT() 745{ 746 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 747 return *m_pRelPLT; 748} 749 750const OutputRelocSection& X86GNULDBackend::getRelPLT() const 751{ 752 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 753 return *m_pRelPLT; 754} 755 756unsigned int 757X86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 758{ 759 const ELFFileFormat* file_format = getOutputFormat(); 760 761 if (&pSectHdr == &file_format->getGOT()) { 762 if (config().options().hasNow()) 763 return SHO_RELRO; 764 return SHO_RELRO_LAST; 765 } 766 767 if (&pSectHdr == &file_format->getGOTPLT()) { 768 if (config().options().hasNow()) 769 return SHO_RELRO; 770 return SHO_NON_RELRO_FIRST; 771 } 772 773 if (&pSectHdr == &file_format->getPLT()) 774 return SHO_PLT; 775 776 return SHO_UNDEFINED; 777} 778 779unsigned int X86GNULDBackend::bitclass() const 780{ 781 return 32; 782} 783 784void X86GNULDBackend::initTargetSections(Module& pModule, 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 X86GOT(got); 791 792 // initialize .got.plt 793 LDSection& gotplt = file_format->getGOTPLT(); 794 m_pGOTPLT = new X86GOTPLT(gotplt); 795 796 // initialize .plt 797 LDSection& plt = file_format->getPLT(); 798 m_pPLT = new X86PLT(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, 806 relplt, 807 getRelEntrySize()); 808 // initialize .rel.dyn 809 LDSection& reldyn = file_format->getRelDyn(); 810 m_pRelDyn = new OutputRelocSection(pModule, 811 reldyn, 812 getRelEntrySize()); 813 } 814} 815 816void X86GNULDBackend::initTargetSymbols(FragmentLinker& pLinker) 817{ 818 if (LinkerConfig::Object != config().codeGenType()) { 819 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 820 // same name in input 821 m_pGOTSymbol = 822 pLinker.defineSymbol<FragmentLinker::AsRefered, 823 FragmentLinker::Resolve>("_GLOBAL_OFFSET_TABLE_", 824 false, 825 ResolveInfo::Object, 826 ResolveInfo::Define, 827 ResolveInfo::Local, 828 0x0, // size 829 0x0, // value 830 FragmentRef::Null(), // FragRef 831 ResolveInfo::Hidden); 832 } 833} 834 835/// finalizeSymbol - finalize the symbol value 836bool X86GNULDBackend::finalizeTargetSymbols(FragmentLinker& pLinker) 837{ 838 return true; 839} 840 841/// doCreateProgramHdrs - backend can implement this function to create the 842/// target-dependent segments 843void X86GNULDBackend::doCreateProgramHdrs(Module& pModule, 844 const FragmentLinker& pLinker) 845{ 846 // TODO 847} 848 849namespace mcld { 850 851//===----------------------------------------------------------------------===// 852/// createX86LDBackend - the help funtion to create corresponding X86LDBackend 853/// 854TargetLDBackend* createX86LDBackend(const llvm::Target& pTarget, 855 const LinkerConfig& pConfig) 856{ 857 if (pConfig.triple().isOSDarwin()) { 858 assert(0 && "MachO linker is not supported yet"); 859 /** 860 return new X86MachOLDBackend(createX86MachOArchiveReader, 861 createX86MachOObjectReader, 862 createX86MachOObjectWriter); 863 **/ 864 } 865 if (pConfig.triple().isOSWindows()) { 866 assert(0 && "COFF linker is not supported yet"); 867 /** 868 return new X86COFFLDBackend(createX86COFFArchiveReader, 869 createX86COFFObjectReader, 870 createX86COFFObjectWriter); 871 **/ 872 } 873 return new X86GNULDBackend(pConfig); 874} 875 876} // namespace of mcld 877 878//===----------------------------------------------------------------------===// 879// Force static initialization. 880//===----------------------------------------------------------------------===// 881extern "C" void MCLDInitializeX86LDBackend() { 882 // Register the linker backend 883 mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend); 884} 885