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