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