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 10#include "Mips.h" 11#include "MipsELFDynamic.h" 12#include "MipsLDBackend.h" 13#include "MipsRelocationFactory.h" 14 15#include <llvm/ADT/Triple.h> 16#include <llvm/Support/ELF.h> 17 18#include <mcld/LD/FillFragment.h> 19#include <mcld/LD/SectionMap.h> 20#include <mcld/MC/MCLDInfo.h> 21#include <mcld/MC/MCLinker.h> 22#include <mcld/Support/MemoryRegion.h> 23#include <mcld/Support/MsgHandling.h> 24#include <mcld/Support/TargetRegistry.h> 25#include <mcld/Target/OutputRelocSection.h> 26 27enum { 28 // The original o32 abi. 29 E_MIPS_ABI_O32 = 0x00001000, 30 // O32 extended to work on 64 bit architectures. 31 E_MIPS_ABI_O64 = 0x00002000, 32 // EABI in 32 bit mode. 33 E_MIPS_ABI_EABI32 = 0x00003000, 34 // EABI in 64 bit mode. 35 E_MIPS_ABI_EABI64 = 0x00004000 36}; 37 38namespace mcld { 39 40MipsGNULDBackend::MipsGNULDBackend() 41 : m_pRelocFactory(NULL), 42 m_pGOT(NULL), 43 m_pRelDyn(NULL), 44 m_pDynamic(NULL), 45 m_pGOTSymbol(NULL), 46 m_pGpDispSymbol(NULL) 47{ 48} 49 50MipsGNULDBackend::~MipsGNULDBackend() 51{ 52 if (NULL != m_pRelocFactory) 53 delete m_pRelocFactory; 54 if (NULL != m_pGOT) 55 delete m_pGOT; 56 if (NULL != m_pRelDyn) 57 delete m_pRelDyn; 58 if (NULL != m_pDynamic) 59 delete m_pDynamic; 60} 61 62bool MipsGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap) 63{ 64 // Nothing to do because we do not support 65 // any MIPS specific sections now. 66 return true; 67} 68 69void MipsGNULDBackend::initTargetSections(MCLinker& pLinker) 70{ 71} 72 73void MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput) 74{ 75 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 76 // same name in input 77 m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 78 "_GLOBAL_OFFSET_TABLE_", 79 false, 80 ResolveInfo::Object, 81 ResolveInfo::Define, 82 ResolveInfo::Local, 83 0x0, // size 84 0x0, // value 85 NULL, // FragRef 86 ResolveInfo::Hidden); 87 88 m_pGpDispSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 89 "_gp_disp", 90 false, 91 ResolveInfo::Section, 92 ResolveInfo::Define, 93 ResolveInfo::Absolute, 94 0x0, // size 95 0x0, // value 96 NULL, // FragRef 97 ResolveInfo::Default); 98 99 if (NULL != m_pGpDispSymbol) { 100 m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp); 101 } 102} 103 104bool MipsGNULDBackend::initRelocFactory(const MCLinker& pLinker) 105{ 106 if (NULL == m_pRelocFactory) { 107 m_pRelocFactory = new MipsRelocationFactory(1024, *this); 108 m_pRelocFactory->setLayout(pLinker.getLayout()); 109 } 110 return true; 111} 112 113RelocationFactory* MipsGNULDBackend::getRelocFactory() 114{ 115 assert(NULL != m_pRelocFactory); 116 return m_pRelocFactory; 117} 118 119void MipsGNULDBackend::scanRelocation(Relocation& pReloc, 120 const LDSymbol& pInputSym, 121 MCLinker& pLinker, 122 const MCLDInfo& pLDInfo, 123 const Output& pOutput, 124 const LDSection& pSection) 125{ 126 // rsym - The relocation target symbol 127 ResolveInfo* rsym = pReloc.symInfo(); 128 assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 129 130 assert(NULL != pSection.getLink()); 131 if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) { 132 if (rsym->isLocal()) { 133 updateAddend(pReloc, pInputSym, pLinker.getLayout()); 134 } 135 return; 136 } 137 138 // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies 139 // that a .got section is needed. 140 if (NULL == m_pGOT && NULL != m_pGOTSymbol) { 141 if (rsym == m_pGOTSymbol->resolveInfo()) { 142 createGOT(pLinker, pOutput); 143 } 144 } 145 146 // Skip relocation against _gp_disp 147 if (strcmp("_gp_disp", pInputSym.name()) == 0) 148 return; 149 150 // We test isLocal or if pInputSym is not a dynamic symbol 151 // We assume -Bsymbolic to bind all symbols internaly via !rsym->isDyn() 152 // Don't put undef symbols into local entries. 153 if ((rsym->isLocal() || !isDynamicSymbol(pInputSym, pOutput) || 154 !rsym->isDyn()) && !rsym->isUndef()) 155 scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 156 else 157 scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 158} 159 160uint32_t MipsGNULDBackend::machine() const 161{ 162 return llvm::ELF::EM_MIPS; 163} 164 165uint8_t MipsGNULDBackend::OSABI() const 166{ 167 return llvm::ELF::ELFOSABI_NONE; 168} 169 170uint8_t MipsGNULDBackend::ABIVersion() const 171{ 172 return 0; 173} 174 175uint64_t MipsGNULDBackend::flags() const 176{ 177 // TODO: (simon) The correct flag's set depend on command line 178 // arguments and flags from input .o files. 179 return llvm::ELF::EF_MIPS_ARCH_32R2 | 180 llvm::ELF::EF_MIPS_NOREORDER | 181 llvm::ELF::EF_MIPS_PIC | 182 llvm::ELF::EF_MIPS_CPIC | 183 E_MIPS_ABI_O32; 184} 185 186bool MipsGNULDBackend::isLittleEndian() const 187{ 188 // Now we support little endian (mipsel) target only. 189 return true; 190} 191 192unsigned int MipsGNULDBackend::bitclass() const 193{ 194 return 32; 195} 196 197uint64_t MipsGNULDBackend::defaultTextSegmentAddr() const 198{ 199 return 0x80000; 200} 201 202uint64_t MipsGNULDBackend::abiPageSize(const MCLDInfo& pInfo) const 203{ 204 if (pInfo.options().maxPageSize() > 0) 205 return pInfo.options().maxPageSize(); 206 else 207 return static_cast<uint64_t>(0x10000); 208} 209 210void MipsGNULDBackend::doPreLayout(const Output& pOutput, 211 const MCLDInfo& pInfo, 212 MCLinker& pLinker) 213{ 214 // when building shared object, the .got section is must. 215 if (pOutput.type() == Output::DynObj && NULL == m_pGOT) { 216 createGOT(pLinker, pOutput); 217 } 218} 219 220void MipsGNULDBackend::doPostLayout(const Output& pOutput, 221 const MCLDInfo& pInfo, 222 MCLinker& pLinker) 223{ 224} 225 226/// dynamic - the dynamic section of the target machine. 227/// Use co-variant return type to return its own dynamic section. 228MipsELFDynamic& MipsGNULDBackend::dynamic() 229{ 230 if (NULL == m_pDynamic) 231 m_pDynamic = new MipsELFDynamic(*this); 232 233 return *m_pDynamic; 234} 235 236/// dynamic - the dynamic section of the target machine. 237/// Use co-variant return type to return its own dynamic section. 238const MipsELFDynamic& MipsGNULDBackend::dynamic() const 239{ 240 assert( NULL != m_pDynamic); 241 return *m_pDynamic; 242} 243 244uint64_t MipsGNULDBackend::emitSectionData(const Output& pOutput, 245 const LDSection& pSection, 246 const MCLDInfo& pInfo, 247 const Layout& pLayout, 248 MemoryRegion& pRegion) const 249{ 250 assert(pRegion.size() && "Size of MemoryRegion is zero!"); 251 252 const ELFFileFormat* file_format = getOutputFormat(pOutput); 253 254 if (&pSection == &(file_format->getGOT())) { 255 assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 256 uint64_t result = m_pGOT->emit(pRegion); 257 return result; 258 } 259 260 fatal(diag::unrecognized_output_sectoin) 261 << pSection.name() 262 << "mclinker@googlegroups.com"; 263 return 0; 264} 265/// isGlobalGOTSymbol - return true if the symbol is the global GOT entry. 266bool MipsGNULDBackend::isGlobalGOTSymbol(const LDSymbol& pSymbol) const 267{ 268 return std::find(m_GlobalGOTSyms.begin(), 269 m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end(); 270} 271 272/// emitDynamicSymbol - emit dynamic symbol. 273void MipsGNULDBackend::emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32, 274 Output& pOutput, 275 LDSymbol& pSymbol, 276 const Layout& pLayout, 277 char* strtab, 278 size_t strtabsize, 279 size_t symtabIdx) 280{ 281 // maintain output's symbol and index map 282 bool sym_exist = false; 283 HashTableType::entry_type* entry = 0; 284 entry = m_pSymIndexMap->insert(&pSymbol, sym_exist); 285 entry->setValue(symtabIdx); 286 287 // FIXME: check the endian between host and target 288 // write out symbol 289 sym32.st_name = strtabsize; 290 sym32.st_value = pSymbol.value(); 291 sym32.st_size = getSymbolSize(pSymbol); 292 sym32.st_info = getSymbolInfo(pSymbol); 293 sym32.st_other = pSymbol.visibility(); 294 sym32.st_shndx = getSymbolShndx(pSymbol, pLayout); 295 // write out string 296 strcpy((strtab + strtabsize), pSymbol.name()); 297} 298 299/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 300/// 301/// the size of these tables should be computed before layout 302/// layout should computes the start offset of these tables 303void MipsGNULDBackend::emitDynNamePools(Output& pOutput, 304 SymbolCategory& pSymbols, 305 const Layout& pLayout, 306 const MCLDInfo& pLDInfo) 307{ 308 assert(pOutput.hasMemArea()); 309 ELFFileFormat* file_format = getOutputFormat(pOutput); 310 311 LDSection& symtab_sect = file_format->getDynSymTab(); 312 LDSection& strtab_sect = file_format->getDynStrTab(); 313 LDSection& hash_sect = file_format->getHashTab(); 314 LDSection& dyn_sect = file_format->getDynamic(); 315 316 MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(), 317 symtab_sect.size()); 318 MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(), 319 strtab_sect.size()); 320 MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(), 321 hash_sect.size()); 322 MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(), 323 dyn_sect.size()); 324 // set up symtab_region 325 llvm::ELF::Elf32_Sym* symtab32 = NULL; 326 symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start(); 327 328 symtab32[0].st_name = 0; 329 symtab32[0].st_value = 0; 330 symtab32[0].st_size = 0; 331 symtab32[0].st_info = 0; 332 symtab32[0].st_other = 0; 333 symtab32[0].st_shndx = 0; 334 335 // set up strtab_region 336 char* strtab = (char*)strtab_region->start(); 337 strtab[0] = '\0'; 338 339 bool sym_exist = false; 340 HashTableType::entry_type* entry = 0; 341 342 // add index 0 symbol into SymIndexMap 343 entry = m_pSymIndexMap->insert(NULL, sym_exist); 344 entry->setValue(0); 345 346 size_t symtabIdx = 1; 347 size_t strtabsize = 1; 348 349 // emit of .dynsym, and .dynstr except GOT entries 350 for (SymbolCategory::iterator symbol = pSymbols.begin(), 351 sym_end = pSymbols.end(); symbol != sym_end; ++symbol) { 352 if (!isDynamicSymbol(**symbol, pOutput)) 353 continue; 354 355 if (isGlobalGOTSymbol(**symbol)) 356 continue; 357 358 emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab, 359 strtabsize, symtabIdx); 360 361 // sum up counters 362 ++symtabIdx; 363 strtabsize += (*symbol)->nameSize() + 1; 364 } 365 366 // emit global GOT 367 for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(), 368 symbol_end = m_GlobalGOTSyms.end(); 369 symbol != symbol_end; ++symbol) { 370 371 // Make sure this golbal GOT entry is a dynamic symbol. 372 // If not, something is wrong earlier when putting this symbol into 373 // global GOT. 374 if (!isDynamicSymbol(**symbol, pOutput)) 375 fatal(diag::mips_got_symbol) << (*symbol)->name(); 376 377 emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab, 378 strtabsize, symtabIdx); 379 380 // sum up counters 381 ++symtabIdx; 382 strtabsize += (*symbol)->nameSize() + 1; 383 } 384 385 // emit DT_NEED 386 // add DT_NEED strings into .dynstr 387 // Rules: 388 // 1. ignore --no-add-needed 389 // 2. force count in --no-as-needed 390 // 3. judge --as-needed 391 ELFDynamic::iterator dt_need = dynamic().needBegin(); 392 InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end(); 393 for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) { 394 if (Input::DynObj == (*input)->type()) { 395 // --add-needed 396 if ((*input)->attribute()->isAddNeeded()) { 397 // --no-as-needed 398 if (!(*input)->attribute()->isAsNeeded()) { 399 strcpy((strtab + strtabsize), (*input)->name().c_str()); 400 (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 401 strtabsize += (*input)->name().size() + 1; 402 ++dt_need; 403 } 404 // --as-needed 405 else if ((*input)->isNeeded()) { 406 strcpy((strtab + strtabsize), (*input)->name().c_str()); 407 (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 408 strtabsize += (*input)->name().size() + 1; 409 ++dt_need; 410 } 411 } 412 } 413 } // for 414 415 // emit soname 416 // initialize value of ELF .dynamic section 417 if (Output::DynObj == pOutput.type()) 418 dynamic().applySoname(strtabsize); 419 dynamic().applyEntries(pLDInfo, *file_format); 420 dynamic().emit(dyn_sect, *dyn_region); 421 422 strcpy((strtab + strtabsize), pOutput.name().c_str()); 423 strtabsize += pOutput.name().size() + 1; 424 425 // emit hash table 426 // FIXME: this verion only emit SVR4 hash section. 427 // Please add GNU new hash section 428 429 // both 32 and 64 bits hash table use 32-bit entry 430 // set up hash_region 431 uint32_t* word_array = (uint32_t*)hash_region->start(); 432 uint32_t& nbucket = word_array[0]; 433 uint32_t& nchain = word_array[1]; 434 435 nbucket = getHashBucketCount(symtabIdx, false); 436 nchain = symtabIdx; 437 438 uint32_t* bucket = (word_array + 2); 439 uint32_t* chain = (bucket + nbucket); 440 441 // initialize bucket 442 bzero((void*)bucket, nbucket); 443 444 StringHash<ELF> hash_func; 445 446 for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) { 447 llvm::StringRef name(strtab + symtab32[sym_idx].st_name); 448 size_t bucket_pos = hash_func(name) % nbucket; 449 chain[sym_idx] = bucket[bucket_pos]; 450 bucket[bucket_pos] = sym_idx; 451 } 452 453} 454 455MipsGOT& MipsGNULDBackend::getGOT() 456{ 457 assert(NULL != m_pGOT); 458 return *m_pGOT; 459} 460 461const MipsGOT& MipsGNULDBackend::getGOT() const 462{ 463 assert(NULL != m_pGOT); 464 return *m_pGOT; 465} 466 467OutputRelocSection& MipsGNULDBackend::getRelDyn() 468{ 469 assert(NULL != m_pRelDyn); 470 return *m_pRelDyn; 471} 472 473const OutputRelocSection& MipsGNULDBackend::getRelDyn() const 474{ 475 assert(NULL != m_pRelDyn); 476 return *m_pRelDyn; 477} 478 479unsigned int 480MipsGNULDBackend::getTargetSectionOrder(const Output& pOutput, 481 const LDSection& pSectHdr, 482 const MCLDInfo& pInfo) const 483{ 484 const ELFFileFormat* file_format = getOutputFormat(pOutput); 485 486 if (&pSectHdr == &file_format->getGOT()) 487 return SHO_DATA; 488 489 return SHO_UNDEFINED; 490} 491 492/// finalizeSymbol - finalize the symbol value 493bool MipsGNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput) 494{ 495 if (NULL != m_pGpDispSymbol) 496 m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0); 497 return true; 498} 499 500/// allocateCommonSymbols - allocate common symbols in the corresponding 501/// sections. 502/// @refer Google gold linker: common.cc: 214 503/// FIXME: Mips needs to allocate small common symbol 504bool 505MipsGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const 506{ 507 SymbolCategory& symbol_list = pLinker.getOutputSymbols(); 508 509 if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) 510 return true; 511 512 SymbolCategory::iterator com_sym, com_end; 513 514 // FIXME: If the order of common symbols is defined, then sort common symbols 515 // std::sort(com_sym, com_end, some kind of order); 516 517 // get or create corresponding BSS LDSection 518 LDSection* bss_sect = &pLinker.getOrCreateOutputSectHdr(".bss", 519 LDFileFormat::BSS, 520 llvm::ELF::SHT_NOBITS, 521 llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 522 523 LDSection* tbss_sect = &pLinker.getOrCreateOutputSectHdr( 524 ".tbss", 525 LDFileFormat::BSS, 526 llvm::ELF::SHT_NOBITS, 527 llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 528 529 // FIXME: .sbss amd .lbss currently unused. 530 /* 531 LDSection* sbss_sect = &pLinker.getOrCreateOutputSectHdr( 532 ".sbss", 533 LDFileFormat::BSS, 534 llvm::ELF::SHT_NOBITS, 535 llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC | 536 llvm::ELF::SHF_MIPS_GPREL); 537 538 LDSection* lbss_sect = &pLinker.getOrCreateOutputSectHdr( 539 ".lbss", 540 LDFileFormat::BSS, 541 llvm::ELF::SHT_NOBITS, 542 llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC | 543 llvm::ELF::SHF_MIPS_LOCAL); 544 */ 545 546 assert(NULL != bss_sect && NULL != tbss_sect); 547 548 // get or create corresponding BSS SectionData 549 SectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect); 550 SectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect); 551 552 // remember original BSS size 553 uint64_t bss_offset = bss_sect->size(); 554 uint64_t tbss_offset = tbss_sect->size(); 555 556 // allocate all local common symbols 557 com_end = symbol_list.localEnd(); 558 559 for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 560 if (ResolveInfo::Common == (*com_sym)->desc()) { 561 // We have to reset the description of the symbol here. When doing 562 // incremental linking, the output relocatable object may have common 563 // symbols. Therefore, we can not treat common symbols as normal symbols 564 // when emitting the regular name pools. We must change the symbols' 565 // description here. 566 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 567 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 568 (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0)); 569 570 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 571 // allocate TLS common symbol in tbss section 572 tbss_offset += pLinker.getLayout().appendFragment(*frag, 573 tbss_sect_data, 574 (*com_sym)->value()); 575 } 576 // FIXME: how to identify small and large common symbols? 577 else { 578 bss_offset += pLinker.getLayout().appendFragment(*frag, 579 bss_sect_data, 580 (*com_sym)->value()); 581 } 582 } 583 } 584 585 // allocate all global common symbols 586 com_end = symbol_list.commonEnd(); 587 for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 588 // We have to reset the description of the symbol here. When doing 589 // incremental linking, the output relocatable object may have common 590 // symbols. Therefore, we can not treat common symbols as normal symbols 591 // when emitting the regular name pools. We must change the symbols' 592 // description here. 593 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 594 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 595 (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0)); 596 597 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 598 // allocate TLS common symbol in tbss section 599 tbss_offset += pLinker.getLayout().appendFragment(*frag, 600 tbss_sect_data, 601 (*com_sym)->value()); 602 } 603 // FIXME: how to identify small and large common symbols? 604 else { 605 bss_offset += pLinker.getLayout().appendFragment(*frag, 606 bss_sect_data, 607 (*com_sym)->value()); 608 } 609 } 610 611 bss_sect->setSize(bss_offset); 612 tbss_sect->setSize(tbss_offset); 613 symbol_list.changeCommonsToGlobal(); 614 return true; 615} 616 617void MipsGNULDBackend::updateAddend(Relocation& pReloc, 618 const LDSymbol& pInputSym, 619 const Layout& pLayout) const 620{ 621 // Update value keep in addend if we meet a section symbol 622 if (pReloc.symInfo()->type() == ResolveInfo::Section) { 623 pReloc.setAddend(pLayout.getOutputOffset( 624 *pInputSym.fragRef()) + pReloc.addend()); 625 } 626} 627 628void MipsGNULDBackend::scanLocalReloc(Relocation& pReloc, 629 const LDSymbol& pInputSym, 630 MCLinker& pLinker, 631 const MCLDInfo& pLDInfo, 632 const Output& pOutput) 633{ 634 ResolveInfo* rsym = pReloc.symInfo(); 635 636 updateAddend(pReloc, pInputSym, pLinker.getLayout()); 637 638 switch (pReloc.type()){ 639 case llvm::ELF::R_MIPS_NONE: 640 case llvm::ELF::R_MIPS_16: 641 break; 642 case llvm::ELF::R_MIPS_32: 643 if (Output::DynObj == pOutput.type()) { 644 // TODO: (simon) The gold linker does not create an entry in .rel.dyn 645 // section if the symbol section flags contains SHF_EXECINSTR. 646 // 1. Find the reason of this condition. 647 // 2. Check this condition here. 648 if (NULL == m_pRelDyn) 649 createRelDyn(pLinker, pOutput); 650 651 m_pRelDyn->reserveEntry(*m_pRelocFactory); 652 rsym->setReserved(rsym->reserved() | ReserveRel); 653 654 // Remeber this rsym is a local GOT entry (as if it needs an entry). 655 // Actually we don't allocate an GOT entry. 656 if (NULL == m_pGOT) 657 createGOT(pLinker, pOutput); 658 m_pGOT->setLocal(rsym); 659 } 660 break; 661 case llvm::ELF::R_MIPS_REL32: 662 case llvm::ELF::R_MIPS_26: 663 case llvm::ELF::R_MIPS_HI16: 664 case llvm::ELF::R_MIPS_LO16: 665 case llvm::ELF::R_MIPS_PC16: 666 case llvm::ELF::R_MIPS_SHIFT5: 667 case llvm::ELF::R_MIPS_SHIFT6: 668 case llvm::ELF::R_MIPS_64: 669 case llvm::ELF::R_MIPS_GOT_PAGE: 670 case llvm::ELF::R_MIPS_GOT_OFST: 671 case llvm::ELF::R_MIPS_SUB: 672 case llvm::ELF::R_MIPS_INSERT_A: 673 case llvm::ELF::R_MIPS_INSERT_B: 674 case llvm::ELF::R_MIPS_DELETE: 675 case llvm::ELF::R_MIPS_HIGHER: 676 case llvm::ELF::R_MIPS_HIGHEST: 677 case llvm::ELF::R_MIPS_SCN_DISP: 678 case llvm::ELF::R_MIPS_REL16: 679 case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 680 case llvm::ELF::R_MIPS_PJUMP: 681 case llvm::ELF::R_MIPS_RELGOT: 682 case llvm::ELF::R_MIPS_JALR: 683 case llvm::ELF::R_MIPS_GLOB_DAT: 684 case llvm::ELF::R_MIPS_COPY: 685 case llvm::ELF::R_MIPS_JUMP_SLOT: 686 break; 687 case llvm::ELF::R_MIPS_GOT16: 688 case llvm::ELF::R_MIPS_CALL16: 689 if (NULL == m_pGOT) 690 createGOT(pLinker, pOutput); 691 692 // For got16 section based relocations, we need to reserve got entries. 693 if (rsym->type() == ResolveInfo::Section) { 694 m_pGOT->reserveLocalEntry(); 695 // Remeber this rsym is a local GOT entry 696 m_pGOT->setLocal(rsym); 697 return; 698 } 699 700 if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 701 m_pGOT->reserveLocalEntry(); 702 rsym->setReserved(rsym->reserved() | ReserveGot); 703 // Remeber this rsym is a local GOT entry 704 m_pGOT->setLocal(rsym); 705 } 706 break; 707 case llvm::ELF::R_MIPS_GPREL32: 708 case llvm::ELF::R_MIPS_GPREL16: 709 case llvm::ELF::R_MIPS_LITERAL: 710 break; 711 case llvm::ELF::R_MIPS_GOT_DISP: 712 case llvm::ELF::R_MIPS_GOT_HI16: 713 case llvm::ELF::R_MIPS_CALL_HI16: 714 case llvm::ELF::R_MIPS_GOT_LO16: 715 case llvm::ELF::R_MIPS_CALL_LO16: 716 break; 717 case llvm::ELF::R_MIPS_TLS_DTPMOD32: 718 case llvm::ELF::R_MIPS_TLS_DTPREL32: 719 case llvm::ELF::R_MIPS_TLS_DTPMOD64: 720 case llvm::ELF::R_MIPS_TLS_DTPREL64: 721 case llvm::ELF::R_MIPS_TLS_GD: 722 case llvm::ELF::R_MIPS_TLS_LDM: 723 case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 724 case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 725 case llvm::ELF::R_MIPS_TLS_GOTTPREL: 726 case llvm::ELF::R_MIPS_TLS_TPREL32: 727 case llvm::ELF::R_MIPS_TLS_TPREL64: 728 case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 729 case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 730 break; 731 default: 732 fatal(diag::unknown_relocation) << (int)pReloc.type() 733 << pReloc.symInfo()->name(); 734 } 735} 736 737void MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc, 738 const LDSymbol& pInputSym, 739 MCLinker& pLinker, 740 const MCLDInfo& pLDInfo, 741 const Output& pOutput) 742{ 743 ResolveInfo* rsym = pReloc.symInfo(); 744 745 switch (pReloc.type()){ 746 case llvm::ELF::R_MIPS_NONE: 747 case llvm::ELF::R_MIPS_INSERT_A: 748 case llvm::ELF::R_MIPS_INSERT_B: 749 case llvm::ELF::R_MIPS_DELETE: 750 case llvm::ELF::R_MIPS_TLS_DTPMOD64: 751 case llvm::ELF::R_MIPS_TLS_DTPREL64: 752 case llvm::ELF::R_MIPS_REL16: 753 case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 754 case llvm::ELF::R_MIPS_PJUMP: 755 case llvm::ELF::R_MIPS_RELGOT: 756 case llvm::ELF::R_MIPS_TLS_TPREL64: 757 break; 758 case llvm::ELF::R_MIPS_32: 759 case llvm::ELF::R_MIPS_64: 760 case llvm::ELF::R_MIPS_HI16: 761 case llvm::ELF::R_MIPS_LO16: 762 if (symbolNeedsDynRel(*rsym, false, pLDInfo, pOutput, true)) { 763 if (NULL == m_pRelDyn) 764 createRelDyn(pLinker, pOutput); 765 766 m_pRelDyn->reserveEntry(*m_pRelocFactory); 767 rsym->setReserved(rsym->reserved() | ReserveRel); 768 769 // Remeber this rsym is a global GOT entry (as if it needs an entry). 770 // Actually we don't allocate an GOT entry. 771 if (NULL == m_pGOT) 772 createGOT(pLinker, pOutput); 773 m_pGOT->setGlobal(rsym); 774 } 775 break; 776 case llvm::ELF::R_MIPS_GOT16: 777 case llvm::ELF::R_MIPS_CALL16: 778 case llvm::ELF::R_MIPS_GOT_DISP: 779 case llvm::ELF::R_MIPS_GOT_HI16: 780 case llvm::ELF::R_MIPS_CALL_HI16: 781 case llvm::ELF::R_MIPS_GOT_LO16: 782 case llvm::ELF::R_MIPS_CALL_LO16: 783 case llvm::ELF::R_MIPS_GOT_PAGE: 784 case llvm::ELF::R_MIPS_GOT_OFST: 785 if (NULL == m_pGOT) 786 createGOT(pLinker, pOutput); 787 788 if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 789 m_pGOT->reserveGlobalEntry(); 790 rsym->setReserved(rsym->reserved() | ReserveGot); 791 m_GlobalGOTSyms.push_back(rsym->outSymbol()); 792 // Remeber this rsym is a global GOT entry 793 m_pGOT->setGlobal(rsym); 794 } 795 break; 796 case llvm::ELF::R_MIPS_LITERAL: 797 case llvm::ELF::R_MIPS_GPREL32: 798 fatal(diag::invalid_global_relocation) << (int)pReloc.type() 799 << pReloc.symInfo()->name(); 800 break; 801 case llvm::ELF::R_MIPS_GPREL16: 802 break; 803 case llvm::ELF::R_MIPS_26: 804 case llvm::ELF::R_MIPS_PC16: 805 break; 806 case llvm::ELF::R_MIPS_16: 807 case llvm::ELF::R_MIPS_SHIFT5: 808 case llvm::ELF::R_MIPS_SHIFT6: 809 case llvm::ELF::R_MIPS_SUB: 810 case llvm::ELF::R_MIPS_HIGHER: 811 case llvm::ELF::R_MIPS_HIGHEST: 812 case llvm::ELF::R_MIPS_SCN_DISP: 813 break; 814 case llvm::ELF::R_MIPS_TLS_DTPREL32: 815 case llvm::ELF::R_MIPS_TLS_GD: 816 case llvm::ELF::R_MIPS_TLS_LDM: 817 case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 818 case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 819 case llvm::ELF::R_MIPS_TLS_GOTTPREL: 820 case llvm::ELF::R_MIPS_TLS_TPREL32: 821 case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 822 case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 823 break; 824 case llvm::ELF::R_MIPS_REL32: 825 break; 826 case llvm::ELF::R_MIPS_JALR: 827 break; 828 case llvm::ELF::R_MIPS_COPY: 829 case llvm::ELF::R_MIPS_GLOB_DAT: 830 case llvm::ELF::R_MIPS_JUMP_SLOT: 831 fatal(diag::dynamic_relocation) << (int)pReloc.type(); 832 break; 833 default: 834 fatal(diag::unknown_relocation) << (int)pReloc.type() 835 << pReloc.symInfo()->name(); 836 } 837} 838 839void MipsGNULDBackend::createGOT(MCLinker& pLinker, const Output& pOutput) 840{ 841 ELFFileFormat* file_format = getOutputFormat(pOutput); 842 843 LDSection& got = file_format->getGOT(); 844 m_pGOT = new MipsGOT(got, pLinker.getOrCreateSectData(got)); 845 846 // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 847 if ( m_pGOTSymbol != NULL ) { 848 pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>( 849 "_GLOBAL_OFFSET_TABLE_", 850 false, 851 ResolveInfo::Object, 852 ResolveInfo::Define, 853 ResolveInfo::Local, 854 0x0, // size 855 0x0, // value 856 pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 857 ResolveInfo::Hidden); 858 } 859 else { 860 m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 861 "_GLOBAL_OFFSET_TABLE_", 862 false, 863 ResolveInfo::Object, 864 ResolveInfo::Define, 865 ResolveInfo::Local, 866 0x0, // size 867 0x0, // value 868 pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 869 ResolveInfo::Hidden); 870 } 871} 872 873void MipsGNULDBackend::createRelDyn(MCLinker& pLinker, const Output& pOutput) 874{ 875 ELFFileFormat* file_format = getOutputFormat(pOutput); 876 877 // get .rel.dyn LDSection and create SectionData 878 LDSection& reldyn = file_format->getRelDyn(); 879 // create SectionData and ARMRelDynSection 880 m_pRelDyn = new OutputRelocSection(reldyn, 881 pLinker.getOrCreateSectData(reldyn), 882 8); 883} 884 885//===----------------------------------------------------------------------===// 886/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend 887/// 888static TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget, 889 const std::string& pTriple) 890{ 891 llvm::Triple theTriple(pTriple); 892 if (theTriple.isOSDarwin()) { 893 assert(0 && "MachO linker is not supported yet"); 894 } 895 if (theTriple.isOSWindows()) { 896 assert(0 && "COFF linker is not supported yet"); 897 } 898 return new MipsGNULDBackend(); 899} 900 901} // namespace of mcld 902 903//============================= 904// Force static initialization. 905extern "C" void LLVMInitializeMipsLDBackend() { 906 // Register the linker backend 907 mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget, 908 mcld::createMipsLDBackend); 909} 910