X86Relocator.cpp revision a790f0a8f3175183bea088389b3e4ae41813e192
1//===- X86Relocator.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 "X86Relocator.h" 10#include "X86RelocationFunctions.h" 11 12#include <mcld/LinkerConfig.h> 13#include <mcld/IRBuilder.h> 14#include <mcld/Support/MsgHandling.h> 15#include <mcld/LD/LDSymbol.h> 16#include <mcld/LD/ELFFileFormat.h> 17#include <mcld/LD/ELFSegmentFactory.h> 18#include <mcld/LD/ELFSegment.h> 19#include <mcld/Object/ObjectBuilder.h> 20 21#include <llvm/ADT/Twine.h> 22#include <llvm/Support/DataTypes.h> 23#include <llvm/Support/ELF.h> 24 25using namespace mcld; 26 27//===--------------------------------------------------------------------===// 28// X86_32 Relocation helper function 29//===--------------------------------------------------------------------===// 30/// helper_DynRel - Get an relocation entry in .rel.dyn 31static 32Relocation& helper_DynRel_init(ResolveInfo* pSym, 33 Fragment& pFrag, 34 uint64_t pOffset, 35 Relocator::Type pType, 36 X86_32Relocator& pParent) 37{ 38 X86_32GNULDBackend& ld_backend = pParent.getTarget(); 39 Relocation& rel_entry = *ld_backend.getRelDyn().create(); 40 rel_entry.setType(pType); 41 rel_entry.targetRef().assign(pFrag, pOffset); 42 if (pType == llvm::ELF::R_386_RELATIVE || NULL == pSym) 43 rel_entry.setSymInfo(NULL); 44 else 45 rel_entry.setSymInfo(pSym); 46 47 return rel_entry; 48} 49 50/// helper_use_relative_reloc - Check if symbol ceuse relocation 51/// R_386_RELATIVE 52static bool 53helper_use_relative_reloc(const ResolveInfo& pSym, 54 const X86_32Relocator& pFactory) 55 56{ 57 // if symbol is dynamic or undefine or preemptible 58 if (pSym.isDyn() || 59 pSym.isUndef() || 60 pFactory.getTarget().isSymbolPreemptible(pSym)) 61 return false; 62 return true; 63} 64 65static 66X86_32GOTEntry& helper_GOT_init(Relocation& pReloc, 67 bool pHasRel, 68 X86_32Relocator& pParent) 69{ 70 // rsym - The relocation target symbol 71 ResolveInfo* rsym = pReloc.symInfo(); 72 X86_32GNULDBackend& ld_backend = pParent.getTarget(); 73 assert(NULL == pParent.getSymGOTMap().lookUp(*rsym)); 74 75 X86_32GOTEntry* got_entry = ld_backend.getGOT().create(); 76 pParent.getSymGOTMap().record(*rsym, *got_entry); 77 78 if (!pHasRel) { 79 // No corresponding dynamic relocation, initialize to the symbol value. 80 got_entry->setValue(X86Relocator::SymVal); 81 } 82 else { 83 // Initialize got_entry content and the corresponding dynamic relocation. 84 if (helper_use_relative_reloc(*rsym, pParent)) { 85 helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_RELATIVE, 86 pParent); 87 got_entry->setValue(X86Relocator::SymVal); 88 } 89 else { 90 helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_GLOB_DAT, 91 pParent); 92 got_entry->setValue(0x0); 93 } 94 } 95 return *got_entry; 96} 97 98static 99Relocator::Address helper_GOT_ORG(X86_32Relocator& pParent) 100{ 101 return pParent.getTarget().getGOTPLT().addr(); 102} 103 104static 105Relocator::Address helper_get_GOT_address(Relocation& pReloc, 106 X86_32Relocator& pParent) 107{ 108 X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); 109 assert(NULL != got_entry); 110 return pParent.getTarget().getGOT().addr() + got_entry->getOffset(); 111} 112 113static 114PLTEntryBase& helper_PLT_init(Relocation& pReloc, X86_32Relocator& pParent) 115{ 116 // rsym - The relocation target symbol 117 ResolveInfo* rsym = pReloc.symInfo(); 118 X86_32GNULDBackend& ld_backend = pParent.getTarget(); 119 assert(NULL == pParent.getSymPLTMap().lookUp(*rsym)); 120 121 PLTEntryBase* plt_entry = ld_backend.getPLT().create(); 122 pParent.getSymPLTMap().record(*rsym, *plt_entry); 123 124 // initialize plt and the corresponding gotplt and dyn rel entry. 125 assert(NULL == pParent.getSymGOTPLTMap().lookUp(*rsym) && 126 "PLT entry not exist, but GOTPLT entry exist!"); 127 X86_32GOTEntry* gotplt_entry = ld_backend.getGOTPLT().create(); 128 pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry); 129 130 // init the corresponding rel entry in .rel.plt 131 Relocation& rel_entry = *ld_backend.getRelPLT().create(); 132 rel_entry.setType(llvm::ELF::R_386_JUMP_SLOT); 133 rel_entry.targetRef().assign(*gotplt_entry); 134 rel_entry.setSymInfo(rsym); 135 return *plt_entry; 136} 137 138static Relocator::Address 139helper_get_PLT_address(ResolveInfo& pSym, X86_32Relocator& pParent) 140{ 141 PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym); 142 assert(NULL != plt_entry); 143 return pParent.getTarget().getPLT().addr() + plt_entry->getOffset(); 144} 145 146//===--------------------------------------------------------------------===// 147// X86_32 Relocation Functions and Tables 148//===--------------------------------------------------------------------===// 149DECL_X86_32_APPLY_RELOC_FUNCS 150 151/// the prototype of applying function 152typedef Relocator::Result (*X86_32ApplyFunctionType)(Relocation& pReloc, 153 X86_32Relocator& pParent); 154 155// the table entry of applying functions 156struct X86_32ApplyFunctionTriple 157{ 158 X86_32ApplyFunctionType func; 159 unsigned int type; 160 const char* name; 161 unsigned int size; 162}; 163 164// declare the table of applying functions 165static const X86_32ApplyFunctionTriple X86_32ApplyFunctions[] = { 166 DECL_X86_32_APPLY_RELOC_FUNC_PTRS 167}; 168 169//===--------------------------------------------------------------------===// 170// X86Relocator 171//===--------------------------------------------------------------------===// 172X86Relocator::X86Relocator(const LinkerConfig& pConfig) 173 : Relocator(pConfig) { 174} 175 176X86Relocator::~X86Relocator() 177{ 178} 179 180void X86Relocator::scanRelocation(Relocation& pReloc, 181 IRBuilder& pLinker, 182 Module& pModule, 183 LDSection& pSection, 184 Input& pInput) 185{ 186 if (LinkerConfig::Object == config().codeGenType()) 187 return; 188 // rsym - The relocation target symbol 189 ResolveInfo* rsym = pReloc.symInfo(); 190 assert(NULL != rsym && 191 "ResolveInfo of relocation not set while scanRelocation"); 192 193 assert(NULL != pSection.getLink()); 194 if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) 195 return; 196 197 // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation 198 // entries should be created. 199 if (rsym->isLocal()) // rsym is local 200 scanLocalReloc(pReloc, pLinker, pModule, pSection); 201 else // rsym is external 202 scanGlobalReloc(pReloc, pLinker, pModule, pSection); 203 204 // check if we should issue undefined reference for the relocation target 205 // symbol 206 if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull()) 207 issueUndefRef(pReloc, pSection, pInput); 208} 209 210void X86Relocator::addCopyReloc(ResolveInfo& pSym, X86GNULDBackend& pTarget) 211{ 212 Relocation& rel_entry = *pTarget.getRelDyn().create(); 213 rel_entry.setType(pTarget.getCopyRelType()); 214 assert(pSym.outSymbol()->hasFragRef()); 215 rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef()); 216 rel_entry.setSymInfo(&pSym); 217} 218 219/// defineSymbolforCopyReloc 220/// For a symbol needing copy relocation, define a copy symbol in the BSS 221/// section and all other reference to this symbol should refer to this 222/// copy. 223/// @note This is executed at `scan relocation' stage. 224LDSymbol& X86Relocator::defineSymbolforCopyReloc(IRBuilder& pBuilder, 225 const ResolveInfo& pSym, 226 X86GNULDBackend& pTarget) 227{ 228 // get or create corresponding BSS LDSection 229 LDSection* bss_sect_hdr = NULL; 230 ELFFileFormat* file_format = pTarget.getOutputFormat(); 231 if (ResolveInfo::ThreadLocal == pSym.type()) 232 bss_sect_hdr = &file_format->getTBSS(); 233 else 234 bss_sect_hdr = &file_format->getBSS(); 235 236 // get or create corresponding BSS SectionData 237 assert(NULL != bss_sect_hdr); 238 SectionData* bss_section = NULL; 239 if (bss_sect_hdr->hasSectionData()) 240 bss_section = bss_sect_hdr->getSectionData(); 241 else 242 bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr); 243 244 // Determine the alignment by the symbol value 245 // FIXME: here we use the largest alignment 246 uint32_t addralign = config().targets().bitclass() / 8; 247 248 // allocate space in BSS for the copy symbol 249 Fragment* frag = new FillFragment(0x0, 1, pSym.size()); 250 uint64_t size = ObjectBuilder::AppendFragment(*frag, 251 *bss_section, 252 addralign); 253 bss_sect_hdr->setSize(bss_sect_hdr->size() + size); 254 255 // change symbol binding to Global if it's a weak symbol 256 ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding(); 257 if (binding == ResolveInfo::Weak) 258 binding = ResolveInfo::Global; 259 260 // Define the copy symbol in the bss section and resolve it 261 LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 262 pSym.name(), 263 (ResolveInfo::Type)pSym.type(), 264 ResolveInfo::Define, 265 binding, 266 pSym.size(), // size 267 0x0, // value 268 FragmentRef::Create(*frag, 0x0), 269 (ResolveInfo::Visibility)pSym.other()); 270 271 // output all other alias symbols if any 272 Module &pModule = pBuilder.getModule(); 273 Module::AliasList* alias_list = pModule.getAliasList(pSym); 274 if (NULL!=alias_list) { 275 Module::alias_iterator it, it_e=alias_list->end(); 276 for (it=alias_list->begin(); it!=it_e; ++it) { 277 const ResolveInfo* alias = *it; 278 if (alias!=&pSym && alias->isDyn()) { 279 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 280 alias->name(), 281 (ResolveInfo::Type)alias->type(), 282 ResolveInfo::Define, 283 binding, 284 alias->size(), // size 285 0x0, // value 286 FragmentRef::Create(*frag, 0x0), 287 (ResolveInfo::Visibility)alias->other()); 288 } 289 } 290 } 291 292 return *cpy_sym; 293} 294 295//===--------------------------------------------------------------------===// 296// X86_32Relocator 297//===--------------------------------------------------------------------===// 298X86_32Relocator::X86_32Relocator(X86_32GNULDBackend& pParent, 299 const LinkerConfig& pConfig) 300 : X86Relocator(pConfig), m_Target(pParent) { 301} 302 303Relocator::Result 304X86_32Relocator::applyRelocation(Relocation& pRelocation) 305{ 306 Relocation::Type type = pRelocation.type(); 307 308 if (type >= sizeof (X86_32ApplyFunctions) / sizeof (X86_32ApplyFunctions[0]) ) { 309 return Unknown; 310 } 311 312 // apply the relocation 313 return X86_32ApplyFunctions[type].func(pRelocation, *this); 314} 315 316const char* X86_32Relocator::getName(Relocation::Type pType) const 317{ 318 return X86_32ApplyFunctions[pType].name; 319} 320 321Relocator::Size X86_32Relocator::getSize(Relocation::Type pType) const 322{ 323 return X86_32ApplyFunctions[pType].size;; 324} 325 326bool 327X86_32Relocator::mayHaveFunctionPointerAccess(const Relocation& pReloc) const 328{ 329 switch (pReloc.type()) { 330 case llvm::ELF::R_386_32: 331 case llvm::ELF::R_386_16: 332 case llvm::ELF::R_386_8: 333 case llvm::ELF::R_386_GOTOFF: 334 case llvm::ELF::R_386_GOT32: { 335 return true; 336 } 337 default: { 338 return false; 339 } 340 } 341} 342 343void X86_32Relocator::scanLocalReloc(Relocation& pReloc, 344 IRBuilder& pBuilder, 345 Module& pModule, 346 LDSection& pSection) 347{ 348 // rsym - The relocation target symbol 349 ResolveInfo* rsym = pReloc.symInfo(); 350 351 switch(pReloc.type()){ 352 353 case llvm::ELF::R_386_32: 354 // If buiding PIC object (shared library or PIC executable), 355 // a dynamic relocations with RELATIVE type to this location is needed. 356 // Reserve an entry in .rel.dyn 357 if (config().isCodeIndep()) { 358 // set Rel bit 359 rsym->setReserved(rsym->reserved() | ReserveRel); 360 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 361 // set up the dyn rel directly 362 helper_DynRel_init(rsym, 363 *pReloc.targetRef().frag(), 364 pReloc.targetRef().offset(), 365 llvm::ELF::R_386_RELATIVE, 366 *this); 367 } 368 return; 369 370 case llvm::ELF::R_386_16: 371 case llvm::ELF::R_386_8: 372 // If buiding PIC object (shared library or PIC executable), 373 // a dynamic relocations with RELATIVE type to this location is needed. 374 // Reserve an entry in .rel.dyn 375 if (config().isCodeIndep()) { 376 // set up the dyn rel directly 377 helper_DynRel_init(rsym, *pReloc.targetRef().frag(), 378 pReloc.targetRef().offset(), pReloc.type(), *this); 379 // set Rel bit 380 rsym->setReserved(rsym->reserved() | ReserveRel); 381 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 382 } 383 return; 384 385 case llvm::ELF::R_386_PLT32: 386 return; 387 388 case llvm::ELF::R_386_GOTOFF: 389 case llvm::ELF::R_386_GOTPC: 390 // FIXME: A GOT section is needed 391 return; 392 393 case llvm::ELF::R_386_GOT32: 394 // Symbol needs GOT entry, reserve entry in .got 395 // return if we already create GOT for this symbol 396 if (rsym->reserved() & ReserveGOT) 397 return; 398 399 // FIXME: check STT_GNU_IFUNC symbol 400 401 // If building shared object or the symbol is undefined, a dynamic 402 // relocation is needed to relocate this GOT entry. Reserve an 403 // entry in .rel.dyn 404 if (LinkerConfig::DynObj == 405 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) { 406 helper_GOT_init(pReloc, true, *this); 407 // set GOT bit 408 rsym->setReserved(rsym->reserved() | ReserveGOT); 409 return; 410 } 411 412 // elsewhere if the GOT is used in statically linked binaries, 413 // the GOT entry is enough and no relocation is needed. 414 helper_GOT_init(pReloc, false, *this); 415 rsym->setReserved(rsym->reserved() | ReserveGOT); 416 return; 417 418 case llvm::ELF::R_386_PC32: 419 case llvm::ELF::R_386_PC16: 420 case llvm::ELF::R_386_PC8: 421 return; 422 423 case llvm::ELF::R_386_TLS_GD: { 424 // FIXME: no linker optimization for TLS relocation 425 if (rsym->reserved() & ReserveGOT) 426 return; 427 428 // define the section symbol for .tdata or .tbss 429 // the target symbol of the created dynamic relocation should be the 430 // section symbol of the section which this symbol defined. so we 431 // need to define that section symbol here 432 ELFFileFormat* file_format = getTarget().getOutputFormat(); 433 const LDSection* sym_sect = 434 &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection(); 435 LDSymbol* sect_sym = NULL; 436 if (&file_format->getTData() == sym_sect) { 437 if (!getTarget().hasTDATASymbol()) { 438 sect_sym = pModule.getSectionSymbolSet().get(*sym_sect); 439 getTarget().setTDATASymbol(*sect_sym); 440 } 441 } 442 else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) { 443 if (!getTarget().hasTBSSSymbol()) { 444 sect_sym = pModule.getSectionSymbolSet().get(*sym_sect); 445 getTarget().setTBSSSymbol(*sect_sym); 446 } 447 } 448 else 449 error(diag::invalid_tls) << rsym->name() << sym_sect->name(); 450 451 // set up a pair of got entries and a dyn rel 452 // set GOT bit 453 rsym->setReserved(rsym->reserved() | ReserveGOT); 454 X86_32GOTEntry* got_entry1 = getTarget().getGOT().create(); 455 X86_32GOTEntry* got_entry2 = getTarget().getGOT().create(); 456 getSymGOTMap().record(*rsym, *got_entry1, *got_entry2); 457 // set up value of got entries, the value of got_entry2 should be the 458 // symbol value, which has to be set during apply relocation 459 got_entry1->setValue(0x0); 460 461 // setup dyn rel for got_entry1 462 Relocation& rel_entry1 = helper_DynRel_init(rsym, *got_entry1, 0x0, 463 llvm::ELF::R_386_TLS_DTPMOD32, *this); 464 // for local tls symbol, add rel entry against the section symbol this 465 // symbol belong to (.tdata or .tbss) 466 rel_entry1.setSymInfo(sect_sym->resolveInfo()); 467 return; 468 } 469 case llvm::ELF::R_386_TLS_LDM: 470 getTLSModuleID(); 471 return; 472 473 case llvm::ELF::R_386_TLS_LDO_32: 474 return; 475 476 case llvm::ELF::R_386_TLS_IE: { 477 getTarget().setHasStaticTLS(); 478 479 // if building shared object, a RELATIVE dynamic relocation is needed 480 if (LinkerConfig::DynObj == config().codeGenType()) { 481 helper_DynRel_init(rsym, *pReloc.targetRef().frag(), 482 pReloc.targetRef().offset(), 483 llvm::ELF::R_386_RELATIVE, *this); 484 rsym->setReserved(rsym->reserved() | ReserveRel); 485 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 486 } 487 else { 488 // for local sym, we can convert ie to le if not building shared object 489 convertTLSIEtoLE(pReloc, pSection); 490 return; 491 } 492 493 if (rsym->reserved() & ReserveGOT) 494 return; 495 496 // set up the got and the corresponding rel entry 497 X86_32GOTEntry* got_entry = getTarget().getGOT().create(); 498 getSymGOTMap().record(*rsym, *got_entry); 499 got_entry->setValue(0x0); 500 helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF, 501 *this); 502 // set GOT bit 503 rsym->setReserved(rsym->reserved() | ReserveGOT); 504 // add symbol to dyn sym table 505 getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol()); 506 return; 507 } 508 509 case llvm::ELF::R_386_TLS_GOTIE: { 510 getTarget().setHasStaticTLS(); 511 if (rsym->reserved() & ReserveGOT) 512 return; 513 // set up the got and the corresponding dyn rel 514 X86_32GOTEntry* got_entry = getTarget().getGOT().create(); 515 getSymGOTMap().record(*rsym, *got_entry); 516 got_entry->setValue(0x0); 517 helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF, 518 *this); 519 // set GOT bit 520 rsym->setReserved(rsym->reserved() | ReserveGOT); 521 getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol()); 522 return; 523 } 524 525 case llvm::ELF::R_386_TLS_LE: 526 case llvm::ELF::R_386_TLS_LE_32: 527 getTarget().setHasStaticTLS(); 528 // if buildint shared object, a dynamic relocation is needed 529 if (LinkerConfig::DynObj == config().codeGenType()) { 530 helper_DynRel_init(rsym, 531 *pReloc.targetRef().frag(), 532 pReloc.targetRef().offset(), 533 llvm::ELF::R_386_TLS_TPOFF, 534 *this); 535 rsym->setReserved(rsym->reserved() | ReserveRel); 536 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 537 // the target symbol of the dynamic relocation is rsym, so we need to 538 // emit it into .dynsym 539 assert(NULL != rsym->outSymbol()); 540 getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol()); 541 } 542 return; 543 544 default: 545 fatal(diag::unsupported_relocation) << (int)pReloc.type() 546 << "mclinker@googlegroups.com"; 547 break; 548 } // end switch 549} 550 551void X86_32Relocator::scanGlobalReloc(Relocation& pReloc, 552 IRBuilder& pBuilder, 553 Module& pModule, 554 LDSection& pSection) 555{ 556 // rsym - The relocation target symbol 557 ResolveInfo* rsym = pReloc.symInfo(); 558 559 switch(pReloc.type()) { 560 case llvm::ELF::R_386_32: 561 case llvm::ELF::R_386_16: 562 case llvm::ELF::R_386_8: 563 // Absolute relocation type, symbol may needs PLT entry or 564 // dynamic relocation entry 565 if (getTarget().symbolNeedsPLT(*rsym)) { 566 // create plt for this symbol if it does not have one 567 if (!(rsym->reserved() & ReservePLT)){ 568 // Symbol needs PLT entry, we need a PLT entry 569 // and the corresponding GOT and dynamic relocation entry 570 // in .got and .rel.plt. 571 helper_PLT_init(pReloc, *this); 572 // set PLT bit 573 rsym->setReserved(rsym->reserved() | ReservePLT); 574 } 575 } 576 577 if (getTarget().symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), 578 true)) { 579 // symbol needs dynamic relocation entry, set up the dynrel entry 580 if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) { 581 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, getTarget()); 582 addCopyReloc(*cpy_sym.resolveInfo(), getTarget()); 583 } 584 else { 585 // set Rel bit and the dyn rel 586 rsym->setReserved(rsym->reserved() | ReserveRel); 587 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 588 if (llvm::ELF::R_386_32 == pReloc.type() && 589 helper_use_relative_reloc(*rsym, *this)) 590 helper_DynRel_init(rsym, 591 *pReloc.targetRef().frag(), 592 pReloc.targetRef().offset(), 593 llvm::ELF::R_386_RELATIVE, 594 *this); 595 else 596 helper_DynRel_init(rsym, 597 *pReloc.targetRef().frag(), 598 pReloc.targetRef().offset(), 599 pReloc.type(), 600 *this); 601 } 602 } 603 return; 604 605 case llvm::ELF::R_386_GOTOFF: 606 case llvm::ELF::R_386_GOTPC: { 607 // FIXME: A GOT section is needed 608 return; 609 } 610 611 case llvm::ELF::R_386_PLT32: 612 // A PLT entry is needed when building shared library 613 614 // return if we already create plt for this symbol 615 if (rsym->reserved() & ReservePLT) 616 return; 617 618 // if the symbol's value can be decided at link time, then no need plt 619 if (getTarget().symbolFinalValueIsKnown(*rsym)) 620 return; 621 622 // if symbol is defined in the ouput file and it's not 623 // preemptible, no need plt 624 if (rsym->isDefine() && !rsym->isDyn() && 625 !getTarget().isSymbolPreemptible(*rsym)) 626 return; 627 628 // Symbol needs PLT entry, we need a PLT entry 629 // and the corresponding GOT and dynamic relocation entry 630 // in .got and .rel.plt 631 helper_PLT_init(pReloc, *this); 632 // set PLT bit 633 rsym->setReserved(rsym->reserved() | ReservePLT); 634 return; 635 636 case llvm::ELF::R_386_GOT32: 637 // Symbol needs GOT entry, reserve entry in .got 638 // return if we already create GOT for this symbol 639 if (rsym->reserved() & ReserveGOT) 640 return; 641 // If building shared object or the symbol is undefined, a dynamic 642 // relocation is needed to relocate this GOT entry. Reserve an 643 // entry in .rel.dyn 644 if (LinkerConfig::DynObj == 645 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) 646 helper_GOT_init(pReloc, true, *this); 647 else 648 helper_GOT_init(pReloc, false, *this); 649 // set GOT bit 650 rsym->setReserved(rsym->reserved() | ReserveGOT); 651 return; 652 653 case llvm::ELF::R_386_PC32: 654 case llvm::ELF::R_386_PC16: 655 case llvm::ELF::R_386_PC8: 656 657 if (getTarget().symbolNeedsPLT(*rsym) && 658 LinkerConfig::DynObj != config().codeGenType()) { 659 // create plt for this symbol if it does not have one 660 if (!(rsym->reserved() & ReservePLT)){ 661 // Symbol needs PLT entry, we need a PLT entry 662 // and the corresponding GOT and dynamic relocation entry 663 // in .got and .rel.plt. 664 // set PLT bit 665 helper_PLT_init(pReloc, *this); 666 rsym->setReserved(rsym->reserved() | ReservePLT); 667 } 668 } 669 670 if (getTarget().symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), 671 false)) { 672 // symbol needs dynamic relocation entry, setup an entry in .rel.dyn 673 if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) { 674 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, 675 getTarget()); 676 addCopyReloc(*cpy_sym.resolveInfo(), getTarget()); 677 } 678 else { 679 // set Rel bit and the dyn rel 680 rsym->setReserved(rsym->reserved() | ReserveRel); 681 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 682 if (llvm::ELF::R_386_32 == pReloc.type() && 683 helper_use_relative_reloc(*rsym, *this)) 684 helper_DynRel_init(rsym, 685 *pReloc.targetRef().frag(), 686 pReloc.targetRef().offset(), 687 llvm::ELF::R_386_RELATIVE, 688 *this); 689 else 690 helper_DynRel_init(rsym, 691 *pReloc.targetRef().frag(), 692 pReloc.targetRef().offset(), 693 pReloc.type(), 694 *this); 695 } 696 } 697 return; 698 699 case llvm::ELF::R_386_TLS_GD: { 700 // FIXME: no linker optimization for TLS relocation 701 if (rsym->reserved() & ReserveGOT) 702 return; 703 704 // set up a pair of got entries and a pair of dyn rel 705 X86_32GOTEntry* got_entry1 = getTarget().getGOT().create(); 706 X86_32GOTEntry* got_entry2 = getTarget().getGOT().create(); 707 getSymGOTMap().record(*rsym, *got_entry1, *got_entry2); 708 got_entry1->setValue(0x0); 709 got_entry2->setValue(0x0); 710 // setup dyn rel for got entries against rsym 711 helper_DynRel_init(rsym, *got_entry1, 0x0, 712 llvm::ELF::R_386_TLS_DTPMOD32, *this); 713 helper_DynRel_init(rsym, *got_entry2, 0x0, 714 llvm::ELF::R_386_TLS_DTPOFF32, *this); 715 716 // add the rsym to dynamic symbol table 717 getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol()); 718 // set GOT bit 719 rsym->setReserved(rsym->reserved() | ReserveGOT); 720 return; 721 } 722 723 case llvm::ELF::R_386_TLS_LDM: 724 getTLSModuleID(); 725 return; 726 727 case llvm::ELF::R_386_TLS_LDO_32: 728 return; 729 730 case llvm::ELF::R_386_TLS_IE: { 731 getTarget().setHasStaticTLS(); 732 // if buildint shared object, a RELATIVE dynamic relocation is needed 733 if (LinkerConfig::DynObj == config().codeGenType()) { 734 helper_DynRel_init(rsym, *pReloc.targetRef().frag(), 735 pReloc.targetRef().offset(), 736 llvm::ELF::R_386_RELATIVE, *this); 737 rsym->setReserved(rsym->reserved() | ReserveRel); 738 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 739 } else { 740 // for global sym, we can convert ie to le if its final value is known 741 if (getTarget().symbolFinalValueIsKnown(*rsym)) { 742 convertTLSIEtoLE(pReloc, pSection); 743 return; 744 } 745 } 746 if (rsym->reserved() & ReserveGOT) 747 return; 748 // set up the got and the corresponding rel entry 749 X86_32GOTEntry* got_entry = getTarget().getGOT().create(); 750 getSymGOTMap().record(*rsym, *got_entry); 751 got_entry->setValue(0x0); 752 helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF, 753 *this); 754 // set GOT bit 755 rsym->setReserved(rsym->reserved() | ReserveGOT); 756 return; 757 } 758 759 case llvm::ELF::R_386_TLS_GOTIE: { 760 getTarget().setHasStaticTLS(); 761 if (rsym->reserved() & ReserveGOT) 762 return; 763 // set up the got and the corresponding dyn rel 764 X86_32GOTEntry* got_entry = getTarget().getGOT().create(); 765 getSymGOTMap().record(*rsym, *got_entry); 766 got_entry->setValue(0x0); 767 helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF, 768 *this); 769 getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol()); 770 // set GOT bit 771 rsym->setReserved(rsym->reserved() | ReserveGOT); 772 return; 773 } 774 775 case llvm::ELF::R_386_TLS_LE: 776 case llvm::ELF::R_386_TLS_LE_32: 777 getTarget().setHasStaticTLS(); 778 // if buildint shared object, a dynamic relocation is needed 779 if (LinkerConfig::DynObj == config().codeGenType()) { 780 helper_DynRel_init(rsym, 781 *pReloc.targetRef().frag(), 782 pReloc.targetRef().offset(), 783 llvm::ELF::R_386_TLS_TPOFF, 784 *this); 785 getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol()); 786 rsym->setReserved(rsym->reserved() | ReserveRel); 787 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 788 } 789 return; 790 791 default: { 792 fatal(diag::unsupported_relocation) << (int)pReloc.type() 793 << "mclinker@googlegroups.com"; 794 break; 795 } 796 } // end switch 797} 798 799// Create a GOT entry for the TLS module index 800X86_32GOTEntry& X86_32Relocator::getTLSModuleID() 801{ 802 static X86_32GOTEntry* got_entry = NULL; 803 if (NULL != got_entry) 804 return *got_entry; 805 806 // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM 807 got_entry = getTarget().getGOT().create(); 808 getTarget().getGOT().create()->setValue(0x0); 809 810 helper_DynRel_init(NULL, *got_entry, 0x0, llvm::ELF::R_386_TLS_DTPMOD32, 811 *this); 812 return *got_entry; 813} 814 815/// convert R_386_TLS_IE to R_386_TLS_LE 816void X86_32Relocator::convertTLSIEtoLE(Relocation& pReloc, 817 LDSection& pSection) 818{ 819 assert(pReloc.type() == llvm::ELF::R_386_TLS_IE); 820 assert(NULL != pReloc.targetRef().frag()); 821 822 // 1. create the new relocs 823 Relocation* reloc = 824 Relocation::Create(X86_32Relocator::R_386_TLS_OPT, 825 *FragmentRef::Create(*pReloc.targetRef().frag(), 826 pReloc.targetRef().offset() - 1), 827 0x0); 828 // FIXME: should we create a special symbol for the tls opt instead? 829 reloc->setSymInfo(pReloc.symInfo()); 830 831 // 2. modify the opcodes to the appropriate ones 832 uint8_t* op = (reinterpret_cast<uint8_t*>(&reloc->target())); 833 if (op[0] == 0xa1) { 834 op[0] = 0xb8; 835 } else { 836 // create the new reloc (move 1 byte forward). 837 reloc = Relocation::Create(X86_32Relocator::R_386_TLS_OPT, 838 *FragmentRef::Create(*pReloc.targetRef().frag(), 839 pReloc.targetRef().offset() - 2), 840 0x0); 841 reloc->setSymInfo(pReloc.symInfo()); 842 op = (reinterpret_cast<uint8_t*>(&reloc->target())); 843 switch (op[0]) { 844 case 0x8b: 845 assert((op[1] & 0xc7) == 0x05); 846 op[0] = 0xc7; 847 op[1] = 0xc0 | ((op[1] >> 3) & 7); 848 break; 849 case 0x03: 850 assert((op[1] & 0xc7) == 0x05); 851 op[0] = 0x81; 852 op[1] = 0xc0 | ((op[1] >> 3) & 7); 853 break; 854 default: 855 assert(0); 856 break; 857 } 858 } 859 860 // 3. insert the new relocs "BEFORE" the original reloc. 861 assert(reloc != NULL); 862 pSection.getRelocData()->getRelocationList().insert( 863 RelocData::iterator(pReloc), reloc); 864 865 // 4. change the type of the original reloc 866 pReloc.setType(llvm::ELF::R_386_TLS_LE); 867} 868 869//================================================// 870// X86_32 Each relocation function implementation // 871//================================================// 872 873// R_386_NONE 874Relocator::Result none(Relocation& pReloc, X86_32Relocator& pParent) 875{ 876 return Relocator::OK; 877} 878 879// R_386_32: S + A 880// R_386_16 881// R_386_8 882Relocator::Result abs(Relocation& pReloc, X86_32Relocator& pParent) 883{ 884 ResolveInfo* rsym = pReloc.symInfo(); 885 Relocator::DWord A = pReloc.target() + pReloc.addend(); 886 Relocator::DWord S = pReloc.symValue(); 887 bool has_dyn_rel = pParent.getTarget().symbolNeedsDynRel( 888 *rsym, 889 (rsym->reserved() & X86Relocator::ReservePLT), 890 true); 891 892 893 LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); 894 // If the flag of target section is not ALLOC, we will not scan this relocation 895 // but perform static relocation. (e.g., applying .debug section) 896 if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { 897 pReloc.target() = S + A; 898 return Relocator::OK; 899 } 900 901 // An external symbol may need PLT and dynamic relocation 902 if (!rsym->isLocal()) { 903 if (rsym->reserved() & X86Relocator::ReservePLT) { 904 S = helper_get_PLT_address(*rsym, pParent); 905 } 906 // If we generate a dynamic relocation (except R_386_RELATIVE) 907 // for a place, we should not perform static relocation on it 908 // in order to keep the addend store in the place correct. 909 if (has_dyn_rel) 910 if (llvm::ELF::R_386_32 != pReloc.type() || 911 (!helper_use_relative_reloc(*rsym, pParent))) 912 return Relocator::OK; 913 } 914 915 // perform static relocation 916 pReloc.target() = S + A; 917 return Relocator::OK; 918} 919 920// R_386_PC32: S + A - P 921// R_386_PC16 922// R_386_PC8 923Relocator::Result rel(Relocation& pReloc, X86_32Relocator& pParent) 924{ 925 ResolveInfo* rsym = pReloc.symInfo(); 926 Relocator::DWord A = pReloc.target() + pReloc.addend(); 927 Relocator::DWord S = pReloc.symValue(); 928 Relocator::DWord P = pReloc.place(); 929 bool has_dyn_rel = pParent.getTarget().symbolNeedsDynRel( 930 *rsym, 931 (rsym->reserved() & X86Relocator::ReservePLT), 932 true); 933 934 LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); 935 // If the flag of target section is not ALLOC, we will not scan this relocation 936 // but perform static relocation. (e.g., applying .debug section) 937 if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { 938 pReloc.target() = S + A - P; 939 return Relocator::OK; 940 } 941 942 // An external symbol may need PLT and dynamic relocation 943 if (!rsym->isLocal()) { 944 if (rsym->reserved() & X86Relocator::ReservePLT) { 945 S = helper_get_PLT_address(*rsym, pParent); 946 pReloc.target() = S + A - P; 947 } 948 if (has_dyn_rel) 949 if (!helper_use_relative_reloc(*rsym, pParent)) 950 return Relocator::OK; 951 } 952 953 // perform static relocation 954 pReloc.target() = S + A - P; 955 return Relocator::OK; 956} 957 958// R_386_GOTOFF: S + A - GOT_ORG 959Relocator::Result gotoff32(Relocation& pReloc, X86_32Relocator& pParent) 960{ 961 Relocator::DWord A = pReloc.target() + pReloc.addend(); 962 Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); 963 Relocator::Address S = pReloc.symValue(); 964 965 pReloc.target() = S + A - GOT_ORG; 966 return Relocator::OK; 967} 968 969// R_386_GOTPC: GOT_ORG + A - P 970Relocator::Result gotpc32(Relocation& pReloc, X86_32Relocator& pParent) 971{ 972 Relocator::DWord A = pReloc.target() + pReloc.addend(); 973 Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); 974 // Apply relocation. 975 pReloc.target() = GOT_ORG + A - pReloc.place(); 976 return Relocator::OK; 977} 978 979// R_386_GOT32: GOT(S) + A - GOT_ORG 980Relocator::Result got32(Relocation& pReloc, X86_32Relocator& pParent) 981{ 982 ResolveInfo* rsym = pReloc.symInfo(); 983 if (!(rsym->reserved() & (X86Relocator::ReserveGOT))) 984 return Relocator::BadReloc; 985 986 // set up got entry value if the got has no dyn rel or 987 // the dyn rel is RELATIVE 988 X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); 989 assert(NULL != got_entry); 990 if (got_entry->getValue() == X86Relocator::SymVal) 991 got_entry->setValue(pReloc.symValue()); 992 993 Relocator::Address GOT_S = helper_get_GOT_address(pReloc, pParent); 994 Relocator::DWord A = pReloc.target() + pReloc.addend(); 995 Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); 996 // Apply relocation. 997 pReloc.target() = GOT_S + A - GOT_ORG; 998 return Relocator::OK; 999} 1000 1001// R_386_PLT32: PLT(S) + A - P 1002Relocator::Result plt32(Relocation& pReloc, X86_32Relocator& pParent) 1003{ 1004 // PLT_S depends on if there is a PLT entry. 1005 Relocator::Address PLT_S; 1006 if ((pReloc.symInfo()->reserved() & X86Relocator::ReservePLT)) 1007 PLT_S = helper_get_PLT_address(*pReloc.symInfo(), pParent); 1008 else 1009 PLT_S = pReloc.symValue(); 1010 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1011 Relocator::Address P = pReloc.place(); 1012 pReloc.target() = PLT_S + A - P; 1013 return Relocator::OK; 1014} 1015 1016// R_386_TLS_GD: 1017Relocator::Result tls_gd(Relocation& pReloc, X86_32Relocator& pParent) 1018{ 1019 // global-dynamic 1020 ResolveInfo* rsym = pReloc.symInfo(); 1021 // must reserve two pairs of got and dynamic relocation 1022 if (!(rsym->reserved() & X86Relocator::ReserveGOT)) 1023 return Relocator::BadReloc; 1024 1025 ELFFileFormat* file_format = pParent.getTarget().getOutputFormat(); 1026 // setup corresponding got and dynamic relocatio entries: 1027 // get first got entry, if there is already a got entry for rsym, then apply 1028 // this relocation to the got entry directly. If not, setup the corresponding 1029 // got and dyn relocation entries 1030 X86_32GOTEntry* got_entry1 = pParent.getSymGOTMap().lookUpFirstEntry(*rsym); 1031 1032 // set the got_entry2 value to symbol value 1033 if (rsym->isLocal()) 1034 pParent.getSymGOTMap().lookUpSecondEntry(*rsym)->setValue(pReloc.symValue()); 1035 1036 // perform relocation to the first got entry 1037 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1038 // GOT_OFF - the offset between the got_entry1 and _GLOBAL_OFFSET_TABLE (the 1039 // .got.plt section) 1040 Relocator::Address GOT_OFF = 1041 file_format->getGOT().addr() + 1042 got_entry1->getOffset() - 1043 file_format->getGOTPLT().addr(); 1044 pReloc.target() = GOT_OFF + A; 1045 return Relocator::OK; 1046} 1047 1048// R_386_TLS_LDM 1049Relocator::Result tls_ldm(Relocation& pReloc, X86_32Relocator& pParent) 1050{ 1051 // FIXME: no linker optimization for TLS relocation 1052 const X86_32GOTEntry& got_entry = pParent.getTLSModuleID(); 1053 1054 // All GOT offsets are relative to the end of the GOT. 1055 X86Relocator::SWord GOT_S = got_entry.getOffset() - 1056 (pParent.getTarget().getGOTPLT().addr() - 1057 pParent.getTarget().getGOT().addr()); 1058 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1059 pReloc.target() = GOT_S + A; 1060 1061 return Relocator::OK; 1062} 1063 1064// R_386_TLS_LDO_32 1065Relocator::Result tls_ldo_32(Relocation& pReloc, X86_32Relocator& pParent) 1066{ 1067 // FIXME: no linker optimization for TLS relocation 1068 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1069 Relocator::Address S = pReloc.symValue(); 1070 pReloc.target() = S + A; 1071 return Relocator::OK; 1072} 1073 1074// R_X86_TLS_IE 1075Relocator::Result tls_ie(Relocation& pReloc, X86_32Relocator& pParent) 1076{ 1077 ResolveInfo* rsym = pReloc.symInfo(); 1078 if (!(rsym->reserved() & X86Relocator::ReserveGOT)) { 1079 return Relocator::BadReloc; 1080 } 1081 1082 // set up the got and dynamic relocation entries if not exist 1083 X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym); 1084 assert(NULL != got_entry); 1085 // perform relocation to the absolute address of got_entry 1086 Relocator::Address GOT_S = 1087 pParent.getTarget().getGOT().addr() + got_entry->getOffset(); 1088 1089 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1090 pReloc.target() = GOT_S + A; 1091 1092 return Relocator::OK; 1093} 1094 1095// R_386_TLS_GOTIE 1096Relocator::Result tls_gotie(Relocation& pReloc, X86_32Relocator& pParent) 1097{ 1098 ResolveInfo* rsym = pReloc.symInfo(); 1099 if (!(rsym->reserved() & X86Relocator::ReserveGOT)) { 1100 return Relocator::BadReloc; 1101 } 1102 1103 // set up the got and dynamic relocation entries if not exist 1104 X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym); 1105 assert(NULL != got_entry); 1106 1107 // All GOT offsets are relative to the end of the GOT. 1108 X86Relocator::SWord GOT_S = got_entry->getOffset() - 1109 (pParent.getTarget().getGOTPLT().addr() - pParent.getTarget().getGOT().addr()); 1110 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1111 pReloc.target() = GOT_S + A; 1112 1113 return Relocator::OK; 1114} 1115 1116// R_X86_TLS_LE 1117Relocator::Result tls_le(Relocation& pReloc, X86_32Relocator& pParent) 1118{ 1119 if (pReloc.symInfo()->reserved() & X86Relocator::ReserveRel) 1120 return Relocator::OK; 1121 1122 // perform static relocation 1123 // get TLS segment 1124 ELFSegmentFactory::const_iterator tls_seg = 1125 pParent.getTarget().elfSegmentTable().find(llvm::ELF::PT_TLS, 1126 llvm::ELF::PF_R, 1127 0x0); 1128 assert(tls_seg != pParent.getTarget().elfSegmentTable().end()); 1129 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1130 Relocator::Address S = pReloc.symValue(); 1131 pReloc.target() = S + A - (*tls_seg)->memsz(); 1132 return Relocator::OK; 1133} 1134 1135Relocator::Result unsupport(Relocation& pReloc, X86_32Relocator& pParent) 1136{ 1137 return Relocator::Unsupport; 1138} 1139 1140//===--------------------------------------------------------------------===// 1141// X86_64 Relocation helper function 1142//===--------------------------------------------------------------------===// 1143/// helper_DynRel - Get an relocation entry in .rela.dyn 1144static 1145Relocation& helper_DynRel_init(ResolveInfo* pSym, 1146 Fragment& pFrag, 1147 uint64_t pOffset, 1148 Relocator::Type pType, 1149 X86_64Relocator& pParent) 1150{ 1151 X86_64GNULDBackend& ld_backend = pParent.getTarget(); 1152 Relocation& rel_entry = *ld_backend.getRelDyn().create(); 1153 rel_entry.setType(pType); 1154 rel_entry.targetRef().assign(pFrag, pOffset); 1155 if (pType == llvm::ELF::R_X86_64_RELATIVE || NULL == pSym) 1156 rel_entry.setSymInfo(NULL); 1157 else 1158 rel_entry.setSymInfo(pSym); 1159 1160 return rel_entry; 1161} 1162 1163 1164/// helper_use_relative_reloc - Check if symbol can use relocation 1165/// R_X86_64_RELATIVE 1166static bool 1167helper_use_relative_reloc(const ResolveInfo& pSym, 1168 const X86_64Relocator& pFactory) 1169 1170{ 1171 // if symbol is dynamic or undefine or preemptible 1172 if (pSym.isDyn() || 1173 pSym.isUndef() || 1174 pFactory.getTarget().isSymbolPreemptible(pSym)) 1175 return false; 1176 return true; 1177} 1178 1179static 1180X86_64GOTEntry& helper_GOT_init(Relocation& pReloc, 1181 bool pHasRel, 1182 X86_64Relocator& pParent) 1183{ 1184 // rsym - The relocation target symbol 1185 ResolveInfo* rsym = pReloc.symInfo(); 1186 X86_64GNULDBackend& ld_backend = pParent.getTarget(); 1187 assert(NULL == pParent.getSymGOTMap().lookUp(*rsym)); 1188 1189 X86_64GOTEntry* got_entry = ld_backend.getGOT().create(); 1190 pParent.getSymGOTMap().record(*rsym, *got_entry); 1191 1192 // If we first get this GOT entry, we should initialize it. 1193 if (!pHasRel) { 1194 // No corresponding dynamic relocation, initialize to the symbol value. 1195 got_entry->setValue(X86Relocator::SymVal); 1196 } 1197 else { 1198 // Initialize got_entry content and the corresponding dynamic relocation. 1199 if (helper_use_relative_reloc(*rsym, pParent)) { 1200 Relocation& rel_entry = helper_DynRel_init(rsym, *got_entry, 0x0, 1201 llvm::ELF::R_X86_64_RELATIVE, pParent); 1202 rel_entry.setAddend(X86Relocator::SymVal); 1203 pParent.getRelRelMap().record(pReloc, rel_entry); 1204 } 1205 else { 1206 helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_X86_64_GLOB_DAT, 1207 pParent); 1208 } 1209 got_entry->setValue(0); 1210 } 1211 return *got_entry; 1212} 1213 1214static 1215Relocator::Address helper_GOT_ORG(X86_64Relocator& pParent) 1216{ 1217 return pParent.getTarget().getGOT().addr(); 1218} 1219 1220static 1221Relocator::Address helper_get_GOT_address(Relocation& pReloc, 1222 X86_64Relocator& pParent) 1223{ 1224 X86_64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); 1225 assert(NULL != got_entry); 1226 return got_entry->getOffset(); 1227} 1228 1229static 1230Relocator::Address helper_get_PLT_address(ResolveInfo& pSym, 1231 X86_64Relocator& pParent) 1232{ 1233 PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym); 1234 assert(NULL != plt_entry); 1235 return pParent.getTarget().getPLT().addr() + plt_entry->getOffset(); 1236} 1237 1238static 1239PLTEntryBase& helper_PLT_init(Relocation& pReloc, X86_64Relocator& pParent) 1240{ 1241 // rsym - The relocation target symbol 1242 ResolveInfo* rsym = pReloc.symInfo(); 1243 X86_64GNULDBackend& ld_backend = pParent.getTarget(); 1244 assert(NULL == pParent.getSymPLTMap().lookUp(*rsym)); 1245 1246 PLTEntryBase* plt_entry = ld_backend.getPLT().create(); 1247 pParent.getSymPLTMap().record(*rsym, *plt_entry); 1248 1249 // initialize plt and the corresponding gotplt and dyn rel entry. 1250 assert(NULL == pParent.getSymGOTPLTMap().lookUp(*rsym) && 1251 "PLT entry not exist, but DynRel entry exist!"); 1252 X86_64GOTEntry* gotplt_entry = ld_backend.getGOTPLT().create(); 1253 pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry); 1254 1255 // init the corresponding rel entry in .rel.plt 1256 Relocation& rel_entry = *ld_backend.getRelPLT().create(); 1257 rel_entry.setType(llvm::ELF::R_X86_64_JUMP_SLOT); 1258 rel_entry.targetRef().assign(*gotplt_entry); 1259 rel_entry.setSymInfo(rsym); 1260 return *plt_entry; 1261} 1262 1263//===--------------------------------------------------------------------===// 1264// X86_64 Relocation Functions and Tables 1265//===--------------------------------------------------------------------===// 1266DECL_X86_64_APPLY_RELOC_FUNCS 1267 1268/// the prototype of applying function 1269typedef Relocator::Result (*X86_64ApplyFunctionType)(Relocation& pReloc, 1270 X86_64Relocator& pParent); 1271 1272// the table entry of applying functions 1273struct X86_64ApplyFunctionTriple 1274{ 1275 X86_64ApplyFunctionType func; 1276 unsigned int type; 1277 const char* name; 1278 unsigned int size; 1279}; 1280 1281// declare the table of applying functions 1282static const X86_64ApplyFunctionTriple X86_64ApplyFunctions[] = { 1283 DECL_X86_64_APPLY_RELOC_FUNC_PTRS 1284}; 1285 1286//===--------------------------------------------------------------------===// 1287// X86_64Relocator 1288//===--------------------------------------------------------------------===// 1289X86_64Relocator::X86_64Relocator(X86_64GNULDBackend& pParent, 1290 const LinkerConfig& pConfig) 1291 : X86Relocator(pConfig), m_Target(pParent) { 1292} 1293 1294Relocator::Result 1295X86_64Relocator::applyRelocation(Relocation& pRelocation) 1296{ 1297 Relocation::Type type = pRelocation.type(); 1298 1299 if (type >= sizeof (X86_64ApplyFunctions) / sizeof (X86_64ApplyFunctions[0]) ) { 1300 return Unknown; 1301 } 1302 1303 // apply the relocation 1304 return X86_64ApplyFunctions[type].func(pRelocation, *this); 1305} 1306 1307const char* X86_64Relocator::getName(Relocation::Type pType) const 1308{ 1309 return X86_64ApplyFunctions[pType].name; 1310} 1311 1312Relocator::Size X86_64Relocator::getSize(Relocation::Type pType) const 1313{ 1314 return X86_64ApplyFunctions[pType].size; 1315} 1316 1317bool 1318X86_64Relocator::mayHaveFunctionPointerAccess(const Relocation& pReloc) const 1319{ 1320 bool possible_funcptr_reloc = false; 1321 switch (pReloc.type()) { 1322 case llvm::ELF::R_X86_64_64: 1323 case llvm::ELF::R_X86_64_32: 1324 case llvm::ELF::R_X86_64_32S: 1325 case llvm::ELF::R_X86_64_16: 1326 case llvm::ELF::R_X86_64_8: 1327 case llvm::ELF::R_X86_64_GOT64: 1328 case llvm::ELF::R_X86_64_GOT32: 1329 case llvm::ELF::R_X86_64_GOTPCREL64: 1330 case llvm::ELF::R_X86_64_GOTPCREL: 1331 case llvm::ELF::R_X86_64_GOTPLT64: { 1332 possible_funcptr_reloc = true; 1333 break; 1334 } 1335 default: { 1336 possible_funcptr_reloc = false; 1337 break; 1338 } 1339 } 1340 1341 if (pReloc.symInfo()->isGlobal()) { 1342 return (config().codeGenType() == LinkerConfig::DynObj) && 1343 ((pReloc.symInfo()->visibility() != ResolveInfo::Default) || 1344 possible_funcptr_reloc); 1345 } else { 1346 return (config().codeGenType() == LinkerConfig::DynObj) || 1347 possible_funcptr_reloc; 1348 } 1349} 1350 1351void X86_64Relocator::scanLocalReloc(Relocation& pReloc, 1352 IRBuilder& pBuilder, 1353 Module& pModule, 1354 LDSection& pSection) 1355{ 1356 // rsym - The relocation target symbol 1357 ResolveInfo* rsym = pReloc.symInfo(); 1358 1359 switch(pReloc.type()){ 1360 case llvm::ELF::R_X86_64_64: 1361 // If buiding PIC object (shared library or PIC executable), 1362 // a dynamic relocations with RELATIVE type to this location is needed. 1363 // Reserve an entry in .rela.dyn 1364 if (config().isCodeIndep()) { 1365 Relocation& reloc = helper_DynRel_init(rsym, 1366 *pReloc.targetRef().frag(), 1367 pReloc.targetRef().offset(), 1368 llvm::ELF::R_X86_64_RELATIVE, 1369 *this); 1370 getRelRelMap().record(pReloc, reloc); 1371 // set Rel bit 1372 rsym->setReserved(rsym->reserved() | ReserveRel); 1373 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 1374 } 1375 return; 1376 1377 case llvm::ELF::R_X86_64_32: 1378 case llvm::ELF::R_X86_64_16: 1379 case llvm::ELF::R_X86_64_8: 1380 case llvm::ELF::R_X86_64_32S: 1381 // If buiding PIC object (shared library or PIC executable), 1382 // a dynamic relocations with RELATIVE type to this location is needed. 1383 // Reserve an entry in .rela.dyn 1384 if (config().isCodeIndep()) { 1385 Relocation& reloc = helper_DynRel_init(rsym, 1386 *pReloc.targetRef().frag(), 1387 pReloc.targetRef().offset(), 1388 pReloc.type(), 1389 *this); 1390 getRelRelMap().record(pReloc, reloc); 1391 // set Rel bit 1392 rsym->setReserved(rsym->reserved() | ReserveRel); 1393 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 1394 } 1395 return; 1396 1397 case llvm::ELF::R_X86_64_PC32: 1398 case llvm::ELF::R_X86_64_PC16: 1399 case llvm::ELF::R_X86_64_PC8: 1400 return; 1401 1402 case llvm::ELF::R_X86_64_GOTPCREL: 1403 // Symbol needs GOT entry, reserve entry in .got 1404 // return if we already create GOT for this symbol 1405 if (rsym->reserved() & ReserveGOT) 1406 return; 1407 1408 // If building shared object or the symbol is undefined, a dynamic 1409 // relocation is needed to relocate this GOT entry. Reserve an 1410 // entry in .rela.dyn 1411 if (LinkerConfig::DynObj == 1412 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) 1413 helper_GOT_init(pReloc, true, *this); 1414 else 1415 helper_GOT_init(pReloc, false, *this); 1416 rsym->setReserved(rsym->reserved() | ReserveGOT); 1417 return; 1418 1419 default: 1420 fatal(diag::unsupported_relocation) << (int)pReloc.type() 1421 << "mclinker@googlegroups.com"; 1422 break; 1423 } // end switch 1424} 1425 1426void X86_64Relocator::scanGlobalReloc(Relocation& pReloc, 1427 IRBuilder& pBuilder, 1428 Module& pModule, 1429 LDSection& pSection) 1430{ 1431 // rsym - The relocation target symbol 1432 ResolveInfo* rsym = pReloc.symInfo(); 1433 1434 switch(pReloc.type()) { 1435 case llvm::ELF::R_X86_64_64: 1436 case llvm::ELF::R_X86_64_32: 1437 case llvm::ELF::R_X86_64_16: 1438 case llvm::ELF::R_X86_64_8: 1439 case llvm::ELF::R_X86_64_32S: 1440 // Absolute relocation type, symbol may needs PLT entry or 1441 // dynamic relocation entry 1442 if (getTarget().symbolNeedsPLT(*rsym)) { 1443 // create plt for this symbol if it does not have one 1444 if (!(rsym->reserved() & ReservePLT)){ 1445 // Symbol needs PLT entry, we need to reserve a PLT entry 1446 // and the corresponding GOT and dynamic relocation entry 1447 // in .got and .rela.plt. 1448 helper_PLT_init(pReloc, *this); 1449 // set PLT bit 1450 rsym->setReserved(rsym->reserved() | ReservePLT); 1451 } 1452 } 1453 1454 if (getTarget().symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), 1455 true)) { 1456 // symbol needs dynamic relocation entry, set up the dynrel entry 1457 if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) { 1458 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, getTarget()); 1459 addCopyReloc(*cpy_sym.resolveInfo(), getTarget()); 1460 } 1461 else { 1462 // set Rel bit and the dyn rel 1463 rsym->setReserved(rsym->reserved() | ReserveRel); 1464 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 1465 if (llvm::ELF::R_386_32 == pReloc.type() && 1466 helper_use_relative_reloc(*rsym, *this)) { 1467 Relocation& reloc = helper_DynRel_init(rsym, 1468 *pReloc.targetRef().frag(), 1469 pReloc.targetRef().offset(), 1470 llvm::ELF::R_X86_64_RELATIVE, 1471 *this); 1472 getRelRelMap().record(pReloc, reloc); 1473 } 1474 else { 1475 Relocation& reloc = helper_DynRel_init(rsym, 1476 *pReloc.targetRef().frag(), 1477 pReloc.targetRef().offset(), 1478 pReloc.type(), 1479 *this); 1480 getRelRelMap().record(pReloc, reloc); 1481 } 1482 getTarget().checkAndSetHasTextRel(*pSection.getLink()); 1483 } 1484 } 1485 return; 1486 1487 case llvm::ELF::R_X86_64_GOTPCREL: 1488 // Symbol needs GOT entry, reserve entry in .got 1489 // return if we already create GOT for this symbol 1490 if (rsym->reserved() & ReserveGOT) 1491 return; 1492 1493 // If building shared object or the symbol is undefined, a dynamic 1494 // relocation is needed to relocate this GOT entry. Reserve an 1495 // entry in .rela.dyn 1496 if (LinkerConfig::DynObj == 1497 config().codeGenType() || rsym->isUndef() || rsym->isDyn()) 1498 helper_GOT_init(pReloc, true, *this); 1499 else 1500 helper_GOT_init(pReloc, false, *this); 1501 // set GOT bit 1502 rsym->setReserved(rsym->reserved() | ReserveGOT); 1503 return; 1504 1505 case llvm::ELF::R_X86_64_PLT32: 1506 // A PLT entry is needed when building shared library 1507 1508 // return if we already create plt for this symbol 1509 if (rsym->reserved() & ReservePLT) 1510 return; 1511 1512 // if the symbol's value can be decided at link time, then no need plt 1513 if (getTarget().symbolFinalValueIsKnown(*rsym)) 1514 return; 1515 1516 // if symbol is defined in the ouput file and it's not 1517 // preemptible, no need plt 1518 if (rsym->isDefine() && !rsym->isDyn() && 1519 !getTarget().isSymbolPreemptible(*rsym)) { 1520 return; 1521 } 1522 1523 // Symbol needs PLT entry, we need a PLT entry 1524 // and the corresponding GOT and dynamic relocation entry 1525 // in .got and .rel.plt. 1526 helper_PLT_init(pReloc, *this); 1527 // set PLT bit 1528 rsym->setReserved(rsym->reserved() | ReservePLT); 1529 return; 1530 1531 case llvm::ELF::R_X86_64_PC32: 1532 case llvm::ELF::R_X86_64_PC16: 1533 case llvm::ELF::R_X86_64_PC8: 1534 if (getTarget().symbolNeedsPLT(*rsym) && 1535 LinkerConfig::DynObj != config().codeGenType()) { 1536 // create plt for this symbol if it does not have one 1537 if (!(rsym->reserved() & ReservePLT)){ 1538 // Symbol needs PLT entry, we need a PLT entry 1539 // and the corresponding GOT and dynamic relocation entry 1540 // in .got and .rel.plt. 1541 helper_PLT_init(pReloc, *this); 1542 // set PLT bit 1543 rsym->setReserved(rsym->reserved() | ReservePLT); 1544 } 1545 } 1546 1547 // Only PC relative relocation against dynamic symbol needs a 1548 // dynamic relocation. Only dynamic copy relocation is allowed 1549 // and PC relative relocation will be resolved to the local copy. 1550 // All other dynamic relocations may lead to run-time relocation 1551 // overflow. 1552 if (getTarget().isDynamicSymbol(*rsym) && 1553 getTarget().symbolNeedsDynRel(*rsym, 1554 (rsym->reserved() & ReservePLT), 1555 false) && 1556 getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) { 1557 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, getTarget()); 1558 addCopyReloc(*cpy_sym.resolveInfo(), getTarget()); 1559 } 1560 return; 1561 1562 default: 1563 fatal(diag::unsupported_relocation) << (int)pReloc.type() 1564 << "mclinker@googlegroups.com"; 1565 break; 1566 } // end switch 1567} 1568 1569// === 1570// 1571// === 1572// R_X86_64_NONE 1573Relocator::Result none(Relocation& pReloc, X86_64Relocator& pParent) 1574{ 1575 return Relocator::OK; 1576} 1577 1578// R_X86_64_64: S + A 1579// R_X86_64_32: 1580// R_X86_64_16: 1581// R_X86_64_8 1582Relocator::Result abs(Relocation& pReloc, X86_64Relocator& pParent) 1583{ 1584 ResolveInfo* rsym = pReloc.symInfo(); 1585 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1586 Relocator::DWord S = pReloc.symValue(); 1587 Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc); 1588 bool has_dyn_rel = (NULL != dyn_rel); 1589 1590 LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); 1591 // If the flag of target section is not ALLOC, we will not scan this relocation 1592 // but perform static relocation. (e.g., applying .debug section) 1593 if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { 1594 pReloc.target() = S + A; 1595 return Relocator::OK; 1596 } 1597 1598 // A local symbol may need RELA Type dynamic relocation 1599 if (rsym->isLocal() && has_dyn_rel) { 1600 dyn_rel->setAddend(S + A); 1601 return Relocator::OK; 1602 } 1603 1604 // An external symbol may need PLT and dynamic relocation 1605 if (!rsym->isLocal()) { 1606 if (rsym->reserved() & X86Relocator::ReservePLT) { 1607 S = helper_get_PLT_address(*rsym, pParent); 1608 } 1609 // If we generate a dynamic relocation (except R_X86_64_RELATIVE) 1610 // for a place, we should not perform static relocation on it 1611 // in order to keep the addend store in the place correct. 1612 if (has_dyn_rel) { 1613 if (llvm::ELF::R_X86_64_64 == pReloc.type() && 1614 helper_use_relative_reloc(*rsym, pParent)) { 1615 dyn_rel->setAddend(S + A); 1616 } 1617 else { 1618 dyn_rel->setAddend(A); 1619 return Relocator::OK; 1620 } 1621 } 1622 } 1623 1624 // perform static relocation 1625 pReloc.target() = S + A; 1626 return Relocator::OK; 1627} 1628 1629// R_X86_64_32S: S + A 1630Relocator::Result signed32(Relocation& pReloc, X86_64Relocator& pParent) 1631{ 1632 ResolveInfo* rsym = pReloc.symInfo(); 1633 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1634 Relocator::DWord S = pReloc.symValue(); 1635 1636 // There should be no dynamic relocations for R_X86_64_32S. 1637 if (NULL != pParent.getRelRelMap().lookUp(pReloc)) 1638 return Relocator::BadReloc; 1639 1640 LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); 1641 // If the flag of target section is not ALLOC, we will not scan this relocation 1642 // but perform static relocation. (e.g., applying .debug section) 1643 // An external symbol may need PLT and dynamic relocation 1644 if (0x0 != (llvm::ELF::SHF_ALLOC & target_sect.flag()) && 1645 !rsym->isLocal() && rsym->reserved() & X86Relocator::ReservePLT) 1646 S = helper_get_PLT_address(*rsym, pParent); 1647 1648#if notyet 1649 // Check 32-bit signed overflow. 1650 Relocator::SWord V = S + A; 1651 if (V > INT64_C(0x7fffffff) || V < INT64_C(-0x80000000)) 1652 return Relocator::Overflow; 1653#endif 1654 1655 // perform static relocation 1656 pReloc.target() = S + A; 1657 return Relocator::OK; 1658} 1659 1660// R_X86_64_GOTPCREL: GOT(S) + GOT_ORG + A - P 1661Relocator::Result gotpcrel(Relocation& pReloc, X86_64Relocator& pParent) 1662{ 1663 if (!(pReloc.symInfo()->reserved() & X86Relocator::ReserveGOT)) { 1664 return Relocator::BadReloc; 1665 } 1666 1667 // set symbol value of the got entry if needed 1668 X86_64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); 1669 if (X86Relocator::SymVal == got_entry->getValue()) 1670 got_entry->setValue(pReloc.symValue()); 1671 1672 // setup relocation addend if needed 1673 Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc); 1674 if ((NULL != dyn_rel) && (X86Relocator::SymVal == dyn_rel->addend())) { 1675 dyn_rel->setAddend(pReloc.symValue()); 1676 } 1677 1678 Relocator::Address GOT_S = helper_get_GOT_address(pReloc, pParent); 1679 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1680 Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); 1681 // Apply relocation. 1682 pReloc.target() = GOT_S + GOT_ORG + A - pReloc.place(); 1683 return Relocator::OK; 1684} 1685 1686// R_X86_64_PLT32: PLT(S) + A - P 1687Relocator::Result plt32(Relocation& pReloc, X86_64Relocator& pParent) 1688{ 1689 // PLT_S depends on if there is a PLT entry. 1690 Relocator::Address PLT_S; 1691 if ((pReloc.symInfo()->reserved() & X86Relocator::ReservePLT)) 1692 PLT_S = helper_get_PLT_address(*pReloc.symInfo(), pParent); 1693 else 1694 PLT_S = pReloc.symValue(); 1695 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1696 Relocator::Address P = pReloc.place(); 1697 pReloc.target() = PLT_S + A - P; 1698 return Relocator::OK; 1699} 1700 1701// R_X86_64_PC32: S + A - P 1702// R_X86_64_PC16 1703// R_X86_64_PC8 1704Relocator::Result rel(Relocation& pReloc, X86_64Relocator& pParent) 1705{ 1706 ResolveInfo* rsym = pReloc.symInfo(); 1707 Relocator::DWord A = pReloc.target() + pReloc.addend(); 1708 Relocator::DWord S = pReloc.symValue(); 1709 Relocator::DWord P = pReloc.place(); 1710 1711 LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); 1712 // If the flag of target section is not ALLOC, we will not scan this relocation 1713 // but perform static relocation. (e.g., applying .debug section) 1714 if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { 1715 pReloc.target() = S + A - P; 1716 return Relocator::OK; 1717 } 1718 1719 // setup relocation addend if needed 1720 Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc); 1721 if ((NULL != dyn_rel) && (X86Relocator::SymVal == dyn_rel->addend())) { 1722 dyn_rel->setAddend(S); 1723 } 1724 1725 // An external symbol may need PLT and dynamic relocation 1726 if (!rsym->isLocal()) { 1727 if (rsym->reserved() & X86Relocator::ReservePLT) { 1728 S = helper_get_PLT_address(*rsym, pParent); 1729 } 1730 if (pParent.getTarget().symbolNeedsDynRel( 1731 *rsym, 1732 (rsym->reserved() & X86Relocator::ReservePLT), 1733 false)) { 1734 return Relocator::Overflow; 1735 } 1736 } 1737 1738 // perform static relocation 1739 pReloc.target() = S + A - P; 1740 return Relocator::OK; 1741} 1742 1743Relocator::Result unsupport(Relocation& pReloc, X86_64Relocator& pParent) 1744{ 1745 return Relocator::Unsupport; 1746} 1747