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