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 "ARMELFDynamic.h" 12 #include "ARMLDBackend.h" 13 #include "ARMRelocator.h" 14 #include "ARMToARMStub.h" 15 #include "ARMToTHMStub.h" 16 #include "THMToTHMStub.h" 17 #include "THMToARMStub.h" 18 19 #include <cstring> 20 21 #include <llvm/ADT/Triple.h> 22 #include <llvm/ADT/Twine.h> 23 #include <llvm/Support/ELF.h> 24 #include <llvm/Support/Casting.h> 25 26 #include <mcld/IRBuilder.h> 27 #include <mcld/LinkerConfig.h> 28 #include <mcld/Fragment/FillFragment.h> 29 #include <mcld/Fragment/AlignFragment.h> 30 #include <mcld/Fragment/RegionFragment.h> 31 #include <mcld/Support/MemoryRegion.h> 32 #include <mcld/Support/MemoryArea.h> 33 #include <mcld/Support/MsgHandling.h> 34 #include <mcld/Support/TargetRegistry.h> 35 #include <mcld/Fragment/Stub.h> 36 #include <mcld/LD/BranchIslandFactory.h> 37 #include <mcld/LD/StubFactory.h> 38 #include <mcld/Object/ObjectBuilder.h> 39 #include <mcld/Fragment/NullFragment.h> 40 #include <mcld/LD/LDContext.h> 41 #include <mcld/Target/GNUInfo.h> 42 43 using namespace mcld; 44 45 //===----------------------------------------------------------------------===// 46 // ARMGNULDBackend 47 //===----------------------------------------------------------------------===// 48 ARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo) 49 : GNULDBackend(pConfig, pInfo), 50 m_pRelocator(NULL), 51 m_pGOT(NULL), 52 m_pPLT(NULL), 53 m_pRelDyn(NULL), 54 m_pRelPLT(NULL), 55 m_pDynamic(NULL), 56 m_pGOTSymbol(NULL), 57 m_pEXIDXStart(NULL), 58 m_pEXIDXEnd(NULL), 59 m_pEXIDX(NULL), 60 m_pEXTAB(NULL), 61 m_pAttributes(NULL) { 62 } 63 64 ARMGNULDBackend::~ARMGNULDBackend() 65 { 66 delete m_pRelocator; 67 delete m_pGOT; 68 delete m_pPLT; 69 delete m_pRelDyn; 70 delete m_pRelPLT; 71 delete m_pDynamic; 72 } 73 74 void ARMGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder) 75 { 76 // FIXME: Currently we set exidx and extab to "Exception" and directly emit 77 // them from input 78 m_pEXIDX = pBuilder.CreateSection(".ARM.exidx", 79 LDFileFormat::Target, 80 llvm::ELF::SHT_ARM_EXIDX, 81 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER, 82 config().targets().bitclass() / 8); 83 m_pEXTAB = pBuilder.CreateSection(".ARM.extab", 84 LDFileFormat::Target, 85 llvm::ELF::SHT_PROGBITS, 86 llvm::ELF::SHF_ALLOC, 87 0x1); 88 m_pAttributes = pBuilder.CreateSection(".ARM.attributes", 89 LDFileFormat::Target, 90 llvm::ELF::SHT_ARM_ATTRIBUTES, 91 0x0, 92 0x1); 93 94 if (LinkerConfig::Object != config().codeGenType()) { 95 ELFFileFormat* file_format = getOutputFormat(); 96 97 // initialize .got 98 LDSection& got = file_format->getGOT(); 99 m_pGOT = new ARMGOT(got); 100 101 // initialize .plt 102 LDSection& plt = file_format->getPLT(); 103 m_pPLT = new ARMPLT(plt, *m_pGOT); 104 105 // initialize .rel.plt 106 LDSection& relplt = file_format->getRelPlt(); 107 relplt.setLink(&plt); 108 // create SectionData and ARMRelDynSection 109 m_pRelPLT = new OutputRelocSection(pModule, relplt); 110 111 // initialize .rel.dyn 112 LDSection& reldyn = file_format->getRelDyn(); 113 m_pRelDyn = new OutputRelocSection(pModule, reldyn); 114 } 115 } 116 117 void ARMGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 118 { 119 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 120 // same name in input 121 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 122 "_GLOBAL_OFFSET_TABLE_", 123 ResolveInfo::Object, 124 ResolveInfo::Define, 125 ResolveInfo::Local, 126 0x0, // size 127 0x0, // value 128 FragmentRef::Null(), 129 ResolveInfo::Hidden); 130 if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) { 131 FragmentRef* exidx_start = 132 FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 0x0); 133 FragmentRef* exidx_end = 134 FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 135 m_pEXIDX->size()); 136 m_pEXIDXStart = 137 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 138 "__exidx_start", 139 ResolveInfo::Object, 140 ResolveInfo::Define, 141 ResolveInfo::Local, 142 0x0, // size 143 0x0, // value 144 exidx_start, // FragRef 145 ResolveInfo::Default); 146 147 m_pEXIDXEnd = 148 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 149 "__exidx_end", 150 ResolveInfo::Object, 151 ResolveInfo::Define, 152 ResolveInfo::Local, 153 0x0, // size 154 0x0, // value 155 exidx_end, // FragRef 156 ResolveInfo::Default); 157 // change __exidx_start/_end to local dynamic category 158 if (NULL != m_pEXIDXStart) 159 pModule.getSymbolTable().changeLocalToDynamic(*m_pEXIDXStart); 160 if (NULL != m_pEXIDXEnd) 161 pModule.getSymbolTable().changeLocalToDynamic(*m_pEXIDXEnd); 162 } else { 163 m_pEXIDXStart = 164 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 165 "__exidx_start", 166 ResolveInfo::NoType, 167 ResolveInfo::Define, 168 ResolveInfo::Absolute, 169 0x0, // size 170 0x0, // value 171 FragmentRef::Null(), 172 ResolveInfo::Default); 173 174 m_pEXIDXEnd = 175 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 176 "__exidx_end", 177 ResolveInfo::NoType, 178 ResolveInfo::Define, 179 ResolveInfo::Absolute, 180 0x0, // size 181 0x0, // value 182 FragmentRef::Null(), 183 ResolveInfo::Default); 184 } 185 } 186 187 bool ARMGNULDBackend::initRelocator() 188 { 189 if (NULL == m_pRelocator) { 190 m_pRelocator = new ARMRelocator(*this); 191 } 192 return true; 193 } 194 195 Relocator* ARMGNULDBackend::getRelocator() 196 { 197 assert(NULL != m_pRelocator); 198 return m_pRelocator; 199 } 200 201 void ARMGNULDBackend::doPreLayout(IRBuilder& pBuilder) 202 { 203 // initialize .dynamic data 204 if (!config().isCodeStatic() && NULL == m_pDynamic) 205 m_pDynamic = new ARMELFDynamic(*this, config()); 206 207 // set .got size 208 // when building shared object, the .got section is must 209 if (LinkerConfig::Object != config().codeGenType()) { 210 if (LinkerConfig::DynObj == config().codeGenType() || 211 m_pGOT->hasGOT1() || 212 NULL != m_pGOTSymbol) { 213 m_pGOT->finalizeSectionSize(); 214 defineGOTSymbol(pBuilder); 215 } 216 217 // set .plt size 218 if (m_pPLT->hasPLT1()) 219 m_pPLT->finalizeSectionSize(); 220 221 ELFFileFormat* file_format = getOutputFormat(); 222 // set .rel.dyn size 223 if (!m_pRelDyn->empty()) { 224 assert(!config().isCodeStatic() && 225 "static linkage should not result in a dynamic relocation section"); 226 file_format->getRelDyn().setSize( 227 m_pRelDyn->numOfRelocs() * getRelEntrySize()); 228 } 229 230 // set .rel.plt size 231 if (!m_pRelPLT->empty()) { 232 assert(!config().isCodeStatic() && 233 "static linkage should not result in a dynamic relocation section"); 234 file_format->getRelPlt().setSize( 235 m_pRelPLT->numOfRelocs() * getRelEntrySize()); 236 } 237 } 238 } 239 240 void ARMGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) 241 { 242 const ELFFileFormat *file_format = getOutputFormat(); 243 244 // apply PLT 245 if (file_format->hasPLT()) { 246 // Since we already have the size of LDSection PLT, m_pPLT should not be 247 // NULL. 248 assert(NULL != m_pPLT); 249 m_pPLT->applyPLT0(); 250 m_pPLT->applyPLT1(); 251 } 252 253 // apply GOT 254 if (file_format->hasGOT()) { 255 // Since we already have the size of GOT, m_pGOT should not be NULL. 256 assert(NULL != m_pGOT); 257 if (LinkerConfig::DynObj == config().codeGenType()) 258 m_pGOT->applyGOT0(file_format->getDynamic().addr()); 259 else { 260 // executable file and object file? should fill with zero. 261 m_pGOT->applyGOT0(0); 262 } 263 } 264 } 265 266 /// dynamic - the dynamic section of the target machine. 267 /// Use co-variant return type to return its own dynamic section. 268 ARMELFDynamic& ARMGNULDBackend::dynamic() 269 { 270 assert(NULL != m_pDynamic); 271 return *m_pDynamic; 272 } 273 274 /// dynamic - the dynamic section of the target machine. 275 /// Use co-variant return type to return its own dynamic section. 276 const ARMELFDynamic& ARMGNULDBackend::dynamic() const 277 { 278 assert(NULL != m_pDynamic); 279 return *m_pDynamic; 280 } 281 282 void ARMGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) 283 { 284 // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 285 if (m_pGOTSymbol != NULL) { 286 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 287 "_GLOBAL_OFFSET_TABLE_", 288 ResolveInfo::Object, 289 ResolveInfo::Define, 290 ResolveInfo::Local, 291 0x0, // size 292 0x0, // value 293 FragmentRef::Create(*(m_pGOT->begin()), 0x0), 294 ResolveInfo::Hidden); 295 } 296 else { 297 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 298 "_GLOBAL_OFFSET_TABLE_", 299 ResolveInfo::Object, 300 ResolveInfo::Define, 301 ResolveInfo::Local, 302 0x0, // size 303 0x0, // value 304 FragmentRef::Create(*(m_pGOT->begin()), 0x0), 305 ResolveInfo::Hidden); 306 } 307 308 } 309 310 void ARMGNULDBackend::addCopyReloc(ResolveInfo& pSym) 311 { 312 Relocation& rel_entry = *m_pRelDyn->consumeEntry(); 313 rel_entry.setType(llvm::ELF::R_ARM_COPY); 314 assert(pSym.outSymbol()->hasFragRef()); 315 rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef()); 316 rel_entry.setSymInfo(&pSym); 317 } 318 319 /// defineSymbolForCopyReloc 320 /// For a symbol needing copy relocation, define a copy symbol in the BSS 321 /// section and all other reference to this symbol should refer to this 322 /// copy. 323 /// This is executed at scan relocation stage. 324 LDSymbol& 325 ARMGNULDBackend::defineSymbolforCopyReloc(IRBuilder& pBuilder, 326 const ResolveInfo& pSym) 327 { 328 // get or create corresponding BSS LDSection 329 LDSection* bss_sect_hdr = NULL; 330 ELFFileFormat* file_format = getOutputFormat(); 331 if (ResolveInfo::ThreadLocal == pSym.type()) 332 bss_sect_hdr = &file_format->getTBSS(); 333 else 334 bss_sect_hdr = &file_format->getBSS(); 335 336 // get or create corresponding BSS SectionData 337 SectionData* bss_data = NULL; 338 if (bss_sect_hdr->hasSectionData()) 339 bss_data = bss_sect_hdr->getSectionData(); 340 else 341 bss_data = IRBuilder::CreateSectionData(*bss_sect_hdr); 342 343 // Determine the alignment by the symbol value 344 // FIXME: here we use the largest alignment 345 uint32_t addralign = config().targets().bitclass() / 8; 346 347 // allocate space in BSS for the copy symbol 348 Fragment* frag = new FillFragment(0x0, 1, pSym.size()); 349 uint64_t size = ObjectBuilder::AppendFragment(*frag, 350 *bss_data, 351 addralign); 352 bss_sect_hdr->setSize(bss_sect_hdr->size() + size); 353 354 // change symbol binding to Global if it's a weak symbol 355 ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding(); 356 if (binding == ResolveInfo::Weak) 357 binding = ResolveInfo::Global; 358 359 // Define the copy symbol in the bss section and resolve it 360 LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 361 pSym.name(), 362 (ResolveInfo::Type)pSym.type(), 363 ResolveInfo::Define, 364 binding, 365 pSym.size(), // size 366 0x0, // value 367 FragmentRef::Create(*frag, 0x0), 368 (ResolveInfo::Visibility)pSym.other()); 369 370 return *cpy_sym; 371 } 372 373 /// checkValidReloc - When we attempt to generate a dynamic relocation for 374 /// ouput file, check if the relocation is supported by dynamic linker. 375 void ARMGNULDBackend::checkValidReloc(Relocation& pReloc) const 376 { 377 // If not PIC object, no relocation type is invalid 378 if (!config().isCodeIndep()) 379 return; 380 381 switch(pReloc.type()) { 382 case llvm::ELF::R_ARM_RELATIVE: 383 case llvm::ELF::R_ARM_COPY: 384 case llvm::ELF::R_ARM_GLOB_DAT: 385 case llvm::ELF::R_ARM_JUMP_SLOT: 386 case llvm::ELF::R_ARM_ABS32: 387 case llvm::ELF::R_ARM_ABS32_NOI: 388 case llvm::ELF::R_ARM_PC24: 389 case llvm::ELF::R_ARM_TLS_DTPMOD32: 390 case llvm::ELF::R_ARM_TLS_DTPOFF32: 391 case llvm::ELF::R_ARM_TLS_TPOFF32: 392 break; 393 394 default: 395 error(diag::non_pic_relocation) << (int)pReloc.type() 396 << pReloc.symInfo()->name(); 397 break; 398 } 399 } 400 401 void 402 ARMGNULDBackend::scanLocalReloc(Relocation& pReloc, const LDSection& pSection) 403 { 404 // rsym - The relocation target symbol 405 ResolveInfo* rsym = pReloc.symInfo(); 406 407 switch(pReloc.type()){ 408 409 // Set R_ARM_TARGET1 to R_ARM_ABS32 410 // Ref: GNU gold 1.11 arm.cc, line 9892 411 // FIXME: R_ARM_TARGET1 should be set by option --target1-rel 412 // or --target1-rel 413 case llvm::ELF::R_ARM_TARGET1: 414 pReloc.setType(llvm::ELF::R_ARM_ABS32); 415 case llvm::ELF::R_ARM_ABS32: 416 case llvm::ELF::R_ARM_ABS32_NOI: { 417 // If buiding PIC object (shared library or PIC executable), 418 // a dynamic relocations with RELATIVE type to this location is needed. 419 // Reserve an entry in .rel.dyn 420 if (config().isCodeIndep()) { 421 m_pRelDyn->reserveEntry(); 422 // set Rel bit 423 rsym->setReserved(rsym->reserved() | ReserveRel); 424 checkAndSetHasTextRel(*pSection.getLink()); 425 } 426 return; 427 } 428 429 case llvm::ELF::R_ARM_ABS16: 430 case llvm::ELF::R_ARM_ABS12: 431 case llvm::ELF::R_ARM_THM_ABS5: 432 case llvm::ELF::R_ARM_ABS8: 433 case llvm::ELF::R_ARM_BASE_ABS: 434 case llvm::ELF::R_ARM_MOVW_ABS_NC: 435 case llvm::ELF::R_ARM_MOVT_ABS: 436 case llvm::ELF::R_ARM_THM_MOVW_ABS_NC: 437 case llvm::ELF::R_ARM_THM_MOVT_ABS: { 438 // PIC code should not contain these kinds of relocation 439 if (config().isCodeIndep()) { 440 error(diag::non_pic_relocation) << (int)pReloc.type() 441 << pReloc.symInfo()->name(); 442 } 443 return; 444 } 445 case llvm::ELF::R_ARM_GOTOFF32: 446 case llvm::ELF::R_ARM_GOTOFF12: { 447 // FIXME: A GOT section is needed 448 return; 449 } 450 451 // Set R_ARM_TARGET2 to R_ARM_GOT_PREL 452 // Ref: GNU gold 1.11 arm.cc, line 9892 453 // FIXME: R_ARM_TARGET2 should be set by option --target2 454 case llvm::ELF::R_ARM_TARGET2: 455 pReloc.setType(llvm::ELF::R_ARM_GOT_PREL); 456 case llvm::ELF::R_ARM_GOT_BREL: 457 case llvm::ELF::R_ARM_GOT_PREL: { 458 // A GOT entry is needed for these relocation type. 459 // return if we already create GOT for this symbol 460 if (rsym->reserved() & (ReserveGOT | GOTRel)) 461 return; 462 m_pGOT->reserveGOT(); 463 // If building PIC object, a dynamic relocation with 464 // type RELATIVE is needed to relocate this GOT entry. 465 // Reserve an entry in .rel.dyn 466 if (config().isCodeIndep()) { 467 // create .rel.dyn section if not exist 468 m_pRelDyn->reserveEntry(); 469 // set GOTRel bit 470 rsym->setReserved(rsym->reserved() | 0x4u); 471 return; 472 } 473 // set GOT bit 474 rsym->setReserved(rsym->reserved() | 0x2u); 475 return; 476 } 477 478 case llvm::ELF::R_ARM_BASE_PREL: { 479 // FIXME: Currently we only support R_ARM_BASE_PREL against 480 // symbol _GLOBAL_OFFSET_TABLE_ 481 if (rsym != m_pGOTSymbol->resolveInfo()) 482 fatal(diag::base_relocation) << (int)pReloc.type() << rsym->name() 483 << "mclinker (at) googlegroups.com"; 484 return; 485 } 486 case llvm::ELF::R_ARM_COPY: 487 case llvm::ELF::R_ARM_GLOB_DAT: 488 case llvm::ELF::R_ARM_JUMP_SLOT: 489 case llvm::ELF::R_ARM_RELATIVE: { 490 // These are relocation type for dynamic linker, shold not 491 // appear in object file. 492 fatal(diag::dynamic_relocation) << (int)pReloc.type(); 493 break; 494 } 495 default: { 496 break; 497 } 498 } // end switch 499 } 500 501 void ARMGNULDBackend::scanGlobalReloc(Relocation& pReloc, 502 IRBuilder& pBuilder, 503 const LDSection& pSection) 504 { 505 // rsym - The relocation target symbol 506 ResolveInfo* rsym = pReloc.symInfo(); 507 508 switch(pReloc.type()) { 509 510 // Set R_ARM_TARGET1 to R_ARM_ABS32 511 // Ref: GNU gold 1.11 arm.cc, line 9892 512 // FIXME: R_ARM_TARGET1 should be set by option --target1-rel 513 // or --target1-rel 514 case llvm::ELF::R_ARM_TARGET1: 515 pReloc.setType(llvm::ELF::R_ARM_ABS32); 516 case llvm::ELF::R_ARM_ABS32: 517 case llvm::ELF::R_ARM_ABS16: 518 case llvm::ELF::R_ARM_ABS12: 519 case llvm::ELF::R_ARM_THM_ABS5: 520 case llvm::ELF::R_ARM_ABS8: 521 case llvm::ELF::R_ARM_BASE_ABS: 522 case llvm::ELF::R_ARM_MOVW_ABS_NC: 523 case llvm::ELF::R_ARM_MOVT_ABS: 524 case llvm::ELF::R_ARM_THM_MOVW_ABS_NC: 525 case llvm::ELF::R_ARM_THM_MOVT_ABS: 526 case llvm::ELF::R_ARM_ABS32_NOI: { 527 // Absolute relocation type, symbol may needs PLT entry or 528 // dynamic relocation entry 529 if (symbolNeedsPLT(*rsym)) { 530 // create plt for this symbol if it does not have one 531 if (!(rsym->reserved() & ReservePLT)){ 532 // Symbol needs PLT entry, we need to reserve a PLT entry 533 // and the corresponding GOT and dynamic relocation entry 534 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 535 // when calling ARMPLT->reserveEntry()) 536 m_pPLT->reserveEntry(); 537 m_pRelPLT->reserveEntry(); 538 // set PLT bit 539 rsym->setReserved(rsym->reserved() | ReservePLT); 540 } 541 } 542 543 if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) { 544 // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 545 m_pRelDyn->reserveEntry(); 546 if (symbolNeedsCopyReloc(pReloc, *rsym)) { 547 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym); 548 addCopyReloc(*cpy_sym.resolveInfo()); 549 } 550 else { 551 checkValidReloc(pReloc); 552 // set Rel bit 553 rsym->setReserved(rsym->reserved() | ReserveRel); 554 checkAndSetHasTextRel(*pSection.getLink()); 555 } 556 } 557 return; 558 } 559 560 case llvm::ELF::R_ARM_GOTOFF32: 561 case llvm::ELF::R_ARM_GOTOFF12: { 562 // FIXME: A GOT section is needed 563 return; 564 } 565 566 case llvm::ELF::R_ARM_BASE_PREL: 567 case llvm::ELF::R_ARM_THM_MOVW_BREL_NC: 568 case llvm::ELF::R_ARM_THM_MOVW_BREL: 569 case llvm::ELF::R_ARM_THM_MOVT_BREL: 570 // FIXME: Currently we only support these relocations against 571 // symbol _GLOBAL_OFFSET_TABLE_ 572 if (rsym != m_pGOTSymbol->resolveInfo()) { 573 fatal(diag::base_relocation) << (int)pReloc.type() << rsym->name() 574 << "mclinker (at) googlegroups.com"; 575 } 576 case llvm::ELF::R_ARM_REL32: 577 case llvm::ELF::R_ARM_LDR_PC_G0: 578 case llvm::ELF::R_ARM_SBREL32: 579 case llvm::ELF::R_ARM_THM_PC8: 580 case llvm::ELF::R_ARM_MOVW_PREL_NC: 581 case llvm::ELF::R_ARM_MOVT_PREL: 582 case llvm::ELF::R_ARM_THM_MOVW_PREL_NC: 583 case llvm::ELF::R_ARM_THM_MOVT_PREL: 584 case llvm::ELF::R_ARM_THM_ALU_PREL_11_0: 585 case llvm::ELF::R_ARM_THM_PC12: 586 case llvm::ELF::R_ARM_REL32_NOI: 587 case llvm::ELF::R_ARM_ALU_PC_G0_NC: 588 case llvm::ELF::R_ARM_ALU_PC_G0: 589 case llvm::ELF::R_ARM_ALU_PC_G1_NC: 590 case llvm::ELF::R_ARM_ALU_PC_G1: 591 case llvm::ELF::R_ARM_ALU_PC_G2: 592 case llvm::ELF::R_ARM_LDR_PC_G1: 593 case llvm::ELF::R_ARM_LDR_PC_G2: 594 case llvm::ELF::R_ARM_LDRS_PC_G0: 595 case llvm::ELF::R_ARM_LDRS_PC_G1: 596 case llvm::ELF::R_ARM_LDRS_PC_G2: 597 case llvm::ELF::R_ARM_LDC_PC_G0: 598 case llvm::ELF::R_ARM_LDC_PC_G1: 599 case llvm::ELF::R_ARM_LDC_PC_G2: 600 case llvm::ELF::R_ARM_ALU_SB_G0_NC: 601 case llvm::ELF::R_ARM_ALU_SB_G0: 602 case llvm::ELF::R_ARM_ALU_SB_G1_NC: 603 case llvm::ELF::R_ARM_ALU_SB_G1: 604 case llvm::ELF::R_ARM_ALU_SB_G2: 605 case llvm::ELF::R_ARM_LDR_SB_G0: 606 case llvm::ELF::R_ARM_LDR_SB_G1: 607 case llvm::ELF::R_ARM_LDR_SB_G2: 608 case llvm::ELF::R_ARM_LDRS_SB_G0: 609 case llvm::ELF::R_ARM_LDRS_SB_G1: 610 case llvm::ELF::R_ARM_LDRS_SB_G2: 611 case llvm::ELF::R_ARM_LDC_SB_G0: 612 case llvm::ELF::R_ARM_LDC_SB_G1: 613 case llvm::ELF::R_ARM_LDC_SB_G2: 614 case llvm::ELF::R_ARM_MOVW_BREL_NC: 615 case llvm::ELF::R_ARM_MOVT_BREL: 616 case llvm::ELF::R_ARM_MOVW_BREL: { 617 // Relative addressing relocation, may needs dynamic relocation 618 if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false)) { 619 // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 620 m_pRelDyn->reserveEntry(); 621 if (symbolNeedsCopyReloc(pReloc, *rsym)) { 622 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym); 623 addCopyReloc(*cpy_sym.resolveInfo()); 624 } 625 else { 626 checkValidReloc(pReloc); 627 // set Rel bit 628 rsym->setReserved(rsym->reserved() | ReserveRel); 629 checkAndSetHasTextRel(*pSection.getLink()); 630 } 631 } 632 return; 633 } 634 635 case llvm::ELF::R_ARM_THM_CALL: 636 case llvm::ELF::R_ARM_PLT32: 637 case llvm::ELF::R_ARM_CALL: 638 case llvm::ELF::R_ARM_JUMP24: 639 case llvm::ELF::R_ARM_THM_JUMP24: 640 case llvm::ELF::R_ARM_SBREL31: 641 case llvm::ELF::R_ARM_PREL31: 642 case llvm::ELF::R_ARM_THM_JUMP19: 643 case llvm::ELF::R_ARM_THM_JUMP6: 644 case llvm::ELF::R_ARM_THM_JUMP11: 645 case llvm::ELF::R_ARM_THM_JUMP8: { 646 // These are branch relocation (except PREL31) 647 // A PLT entry is needed when building shared library 648 649 // return if we already create plt for this symbol 650 if (rsym->reserved() & ReservePLT) 651 return; 652 653 // if the symbol's value can be decided at link time, then no need plt 654 if (symbolFinalValueIsKnown(*rsym)) 655 return; 656 657 // if symbol is defined in the ouput file and it's not 658 // preemptible, no need plt 659 if (rsym->isDefine() && !rsym->isDyn() && 660 !isSymbolPreemptible(*rsym)) { 661 return; 662 } 663 664 // Symbol needs PLT entry, we need to reserve a PLT entry 665 // and the corresponding GOT and dynamic relocation entry 666 // in .got and .rel.plt. (GOT entry will be reserved simultaneously 667 // when calling ARMPLT->reserveEntry()) 668 m_pPLT->reserveEntry(); 669 m_pRelPLT->reserveEntry(); 670 // set PLT bit 671 rsym->setReserved(rsym->reserved() | ReservePLT); 672 return; 673 } 674 675 // Set R_ARM_TARGET2 to R_ARM_GOT_PREL 676 // Ref: GNU gold 1.11 arm.cc, line 9892 677 // FIXME: R_ARM_TARGET2 should be set by option --target2 678 case llvm::ELF::R_ARM_TARGET2: 679 pReloc.setType(llvm::ELF::R_ARM_GOT_PREL); 680 case llvm::ELF::R_ARM_GOT_BREL: 681 case llvm::ELF::R_ARM_GOT_ABS: 682 case llvm::ELF::R_ARM_GOT_PREL: { 683 // Symbol needs GOT entry, reserve entry in .got 684 // return if we already create GOT for this symbol 685 if (rsym->reserved() & (ReserveGOT | GOTRel)) 686 return; 687 m_pGOT->reserveGOT(); 688 // if the symbol cannot be fully resolved at link time, then we need a 689 // dynamic relocation 690 if (!symbolFinalValueIsKnown(*rsym)) { 691 m_pRelDyn->reserveEntry(); 692 // set GOTRel bit 693 rsym->setReserved(rsym->reserved() | GOTRel); 694 return; 695 } 696 // set GOT bit 697 rsym->setReserved(rsym->reserved() | ReserveGOT); 698 return; 699 } 700 701 case llvm::ELF::R_ARM_COPY: 702 case llvm::ELF::R_ARM_GLOB_DAT: 703 case llvm::ELF::R_ARM_JUMP_SLOT: 704 case llvm::ELF::R_ARM_RELATIVE: { 705 // These are relocation type for dynamic linker, shold not 706 // appear in object file. 707 fatal(diag::dynamic_relocation) << (int)pReloc.type(); 708 break; 709 } 710 default: { 711 break; 712 } 713 } // end switch 714 } 715 716 void ARMGNULDBackend::scanRelocation(Relocation& pReloc, 717 IRBuilder& pBuilder, 718 Module& pModule, 719 LDSection& pSection) 720 { 721 // rsym - The relocation target symbol 722 ResolveInfo* rsym = pReloc.symInfo(); 723 assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 724 725 pReloc.updateAddend(); 726 assert(NULL != pSection.getLink()); 727 if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) 728 return; 729 730 // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation 731 // entries should be created. 732 // FIXME: Below judgements concern nothing about TLS related relocation 733 734 // rsym is local 735 if (rsym->isLocal()) 736 scanLocalReloc(pReloc, pSection); 737 738 // rsym is external 739 else 740 scanGlobalReloc(pReloc, pBuilder, pSection); 741 742 // check if we shoule issue undefined reference for the relocation target 743 // symbol 744 if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull()) 745 fatal(diag::undefined_reference) << rsym->name(); 746 } 747 748 uint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection, 749 MemoryRegion& pRegion) const 750 { 751 assert(pRegion.size() && "Size of MemoryRegion is zero!"); 752 753 const ELFFileFormat* file_format = getOutputFormat(); 754 755 if (&pSection == m_pAttributes || 756 &pSection == m_pEXIDX || 757 &pSection == m_pEXTAB) { 758 // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab 759 // directly from the input file. 760 const SectionData* sect_data = pSection.getSectionData(); 761 SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 762 uint8_t* out_offset = pRegion.start(); 763 for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 764 size_t size = frag_iter->size(); 765 switch(frag_iter->getKind()) { 766 case Fragment::Fillment: { 767 const FillFragment& fill_frag = 768 llvm::cast<FillFragment>(*frag_iter); 769 if (0 == fill_frag.getValueSize()) { 770 // virtual fillment, ignore it. 771 break; 772 } 773 774 memset(out_offset, fill_frag.getValue(), fill_frag.size()); 775 break; 776 } 777 case Fragment::Region: { 778 const RegionFragment& region_frag = 779 llvm::cast<RegionFragment>(*frag_iter); 780 const uint8_t* start = region_frag.getRegion().start(); 781 memcpy(out_offset, start, size); 782 break; 783 } 784 case Fragment::Alignment: { 785 const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); 786 uint64_t count = size / align_frag.getValueSize(); 787 switch (align_frag.getValueSize()) { 788 case 1u: 789 std::memset(out_offset, align_frag.getValue(), count); 790 break; 791 default: 792 llvm::report_fatal_error( 793 "unsupported value size for align fragment emission yet.\n"); 794 break; 795 } // end switch 796 break; 797 } 798 case Fragment::Null: { 799 assert(0x0 == size); 800 break; 801 } 802 default: 803 llvm::report_fatal_error("unsupported fragment type.\n"); 804 break; 805 } // end switch 806 out_offset += size; 807 } // end for 808 return pRegion.size(); 809 } // end if 810 811 if (&pSection == &(file_format->getPLT())) { 812 assert(NULL != m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); 813 uint64_t result = m_pPLT->emit(pRegion); 814 return result; 815 } 816 817 if (&pSection == &(file_format->getGOT())) { 818 assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 819 uint64_t result = m_pGOT->emit(pRegion); 820 return result; 821 } 822 fatal(diag::unrecognized_output_sectoin) 823 << pSection.name() 824 << "mclinker (at) googlegroups.com"; 825 return 0x0; 826 } 827 828 /// finalizeSymbol - finalize the symbol value 829 bool ARMGNULDBackend::finalizeTargetSymbols() 830 { 831 return true; 832 } 833 834 bool ARMGNULDBackend::mergeSection(Module& pModule, LDSection& pSection) 835 { 836 switch (pSection.type()) { 837 case llvm::ELF::SHT_ARM_ATTRIBUTES: { 838 // FIXME: (Luba) 839 // Handle ARM attributes in the right way. 840 // In current milestone, we goes through the shortcut. 841 // It reads input's ARM attributes and copies the first ARM attributes 842 // into the output file. The correct way is merge these sections, not 843 // just copy. 844 if (0 != m_pAttributes->size()) 845 return true; 846 847 // First time we meet a ARM attributes section. 848 SectionData* sd = IRBuilder::CreateSectionData(*m_pAttributes); 849 ObjectBuilder::MoveSectionData(*pSection.getSectionData(), *sd); 850 return true; 851 } 852 default: { 853 ObjectBuilder builder(config(), pModule); 854 return builder.MergeSection(pSection); 855 } 856 } // end of switch 857 return true; 858 } 859 860 bool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD) 861 { 862 Fragment* frag = NULL; 863 uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 864 uint32_t size = pSD.getSection().size(); 865 866 MemoryRegion* region = pInput.memArea()->request(offset, size); 867 if (NULL == region) { 868 // If the input section's size is zero, we got a NULL region. 869 // use a virtual fill fragment 870 frag = new FillFragment(0x0, 0, 0); 871 } 872 else { 873 frag = new RegionFragment(*region); 874 } 875 876 ObjectBuilder::AppendFragment(*frag, pSD); 877 return true; 878 } 879 880 ARMGOT& ARMGNULDBackend::getGOT() 881 { 882 assert(NULL != m_pGOT && "GOT section not exist"); 883 return *m_pGOT; 884 } 885 886 const ARMGOT& ARMGNULDBackend::getGOT() const 887 { 888 assert(NULL != m_pGOT && "GOT section not exist"); 889 return *m_pGOT; 890 } 891 892 ARMPLT& ARMGNULDBackend::getPLT() 893 { 894 assert(NULL != m_pPLT && "PLT section not exist"); 895 return *m_pPLT; 896 } 897 898 const ARMPLT& ARMGNULDBackend::getPLT() const 899 { 900 assert(NULL != m_pPLT && "PLT section not exist"); 901 return *m_pPLT; 902 } 903 904 OutputRelocSection& ARMGNULDBackend::getRelDyn() 905 { 906 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 907 return *m_pRelDyn; 908 } 909 910 const OutputRelocSection& ARMGNULDBackend::getRelDyn() const 911 { 912 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 913 return *m_pRelDyn; 914 } 915 916 OutputRelocSection& ARMGNULDBackend::getRelPLT() 917 { 918 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 919 return *m_pRelPLT; 920 } 921 922 const OutputRelocSection& ARMGNULDBackend::getRelPLT() const 923 { 924 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 925 return *m_pRelPLT; 926 } 927 928 unsigned int 929 ARMGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 930 { 931 const ELFFileFormat* file_format = getOutputFormat(); 932 933 if (&pSectHdr == &file_format->getGOT()) { 934 if (config().options().hasNow()) 935 return SHO_RELRO_LAST; 936 return SHO_DATA; 937 } 938 939 if (&pSectHdr == &file_format->getPLT()) 940 return SHO_PLT; 941 942 if (&pSectHdr == m_pEXIDX || &pSectHdr == m_pEXTAB) { 943 // put ARM.exidx and ARM.extab in the same order of .eh_frame 944 return SHO_EXCEPTION; 945 } 946 947 return SHO_UNDEFINED; 948 } 949 950 /// doRelax 951 bool 952 ARMGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) 953 { 954 assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); 955 956 bool isRelaxed = false; 957 ELFFileFormat* file_format = getOutputFormat(); 958 // check branch relocs and create the related stubs if needed 959 Module::obj_iterator input, inEnd = pModule.obj_end(); 960 for (input = pModule.obj_begin(); input != inEnd; ++input) { 961 LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 962 for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 963 if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 964 continue; 965 RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 966 for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 967 Relocation* relocation = llvm::cast<Relocation>(reloc); 968 969 switch (relocation->type()) { 970 case llvm::ELF::R_ARM_CALL: 971 case llvm::ELF::R_ARM_JUMP24: 972 case llvm::ELF::R_ARM_PLT32: 973 case llvm::ELF::R_ARM_THM_CALL: 974 case llvm::ELF::R_ARM_THM_XPC22: 975 case llvm::ELF::R_ARM_THM_JUMP24: 976 case llvm::ELF::R_ARM_THM_JUMP19: 977 case llvm::ELF::R_ARM_V4BX: { 978 // calculate the possible symbol value 979 uint64_t sym_value = 0x0; 980 LDSymbol* symbol = relocation->symInfo()->outSymbol(); 981 if (symbol->hasFragRef()) { 982 uint64_t value = symbol->fragRef()->getOutputOffset(); 983 uint64_t addr = 984 symbol->fragRef()->frag()->getParent()->getSection().addr(); 985 sym_value = addr + value; 986 } 987 if (relocation->symInfo()->isGlobal() && 988 (relocation->symInfo()->reserved() & ReservePLT) != 0x0) { 989 // FIXME: we need to find out the address of the specific plt entry 990 assert(file_format->hasPLT()); 991 sym_value = file_format->getPLT().addr(); 992 } 993 994 Stub* stub = getStubFactory()->create(*relocation, // relocation 995 sym_value, // symbol value 996 pBuilder, 997 *getBRIslandFactory()); 998 if (NULL != stub) { 999 // a stub symbol should be local 1000 assert(NULL != stub->symInfo() && stub->symInfo()->isLocal()); 1001 LDSection& symtab = file_format->getSymTab(); 1002 LDSection& strtab = file_format->getStrTab(); 1003 1004 // increase the size of .symtab and .strtab if needed 1005 if (config().targets().is32Bits()) 1006 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 1007 else 1008 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf64_Sym)); 1009 symtab.setInfo(symtab.getInfo() + 1); 1010 strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 1011 1012 isRelaxed = true; 1013 } 1014 break; 1015 } 1016 default: 1017 break; 1018 } // end of switch 1019 1020 } // for all relocations 1021 } // for all relocation section 1022 } // for all inputs 1023 1024 // find the first fragment w/ invalid offset due to stub insertion 1025 Fragment* invalid = NULL; 1026 pFinished = true; 1027 for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 1028 island_end = getBRIslandFactory()->end(); island != island_end; ++island) { 1029 if ((*island).end() == file_format->getText().getSectionData()->end()) 1030 break; 1031 1032 Fragment* exit = (*island).end(); 1033 if (((*island).offset() + (*island).size()) > exit->getOffset()) { 1034 invalid = exit; 1035 pFinished = false; 1036 break; 1037 } 1038 } 1039 1040 // reset the offset of invalid fragments 1041 while (NULL != invalid) { 1042 invalid->setOffset(invalid->getPrevNode()->getOffset() + 1043 invalid->getPrevNode()->size()); 1044 invalid = invalid->getNextNode(); 1045 } 1046 1047 // reset the size of .text 1048 if (isRelaxed) { 1049 file_format->getText().setSize( 1050 file_format->getText().getSectionData()->back().getOffset() + 1051 file_format->getText().getSectionData()->back().size()); 1052 } 1053 return isRelaxed; 1054 } 1055 1056 /// initTargetStubs 1057 bool ARMGNULDBackend::initTargetStubs() 1058 { 1059 if (NULL != getStubFactory()) { 1060 getStubFactory()->addPrototype(new ARMToARMStub(config().isCodeIndep())); 1061 getStubFactory()->addPrototype(new ARMToTHMStub(config().isCodeIndep())); 1062 getStubFactory()->addPrototype(new THMToTHMStub(config().isCodeIndep())); 1063 getStubFactory()->addPrototype(new THMToARMStub(config().isCodeIndep())); 1064 return true; 1065 } 1066 return false; 1067 } 1068 1069 /// doCreateProgramHdrs - backend can implement this function to create the 1070 /// target-dependent segments 1071 void ARMGNULDBackend::doCreateProgramHdrs(Module& pModule) 1072 { 1073 if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) { 1074 // make PT_ARM_EXIDX 1075 ELFSegment* exidx_seg = elfSegmentTable().produce(llvm::ELF::PT_ARM_EXIDX, 1076 llvm::ELF::PF_R); 1077 exidx_seg->addSection(m_pEXIDX); 1078 } 1079 } 1080 1081 namespace mcld { 1082 1083 //===----------------------------------------------------------------------===// 1084 /// createARMLDBackend - the help funtion to create corresponding ARMLDBackend 1085 /// 1086 TargetLDBackend* createARMLDBackend(const llvm::Target& pTarget, 1087 const LinkerConfig& pConfig) 1088 { 1089 if (pConfig.targets().triple().isOSDarwin()) { 1090 assert(0 && "MachO linker is not supported yet"); 1091 /** 1092 return new ARMMachOLDBackend(createARMMachOArchiveReader, 1093 createARMMachOObjectReader, 1094 createARMMachOObjectWriter); 1095 **/ 1096 } 1097 if (pConfig.targets().triple().isOSWindows()) { 1098 assert(0 && "COFF linker is not supported yet"); 1099 /** 1100 return new ARMCOFFLDBackend(createARMCOFFArchiveReader, 1101 createARMCOFFObjectReader, 1102 createARMCOFFObjectWriter); 1103 **/ 1104 } 1105 return new ARMGNULDBackend(pConfig, new ARMGNUInfo(pConfig.targets().triple())); 1106 } 1107 1108 } // namespace of mcld 1109 1110 //===----------------------------------------------------------------------===// 1111 // Force static initialization. 1112 //===----------------------------------------------------------------------===// 1113 extern "C" void MCLDInitializeARMLDBackend() { 1114 // Register the linker backend 1115 mcld::TargetRegistry::RegisterTargetLDBackend(TheARMTarget, createARMLDBackend); 1116 mcld::TargetRegistry::RegisterTargetLDBackend(TheThumbTarget, createARMLDBackend); 1117 } 1118 1119