1 //===- HexagonLDBackend.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 "Hexagon.h" 10 #include "HexagonELFDynamic.h" 11 #include "HexagonLDBackend.h" 12 #include "HexagonRelocator.h" 13 #include "HexagonGNUInfo.h" 14 #include "HexagonAbsoluteStub.h" 15 16 #include <llvm/ADT/Triple.h> 17 #include <llvm/Support/Casting.h> 18 19 #include <mcld/LinkerConfig.h> 20 #include <mcld/IRBuilder.h> 21 #include <mcld/Fragment/AlignFragment.h> 22 #include <mcld/Fragment/FillFragment.h> 23 #include <mcld/Fragment/RegionFragment.h> 24 #include <mcld/Support/MemoryArea.h> 25 #include <mcld/Support/MsgHandling.h> 26 #include <mcld/Support/TargetRegistry.h> 27 #include <mcld/Object/ObjectBuilder.h> 28 #include <mcld/Fragment/Stub.h> 29 #include <mcld/LD/BranchIslandFactory.h> 30 #include <mcld/LD/StubFactory.h> 31 #include <mcld/LD/LDContext.h> 32 #include <mcld/LD/ELFFileFormat.h> 33 #include <mcld/LD/ELFSegmentFactory.h> 34 #include <mcld/LD/ELFSegment.h> 35 36 #include <cstring> 37 38 using namespace mcld; 39 40 //===----------------------------------------------------------------------===// 41 // HexagonLDBackend 42 //===----------------------------------------------------------------------===// 43 HexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig, 44 HexagonGNUInfo* pInfo) 45 : GNULDBackend(pConfig, pInfo), 46 m_pRelocator(NULL), 47 m_pGOT(NULL), 48 m_pGOTPLT(NULL), 49 m_pPLT(NULL), 50 m_pRelaDyn(NULL), 51 m_pRelaPLT(NULL), 52 m_pDynamic(NULL), 53 m_pGOTSymbol(NULL), 54 m_CopyRel(llvm::ELF::R_HEX_COPY) { 55 } 56 57 HexagonLDBackend::~HexagonLDBackend() 58 { 59 delete m_pRelocator; 60 delete m_pGOT; 61 delete m_pPLT; 62 delete m_pRelaDyn; 63 delete m_pRelaPLT; 64 delete m_pDynamic; 65 } 66 67 bool HexagonLDBackend::initRelocator() 68 { 69 if (NULL == m_pRelocator) { 70 m_pRelocator = new HexagonRelocator(*this, config()); 71 } 72 return true; 73 } 74 75 const Relocator* HexagonLDBackend::getRelocator() const 76 { 77 assert(NULL != m_pRelocator); 78 return m_pRelocator; 79 } 80 81 Relocator* HexagonLDBackend::getRelocator() 82 { 83 assert(NULL != m_pRelocator); 84 return m_pRelocator; 85 } 86 87 void HexagonLDBackend::doPreLayout(IRBuilder& pBuilder) 88 { 89 // initialize .dynamic data 90 if (!config().isCodeStatic() && NULL == m_pDynamic) 91 m_pDynamic = new HexagonELFDynamic(*this, config()); 92 93 // set .got.plt and .got sizes 94 // when building shared object, the .got section is must 95 if ((LinkerConfig::Object != config().codeGenType()) && 96 (!config().isCodeStatic())) { 97 setGOTSectionSize(pBuilder); 98 99 // set .plt size 100 if (m_pPLT->hasPLT1()) 101 m_pPLT->finalizeSectionSize(); 102 103 // set .rela.dyn size 104 if (!m_pRelaDyn->empty()) { 105 assert(!config().isCodeStatic() && 106 "static linkage should not result in a dynamic relocation section"); 107 setRelaDynSize(); 108 } 109 // set .rela.plt size 110 if (!m_pRelaPLT->empty()) { 111 assert(!config().isCodeStatic() && 112 "static linkage should not result in a dynamic relocation section"); 113 setRelaPLTSize(); 114 } 115 } 116 // Shared libraries are compiled with -G0 so there is no need to set SData. 117 if (LinkerConfig::Object == config().codeGenType()) 118 SetSDataSection(); 119 } 120 121 void HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) 122 { 123 } 124 125 /// dynamic - the dynamic section of the target machine. 126 /// Use co-variant return type to return its own dynamic section. 127 HexagonELFDynamic& HexagonLDBackend::dynamic() 128 { 129 assert(NULL != m_pDynamic); 130 return *m_pDynamic; 131 } 132 133 /// dynamic - the dynamic section of the target machine. 134 /// Use co-variant return type to return its own dynamic section. 135 const HexagonELFDynamic& HexagonLDBackend::dynamic() const 136 { 137 assert(NULL != m_pDynamic); 138 return *m_pDynamic; 139 } 140 141 uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection, 142 MemoryRegion& pRegion) const 143 { 144 if (!pRegion.size()) 145 return 0; 146 147 const ELFFileFormat* FileFormat = getOutputFormat(); 148 unsigned int EntrySize = 0; 149 uint64_t RegionSize = 0; 150 151 if ((LinkerConfig::Object != config().codeGenType()) && 152 (!config().isCodeStatic())) { 153 if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) { 154 155 unsigned char* buffer = pRegion.begin(); 156 157 m_pPLT->applyPLT0(); 158 m_pPLT->applyPLT1(); 159 HexagonPLT::iterator it = m_pPLT->begin(); 160 unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); 161 162 memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); 163 RegionSize += plt0_size; 164 ++it; 165 166 PLTEntryBase* plt1 = 0; 167 HexagonPLT::iterator ie = m_pPLT->end(); 168 while (it != ie) { 169 plt1 = &(llvm::cast<PLTEntryBase>(*it)); 170 EntrySize = plt1->size(); 171 memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); 172 RegionSize += EntrySize; 173 ++it; 174 } 175 return RegionSize; 176 } 177 else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) { 178 RegionSize += emitGOTSectionData(pRegion); 179 return RegionSize; 180 } 181 else if (FileFormat->hasGOTPLT() && 182 (&pSection == &(FileFormat->getGOTPLT()))) { 183 RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); 184 return RegionSize; 185 } 186 } 187 188 const SectionData* sect_data = pSection.getSectionData(); 189 SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 190 uint8_t* out_offset = pRegion.begin(); 191 for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 192 size_t size = frag_iter->size(); 193 switch(frag_iter->getKind()) { 194 case Fragment::Fillment: { 195 const FillFragment& fill_frag = 196 llvm::cast<FillFragment>(*frag_iter); 197 if (0 == fill_frag.getValueSize()) { 198 // virtual fillment, ignore it. 199 break; 200 } 201 memset(out_offset, fill_frag.getValue(), fill_frag.size()); 202 break; 203 } 204 case Fragment::Region: { 205 const RegionFragment& region_frag = 206 llvm::cast<RegionFragment>(*frag_iter); 207 const char* start = region_frag.getRegion().begin(); 208 memcpy(out_offset, start, size); 209 break; 210 } 211 case Fragment::Alignment: { 212 const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); 213 uint64_t count = size / align_frag.getValueSize(); 214 switch (align_frag.getValueSize()) { 215 case 1u: 216 std::memset(out_offset, align_frag.getValue(), count); 217 break; 218 default: 219 llvm::report_fatal_error( 220 "unsupported value size for align fragment emission yet.\n"); 221 break; 222 } // end switch 223 break; 224 } 225 case Fragment::Null: { 226 assert(0x0 == size); 227 break; 228 } 229 default: 230 llvm::report_fatal_error("unsupported fragment type.\n"); 231 break; 232 } // end switch 233 out_offset += size; 234 } // end for 235 236 return pRegion.size(); 237 } 238 239 HexagonGOT& HexagonLDBackend::getGOT() 240 { 241 assert(NULL != m_pGOT); 242 return *m_pGOT; 243 } 244 245 const HexagonGOT& HexagonLDBackend::getGOT() const 246 { 247 assert(NULL != m_pGOT); 248 return *m_pGOT; 249 } 250 251 HexagonPLT& HexagonLDBackend::getPLT() 252 { 253 assert(NULL != m_pPLT && "PLT section not exist"); 254 return *m_pPLT; 255 } 256 257 const HexagonPLT& HexagonLDBackend::getPLT() const 258 { 259 assert(NULL != m_pPLT && "PLT section not exist"); 260 return *m_pPLT; 261 } 262 263 OutputRelocSection& HexagonLDBackend::getRelaDyn() 264 { 265 assert(NULL != m_pRelaDyn && ".rela.dyn section not exist"); 266 return *m_pRelaDyn; 267 } 268 269 const OutputRelocSection& HexagonLDBackend::getRelaDyn() const 270 { 271 assert(NULL != m_pRelaDyn && ".rela.dyn section not exist"); 272 return *m_pRelaDyn; 273 } 274 275 OutputRelocSection& HexagonLDBackend::getRelaPLT() 276 { 277 assert(NULL != m_pRelaPLT && ".rela.plt section not exist"); 278 return *m_pRelaPLT; 279 } 280 281 const OutputRelocSection& HexagonLDBackend::getRelaPLT() const 282 { 283 assert(NULL != m_pRelaPLT && ".rela.plt section not exist"); 284 return *m_pRelaPLT; 285 } 286 287 HexagonGOTPLT& HexagonLDBackend::getGOTPLT() 288 { 289 assert(NULL != m_pGOTPLT); 290 return *m_pGOTPLT; 291 } 292 293 const HexagonGOTPLT& HexagonLDBackend::getGOTPLT() const 294 { 295 assert(NULL != m_pGOTPLT); 296 return *m_pGOTPLT; 297 } 298 299 void HexagonLDBackend::setRelaDynSize() 300 { 301 ELFFileFormat* file_format = getOutputFormat(); 302 file_format->getRelaDyn().setSize 303 (m_pRelaDyn->numOfRelocs() * getRelaEntrySize()); 304 } 305 306 void HexagonLDBackend::setRelaPLTSize() 307 { 308 ELFFileFormat* file_format = getOutputFormat(); 309 file_format->getRelaPlt().setSize 310 (m_pRelaPLT->numOfRelocs() * getRelaEntrySize()); 311 } 312 313 void HexagonLDBackend::setGOTSectionSize(IRBuilder& pBuilder) 314 { 315 // set .got.plt size 316 if (LinkerConfig::DynObj == config().codeGenType() || 317 m_pGOTPLT->hasGOT1() || 318 NULL != m_pGOTSymbol) { 319 m_pGOTPLT->finalizeSectionSize(); 320 defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 321 } 322 323 // set .got size 324 if (!m_pGOT->empty()) 325 m_pGOT->finalizeSectionSize(); 326 } 327 328 uint64_t 329 HexagonLDBackend::emitGOTSectionData(MemoryRegion& pRegion) const 330 { 331 assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 332 333 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 334 335 HexagonGOTEntry* got = 0; 336 unsigned int EntrySize = HexagonGOTEntry::EntrySize; 337 uint64_t RegionSize = 0; 338 339 for (HexagonGOT::iterator it = m_pGOT->begin(), 340 ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 341 got = &(llvm::cast<HexagonGOTEntry>((*it))); 342 *buffer = static_cast<uint32_t>(got->getValue()); 343 RegionSize += EntrySize; 344 } 345 346 return RegionSize; 347 } 348 349 void HexagonLDBackend::defineGOTSymbol(IRBuilder& pBuilder, 350 Fragment& pFrag) 351 { 352 // define symbol _GLOBAL_OFFSET_TABLE_ 353 if (m_pGOTSymbol != NULL) { 354 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 355 "_GLOBAL_OFFSET_TABLE_", 356 ResolveInfo::Object, 357 ResolveInfo::Define, 358 ResolveInfo::Local, 359 0x0, // size 360 0x0, // value 361 FragmentRef::Create(pFrag, 0x0), 362 ResolveInfo::Hidden); 363 } 364 else { 365 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 366 "_GLOBAL_OFFSET_TABLE_", 367 ResolveInfo::Object, 368 ResolveInfo::Define, 369 ResolveInfo::Local, 370 0x0, // size 371 0x0, // value 372 FragmentRef::Create(pFrag, 0x0), 373 ResolveInfo::Hidden); 374 } 375 } 376 377 uint64_t HexagonLDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, 378 const ELFFileFormat* FileFormat) const 379 { 380 assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 381 m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 382 m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 383 384 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 385 386 HexagonGOTEntry* got = 0; 387 unsigned int EntrySize = HexagonGOTEntry::EntrySize; 388 uint64_t RegionSize = 0; 389 390 for (HexagonGOTPLT::iterator it = m_pGOTPLT->begin(), 391 ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 392 got = &(llvm::cast<HexagonGOTEntry>((*it))); 393 *buffer = static_cast<uint32_t>(got->getValue()); 394 RegionSize += EntrySize; 395 } 396 397 return RegionSize; 398 } 399 400 unsigned int 401 HexagonLDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 402 { 403 const ELFFileFormat* file_format = getOutputFormat(); 404 405 if (LinkerConfig::Object != config().codeGenType()) { 406 if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 407 if (config().options().hasNow()) 408 return SHO_RELRO; 409 return SHO_RELRO_LAST; 410 } 411 412 if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) { 413 if (config().options().hasNow()) 414 return SHO_RELRO; 415 return SHO_NON_RELRO_FIRST; 416 } 417 418 if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 419 return SHO_PLT; 420 } 421 422 if (&pSectHdr == m_pstart) 423 return SHO_INIT; 424 425 if (&pSectHdr == m_psdata) 426 return SHO_SMALL_DATA; 427 428 return SHO_UNDEFINED; 429 } 430 431 void HexagonLDBackend::initTargetSections(Module& pModule, 432 ObjectBuilder& pBuilder) 433 { 434 435 if ((LinkerConfig::Object != config().codeGenType()) && 436 (!config().isCodeStatic())) { 437 ELFFileFormat* file_format = getOutputFormat(); 438 // initialize .got 439 LDSection& got = file_format->getGOT(); 440 m_pGOT = new HexagonGOT(got); 441 442 // initialize .got.plt 443 LDSection& gotplt = file_format->getGOTPLT(); 444 m_pGOTPLT = new HexagonGOTPLT(gotplt); 445 446 // initialize .plt 447 LDSection& plt = file_format->getPLT(); 448 m_pPLT = new HexagonPLT(plt, 449 *m_pGOTPLT, 450 config()); 451 452 // initialize .rela.plt 453 LDSection& relaplt = file_format->getRelaPlt(); 454 relaplt.setLink(&plt); 455 m_pRelaPLT = new OutputRelocSection(pModule, relaplt); 456 457 // initialize .rela.dyn 458 LDSection& reladyn = file_format->getRelaDyn(); 459 m_pRelaDyn = new OutputRelocSection(pModule, reladyn); 460 461 } 462 m_psdata = pBuilder.CreateSection(".sdata", 463 LDFileFormat::Target, 464 llvm::ELF::SHT_PROGBITS, 465 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 466 4*1024); 467 m_pscommon_1 = pBuilder.CreateSection(".scommon.1", 468 LDFileFormat::Target, 469 llvm::ELF::SHT_PROGBITS, 470 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 471 1); 472 IRBuilder::CreateSectionData(*m_pscommon_1); 473 474 m_pscommon_2 = pBuilder.CreateSection(".scommon.2", 475 LDFileFormat::Target, 476 llvm::ELF::SHT_PROGBITS, 477 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 478 2); 479 IRBuilder::CreateSectionData(*m_pscommon_2); 480 481 m_pscommon_4 = pBuilder.CreateSection(".scommon.4", 482 LDFileFormat::Target, 483 llvm::ELF::SHT_PROGBITS, 484 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 485 4); 486 IRBuilder::CreateSectionData(*m_pscommon_4); 487 488 m_pscommon_8 = pBuilder.CreateSection(".scommon.8", 489 LDFileFormat::Target, 490 llvm::ELF::SHT_PROGBITS, 491 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 492 8); 493 IRBuilder::CreateSectionData(*m_pscommon_8); 494 495 m_pstart = pBuilder.CreateSection(".start", 496 LDFileFormat::Target, 497 llvm::ELF::SHT_PROGBITS, 498 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 499 8); 500 IRBuilder::CreateSectionData(*m_pstart); 501 } 502 503 void HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 504 { 505 if (config().codeGenType() == LinkerConfig::Object) 506 return; 507 508 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 509 // same name in input 510 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 511 "_GLOBAL_OFFSET_TABLE_", 512 ResolveInfo::Object, 513 ResolveInfo::Define, 514 ResolveInfo::Local, 515 0x0, // size 516 0x0, // value 517 FragmentRef::Null(), 518 ResolveInfo::Hidden); 519 m_psdabase = 520 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 521 "_SDA_BASE_", 522 ResolveInfo::Object, 523 ResolveInfo::Define, 524 ResolveInfo::Absolute, 525 0x0, // size 526 0x0, // value 527 FragmentRef::Null(), 528 ResolveInfo::Hidden); 529 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 530 "__sbss_start", 531 ResolveInfo::Object, 532 ResolveInfo::Define, 533 ResolveInfo::Absolute, 534 0x0, // size 535 0x0, // value 536 FragmentRef::Null(), 537 ResolveInfo::Hidden); 538 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 539 "__sbss_end", 540 ResolveInfo::Object, 541 ResolveInfo::Define, 542 ResolveInfo::Absolute, 543 0x0, // size 544 0x0, // value 545 FragmentRef::Null(), 546 ResolveInfo::Hidden); 547 } 548 549 bool HexagonLDBackend::initTargetStubs() 550 { 551 if (NULL != getStubFactory()) { 552 getStubFactory()->addPrototype 553 (new HexagonAbsoluteStub(config().isCodeIndep())); 554 return true; 555 } 556 return false; 557 } 558 559 bool HexagonLDBackend::initBRIslandFactory() 560 { 561 if (NULL == m_pBRIslandFactory) { 562 m_pBRIslandFactory = new BranchIslandFactory(maxFwdBranchOffset(), 563 maxBwdBranchOffset(), 564 0); 565 } 566 return true; 567 } 568 569 bool HexagonLDBackend::initStubFactory() 570 { 571 if (NULL == m_pStubFactory) { 572 m_pStubFactory = new StubFactory(); 573 } 574 return true; 575 } 576 577 bool HexagonLDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, 578 bool& pFinished) 579 { 580 assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); 581 bool isRelaxed = false; 582 ELFFileFormat* file_format = getOutputFormat(); 583 // check branch relocs and create the related stubs if needed 584 Module::obj_iterator input, inEnd = pModule.obj_end(); 585 for (input = pModule.obj_begin(); input != inEnd; ++input) { 586 LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 587 for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 588 if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 589 continue; 590 RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 591 for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 592 switch (reloc->type()) { 593 case llvm::ELF::R_HEX_B22_PCREL: 594 case llvm::ELF::R_HEX_B15_PCREL: 595 case llvm::ELF::R_HEX_B7_PCREL: 596 case llvm::ELF::R_HEX_B13_PCREL: 597 case llvm::ELF::R_HEX_B9_PCREL: { 598 Relocation* relocation = llvm::cast<Relocation>(reloc); 599 uint64_t sym_value = 0x0; 600 LDSymbol* symbol = relocation->symInfo()->outSymbol(); 601 if (symbol->hasFragRef()) { 602 uint64_t value = symbol->fragRef()->getOutputOffset(); 603 uint64_t addr = 604 symbol->fragRef()->frag()->getParent()->getSection().addr(); 605 sym_value = addr + value; 606 } 607 Stub* stub = getStubFactory()->create(*relocation, // relocation 608 sym_value, //symbol value 609 pBuilder, 610 *getBRIslandFactory()); 611 if (NULL != stub) { 612 assert(NULL != stub->symInfo()); 613 // increase the size of .symtab and .strtab 614 LDSection& symtab = file_format->getSymTab(); 615 LDSection& strtab = file_format->getStrTab(); 616 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 617 strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 618 isRelaxed = true; 619 } 620 } 621 break; 622 623 default: 624 break; 625 } 626 } 627 } 628 } 629 630 // find the first fragment w/ invalid offset due to stub insertion 631 Fragment* invalid = NULL; 632 pFinished = true; 633 for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 634 island_end = getBRIslandFactory()->end(); island != island_end; ++island) 635 { 636 if ((*island).end() == file_format->getText().getSectionData()->end()) 637 break; 638 639 Fragment* exit = (*island).end(); 640 if (((*island).offset() + (*island).size()) > exit->getOffset()) { 641 invalid = exit; 642 pFinished = false; 643 break; 644 } 645 } 646 647 // reset the offset of invalid fragments 648 while (NULL != invalid) { 649 invalid->setOffset(invalid->getPrevNode()->getOffset() + 650 invalid->getPrevNode()->size()); 651 invalid = invalid->getNextNode(); 652 } 653 654 // reset the size of .text 655 if (isRelaxed) { 656 file_format->getText().setSize( 657 file_format->getText().getSectionData()->back().getOffset() + 658 file_format->getText().getSectionData()->back().size()); 659 } 660 return isRelaxed; 661 } 662 663 /// finalizeSymbol - finalize the symbol value 664 bool HexagonLDBackend::finalizeTargetSymbols() 665 { 666 if (config().codeGenType() == LinkerConfig::Object) 667 return true; 668 if (m_psdabase) 669 m_psdabase->setValue(m_psdata->addr()); 670 671 ELFSegmentFactory::const_iterator edata = 672 elfSegmentTable().find(llvm::ELF::PT_LOAD, 673 llvm::ELF::PF_W, 674 llvm::ELF::PF_X); 675 if (elfSegmentTable().end() != edata) { 676 if (NULL != f_pEData && ResolveInfo::ThreadLocal != f_pEData->type()) { 677 f_pEData->setValue((*edata)->vaddr() + (*edata)->filesz()); 678 } 679 if (NULL != f_p_EData && ResolveInfo::ThreadLocal != f_p_EData->type()) { 680 f_p_EData->setValue((*edata)->vaddr() + (*edata)->filesz()); 681 } 682 if (NULL != f_pBSSStart && 683 ResolveInfo::ThreadLocal != f_pBSSStart->type()) { 684 f_pBSSStart->setValue((*edata)->vaddr() + (*edata)->filesz()); 685 } 686 if (NULL != f_pEnd && ResolveInfo::ThreadLocal != f_pEnd->type()) { 687 f_pEnd->setValue((((*edata)->vaddr() + 688 (*edata)->memsz()) + 7) & ~7); 689 } 690 if (NULL != f_p_End && ResolveInfo::ThreadLocal != f_p_End->type()) { 691 f_p_End->setValue((((*edata)->vaddr() + 692 (*edata)->memsz()) + 7) & ~7); 693 } 694 } 695 return true; 696 } 697 698 /// merge Input Sections 699 bool HexagonLDBackend::mergeSection(Module& pModule, 700 const Input& pInputFile, 701 LDSection& pInputSection) 702 { 703 if ((pInputSection.flag() & llvm::ELF::SHF_HEX_GPREL) || 704 (pInputSection.kind() == LDFileFormat::LinkOnce) || 705 (pInputSection.kind() == LDFileFormat::Target)) { 706 SectionData *sd = NULL; 707 if (!m_psdata->hasSectionData()) { 708 sd = IRBuilder::CreateSectionData(*m_psdata); 709 m_psdata->setSectionData(sd); 710 } 711 sd = m_psdata->getSectionData(); 712 MoveSectionDataAndSort(*pInputSection.getSectionData(), *sd); 713 } 714 else { 715 ObjectBuilder builder(pModule); 716 builder.MergeSection(pInputFile, pInputSection); 717 } 718 return true; 719 } 720 721 bool HexagonLDBackend::SetSDataSection() { 722 SectionData *pTo = (m_psdata->getSectionData()); 723 724 if (pTo) { 725 MoveCommonData(*m_pscommon_1->getSectionData(), *pTo); 726 MoveCommonData(*m_pscommon_2->getSectionData(), *pTo); 727 MoveCommonData(*m_pscommon_4->getSectionData(), *pTo); 728 MoveCommonData(*m_pscommon_8->getSectionData(), *pTo); 729 730 SectionData::FragmentListType& to_list = pTo->getFragmentList(); 731 SectionData::FragmentListType::iterator fragTo, fragToEnd = to_list.end(); 732 uint32_t offset = 0; 733 for (fragTo = to_list.begin(); fragTo != fragToEnd; ++fragTo) { 734 fragTo->setOffset(offset); 735 offset += fragTo->size(); 736 } 737 738 // set up pTo's header 739 pTo->getSection().setSize(offset); 740 741 SectionData::FragmentListType& newlist = pTo->getFragmentList(); 742 743 for (fragTo = newlist.begin(), fragToEnd = newlist.end(); 744 fragTo != fragToEnd; ++fragTo) { 745 fragTo->setParent(pTo); 746 } 747 } 748 749 return true; 750 } 751 752 /// allocateCommonSymbols - allocate common symbols in the corresponding 753 /// sections. This is called at pre-layout stage. 754 /// @refer Google gold linker: common.cc: 214 755 bool HexagonLDBackend::allocateCommonSymbols(Module& pModule) 756 { 757 SymbolCategory& symbol_list = pModule.getSymbolTable(); 758 759 if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) { 760 SetSDataSection(); 761 return true; 762 } 763 764 int8_t maxGPSize = config().options().getGPSize(); 765 766 SymbolCategory::iterator com_sym, com_end; 767 768 // get corresponding BSS LDSection 769 ELFFileFormat* file_format = getOutputFormat(); 770 LDSection& bss_sect = file_format->getBSS(); 771 LDSection& tbss_sect = file_format->getTBSS(); 772 773 // get or create corresponding BSS SectionData 774 SectionData* bss_sect_data = NULL; 775 if (bss_sect.hasSectionData()) 776 bss_sect_data = bss_sect.getSectionData(); 777 else 778 bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 779 780 SectionData* tbss_sect_data = NULL; 781 if (tbss_sect.hasSectionData()) 782 tbss_sect_data = tbss_sect.getSectionData(); 783 else 784 tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 785 786 // remember original BSS size 787 uint64_t bss_offset = bss_sect.size(); 788 uint64_t tbss_offset = tbss_sect.size(); 789 790 // allocate all local common symbols 791 com_end = symbol_list.localEnd(); 792 793 for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 794 if (ResolveInfo::Common == (*com_sym)->desc()) { 795 // We have to reset the description of the symbol here. When doing 796 // incremental linking, the output relocatable object may have common 797 // symbols. Therefore, we can not treat common symbols as normal symbols 798 // when emitting the regular name pools. We must change the symbols' 799 // description here. 800 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 801 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 802 803 switch((*com_sym)->size()) { 804 case 1: 805 if (maxGPSize <= 0) 806 break; 807 ObjectBuilder::AppendFragment(*frag, 808 *(m_pscommon_1->getSectionData()), 809 (*com_sym)->value()); 810 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 811 continue; 812 case 2: 813 if (maxGPSize <= 1) 814 break; 815 ObjectBuilder::AppendFragment(*frag, 816 *(m_pscommon_2->getSectionData()), 817 (*com_sym)->value()); 818 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 819 continue; 820 case 4: 821 if (maxGPSize <= 3) 822 break; 823 ObjectBuilder::AppendFragment(*frag, 824 *(m_pscommon_4->getSectionData()), 825 (*com_sym)->value()); 826 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 827 continue; 828 case 8: 829 if (maxGPSize <= 7) 830 break; 831 ObjectBuilder::AppendFragment(*frag, 832 *(m_pscommon_8->getSectionData()), 833 (*com_sym)->value()); 834 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 835 continue; 836 default: 837 break; 838 } 839 840 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 841 // allocate TLS common symbol in tbss section 842 tbss_offset += ObjectBuilder::AppendFragment(*frag, 843 *tbss_sect_data, 844 (*com_sym)->value()); 845 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 846 } 847 // FIXME: how to identify small and large common symbols? 848 else { 849 bss_offset += ObjectBuilder::AppendFragment(*frag, 850 *bss_sect_data, 851 (*com_sym)->value()); 852 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 853 } 854 } 855 } 856 857 // allocate all global common symbols 858 com_end = symbol_list.commonEnd(); 859 for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 860 // We have to reset the description of the symbol here. When doing 861 // incremental linking, the output relocatable object may have common 862 // symbols. Therefore, we can not treat common symbols as normal symbols 863 // when emitting the regular name pools. We must change the symbols' 864 // description here. 865 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 866 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 867 868 switch((*com_sym)->size()) { 869 case 1: 870 if (maxGPSize <= 0) 871 break; 872 ObjectBuilder::AppendFragment(*frag, 873 *(m_pscommon_1->getSectionData()), 874 (*com_sym)->value()); 875 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 876 continue; 877 case 2: 878 if (maxGPSize <= 1) 879 break; 880 ObjectBuilder::AppendFragment(*frag, 881 *(m_pscommon_2->getSectionData()), 882 (*com_sym)->value()); 883 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 884 continue; 885 case 4: 886 if (maxGPSize <= 3) 887 break; 888 ObjectBuilder::AppendFragment(*frag, 889 *(m_pscommon_4->getSectionData()), 890 (*com_sym)->value()); 891 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 892 continue; 893 case 8: 894 if (maxGPSize <= 7) 895 break; 896 ObjectBuilder::AppendFragment(*frag, 897 *(m_pscommon_8->getSectionData()), 898 (*com_sym)->value()); 899 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 900 continue; 901 default: 902 break; 903 } 904 905 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 906 // allocate TLS common symbol in tbss section 907 tbss_offset += ObjectBuilder::AppendFragment(*frag, 908 *tbss_sect_data, 909 (*com_sym)->value()); 910 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 911 } 912 // FIXME: how to identify small and large common symbols? 913 else { 914 bss_offset += ObjectBuilder::AppendFragment(*frag, 915 *bss_sect_data, 916 (*com_sym)->value()); 917 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 918 } 919 } 920 921 bss_sect.setSize(bss_offset); 922 tbss_sect.setSize(tbss_offset); 923 symbol_list.changeCommonsToGlobal(); 924 SetSDataSection(); 925 return true; 926 } 927 928 bool HexagonLDBackend::MoveCommonData(SectionData &pFrom, SectionData &pTo) 929 { 930 SectionData::FragmentListType& to_list = pTo.getFragmentList(); 931 SectionData::FragmentListType::iterator frag, fragEnd = to_list.end(); 932 933 uint32_t pFromFlag = pFrom.getSection().align(); 934 bool found = false; 935 936 SectionData::FragmentListType::iterator fragInsert; 937 938 for (frag = to_list.begin(); frag != fragEnd; ++frag) { 939 if (frag->getKind() == mcld::Fragment::Alignment) { 940 fragInsert = frag; 941 continue; 942 } 943 if ((frag->getKind() != mcld::Fragment::Region) && 944 (frag->getKind() != mcld::Fragment::Fillment)) { 945 continue; 946 } 947 uint32_t flag = frag->getParent()->getSection().align(); 948 if (pFromFlag < flag) { 949 found = true; 950 break; 951 } 952 } 953 AlignFragment* align = NULL; 954 if (pFrom.getSection().align() > 1) { 955 // if the align constraint is larger than 1, append an alignment 956 align = new AlignFragment(pFrom.getSection().align(), // alignment 957 0x0, // the filled value 958 1u, // the size of filled value 959 pFrom.getSection().align() - 1 // max bytes to emit 960 ); 961 pFrom.getFragmentList().push_front(align); 962 } 963 if (found) 964 to_list.splice(fragInsert, pFrom.getFragmentList()); 965 else 966 to_list.splice(frag, pFrom.getFragmentList()); 967 968 return true; 969 } 970 971 bool HexagonLDBackend::readSection(Input& pInput, SectionData& pSD) 972 { 973 Fragment* frag = NULL; 974 uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 975 uint32_t size = pSD.getSection().size(); 976 977 if (pSD.getSection().type() == llvm::ELF::SHT_NOBITS) { 978 frag = new FillFragment(0x0, 1, size); 979 } 980 else { 981 llvm::StringRef region = pInput.memArea()->request(offset, size); 982 if (region.size() == 0) { 983 // If the input section's size is zero, we got a NULL region. 984 // use a virtual fill fragment 985 frag = new FillFragment(0x0, 0, 0); 986 } 987 else { 988 frag = new RegionFragment(region); 989 } 990 } 991 992 ObjectBuilder::AppendFragment(*frag, pSD); 993 return true; 994 } 995 996 /// MoveSectionData - move the fragments of pTO section data to pTo 997 bool HexagonLDBackend::MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo) 998 { 999 assert(&pFrom != &pTo && "Cannot move section data to itself!"); 1000 SectionData::FragmentListType& to_list = pTo.getFragmentList(); 1001 SectionData::FragmentListType::iterator frag, fragEnd = to_list.end(); 1002 1003 uint32_t pFromFlag = pFrom.getSection().align(); 1004 bool found = false; 1005 1006 SectionData::FragmentListType::iterator fragInsert; 1007 1008 for (frag = to_list.begin(); frag != fragEnd; ++frag) { 1009 if (frag->getKind() == mcld::Fragment::Alignment) { 1010 fragInsert = frag; 1011 continue; 1012 } 1013 if ((frag->getKind() != mcld::Fragment::Region) && 1014 (frag->getKind() != mcld::Fragment::Fillment)) { 1015 continue; 1016 } 1017 uint32_t flag = frag->getParent()->getSection().align(); 1018 if (pFromFlag < flag) { 1019 found = true; 1020 break; 1021 } 1022 } 1023 AlignFragment* align = NULL; 1024 if (pFrom.getSection().align() > 1) { 1025 // if the align constraint is larger than 1, append an alignment 1026 align = new AlignFragment(pFrom.getSection().align(), // alignment 1027 0x0, // the filled value 1028 1u, // the size of filled value 1029 pFrom.getSection().align() - 1 // max bytes to emit 1030 ); 1031 pFrom.getFragmentList().push_front(align); 1032 } 1033 if (found) 1034 to_list.splice(fragInsert, pFrom.getFragmentList()); 1035 else 1036 to_list.splice(frag, pFrom.getFragmentList()); 1037 1038 uint32_t offset = 0; 1039 for (frag = to_list.begin(); frag != fragEnd; ++frag) { 1040 frag->setOffset(offset); 1041 offset += frag->size(); 1042 } 1043 1044 // set up pTo's header 1045 pTo.getSection().setSize(offset); 1046 1047 if (pFrom.getSection().align() > pTo.getSection().align()) 1048 pTo.getSection().setAlign(pFrom.getSection().align()); 1049 1050 if (pFrom.getSection().flag() > pTo.getSection().flag()) 1051 pTo.getSection().setFlag(pFrom.getSection().flag()); 1052 return true; 1053 } 1054 1055 /// doCreateProgramHdrs - backend can implement this function to create the 1056 /// target-dependent segments 1057 void HexagonLDBackend::doCreateProgramHdrs(Module& pModule) 1058 { 1059 // TODO 1060 } 1061 1062 namespace mcld { 1063 1064 //===----------------------------------------------------------------------===// 1065 /// createHexagonLDBackend - the help funtion to create corresponding 1066 /// HexagonLDBackend 1067 TargetLDBackend* createHexagonLDBackend(const LinkerConfig& pConfig) 1068 { 1069 if (pConfig.targets().triple().isOSDarwin()) { 1070 assert(0 && "MachO linker is not supported yet"); 1071 /** 1072 return new HexagonMachOLDBackend(createHexagonMachOArchiveReader, 1073 createHexagonMachOObjectReader, 1074 createHexagonMachOObjectWriter); 1075 **/ 1076 } 1077 if (pConfig.targets().triple().isOSWindows()) { 1078 assert(0 && "COFF linker is not supported yet"); 1079 /** 1080 return new HexagonCOFFLDBackend(createHexagonCOFFArchiveReader, 1081 createHexagonCOFFObjectReader, 1082 createHexagonCOFFObjectWriter); 1083 **/ 1084 } 1085 return new HexagonLDBackend(pConfig, new HexagonGNUInfo(pConfig.targets())); 1086 } 1087 1088 } // namespace of mcld 1089 1090 //===----------------------------------------------------------------------===// 1091 // Force static initialization. 1092 //===----------------------------------------------------------------------===// 1093 extern "C" void MCLDInitializeHexagonLDBackend() { 1094 // Register the linker backend 1095 mcld::TargetRegistry::RegisterTargetLDBackend(TheHexagonTarget, 1096 createHexagonLDBackend); 1097 } 1098