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