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