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