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