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