1 //===- ARMLDBackend.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 "ARM.h" 10 #include "ARMGNUInfo.h" 11 #include "ARMELFAttributeData.h" 12 #include "ARMELFDynamic.h" 13 #include "ARMException.h" 14 #include "ARMLDBackend.h" 15 #include "ARMRelocator.h" 16 #include "ARMToARMStub.h" 17 #include "ARMToTHMStub.h" 18 #include "THMToTHMStub.h" 19 #include "THMToARMStub.h" 20 21 #include "mcld/IRBuilder.h" 22 #include "mcld/LinkerConfig.h" 23 #include "mcld/ADT/ilist_sort.h" 24 #include "mcld/Fragment/AlignFragment.h" 25 #include "mcld/Fragment/FillFragment.h" 26 #include "mcld/Fragment/NullFragment.h" 27 #include "mcld/Fragment/RegionFragment.h" 28 #include "mcld/Fragment/Stub.h" 29 #include "mcld/LD/BranchIslandFactory.h" 30 #include "mcld/LD/ELFFileFormat.h" 31 #include "mcld/LD/ELFSegment.h" 32 #include "mcld/LD/ELFSegmentFactory.h" 33 #include "mcld/LD/LDContext.h" 34 #include "mcld/LD/StubFactory.h" 35 #include "mcld/Object/ObjectBuilder.h" 36 #include "mcld/Support/MemoryArea.h" 37 #include "mcld/Support/MemoryRegion.h" 38 #include "mcld/Support/MsgHandling.h" 39 #include "mcld/Support/TargetRegistry.h" 40 #include "mcld/Target/ELFAttribute.h" 41 #include "mcld/Target/GNUInfo.h" 42 43 #include <llvm/ADT/StringRef.h> 44 #include <llvm/ADT/Triple.h> 45 #include <llvm/ADT/Twine.h> 46 #include <llvm/Support/Casting.h> 47 #include <llvm/Support/ELF.h> 48 49 #include <cstring> 50 #include <vector> 51 52 namespace mcld { 53 54 /// Fragment data for EXIDX_CANTUNWIND. 55 static const char g_CantUnwindEntry[8] = { 56 // Relocation to text section. 57 0, 0, 0, 0, 58 // EXIDX_CANTUNWIND (little endian.) 59 1, 0, 0, 0, 60 }; 61 62 /// Helper function to create a local symbol at the end of the fragment. 63 static mcld::ResolveInfo* 64 CreateLocalSymbolToFragmentEnd(mcld::Module& pModule, mcld::Fragment& pFrag) { 65 // Create and add symbol to the name pool. 66 mcld::ResolveInfo* resolveInfo = 67 pModule.getNamePool().createSymbol(/* pName */"", 68 /* pIsDyn */false, 69 mcld::ResolveInfo::Section, 70 mcld::ResolveInfo::Define, 71 mcld::ResolveInfo::Local, 72 /* pSize */0, 73 mcld::ResolveInfo::Hidden); 74 if (resolveInfo == nullptr) { 75 return nullptr; 76 } 77 78 // Create input symbol. 79 mcld::LDSymbol* inputSym = mcld::LDSymbol::Create(*resolveInfo); 80 if (inputSym == nullptr) { 81 return nullptr; 82 } 83 84 inputSym->setFragmentRef(mcld::FragmentRef::Create(pFrag, pFrag.size())); 85 inputSym->setValue(/* pValue */0); 86 87 // The output symbol is simply an alias to the input symbol. 88 resolveInfo->setSymPtr(inputSym); 89 90 return resolveInfo; 91 } 92 93 /// Comparator to sort .ARM.exidx fragments according to the address of the 94 /// corresponding .text fragment. 95 class ExIdxFragmentComparator { 96 private: 97 const ARMExData& m_pExData; 98 99 public: 100 explicit ExIdxFragmentComparator(const ARMExData& pExData) 101 : m_pExData(pExData) { 102 } 103 104 bool operator()(const Fragment& a, const Fragment& b) { 105 ARMExSectionTuple* tupleA = m_pExData.getTupleByExIdx(&a); 106 ARMExSectionTuple* tupleB = m_pExData.getTupleByExIdx(&b); 107 108 Fragment* textFragA = tupleA->getTextFragment(); 109 Fragment* textFragB = tupleB->getTextFragment(); 110 111 uint64_t addrA = textFragA->getParent()->getSection().addr() + 112 textFragA->getOffset(); 113 uint64_t addrB = textFragB->getParent()->getSection().addr() + 114 textFragB->getOffset(); 115 return (addrA < addrB); 116 } 117 }; 118 119 //===----------------------------------------------------------------------===// 120 // ARMGNULDBackend 121 //===----------------------------------------------------------------------===// 122 ARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo) 123 : GNULDBackend(pConfig, pInfo), 124 m_pRelocator(NULL), 125 m_pGOT(NULL), 126 m_pPLT(NULL), 127 m_pRelDyn(NULL), 128 m_pRelPLT(NULL), 129 m_pAttrData(NULL), 130 m_pDynamic(NULL), 131 m_pGOTSymbol(NULL), 132 m_pEXIDXStart(NULL), 133 m_pEXIDXEnd(NULL), 134 m_pEXIDX(NULL), 135 m_pEXTAB(NULL), 136 m_pAttributes(NULL) { 137 } 138 139 ARMGNULDBackend::~ARMGNULDBackend() { 140 delete m_pRelocator; 141 delete m_pGOT; 142 delete m_pPLT; 143 delete m_pRelDyn; 144 delete m_pRelPLT; 145 delete m_pDynamic; 146 delete m_pAttrData; 147 } 148 149 void ARMGNULDBackend::initTargetSections(Module& pModule, 150 ObjectBuilder& pBuilder) { 151 // FIXME: Currently we set exidx and extab to "Exception" and directly emit 152 // them from input 153 m_pEXIDX = 154 pBuilder.CreateSection(".ARM.exidx", 155 LDFileFormat::Target, 156 llvm::ELF::SHT_ARM_EXIDX, 157 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER, 158 config().targets().bitclass() / 8); 159 m_pEXTAB = pBuilder.CreateSection(".ARM.extab", 160 LDFileFormat::Target, 161 llvm::ELF::SHT_PROGBITS, 162 llvm::ELF::SHF_ALLOC, 163 0x1); 164 m_pAttributes = pBuilder.CreateSection(".ARM.attributes", 165 LDFileFormat::Target, 166 llvm::ELF::SHT_ARM_ATTRIBUTES, 167 0x0, 168 0x1); 169 170 // initialize "aeabi" attributes subsection 171 m_pAttrData = new ARMELFAttributeData(); 172 attribute().registerAttributeData(*m_pAttrData); 173 174 if (LinkerConfig::Object != config().codeGenType()) { 175 ELFFileFormat* file_format = getOutputFormat(); 176 177 // initialize .got 178 LDSection& got = file_format->getGOT(); 179 m_pGOT = new ARMGOT(got); 180 181 // initialize .plt 182 LDSection& plt = file_format->getPLT(); 183 m_pPLT = new ARMPLT(plt, *m_pGOT); 184 185 // initialize .rel.plt 186 LDSection& relplt = file_format->getRelPlt(); 187 relplt.setLink(&plt); 188 // create SectionData and ARMRelDynSection 189 m_pRelPLT = new OutputRelocSection(pModule, relplt); 190 191 // initialize .rel.dyn 192 LDSection& reldyn = file_format->getRelDyn(); 193 m_pRelDyn = new OutputRelocSection(pModule, reldyn); 194 } 195 } 196 197 void ARMGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) { 198 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 199 // same name in input 200 if (LinkerConfig::Object != config().codeGenType()) { 201 m_pGOTSymbol = 202 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 203 "_GLOBAL_OFFSET_TABLE_", 204 ResolveInfo::Object, 205 ResolveInfo::Define, 206 ResolveInfo::Local, 207 0x0, // size 208 0x0, // value 209 FragmentRef::Null(), 210 ResolveInfo::Hidden); 211 } 212 if (m_pEXIDX != NULL && m_pEXIDX->size() != 0x0) { 213 FragmentRef* exidx_start = 214 FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 0x0); 215 FragmentRef* exidx_end = FragmentRef::Create( 216 m_pEXIDX->getSectionData()->front(), m_pEXIDX->size()); 217 m_pEXIDXStart = 218 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 219 "__exidx_start", 220 ResolveInfo::Object, 221 ResolveInfo::Define, 222 ResolveInfo::Local, 223 0x0, // size 224 0x0, // value 225 exidx_start, // FragRef 226 ResolveInfo::Default); 227 228 m_pEXIDXEnd = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 229 "__exidx_end", 230 ResolveInfo::Object, 231 ResolveInfo::Define, 232 ResolveInfo::Local, 233 0x0, // size 234 0x0, // value 235 exidx_end, // FragRef 236 ResolveInfo::Default); 237 // change __exidx_start/_end to local dynamic category 238 if (m_pEXIDXStart != NULL) 239 pModule.getSymbolTable().changeToDynamic(*m_pEXIDXStart); 240 if (m_pEXIDXEnd != NULL) 241 pModule.getSymbolTable().changeToDynamic(*m_pEXIDXEnd); 242 } else { 243 m_pEXIDXStart = 244 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 245 "__exidx_start", 246 ResolveInfo::NoType, 247 ResolveInfo::Define, 248 ResolveInfo::Absolute, 249 0x0, // size 250 0x0, // value 251 FragmentRef::Null(), 252 ResolveInfo::Default); 253 254 m_pEXIDXEnd = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 255 "__exidx_end", 256 ResolveInfo::NoType, 257 ResolveInfo::Define, 258 ResolveInfo::Absolute, 259 0x0, // size 260 0x0, // value 261 FragmentRef::Null(), 262 ResolveInfo::Default); 263 } 264 } 265 266 bool ARMGNULDBackend::initRelocator() { 267 if (m_pRelocator == NULL) { 268 m_pRelocator = new ARMRelocator(*this, config()); 269 } 270 return true; 271 } 272 273 const Relocator* ARMGNULDBackend::getRelocator() const { 274 assert(m_pRelocator != NULL); 275 return m_pRelocator; 276 } 277 278 Relocator* ARMGNULDBackend::getRelocator() { 279 assert(m_pRelocator != NULL); 280 return m_pRelocator; 281 } 282 283 void ARMGNULDBackend::doPreLayout(IRBuilder& pBuilder) { 284 // initialize .dynamic data 285 if (!config().isCodeStatic() && m_pDynamic == NULL) 286 m_pDynamic = new ARMELFDynamic(*this, config()); 287 288 // set attribute section size 289 m_pAttributes->setSize(attribute().sizeOutput()); 290 291 // set .got size 292 // when building shared object, the .got section is must 293 if (LinkerConfig::Object != config().codeGenType()) { 294 if (LinkerConfig::DynObj == config().codeGenType() || m_pGOT->hasGOT1() || 295 m_pGOTSymbol != NULL) { 296 m_pGOT->finalizeSectionSize(); 297 defineGOTSymbol(pBuilder); 298 } 299 300 // set .plt size 301 if (m_pPLT->hasPLT1()) 302 m_pPLT->finalizeSectionSize(); 303 304 ELFFileFormat* file_format = getOutputFormat(); 305 // set .rel.dyn size 306 if (!m_pRelDyn->empty()) { 307 assert( 308 !config().isCodeStatic() && 309 "static linkage should not result in a dynamic relocation section"); 310 file_format->getRelDyn().setSize(m_pRelDyn->numOfRelocs() * 311 getRelEntrySize()); 312 } 313 314 // set .rel.plt size 315 if (!m_pRelPLT->empty()) { 316 assert( 317 !config().isCodeStatic() && 318 "static linkage should not result in a dynamic relocation section"); 319 file_format->getRelPlt().setSize(m_pRelPLT->numOfRelocs() * 320 getRelEntrySize()); 321 } 322 } 323 } 324 325 void ARMGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) { 326 const ELFFileFormat* file_format = getOutputFormat(); 327 328 // apply PLT 329 if (file_format->hasPLT()) { 330 // Since we already have the size of LDSection PLT, m_pPLT should not be 331 // NULL. 332 assert(m_pPLT != NULL); 333 m_pPLT->applyPLT0(); 334 m_pPLT->applyPLT1(); 335 } 336 337 // apply GOT 338 if (file_format->hasGOT()) { 339 // Since we already have the size of GOT, m_pGOT should not be NULL. 340 assert(m_pGOT != NULL); 341 if (LinkerConfig::DynObj == config().codeGenType()) 342 m_pGOT->applyGOT0(file_format->getDynamic().addr()); 343 else { 344 // executable file and object file? should fill with zero. 345 m_pGOT->applyGOT0(0); 346 } 347 } 348 } 349 350 /// dynamic - the dynamic section of the target machine. 351 /// Use co-variant return type to return its own dynamic section. 352 ARMELFDynamic& ARMGNULDBackend::dynamic() { 353 assert(m_pDynamic != NULL); 354 return *m_pDynamic; 355 } 356 357 /// dynamic - the dynamic section of the target machine. 358 /// Use co-variant return type to return its own dynamic section. 359 const ARMELFDynamic& ARMGNULDBackend::dynamic() const { 360 assert(m_pDynamic != NULL); 361 return *m_pDynamic; 362 } 363 364 void ARMGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) { 365 // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 366 if (m_pGOTSymbol != NULL) { 367 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 368 "_GLOBAL_OFFSET_TABLE_", 369 ResolveInfo::Object, 370 ResolveInfo::Define, 371 ResolveInfo::Local, 372 0x0, // size 373 0x0, // value 374 FragmentRef::Create(*(m_pGOT->begin()), 0x0), 375 ResolveInfo::Hidden); 376 } else { 377 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 378 "_GLOBAL_OFFSET_TABLE_", 379 ResolveInfo::Object, 380 ResolveInfo::Define, 381 ResolveInfo::Local, 382 0x0, // size 383 0x0, // value 384 FragmentRef::Create(*(m_pGOT->begin()), 0x0), 385 ResolveInfo::Hidden); 386 } 387 } 388 389 uint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection, 390 MemoryRegion& pRegion) const { 391 assert(pRegion.size() && "Size of MemoryRegion is zero!"); 392 393 const ELFFileFormat* file_format = getOutputFormat(); 394 395 if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { 396 uint64_t result = m_pPLT->emit(pRegion); 397 return result; 398 } 399 400 if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { 401 uint64_t result = m_pGOT->emit(pRegion); 402 return result; 403 } 404 405 if (&pSection == m_pAttributes) { 406 return attribute().emit(pRegion); 407 } 408 409 // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab 410 // directly from the input file. 411 const SectionData* sect_data = pSection.getSectionData(); 412 SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 413 uint8_t* out_offset = pRegion.begin(); 414 for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 415 size_t size = frag_iter->size(); 416 switch (frag_iter->getKind()) { 417 case Fragment::Fillment: { 418 const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter); 419 if (fill_frag.getValueSize() == 0) { 420 // virtual fillment, ignore it. 421 break; 422 } 423 424 memset(out_offset, fill_frag.getValue(), fill_frag.size()); 425 break; 426 } 427 case Fragment::Region: { 428 const RegionFragment& region_frag = 429 llvm::cast<RegionFragment>(*frag_iter); 430 const char* start = region_frag.getRegion().begin(); 431 memcpy(out_offset, start, size); 432 break; 433 } 434 case Fragment::Alignment: { 435 const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); 436 uint64_t count = size / align_frag.getValueSize(); 437 switch (align_frag.getValueSize()) { 438 case 1u: 439 std::memset(out_offset, align_frag.getValue(), count); 440 break; 441 default: 442 llvm::report_fatal_error( 443 "unsupported value size for align fragment emission yet.\n"); 444 break; 445 } // end switch 446 break; 447 } 448 case Fragment::Null: { 449 assert(0x0 == size); 450 break; 451 } 452 default: 453 llvm::report_fatal_error("unsupported fragment type.\n"); 454 break; 455 } // end switch 456 out_offset += size; 457 } // end for 458 return pRegion.size(); 459 } 460 461 /// finalizeSymbol - finalize the symbol value 462 bool ARMGNULDBackend::finalizeTargetSymbols() { 463 return true; 464 } 465 466 467 /// preMergeSections - hooks to be executed before merging sections 468 void ARMGNULDBackend::preMergeSections(Module& pModule) { 469 // Since the link relationship between .text and .ARM.exidx will be discarded 470 // after merging sections, we have to build the exception handling section 471 // mapping before section merge. 472 m_pExData = ARMExData::create(pModule); 473 } 474 475 /// postMergeSections - hooks to be executed after merging sections 476 void ARMGNULDBackend::postMergeSections(Module& pModule) { 477 if (m_pEXIDX->hasSectionData()) { 478 // Append the NullFragment so that __exidx_end can be correctly inserted. 479 NullFragment* null = new NullFragment(m_pEXIDX->getSectionData()); 480 null->setOffset(m_pEXIDX->size()); 481 } 482 } 483 484 bool ARMGNULDBackend::mergeSection(Module& pModule, 485 const Input& pInput, 486 LDSection& pSection) { 487 switch (pSection.type()) { 488 case llvm::ELF::SHT_ARM_ATTRIBUTES: { 489 return attribute().merge(pInput, pSection); 490 } 491 492 case llvm::ELF::SHT_ARM_EXIDX: { 493 assert(pSection.getLink() != NULL); 494 if ((pSection.getLink()->kind() == LDFileFormat::Ignore) || 495 (pSection.getLink()->kind() == LDFileFormat::Folded)) { 496 // if the target section of the .ARM.exidx is Ignore, then it should be 497 // ignored as well 498 pSection.setKind(LDFileFormat::Ignore); 499 return true; 500 } 501 502 if (!m_pEXIDX->hasSectionData()) { 503 // Create SectionData for m_pEXIDX. 504 SectionData* sectData = IRBuilder::CreateSectionData(*m_pEXIDX); 505 506 // Initialize the alignment of m_pEXIDX. 507 const size_t alignExIdx = 4; 508 m_pEXIDX->setAlign(alignExIdx); 509 510 // Insert an AlignFragment to the beginning of m_pEXIDX. 511 AlignFragment* frag = 512 new AlignFragment(/*alignment*/alignExIdx, 513 /*the filled value*/0x0, 514 /*the size of filled value*/1u, 515 /*max bytes to emit*/alignExIdx - 1); 516 frag->setOffset(0); 517 frag->setParent(sectData); 518 sectData->getFragmentList().push_back(frag); 519 m_pEXIDX->setSize(frag->size()); 520 } 521 522 // Move RegionFragment from pSection to m_pEXIDX. 523 uint64_t offset = m_pEXIDX->size(); 524 SectionData::FragmentListType& src = 525 pSection.getSectionData()->getFragmentList(); 526 SectionData::FragmentListType& dst = 527 m_pEXIDX->getSectionData()->getFragmentList(); 528 SectionData::FragmentListType::iterator frag = src.begin(); 529 SectionData::FragmentListType::iterator fragEnd = src.end(); 530 while (frag != fragEnd) { 531 if (frag->getKind() != Fragment::Region) { 532 ++frag; 533 } else { 534 frag->setParent(m_pEXIDX->getSectionData()); 535 frag->setOffset(offset); 536 offset += frag->size(); 537 dst.splice(dst.end(), src, frag++); 538 } 539 } 540 541 // Update the size of m_pEXIDX. 542 m_pEXIDX->setSize(offset); 543 return true; 544 } 545 546 default: { 547 ObjectBuilder builder(pModule); 548 builder.MergeSection(pInput, pSection); 549 return true; 550 } 551 } // end of switch 552 return true; 553 } 554 555 void ARMGNULDBackend::setUpReachedSectionsForGC( 556 const Module& pModule, 557 GarbageCollection::SectionReachedListMap& pSectReachedListMap) const { 558 // traverse all the input relocations to find the relocation sections applying 559 // .ARM.exidx sections 560 Module::const_obj_iterator input, inEnd = pModule.obj_end(); 561 for (input = pModule.obj_begin(); input != inEnd; ++input) { 562 LDContext::const_sect_iterator rs, 563 rsEnd = (*input)->context()->relocSectEnd(); 564 for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 565 // bypass the discarded relocation section 566 // 1. its section kind is changed to Ignore. (The target section is a 567 // discarded group section.) 568 // 2. it has no reloc data. (All symbols in the input relocs are in the 569 // discarded group sections) 570 LDSection* reloc_sect = *rs; 571 LDSection* apply_sect = reloc_sect->getLink(); 572 if ((LDFileFormat::Ignore == reloc_sect->kind()) || 573 (!reloc_sect->hasRelocData())) 574 continue; 575 576 if (llvm::ELF::SHT_ARM_EXIDX == apply_sect->type()) { 577 // 1. set up the reference according to relocations 578 bool add_first = false; 579 GarbageCollection::SectionListTy* reached_sects = NULL; 580 RelocData::iterator reloc_it, rEnd = reloc_sect->getRelocData()->end(); 581 for (reloc_it = reloc_sect->getRelocData()->begin(); reloc_it != rEnd; 582 ++reloc_it) { 583 Relocation* reloc = llvm::cast<Relocation>(reloc_it); 584 ResolveInfo* sym = reloc->symInfo(); 585 // only the target symbols defined in the input fragments can make the 586 // reference 587 if (sym == NULL) 588 continue; 589 if (!sym->isDefine() || !sym->outSymbol()->hasFragRef()) 590 continue; 591 592 // only the target symbols defined in the concerned sections can make 593 // the reference 594 const LDSection* target_sect = 595 &sym->outSymbol()->fragRef()->frag()->getParent()->getSection(); 596 if (target_sect->kind() != LDFileFormat::TEXT && 597 target_sect->kind() != LDFileFormat::DATA && 598 target_sect->kind() != LDFileFormat::BSS) 599 continue; 600 601 // setup the reached list, if we first add the element to reached list 602 // of this section, create an entry in ReachedSections map 603 if (!add_first) { 604 reached_sects = &pSectReachedListMap.getReachedList(*apply_sect); 605 add_first = true; 606 } 607 reached_sects->insert(target_sect); 608 } 609 reached_sects = NULL; 610 add_first = false; 611 // 2. set up the reference from XXX to .ARM.exidx.XXX 612 assert(apply_sect->getLink() != NULL); 613 pSectReachedListMap.addReference(*apply_sect->getLink(), *apply_sect); 614 } 615 } 616 } 617 } 618 619 bool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD) { 620 Fragment* frag = NULL; 621 uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 622 uint32_t size = pSD.getSection().size(); 623 624 llvm::StringRef region = pInput.memArea()->request(offset, size); 625 if (region.size() == 0) { 626 // If the input section's size is zero, we got a NULL region. 627 // use a virtual fill fragment 628 frag = new FillFragment(0x0, 0, 0); 629 } else { 630 frag = new RegionFragment(region); 631 } 632 633 ObjectBuilder::AppendFragment(*frag, pSD); 634 return true; 635 } 636 637 ARMGOT& ARMGNULDBackend::getGOT() { 638 assert(m_pGOT != NULL && "GOT section not exist"); 639 return *m_pGOT; 640 } 641 642 const ARMGOT& ARMGNULDBackend::getGOT() const { 643 assert(m_pGOT != NULL && "GOT section not exist"); 644 return *m_pGOT; 645 } 646 647 ARMPLT& ARMGNULDBackend::getPLT() { 648 assert(m_pPLT != NULL && "PLT section not exist"); 649 return *m_pPLT; 650 } 651 652 const ARMPLT& ARMGNULDBackend::getPLT() const { 653 assert(m_pPLT != NULL && "PLT section not exist"); 654 return *m_pPLT; 655 } 656 657 OutputRelocSection& ARMGNULDBackend::getRelDyn() { 658 assert(m_pRelDyn != NULL && ".rel.dyn section not exist"); 659 return *m_pRelDyn; 660 } 661 662 const OutputRelocSection& ARMGNULDBackend::getRelDyn() const { 663 assert(m_pRelDyn != NULL && ".rel.dyn section not exist"); 664 return *m_pRelDyn; 665 } 666 667 OutputRelocSection& ARMGNULDBackend::getRelPLT() { 668 assert(m_pRelPLT != NULL && ".rel.plt section not exist"); 669 return *m_pRelPLT; 670 } 671 672 const OutputRelocSection& ARMGNULDBackend::getRelPLT() const { 673 assert(m_pRelPLT != NULL && ".rel.plt section not exist"); 674 return *m_pRelPLT; 675 } 676 677 ARMELFAttributeData& ARMGNULDBackend::getAttributeData() { 678 assert(m_pAttrData != NULL && ".ARM.attributes section not exist"); 679 return *m_pAttrData; 680 } 681 682 const ARMELFAttributeData& ARMGNULDBackend::getAttributeData() const { 683 assert(m_pAttrData != NULL && ".ARM.attributes section not exist"); 684 return *m_pAttrData; 685 } 686 687 unsigned int ARMGNULDBackend::getTargetSectionOrder( 688 const LDSection& pSectHdr) const { 689 const ELFFileFormat* file_format = getOutputFormat(); 690 691 if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 692 if (config().options().hasNow()) 693 return SHO_RELRO_LAST; 694 return SHO_DATA; 695 } 696 697 if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 698 return SHO_PLT; 699 700 if (&pSectHdr == m_pEXIDX || &pSectHdr == m_pEXTAB) { 701 // put ARM.exidx and ARM.extab in the same order of .eh_frame 702 return SHO_EXCEPTION; 703 } 704 705 return SHO_UNDEFINED; 706 } 707 708 void ARMGNULDBackend::rewriteARMExIdxSection(Module& pModule) { 709 if (!m_pEXIDX->hasSectionData()) { 710 // Return if this is empty section. 711 return; 712 } 713 714 SectionData* sectData = m_pEXIDX->getSectionData(); 715 SectionData::FragmentListType& list = sectData->getFragmentList(); 716 717 // Move the first fragment (align fragment) and last fragment (null fragment) 718 // to temporary list because we would only like to sort the region fragment. 719 SectionData::FragmentListType tmp; 720 { 721 SectionData::iterator first = sectData->begin(); 722 SectionData::iterator last = sectData->end(); 723 --last; 724 725 assert(first->getKind() == Fragment::Alignment); 726 assert(last->getKind() == Fragment::Null); 727 728 tmp.splice(tmp.end(), list, first); 729 tmp.splice(tmp.end(), list, last); 730 } 731 732 // Sort the region fragments in the .ARM.exidx output section. 733 sort(list, ExIdxFragmentComparator(*m_pExData)); 734 735 // Fix the coverage of the .ARM.exidx table. 736 llvm::StringRef cantUnwindRegion(g_CantUnwindEntry, 737 sizeof(g_CantUnwindEntry)); 738 739 SectionData::FragmentListType::iterator it = list.begin(); 740 if (it != list.end()) { 741 Fragment* prevTextFrag = m_pExData->getTupleByExIdx(&*it)->getTextFragment(); 742 uint64_t prevTextEnd = prevTextFrag->getParent()->getSection().addr() + 743 prevTextFrag->getOffset() + 744 prevTextFrag->size(); 745 ++it; 746 while (it != list.end()) { 747 Fragment* currTextFrag = 748 m_pExData->getTupleByExIdx(&*it)->getTextFragment(); 749 uint64_t currTextBegin = currTextFrag->getParent()->getSection().addr() + 750 currTextFrag->getOffset(); 751 752 if (currTextBegin > prevTextEnd) { 753 // Found a gap. Insert a can't unwind entry. 754 RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr); 755 frag->setParent(sectData); 756 list.insert(it, frag); 757 758 // Add PREL31 reference to the beginning of the uncovered region. 759 Relocation* reloc = 760 Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31), 761 *FragmentRef::Create(*frag, /* pOffset */0), 762 /* pAddend */0); 763 reloc->setSymInfo( 764 CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag)); 765 addExtraRelocation(reloc); 766 } 767 768 prevTextEnd = currTextBegin + currTextFrag->size(); 769 prevTextFrag = currTextFrag; 770 ++it; 771 } 772 773 // Add a can't unwind entry to terminate .ARM.exidx section. 774 RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr); 775 frag->setParent(sectData); 776 list.push_back(frag); 777 778 // Add PREL31 reference to the end of the .text section. 779 Relocation* reloc = 780 Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31), 781 *FragmentRef::Create(*frag, /* pOffset */0), 782 /* pAddend */0); 783 reloc->setSymInfo(CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag)); 784 addExtraRelocation(reloc); 785 } 786 787 // Add the first and the last fragment back. 788 list.splice(list.begin(), tmp, tmp.begin()); 789 list.splice(list.end(), tmp, tmp.begin()); 790 791 // Update the fragment offsets. 792 uint64_t offset = 0; 793 for (SectionData::iterator it = sectData->begin(), end = sectData->end(); 794 it != end; ++it) { 795 it->setOffset(offset); 796 offset += it->size(); 797 } 798 799 // Update the section size. 800 m_pEXIDX->setSize(offset); 801 802 // Rebuild the section header. 803 setOutputSectionAddress(pModule); 804 } 805 806 /// relax - the relaxation pass 807 bool ARMGNULDBackend::relax(Module& pModule, IRBuilder& pBuilder) { 808 if (!GNULDBackend::relax(pModule, pBuilder)) { 809 return false; 810 } 811 rewriteARMExIdxSection(pModule); 812 return true; 813 } 814 815 /// doRelax 816 bool ARMGNULDBackend::doRelax(Module& pModule, 817 IRBuilder& pBuilder, 818 bool& pFinished) { 819 assert(getStubFactory() != NULL && getBRIslandFactory() != NULL); 820 821 bool isRelaxed = false; 822 ELFFileFormat* file_format = getOutputFormat(); 823 // check branch relocs and create the related stubs if needed 824 Module::obj_iterator input, inEnd = pModule.obj_end(); 825 for (input = pModule.obj_begin(); input != inEnd; ++input) { 826 LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 827 for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 828 if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 829 continue; 830 RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 831 for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 832 Relocation* relocation = llvm::cast<Relocation>(reloc); 833 834 switch (relocation->type()) { 835 case llvm::ELF::R_ARM_PC24: 836 case llvm::ELF::R_ARM_CALL: 837 case llvm::ELF::R_ARM_JUMP24: 838 case llvm::ELF::R_ARM_PLT32: 839 case llvm::ELF::R_ARM_THM_CALL: 840 case llvm::ELF::R_ARM_THM_XPC22: 841 case llvm::ELF::R_ARM_THM_JUMP24: 842 case llvm::ELF::R_ARM_THM_JUMP19: { 843 // calculate the possible symbol value 844 uint64_t sym_value = 0x0; 845 LDSymbol* symbol = relocation->symInfo()->outSymbol(); 846 if (symbol->hasFragRef()) { 847 uint64_t value = symbol->fragRef()->getOutputOffset(); 848 uint64_t addr = 849 symbol->fragRef()->frag()->getParent()->getSection().addr(); 850 sym_value = addr + value; 851 } 852 if ((relocation->symInfo()->reserved() & 853 ARMRelocator::ReservePLT) != 0x0) { 854 // FIXME: we need to find out the address of the specific plt 855 // entry 856 assert(file_format->hasPLT()); 857 sym_value = file_format->getPLT().addr(); 858 } 859 Stub* stub = getStubFactory()->create(*relocation, // relocation 860 sym_value, // symbol value 861 pBuilder, 862 *getBRIslandFactory()); 863 if (stub != NULL) { 864 assert(stub->symInfo() != NULL); 865 // reset the branch target of the reloc to this stub instead 866 relocation->setSymInfo(stub->symInfo()); 867 868 switch (config().options().getStripSymbolMode()) { 869 case GeneralOptions::StripSymbolMode::StripAllSymbols: 870 case GeneralOptions::StripSymbolMode::StripLocals: 871 break; 872 default: { 873 // a stub symbol should be local 874 assert(stub->symInfo() != NULL && stub->symInfo()->isLocal()); 875 LDSection& symtab = file_format->getSymTab(); 876 LDSection& strtab = file_format->getStrTab(); 877 878 // increase the size of .symtab and .strtab if needed 879 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 880 symtab.setInfo(symtab.getInfo() + 1); 881 strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 882 1); 883 } 884 } // end of switch 885 isRelaxed = true; 886 } 887 break; 888 } 889 case llvm::ELF::R_ARM_V4BX: 890 /* FIXME: bypass R_ARM_V4BX relocation now */ 891 break; 892 default: 893 break; 894 } // end of switch 895 } // for all relocations 896 } // for all relocation section 897 } // for all inputs 898 899 // find the first fragment w/ invalid offset due to stub insertion 900 std::vector<Fragment*> invalid_frags; 901 pFinished = true; 902 for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 903 island_end = getBRIslandFactory()->end(); 904 island != island_end; 905 ++island) { 906 if ((*island).size() > stubGroupSize()) { 907 error(diag::err_no_space_to_place_stubs) << stubGroupSize(); 908 return false; 909 } 910 911 if ((*island).numOfStubs() == 0) { 912 continue; 913 } 914 915 Fragment* exit = &*(*island).end(); 916 if (exit == (*island).begin()->getParent()->end()) { 917 continue; 918 } 919 920 if (((*island).offset() + (*island).size()) > exit->getOffset()) { 921 if (invalid_frags.empty() || 922 (invalid_frags.back()->getParent() != (*island).getParent())) { 923 invalid_frags.push_back(exit); 924 pFinished = false; 925 } 926 continue; 927 } 928 } 929 930 // reset the offset of invalid fragments 931 for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie; 932 ++it) { 933 Fragment* invalid = *it; 934 while (invalid != NULL) { 935 invalid->setOffset(invalid->getPrevNode()->getOffset() + 936 invalid->getPrevNode()->size()); 937 invalid = invalid->getNextNode(); 938 } 939 } 940 941 // reset the size of section that has stubs inserted. 942 if (isRelaxed) { 943 SectionData* prev = NULL; 944 for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 945 island_end = getBRIslandFactory()->end(); 946 island != island_end; 947 ++island) { 948 SectionData* sd = (*island).begin()->getParent(); 949 if ((*island).numOfStubs() != 0) { 950 if (sd != prev) { 951 sd->getSection().setSize(sd->back().getOffset() + sd->back().size()); 952 } 953 } 954 prev = sd; 955 } 956 } 957 return isRelaxed; 958 } 959 960 /// initTargetStubs 961 bool ARMGNULDBackend::initTargetStubs() { 962 if (getStubFactory() != NULL) { 963 getStubFactory()->addPrototype(new ARMToARMStub(config().isCodeIndep())); 964 getStubFactory()->addPrototype(new ARMToTHMStub(config().isCodeIndep())); 965 getStubFactory()->addPrototype( 966 new THMToTHMStub(config().isCodeIndep(), m_pAttrData->usingThumb2())); 967 getStubFactory()->addPrototype( 968 new THMToARMStub(config().isCodeIndep(), m_pAttrData->usingThumb2())); 969 return true; 970 } 971 return false; 972 } 973 974 /// maxFwdBranchOffset 975 int64_t ARMGNULDBackend::maxFwdBranchOffset() const { 976 if (m_pAttrData->usingThumb2()) { 977 return THM2_MAX_FWD_BRANCH_OFFSET; 978 } else { 979 return THM_MAX_FWD_BRANCH_OFFSET; 980 } 981 } 982 983 /// maxBwdBranchOffset 984 int64_t ARMGNULDBackend::maxBwdBranchOffset() const { 985 if (m_pAttrData->usingThumb2()) { 986 return THM2_MAX_BWD_BRANCH_OFFSET; 987 } else { 988 return THM_MAX_BWD_BRANCH_OFFSET; 989 } 990 } 991 992 /// doCreateProgramHdrs - backend can implement this function to create the 993 /// target-dependent segments 994 void ARMGNULDBackend::doCreateProgramHdrs(Module& pModule) { 995 if (m_pEXIDX != NULL && m_pEXIDX->size() != 0x0) { 996 // make PT_ARM_EXIDX 997 ELFSegment* exidx_seg = 998 elfSegmentTable().produce(llvm::ELF::PT_ARM_EXIDX, llvm::ELF::PF_R); 999 exidx_seg->append(m_pEXIDX); 1000 } 1001 } 1002 1003 /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe 1004 /// function pointer access 1005 bool ARMGNULDBackend::mayHaveUnsafeFunctionPointerAccess( 1006 const LDSection& pSection) const { 1007 llvm::StringRef name(pSection.name()); 1008 return !name.startswith(".ARM.exidx") && !name.startswith(".ARM.extab") && 1009 GNULDBackend::mayHaveUnsafeFunctionPointerAccess(pSection); 1010 } 1011 1012 //===----------------------------------------------------------------------===// 1013 /// createARMLDBackend - the help funtion to create corresponding ARMLDBackend 1014 /// 1015 TargetLDBackend* createARMLDBackend(const LinkerConfig& pConfig) { 1016 if (pConfig.targets().triple().isOSDarwin()) { 1017 assert(0 && "MachO linker is not supported yet"); 1018 /** 1019 return new ARMMachOLDBackend(createARMMachOArchiveReader, 1020 createARMMachOObjectReader, 1021 createARMMachOObjectWriter); 1022 **/ 1023 } 1024 if (pConfig.targets().triple().isOSWindows()) { 1025 assert(0 && "COFF linker is not supported yet"); 1026 /** 1027 return new ARMCOFFLDBackend(createARMCOFFArchiveReader, 1028 createARMCOFFObjectReader, 1029 createARMCOFFObjectWriter); 1030 **/ 1031 } 1032 return new ARMGNULDBackend(pConfig, 1033 new ARMGNUInfo(pConfig.targets().triple())); 1034 } 1035 1036 } // namespace mcld 1037 1038 //===----------------------------------------------------------------------===// 1039 // Force static initialization. 1040 //===----------------------------------------------------------------------===// 1041 extern "C" void MCLDInitializeARMLDBackend() { 1042 // Register the linker backend 1043 mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheARMTarget, 1044 mcld::createARMLDBackend); 1045 mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheThumbTarget, 1046 mcld::createARMLDBackend); 1047 } 1048