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