1 //===- MipsLDBackend.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 "Mips.h" 10 #include "MipsGNUInfo.h" 11 #include "MipsELFDynamic.h" 12 #include "MipsLA25Stub.h" 13 #include "MipsLDBackend.h" 14 #include "MipsRelocator.h" 15 16 #include <llvm/ADT/Triple.h> 17 #include <llvm/Support/Casting.h> 18 #include <llvm/Support/ELF.h> 19 #include <llvm/Support/Host.h> 20 21 #include <mcld/Module.h> 22 #include <mcld/LinkerConfig.h> 23 #include <mcld/IRBuilder.h> 24 #include <mcld/LD/BranchIslandFactory.h> 25 #include <mcld/LD/LDContext.h> 26 #include <mcld/LD/StubFactory.h> 27 #include <mcld/LD/ELFFileFormat.h> 28 #include <mcld/MC/Attribute.h> 29 #include <mcld/Fragment/FillFragment.h> 30 #include <mcld/Support/MemoryRegion.h> 31 #include <mcld/Support/MemoryArea.h> 32 #include <mcld/Support/MsgHandling.h> 33 #include <mcld/Support/TargetRegistry.h> 34 #include <mcld/Target/OutputRelocSection.h> 35 #include <mcld/Object/ObjectBuilder.h> 36 37 using namespace mcld; 38 39 //===----------------------------------------------------------------------===// 40 // MipsGNULDBackend 41 //===----------------------------------------------------------------------===// 42 MipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig, 43 MipsGNUInfo* pInfo) 44 : GNULDBackend(pConfig, pInfo), 45 m_pRelocator(NULL), 46 m_pGOT(NULL), 47 m_pPLT(NULL), 48 m_pGOTPLT(NULL), 49 m_pInfo(*pInfo), 50 m_pRelPlt(NULL), 51 m_pRelDyn(NULL), 52 m_pDynamic(NULL), 53 m_pGOTSymbol(NULL), 54 m_pPLTSymbol(NULL), 55 m_pGpDispSymbol(NULL) 56 { 57 } 58 59 MipsGNULDBackend::~MipsGNULDBackend() 60 { 61 delete m_pRelocator; 62 delete m_pPLT; 63 delete m_pRelPlt; 64 delete m_pRelDyn; 65 delete m_pDynamic; 66 } 67 68 bool MipsGNULDBackend::needsLA25Stub(Relocation::Type pType, 69 const mcld::ResolveInfo* pSym) 70 { 71 if (config().isCodeIndep()) 72 return false; 73 74 if (llvm::ELF::R_MIPS_26 != pType) 75 return false; 76 77 if (pSym->isLocal()) 78 return false; 79 80 return true; 81 } 82 83 void MipsGNULDBackend::addNonPICBranchSym(ResolveInfo* rsym) 84 { 85 m_HasNonPICBranchSyms.insert(rsym); 86 } 87 88 bool MipsGNULDBackend::hasNonPICBranch(const ResolveInfo* rsym) const 89 { 90 return m_HasNonPICBranchSyms.count(rsym); 91 } 92 93 void MipsGNULDBackend::initTargetSections(Module& pModule, 94 ObjectBuilder& pBuilder) 95 { 96 if (LinkerConfig::Object == config().codeGenType()) 97 return; 98 99 ELFFileFormat* file_format = getOutputFormat(); 100 101 // initialize .rel.plt 102 LDSection& relplt = file_format->getRelPlt(); 103 m_pRelPlt = new OutputRelocSection(pModule, relplt); 104 105 // initialize .rel.dyn 106 LDSection& reldyn = file_format->getRelDyn(); 107 m_pRelDyn = new OutputRelocSection(pModule, reldyn); 108 } 109 110 void MipsGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 111 { 112 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 113 // same name in input 114 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 115 "_GLOBAL_OFFSET_TABLE_", 116 ResolveInfo::Object, 117 ResolveInfo::Define, 118 ResolveInfo::Local, 119 0x0, // size 120 0x0, // value 121 FragmentRef::Null(), // FragRef 122 ResolveInfo::Hidden); 123 124 // Define the symbol _PROCEDURE_LINKAGE_TABLE_ if there is a symbol with the 125 // same name in input 126 m_pPLTSymbol = 127 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 128 "_PROCEDURE_LINKAGE_TABLE_", 129 ResolveInfo::Object, 130 ResolveInfo::Define, 131 ResolveInfo::Local, 132 0x0, // size 133 0x0, // value 134 FragmentRef::Null(), // FragRef 135 ResolveInfo::Hidden); 136 137 m_pGpDispSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 138 "_gp_disp", 139 ResolveInfo::Section, 140 ResolveInfo::Define, 141 ResolveInfo::Absolute, 142 0x0, // size 143 0x0, // value 144 FragmentRef::Null(), // FragRef 145 ResolveInfo::Default); 146 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>( 147 "_gp", 148 ResolveInfo::NoType, 149 ResolveInfo::Define, 150 ResolveInfo::Absolute, 151 0x0, // size 152 0x0, // value 153 FragmentRef::Null(), // FragRef 154 ResolveInfo::Default); 155 } 156 157 const Relocator* MipsGNULDBackend::getRelocator() const 158 { 159 assert(NULL != m_pRelocator); 160 return m_pRelocator; 161 } 162 163 Relocator* MipsGNULDBackend::getRelocator() 164 { 165 assert(NULL != m_pRelocator); 166 return m_pRelocator; 167 } 168 169 void MipsGNULDBackend::doPreLayout(IRBuilder& pBuilder) 170 { 171 // initialize .dynamic data 172 if (!config().isCodeStatic() && NULL == m_pDynamic) 173 m_pDynamic = new MipsELFDynamic(*this, config()); 174 175 // set .got size 176 // when building shared object, the .got section is must. 177 if (LinkerConfig::Object != config().codeGenType()) { 178 if (LinkerConfig::DynObj == config().codeGenType() || 179 m_pGOT->hasGOT1() || 180 NULL != m_pGOTSymbol) { 181 m_pGOT->finalizeScanning(*m_pRelDyn); 182 m_pGOT->finalizeSectionSize(); 183 184 defineGOTSymbol(pBuilder); 185 } 186 187 if (m_pGOTPLT->hasGOT1()) { 188 m_pGOTPLT->finalizeSectionSize(); 189 190 defineGOTPLTSymbol(pBuilder); 191 } 192 193 if (m_pPLT->hasPLT1()) 194 m_pPLT->finalizeSectionSize(); 195 196 ELFFileFormat* file_format = getOutputFormat(); 197 198 // set .rel.plt size 199 if (!m_pRelPlt->empty()) { 200 assert(!config().isCodeStatic() && 201 "static linkage should not result in a dynamic relocation section"); 202 file_format->getRelPlt().setSize( 203 m_pRelPlt->numOfRelocs() * getRelEntrySize()); 204 } 205 206 // set .rel.dyn size 207 if (!m_pRelDyn->empty()) { 208 assert(!config().isCodeStatic() && 209 "static linkage should not result in a dynamic relocation section"); 210 file_format->getRelDyn().setSize( 211 m_pRelDyn->numOfRelocs() * getRelEntrySize()); 212 } 213 } 214 } 215 216 void MipsGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) 217 { 218 const ELFFileFormat *format = getOutputFormat(); 219 220 if (format->hasGOTPLT()) { 221 assert(m_pGOTPLT && "doPostLayout failed, m_pGOTPLT is NULL!"); 222 m_pGOTPLT->applyAllGOTPLT(m_pPLT->addr()); 223 } 224 225 if (format->hasPLT()) { 226 assert(m_pPLT && "doPostLayout failed, m_pPLT is NULL!"); 227 m_pPLT->applyAllPLT(*m_pGOTPLT); 228 } 229 230 m_pInfo.setABIVersion(m_pPLT && m_pPLT->hasPLT1() ? 1 : 0); 231 232 // FIXME: (simon) We need to iterate all input sections 233 // check that flags are consistent and merge them properly. 234 uint64_t picFlags = llvm::ELF::EF_MIPS_CPIC; 235 if (config().targets().triple().isArch64Bit()) { 236 picFlags |= llvm::ELF::EF_MIPS_PIC; 237 } 238 else { 239 if (LinkerConfig::DynObj == config().codeGenType()) 240 picFlags |= llvm::ELF::EF_MIPS_PIC; 241 } 242 243 m_pInfo.setPICFlags(picFlags); 244 } 245 246 /// dynamic - the dynamic section of the target machine. 247 /// Use co-variant return type to return its own dynamic section. 248 MipsELFDynamic& MipsGNULDBackend::dynamic() 249 { 250 assert(NULL != m_pDynamic); 251 return *m_pDynamic; 252 } 253 254 /// dynamic - the dynamic section of the target machine. 255 /// Use co-variant return type to return its own dynamic section. 256 const MipsELFDynamic& MipsGNULDBackend::dynamic() const 257 { 258 assert(NULL != m_pDynamic); 259 return *m_pDynamic; 260 } 261 262 uint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection, 263 MemoryRegion& pRegion) const 264 { 265 assert(pRegion.size() && "Size of MemoryRegion is zero!"); 266 267 const ELFFileFormat* file_format = getOutputFormat(); 268 269 if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { 270 return m_pGOT->emit(pRegion); 271 } 272 273 if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { 274 return m_pPLT->emit(pRegion); 275 } 276 277 if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) { 278 return m_pGOTPLT->emit(pRegion); 279 } 280 281 fatal(diag::unrecognized_output_sectoin) 282 << pSection.name() 283 << "mclinker (at) googlegroups.com"; 284 return 0; 285 } 286 287 bool MipsGNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const 288 { 289 return ResolveInfo::Section != pSym.type() || 290 m_pGpDispSymbol == &pSym; 291 } 292 293 namespace { 294 struct DynsymGOTCompare 295 { 296 const MipsGOT& m_pGOT; 297 298 DynsymGOTCompare(const MipsGOT& pGOT) 299 : m_pGOT(pGOT) 300 { 301 } 302 303 bool operator()(const LDSymbol* X, const LDSymbol* Y) const 304 { 305 return m_pGOT.dynSymOrderCompare(X, Y); 306 } 307 }; 308 } 309 310 void MipsGNULDBackend::orderSymbolTable(Module& pModule) 311 { 312 if (GeneralOptions::GNU == config().options().getHashStyle() || 313 GeneralOptions::Both == config().options().getHashStyle()) { 314 // The MIPS ABI and .gnu.hash require .dynsym to be sorted 315 // in different ways. The MIPS ABI requires a mapping between 316 // the GOT and the symbol table. At the same time .gnu.hash 317 // needs symbols to be grouped by hash code. 318 llvm::errs() << ".gnu.hash is incompatible with the MIPS ABI\n"; 319 } 320 321 Module::SymbolTable& symbols = pModule.getSymbolTable(); 322 323 std::stable_sort(symbols.dynamicBegin(), symbols.dynamicEnd(), 324 DynsymGOTCompare(*m_pGOT)); 325 } 326 327 namespace llvm { 328 namespace ELF { 329 // SHT_MIPS_OPTIONS section's block descriptor. 330 struct Elf_Options { 331 unsigned char kind; // Determines interpretation of variable 332 // part of descriptor. See ODK_xxx enumeration. 333 unsigned char size; // Byte size of descriptor, including this header. 334 Elf64_Half section; // Section header index of section affected, 335 // or 0 for global options. 336 Elf64_Word info; // Kind-specic information. 337 }; 338 339 // Type of SHT_MIPS_OPTIONS section's block. 340 enum { 341 ODK_NULL = 0, // Undefined. 342 ODK_REGINFO = 1, // Register usage and GP value. 343 ODK_EXCEPTIONS = 2, // Exception processing information. 344 ODK_PAD = 3, // Section padding information. 345 ODK_HWPATCH = 4, // Hardware workarounds performed. 346 ODK_FILL = 5, // Fill value used by the linker. 347 ODK_TAGS = 6, // Reserved space for desktop tools. 348 ODK_HWAND = 7, // Hardware workarounds, AND bits when merging. 349 ODK_HWOR = 8, // Hardware workarounds, OR bits when merging. 350 ODK_GP_GROUP = 9, // GP group to use for text/data sections. 351 ODK_IDENT = 10 // ID information. 352 }; 353 354 // Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 32 bit ABI. 355 struct Elf32_RegInfo { 356 Elf32_Word ri_gprmask; // Mask of general purpose registers used. 357 Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used. 358 Elf32_Addr ri_gp_value; // GP register value for this object file. 359 }; 360 361 // Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 64 bit ABI. 362 struct Elf64_RegInfo { 363 Elf32_Word ri_gprmask; // Mask of general purpose registers used. 364 Elf32_Word ri_pad; // Padding. 365 Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used. 366 Elf64_Addr ri_gp_value; // GP register value for this object file. 367 }; 368 369 } 370 } 371 372 bool MipsGNULDBackend::readSection(Input& pInput, SectionData& pSD) 373 { 374 llvm::StringRef name(pSD.getSection().name()); 375 376 if (name.startswith(".sdata")) { 377 uint64_t offset = pInput.fileOffset() + pSD.getSection().offset(); 378 uint64_t size = pSD.getSection().size(); 379 380 Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 381 ObjectBuilder::AppendFragment(*frag, pSD); 382 return true; 383 } 384 385 if (pSD.getSection().type() == llvm::ELF::SHT_MIPS_OPTIONS) { 386 uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 387 uint32_t size = pSD.getSection().size(); 388 389 llvm::StringRef region = pInput.memArea()->request(offset, size); 390 if (region.size() > 0) { 391 const llvm::ELF::Elf_Options* optb = 392 reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin()); 393 const llvm::ELF::Elf_Options* opte = 394 reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin() + size); 395 396 for (const llvm::ELF::Elf_Options* opt = optb; opt < opte; opt += opt->size) { 397 switch (opt->kind) { 398 default: 399 // Nothing to do. 400 break; 401 case llvm::ELF::ODK_REGINFO: 402 if (config().targets().triple().isArch32Bit()) { 403 const llvm::ELF::Elf32_RegInfo* reg = 404 reinterpret_cast<const llvm::ELF::Elf32_RegInfo*>(opt + 1); 405 m_GP0Map[&pInput] = reg->ri_gp_value; 406 } 407 else { 408 const llvm::ELF::Elf64_RegInfo* reg = 409 reinterpret_cast<const llvm::ELF::Elf64_RegInfo*>(opt + 1); 410 m_GP0Map[&pInput] = reg->ri_gp_value; 411 } 412 break; 413 } 414 } 415 } 416 417 return true; 418 } 419 420 return GNULDBackend::readSection(pInput, pSD); 421 } 422 423 MipsGOT& MipsGNULDBackend::getGOT() 424 { 425 assert(NULL != m_pGOT); 426 return *m_pGOT; 427 } 428 429 const MipsGOT& MipsGNULDBackend::getGOT() const 430 { 431 assert(NULL != m_pGOT); 432 return *m_pGOT; 433 } 434 435 MipsPLT& MipsGNULDBackend::getPLT() 436 { 437 assert(NULL != m_pPLT); 438 return *m_pPLT; 439 } 440 441 const MipsPLT& MipsGNULDBackend::getPLT() const 442 { 443 assert(NULL != m_pPLT); 444 return *m_pPLT; 445 } 446 447 MipsGOTPLT& MipsGNULDBackend::getGOTPLT() 448 { 449 assert(NULL != m_pGOTPLT); 450 return *m_pGOTPLT; 451 } 452 453 const MipsGOTPLT& MipsGNULDBackend::getGOTPLT() const 454 { 455 assert(NULL != m_pGOTPLT); 456 return *m_pGOTPLT; 457 } 458 459 OutputRelocSection& MipsGNULDBackend::getRelPLT() 460 { 461 assert(NULL != m_pRelPlt); 462 return *m_pRelPlt; 463 } 464 465 const OutputRelocSection& MipsGNULDBackend::getRelPLT() const 466 { 467 assert(NULL != m_pRelPlt); 468 return *m_pRelPlt; 469 } 470 471 OutputRelocSection& MipsGNULDBackend::getRelDyn() 472 { 473 assert(NULL != m_pRelDyn); 474 return *m_pRelDyn; 475 } 476 477 const OutputRelocSection& MipsGNULDBackend::getRelDyn() const 478 { 479 assert(NULL != m_pRelDyn); 480 return *m_pRelDyn; 481 } 482 483 unsigned int 484 MipsGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 485 { 486 const ELFFileFormat* file_format = getOutputFormat(); 487 488 if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) 489 return SHO_DATA; 490 491 if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) 492 return SHO_DATA; 493 494 if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 495 return SHO_PLT; 496 497 return SHO_UNDEFINED; 498 } 499 500 /// finalizeSymbol - finalize the symbol value 501 bool MipsGNULDBackend::finalizeTargetSymbols() 502 { 503 if (NULL != m_pGpDispSymbol) 504 m_pGpDispSymbol->setValue(m_pGOT->getGPDispAddress()); 505 506 return true; 507 } 508 509 /// allocateCommonSymbols - allocate common symbols in the corresponding 510 /// sections. This is called at pre-layout stage. 511 /// @refer Google gold linker: common.cc: 214 512 /// FIXME: Mips needs to allocate small common symbol 513 bool MipsGNULDBackend::allocateCommonSymbols(Module& pModule) 514 { 515 SymbolCategory& symbol_list = pModule.getSymbolTable(); 516 517 if (symbol_list.emptyCommons() && symbol_list.emptyFiles() && 518 symbol_list.emptyLocals() && symbol_list.emptyLocalDyns()) 519 return true; 520 521 SymbolCategory::iterator com_sym, com_end; 522 523 // FIXME: If the order of common symbols is defined, then sort common symbols 524 // std::sort(com_sym, com_end, some kind of order); 525 526 // get corresponding BSS LDSection 527 ELFFileFormat* file_format = getOutputFormat(); 528 LDSection& bss_sect = file_format->getBSS(); 529 LDSection& tbss_sect = file_format->getTBSS(); 530 531 // get or create corresponding BSS SectionData 532 SectionData* bss_sect_data = NULL; 533 if (bss_sect.hasSectionData()) 534 bss_sect_data = bss_sect.getSectionData(); 535 else 536 bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 537 538 SectionData* tbss_sect_data = NULL; 539 if (tbss_sect.hasSectionData()) 540 tbss_sect_data = tbss_sect.getSectionData(); 541 else 542 tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 543 544 // remember original BSS size 545 uint64_t bss_offset = bss_sect.size(); 546 uint64_t tbss_offset = tbss_sect.size(); 547 548 // allocate all local common symbols 549 com_end = symbol_list.localEnd(); 550 551 for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 552 if (ResolveInfo::Common == (*com_sym)->desc()) { 553 // We have to reset the description of the symbol here. When doing 554 // incremental linking, the output relocatable object may have common 555 // symbols. Therefore, we can not treat common symbols as normal symbols 556 // when emitting the regular name pools. We must change the symbols' 557 // description here. 558 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 559 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 560 561 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 562 // allocate TLS common symbol in tbss section 563 tbss_offset += ObjectBuilder::AppendFragment(*frag, 564 *tbss_sect_data, 565 (*com_sym)->value()); 566 ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 567 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 568 } 569 // FIXME: how to identify small and large common symbols? 570 else { 571 bss_offset += ObjectBuilder::AppendFragment(*frag, 572 *bss_sect_data, 573 (*com_sym)->value()); 574 ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 575 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 576 } 577 } 578 } 579 580 // allocate all global common symbols 581 com_end = symbol_list.commonEnd(); 582 for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 583 // We have to reset the description of the symbol here. When doing 584 // incremental linking, the output relocatable object may have common 585 // symbols. Therefore, we can not treat common symbols as normal symbols 586 // when emitting the regular name pools. We must change the symbols' 587 // description here. 588 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 589 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 590 591 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 592 // allocate TLS common symbol in tbss section 593 tbss_offset += ObjectBuilder::AppendFragment(*frag, 594 *tbss_sect_data, 595 (*com_sym)->value()); 596 ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 597 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 598 } 599 // FIXME: how to identify small and large common symbols? 600 else { 601 bss_offset += ObjectBuilder::AppendFragment(*frag, 602 *bss_sect_data, 603 (*com_sym)->value()); 604 ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 605 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 606 } 607 } 608 609 bss_sect.setSize(bss_offset); 610 tbss_sect.setSize(tbss_offset); 611 symbol_list.changeCommonsToGlobal(); 612 return true; 613 } 614 615 uint64_t MipsGNULDBackend::getGP0(const Input& pInput) const 616 { 617 return m_GP0Map.lookup(&pInput); 618 } 619 620 void MipsGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) 621 { 622 // If we do not reserve any GOT entries, we do not need to re-define GOT 623 // symbol. 624 if (!m_pGOT->hasGOT1()) 625 return; 626 627 // define symbol _GLOBAL_OFFSET_TABLE_ 628 if ( m_pGOTSymbol != NULL ) { 629 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 630 "_GLOBAL_OFFSET_TABLE_", 631 ResolveInfo::Object, 632 ResolveInfo::Define, 633 ResolveInfo::Local, 634 0x0, // size 635 0x0, // value 636 FragmentRef::Create(*(m_pGOT->begin()), 0x0), 637 ResolveInfo::Hidden); 638 } 639 else { 640 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 641 "_GLOBAL_OFFSET_TABLE_", 642 ResolveInfo::Object, 643 ResolveInfo::Define, 644 ResolveInfo::Local, 645 0x0, // size 646 0x0, // value 647 FragmentRef::Create(*(m_pGOT->begin()), 0x0), 648 ResolveInfo::Hidden); 649 } 650 } 651 652 void MipsGNULDBackend::defineGOTPLTSymbol(IRBuilder& pBuilder) 653 { 654 // define symbol _PROCEDURE_LINKAGE_TABLE_ 655 if ( m_pPLTSymbol != NULL ) { 656 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 657 "_PROCEDURE_LINKAGE_TABLE_", 658 ResolveInfo::Object, 659 ResolveInfo::Define, 660 ResolveInfo::Local, 661 0x0, // size 662 0x0, // value 663 FragmentRef::Create(*(m_pPLT->begin()), 0x0), 664 ResolveInfo::Hidden); 665 } 666 else { 667 m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 668 "_PROCEDURE_LINKAGE_TABLE_", 669 ResolveInfo::Object, 670 ResolveInfo::Define, 671 ResolveInfo::Local, 672 0x0, // size 673 0x0, // value 674 FragmentRef::Create(*(m_pPLT->begin()), 0x0), 675 ResolveInfo::Hidden); 676 } 677 } 678 679 /// doCreateProgramHdrs - backend can implement this function to create the 680 /// target-dependent segments 681 void MipsGNULDBackend::doCreateProgramHdrs(Module& pModule) 682 { 683 // TODO 684 } 685 686 bool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel) 687 { 688 uint64_t sym_value = 0x0; 689 690 LDSymbol* symbol = pRel.symInfo()->outSymbol(); 691 if (symbol->hasFragRef()) { 692 uint64_t value = symbol->fragRef()->getOutputOffset(); 693 uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr(); 694 sym_value = addr + value; 695 } 696 697 Stub* stub = 698 getStubFactory()->create(pRel, sym_value, pBuilder, *getBRIslandFactory()); 699 700 if (NULL == stub) 701 return false; 702 703 assert(NULL != stub->symInfo()); 704 // increase the size of .symtab and .strtab 705 LDSection& symtab = getOutputFormat()->getSymTab(); 706 LDSection& strtab = getOutputFormat()->getStrTab(); 707 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 708 strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 709 710 return true; 711 } 712 713 bool MipsGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, 714 bool& pFinished) 715 { 716 assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); 717 718 bool isRelaxed = false; 719 720 for (Module::obj_iterator input = pModule.obj_begin(); 721 input != pModule.obj_end(); ++input) { 722 LDContext* context = (*input)->context(); 723 724 for (LDContext::sect_iterator rs = context->relocSectBegin(); 725 rs != context->relocSectEnd(); ++rs) { 726 LDSection* sec = *rs; 727 728 if (LDFileFormat::Ignore == sec->kind() || !sec->hasRelocData()) 729 continue; 730 731 for (RelocData::iterator reloc = sec->getRelocData()->begin(); 732 reloc != sec->getRelocData()->end(); ++reloc) { 733 if (llvm::ELF::R_MIPS_26 != reloc->type()) 734 continue; 735 736 if (relaxRelocation(pBuilder, *llvm::cast<Relocation>(reloc))) 737 isRelaxed = true; 738 } 739 } 740 } 741 742 SectionData* textData = getOutputFormat()->getText().getSectionData(); 743 744 // find the first fragment w/ invalid offset due to stub insertion 745 Fragment* invalid = NULL; 746 pFinished = true; 747 for (BranchIslandFactory::iterator ii = getBRIslandFactory()->begin(), 748 ie = getBRIslandFactory()->end(); 749 ii != ie; ++ii) 750 { 751 BranchIsland& island = *ii; 752 if (island.end() == textData->end()) 753 break; 754 755 Fragment* exit = island.end(); 756 if ((island.offset() + island.size()) > exit->getOffset()) { 757 invalid = exit; 758 pFinished = false; 759 break; 760 } 761 } 762 763 // reset the offset of invalid fragments 764 while (NULL != invalid) { 765 invalid->setOffset(invalid->getPrevNode()->getOffset() + 766 invalid->getPrevNode()->size()); 767 invalid = invalid->getNextNode(); 768 } 769 770 // reset the size of .text 771 if (isRelaxed) 772 getOutputFormat()->getText().setSize(textData->back().getOffset() + 773 textData->back().size()); 774 775 return isRelaxed; 776 } 777 778 bool MipsGNULDBackend::initTargetStubs() 779 { 780 if (NULL == getStubFactory()) 781 return false; 782 783 getStubFactory()->addPrototype(new MipsLA25Stub(*this)); 784 return true; 785 } 786 787 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel, 788 Relocation::Type& pType, 789 uint32_t& pSymIdx, 790 uint32_t& pOffset) const 791 { 792 return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset); 793 } 794 795 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel, 796 Relocation::Type& pType, 797 uint32_t& pSymIdx, 798 uint32_t& pOffset, 799 int32_t& pAddend) const 800 { 801 return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset, pAddend); 802 } 803 804 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel, 805 Relocation::Type& pType, 806 uint32_t& pSymIdx, 807 uint64_t& pOffset) const 808 { 809 uint64_t r_info = 0x0; 810 if (llvm::sys::IsLittleEndianHost) { 811 pOffset = pRel.r_offset; 812 r_info = pRel.r_info; 813 } 814 else { 815 pOffset = mcld::bswap64(pRel.r_offset); 816 r_info = mcld::bswap64(pRel.r_info); 817 } 818 819 // MIPS 64 little endian (we do not support big endian now) 820 // has a "special" encoding of r_info relocation 821 // field. Instead of one 64 bit little endian number, it is a little 822 // endian 32 bit number followed by a 32 bit big endian number. 823 pType = mcld::bswap32(r_info >> 32); 824 pSymIdx = r_info & 0xffffffff; 825 return true; 826 } 827 828 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel, 829 Relocation::Type& pType, 830 uint32_t& pSymIdx, 831 uint64_t& pOffset, 832 int64_t& pAddend) const 833 { 834 uint64_t r_info = 0x0; 835 if (llvm::sys::IsLittleEndianHost) { 836 pOffset = pRel.r_offset; 837 r_info = pRel.r_info; 838 pAddend = pRel.r_addend; 839 } 840 else { 841 pOffset = mcld::bswap64(pRel.r_offset); 842 r_info = mcld::bswap64(pRel.r_info); 843 pAddend = mcld::bswap64(pRel.r_addend); 844 } 845 846 pType = mcld::bswap32(r_info >> 32); 847 pSymIdx = r_info & 0xffffffff; 848 return true; 849 } 850 851 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel, 852 Relocation::Type pType, 853 uint32_t pSymIdx, 854 uint32_t pOffset) const 855 { 856 GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset); 857 } 858 859 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel, 860 Relocation::Type pType, 861 uint32_t pSymIdx, 862 uint32_t pOffset, 863 int32_t pAddend) const 864 { 865 GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset, pAddend); 866 } 867 868 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel, 869 Relocation::Type pType, 870 uint32_t pSymIdx, 871 uint64_t pOffset) const 872 { 873 uint64_t r_info = mcld::bswap32(pType); 874 r_info <<= 32; 875 r_info |= pSymIdx; 876 877 pRel.r_info = r_info; 878 pRel.r_offset = pOffset; 879 } 880 881 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel, 882 Relocation::Type pType, 883 uint32_t pSymIdx, 884 uint64_t pOffset, 885 int64_t pAddend) const 886 { 887 uint64_t r_info = mcld::bswap32(pType); 888 r_info <<= 32; 889 r_info |= pSymIdx; 890 891 pRel.r_info = r_info; 892 pRel.r_offset = pOffset; 893 pRel.r_addend = pAddend; 894 } 895 896 //===----------------------------------------------------------------------===// 897 // Mips32GNULDBackend 898 //===----------------------------------------------------------------------===// 899 Mips32GNULDBackend::Mips32GNULDBackend(const LinkerConfig& pConfig, 900 MipsGNUInfo* pInfo) 901 : MipsGNULDBackend(pConfig, pInfo) 902 {} 903 904 bool Mips32GNULDBackend::initRelocator() 905 { 906 if (NULL == m_pRelocator) 907 m_pRelocator = new Mips32Relocator(*this, config()); 908 909 return true; 910 } 911 912 void Mips32GNULDBackend::initTargetSections(Module& pModule, 913 ObjectBuilder& pBuilder) 914 { 915 MipsGNULDBackend::initTargetSections(pModule, pBuilder); 916 917 if (LinkerConfig::Object == config().codeGenType()) 918 return; 919 920 ELFFileFormat* fileFormat = getOutputFormat(); 921 922 // initialize .got 923 LDSection& got = fileFormat->getGOT(); 924 m_pGOT = new Mips32GOT(got); 925 926 // initialize .got.plt 927 LDSection& gotplt = fileFormat->getGOTPLT(); 928 m_pGOTPLT = new MipsGOTPLT(gotplt); 929 930 // initialize .plt 931 LDSection& plt = fileFormat->getPLT(); 932 m_pPLT = new MipsPLT(plt); 933 } 934 935 size_t Mips32GNULDBackend::getRelEntrySize() 936 { 937 return 8; 938 } 939 940 size_t Mips32GNULDBackend::getRelaEntrySize() 941 { 942 return 12; 943 } 944 945 //===----------------------------------------------------------------------===// 946 // Mips64GNULDBackend 947 //===----------------------------------------------------------------------===// 948 Mips64GNULDBackend::Mips64GNULDBackend(const LinkerConfig& pConfig, 949 MipsGNUInfo* pInfo) 950 : MipsGNULDBackend(pConfig, pInfo) 951 {} 952 953 bool Mips64GNULDBackend::initRelocator() 954 { 955 if (NULL == m_pRelocator) 956 m_pRelocator = new Mips64Relocator(*this, config()); 957 958 return true; 959 } 960 961 void Mips64GNULDBackend::initTargetSections(Module& pModule, 962 ObjectBuilder& pBuilder) 963 { 964 MipsGNULDBackend::initTargetSections(pModule, pBuilder); 965 966 if (LinkerConfig::Object == config().codeGenType()) 967 return; 968 969 ELFFileFormat* fileFormat = getOutputFormat(); 970 971 // initialize .got 972 LDSection& got = fileFormat->getGOT(); 973 m_pGOT = new Mips64GOT(got); 974 975 // initialize .got.plt 976 LDSection& gotplt = fileFormat->getGOTPLT(); 977 m_pGOTPLT = new MipsGOTPLT(gotplt); 978 979 // initialize .plt 980 LDSection& plt = fileFormat->getPLT(); 981 m_pPLT = new MipsPLT(plt); 982 } 983 984 size_t Mips64GNULDBackend::getRelEntrySize() 985 { 986 return 16; 987 } 988 989 size_t Mips64GNULDBackend::getRelaEntrySize() 990 { 991 return 24; 992 } 993 994 //===----------------------------------------------------------------------===// 995 /// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend 996 /// 997 static TargetLDBackend* createMipsLDBackend(const LinkerConfig& pConfig) 998 { 999 const llvm::Triple& triple = pConfig.targets().triple(); 1000 1001 if (triple.isOSDarwin()) { 1002 assert(0 && "MachO linker is not supported yet"); 1003 } 1004 if (triple.isOSWindows()) { 1005 assert(0 && "COFF linker is not supported yet"); 1006 } 1007 1008 llvm::Triple::ArchType arch = triple.getArch(); 1009 1010 if (llvm::Triple::mips64el == arch) 1011 return new Mips64GNULDBackend(pConfig, new MipsGNUInfo(triple)); 1012 1013 assert (arch == llvm::Triple::mipsel); 1014 return new Mips32GNULDBackend(pConfig, new MipsGNUInfo(triple)); 1015 } 1016 1017 //===----------------------------------------------------------------------===// 1018 // Force static initialization. 1019 //===----------------------------------------------------------------------===// 1020 extern "C" void MCLDInitializeMipsLDBackend() { 1021 mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget, 1022 createMipsLDBackend); 1023 mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMips64elTarget, 1024 createMipsLDBackend); 1025 } 1026