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