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