MipsLDBackend.cpp revision 551ae4ebd3e9d137ea668fb83ae4a55b8cfba451
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 ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 552 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 553 } 554 // FIXME: how to identify small and large common symbols? 555 else { 556 bss_offset += ObjectBuilder::AppendFragment(*frag, 557 *bss_sect_data, 558 (*com_sym)->value()); 559 ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 560 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 561 } 562 } 563 } 564 565 // allocate all global common symbols 566 com_end = symbol_list.commonEnd(); 567 for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 568 // We have to reset the description of the symbol here. When doing 569 // incremental linking, the output relocatable object may have common 570 // symbols. Therefore, we can not treat common symbols as normal symbols 571 // when emitting the regular name pools. We must change the symbols' 572 // description here. 573 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 574 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 575 576 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 577 // allocate TLS common symbol in tbss section 578 tbss_offset += ObjectBuilder::AppendFragment(*frag, 579 *tbss_sect_data, 580 (*com_sym)->value()); 581 ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 582 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 583 } 584 // FIXME: how to identify small and large common symbols? 585 else { 586 bss_offset += ObjectBuilder::AppendFragment(*frag, 587 *bss_sect_data, 588 (*com_sym)->value()); 589 ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 590 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 591 } 592 } 593 594 bss_sect.setSize(bss_offset); 595 tbss_sect.setSize(tbss_offset); 596 symbol_list.changeCommonsToGlobal(); 597 return true; 598} 599 600uint64_t MipsGNULDBackend::getGP0(const Input& pInput) const 601{ 602 return m_GP0Map.lookup(&pInput); 603} 604 605void MipsGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) 606{ 607 // If we do not reserve any GOT entries, we do not need to re-define GOT 608 // symbol. 609 if (!m_pGOT->hasGOT1()) 610 return; 611 612 // define symbol _GLOBAL_OFFSET_TABLE_ 613 if ( m_pGOTSymbol != NULL ) { 614 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 615 "_GLOBAL_OFFSET_TABLE_", 616 ResolveInfo::Object, 617 ResolveInfo::Define, 618 ResolveInfo::Local, 619 0x0, // size 620 0x0, // value 621 FragmentRef::Create(*(m_pGOT->begin()), 0x0), 622 ResolveInfo::Hidden); 623 } 624 else { 625 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 626 "_GLOBAL_OFFSET_TABLE_", 627 ResolveInfo::Object, 628 ResolveInfo::Define, 629 ResolveInfo::Local, 630 0x0, // size 631 0x0, // value 632 FragmentRef::Create(*(m_pGOT->begin()), 0x0), 633 ResolveInfo::Hidden); 634 } 635} 636 637void MipsGNULDBackend::defineGOTPLTSymbol(IRBuilder& pBuilder) 638{ 639 // define symbol _PROCEDURE_LINKAGE_TABLE_ 640 if ( m_pPLTSymbol != NULL ) { 641 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 642 "_PROCEDURE_LINKAGE_TABLE_", 643 ResolveInfo::Object, 644 ResolveInfo::Define, 645 ResolveInfo::Local, 646 0x0, // size 647 0x0, // value 648 FragmentRef::Create(*(m_pPLT->begin()), 0x0), 649 ResolveInfo::Hidden); 650 } 651 else { 652 m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 653 "_PROCEDURE_LINKAGE_TABLE_", 654 ResolveInfo::Object, 655 ResolveInfo::Define, 656 ResolveInfo::Local, 657 0x0, // size 658 0x0, // value 659 FragmentRef::Create(*(m_pPLT->begin()), 0x0), 660 ResolveInfo::Hidden); 661 } 662} 663 664/// doCreateProgramHdrs - backend can implement this function to create the 665/// target-dependent segments 666void MipsGNULDBackend::doCreateProgramHdrs(Module& pModule) 667{ 668 // TODO 669} 670 671bool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel) 672{ 673 uint64_t sym_value = 0x0; 674 675 LDSymbol* symbol = pRel.symInfo()->outSymbol(); 676 if (symbol->hasFragRef()) { 677 uint64_t value = symbol->fragRef()->getOutputOffset(); 678 uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr(); 679 sym_value = addr + value; 680 } 681 682 Stub* stub = 683 getStubFactory()->create(pRel, sym_value, pBuilder, *getBRIslandFactory()); 684 685 if (NULL == stub) 686 return false; 687 688 assert(NULL != stub->symInfo()); 689 // increase the size of .symtab and .strtab 690 LDSection& symtab = getOutputFormat()->getSymTab(); 691 LDSection& strtab = getOutputFormat()->getStrTab(); 692 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 693 strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 694 695 return true; 696} 697 698bool MipsGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, 699 bool& pFinished) 700{ 701 assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); 702 703 bool isRelaxed = false; 704 705 for (Module::obj_iterator input = pModule.obj_begin(); 706 input != pModule.obj_end(); ++input) { 707 LDContext* context = (*input)->context(); 708 709 for (LDContext::sect_iterator rs = context->relocSectBegin(); 710 rs != context->relocSectEnd(); ++rs) { 711 LDSection* sec = *rs; 712 713 if (LDFileFormat::Ignore == sec->kind() || !sec->hasRelocData()) 714 continue; 715 716 for (RelocData::iterator reloc = sec->getRelocData()->begin(); 717 reloc != sec->getRelocData()->end(); ++reloc) { 718 if (llvm::ELF::R_MIPS_26 != reloc->type()) 719 continue; 720 721 if (relaxRelocation(pBuilder, *llvm::cast<Relocation>(reloc))) 722 isRelaxed = true; 723 } 724 } 725 } 726 727 SectionData* textData = getOutputFormat()->getText().getSectionData(); 728 729 // find the first fragment w/ invalid offset due to stub insertion 730 Fragment* invalid = NULL; 731 pFinished = true; 732 for (BranchIslandFactory::iterator ii = getBRIslandFactory()->begin(), 733 ie = getBRIslandFactory()->end(); 734 ii != ie; ++ii) 735 { 736 BranchIsland& island = *ii; 737 if (island.end() == textData->end()) 738 break; 739 740 Fragment* exit = island.end(); 741 if ((island.offset() + island.size()) > exit->getOffset()) { 742 invalid = exit; 743 pFinished = false; 744 break; 745 } 746 } 747 748 // reset the offset of invalid fragments 749 while (NULL != invalid) { 750 invalid->setOffset(invalid->getPrevNode()->getOffset() + 751 invalid->getPrevNode()->size()); 752 invalid = invalid->getNextNode(); 753 } 754 755 // reset the size of .text 756 if (isRelaxed) 757 getOutputFormat()->getText().setSize(textData->back().getOffset() + 758 textData->back().size()); 759 760 return isRelaxed; 761} 762 763bool MipsGNULDBackend::initTargetStubs() 764{ 765 if (NULL == getStubFactory()) 766 return false; 767 768 getStubFactory()->addPrototype(new MipsLA25Stub(*this)); 769 return true; 770} 771 772bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel, 773 Relocation::Type& pType, 774 uint32_t& pSymIdx, 775 uint32_t& pOffset) const 776{ 777 return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset); 778} 779 780bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel, 781 Relocation::Type& pType, 782 uint32_t& pSymIdx, 783 uint32_t& pOffset, 784 int32_t& pAddend) const 785{ 786 return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset, pAddend); 787} 788 789bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel, 790 Relocation::Type& pType, 791 uint32_t& pSymIdx, 792 uint64_t& pOffset) const 793{ 794 uint64_t r_info = 0x0; 795 if (llvm::sys::IsLittleEndianHost) { 796 pOffset = pRel.r_offset; 797 r_info = pRel.r_info; 798 } 799 else { 800 pOffset = mcld::bswap64(pRel.r_offset); 801 r_info = mcld::bswap64(pRel.r_info); 802 } 803 804 // MIPS 64 little endian (we do not support big endian now) 805 // has a "special" encoding of r_info relocation 806 // field. Instead of one 64 bit little endian number, it is a little 807 // endian 32 bit number followed by a 32 bit big endian number. 808 pType = mcld::bswap32(r_info >> 32); 809 pSymIdx = r_info & 0xffffffff; 810 return true; 811} 812 813bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel, 814 Relocation::Type& pType, 815 uint32_t& pSymIdx, 816 uint64_t& pOffset, 817 int64_t& pAddend) const 818{ 819 uint64_t r_info = 0x0; 820 if (llvm::sys::IsLittleEndianHost) { 821 pOffset = pRel.r_offset; 822 r_info = pRel.r_info; 823 pAddend = pRel.r_addend; 824 } 825 else { 826 pOffset = mcld::bswap64(pRel.r_offset); 827 r_info = mcld::bswap64(pRel.r_info); 828 pAddend = mcld::bswap64(pRel.r_addend); 829 } 830 831 pType = mcld::bswap32(r_info >> 32); 832 pSymIdx = r_info & 0xffffffff; 833 return true; 834} 835 836void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel, 837 Relocation::Type pType, 838 uint32_t pSymIdx, 839 uint32_t pOffset) const 840{ 841 GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset); 842} 843 844void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel, 845 Relocation::Type pType, 846 uint32_t pSymIdx, 847 uint32_t pOffset, 848 int32_t pAddend) const 849{ 850 GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset, pAddend); 851} 852 853void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel, 854 Relocation::Type pType, 855 uint32_t pSymIdx, 856 uint64_t pOffset) const 857{ 858 uint64_t r_info = mcld::bswap32(pType); 859 r_info <<= 32; 860 r_info |= pSymIdx; 861 862 pRel.r_info = r_info; 863 pRel.r_offset = pOffset; 864} 865 866void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel, 867 Relocation::Type pType, 868 uint32_t pSymIdx, 869 uint64_t pOffset, 870 int64_t pAddend) const 871{ 872 uint64_t r_info = mcld::bswap32(pType); 873 r_info <<= 32; 874 r_info |= pSymIdx; 875 876 pRel.r_info = r_info; 877 pRel.r_offset = pOffset; 878 pRel.r_addend = pAddend; 879} 880 881//===----------------------------------------------------------------------===// 882// Mips32GNULDBackend 883//===----------------------------------------------------------------------===// 884Mips32GNULDBackend::Mips32GNULDBackend(const LinkerConfig& pConfig, 885 MipsGNUInfo* pInfo) 886 : MipsGNULDBackend(pConfig, pInfo) 887{} 888 889bool Mips32GNULDBackend::initRelocator() 890{ 891 if (NULL == m_pRelocator) 892 m_pRelocator = new Mips32Relocator(*this, config()); 893 894 return true; 895} 896 897void Mips32GNULDBackend::initTargetSections(Module& pModule, 898 ObjectBuilder& pBuilder) 899{ 900 MipsGNULDBackend::initTargetSections(pModule, pBuilder); 901 902 if (LinkerConfig::Object == config().codeGenType()) 903 return; 904 905 ELFFileFormat* fileFormat = getOutputFormat(); 906 907 // initialize .got 908 LDSection& got = fileFormat->getGOT(); 909 m_pGOT = new Mips32GOT(got); 910 911 // initialize .got.plt 912 LDSection& gotplt = fileFormat->getGOTPLT(); 913 m_pGOTPLT = new MipsGOTPLT(gotplt); 914 915 // initialize .plt 916 LDSection& plt = fileFormat->getPLT(); 917 m_pPLT = new MipsPLT(plt); 918} 919 920size_t Mips32GNULDBackend::getRelEntrySize() 921{ 922 return 8; 923} 924 925size_t Mips32GNULDBackend::getRelaEntrySize() 926{ 927 return 12; 928} 929 930//===----------------------------------------------------------------------===// 931// Mips64GNULDBackend 932//===----------------------------------------------------------------------===// 933Mips64GNULDBackend::Mips64GNULDBackend(const LinkerConfig& pConfig, 934 MipsGNUInfo* pInfo) 935 : MipsGNULDBackend(pConfig, pInfo) 936{} 937 938bool Mips64GNULDBackend::initRelocator() 939{ 940 if (NULL == m_pRelocator) 941 m_pRelocator = new Mips64Relocator(*this, config()); 942 943 return true; 944} 945 946void Mips64GNULDBackend::initTargetSections(Module& pModule, 947 ObjectBuilder& pBuilder) 948{ 949 MipsGNULDBackend::initTargetSections(pModule, pBuilder); 950 951 if (LinkerConfig::Object == config().codeGenType()) 952 return; 953 954 ELFFileFormat* fileFormat = getOutputFormat(); 955 956 // initialize .got 957 LDSection& got = fileFormat->getGOT(); 958 m_pGOT = new Mips64GOT(got); 959 960 // initialize .got.plt 961 LDSection& gotplt = fileFormat->getGOTPLT(); 962 m_pGOTPLT = new MipsGOTPLT(gotplt); 963 964 // initialize .plt 965 LDSection& plt = fileFormat->getPLT(); 966 m_pPLT = new MipsPLT(plt); 967} 968 969size_t Mips64GNULDBackend::getRelEntrySize() 970{ 971 return 16; 972} 973 974size_t Mips64GNULDBackend::getRelaEntrySize() 975{ 976 return 24; 977} 978 979//===----------------------------------------------------------------------===// 980/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend 981/// 982static TargetLDBackend* createMipsLDBackend(const LinkerConfig& pConfig) 983{ 984 const llvm::Triple& triple = pConfig.targets().triple(); 985 986 if (triple.isOSDarwin()) { 987 assert(0 && "MachO linker is not supported yet"); 988 } 989 if (triple.isOSWindows()) { 990 assert(0 && "COFF linker is not supported yet"); 991 } 992 993 llvm::Triple::ArchType arch = triple.getArch(); 994 995 if (llvm::Triple::mips64el == arch) 996 return new Mips64GNULDBackend(pConfig, new MipsGNUInfo(triple)); 997 998 assert (arch == llvm::Triple::mipsel); 999 return new Mips32GNULDBackend(pConfig, new MipsGNUInfo(triple)); 1000} 1001 1002//===----------------------------------------------------------------------===// 1003// Force static initialization. 1004//===----------------------------------------------------------------------===// 1005extern "C" void MCLDInitializeMipsLDBackend() { 1006 mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget, 1007 createMipsLDBackend); 1008 mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMips64elTarget, 1009 createMipsLDBackend); 1010} 1011