1 //===- Target.cpp ---------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Machine-specific things, such as applying relocations, creation of 11 // GOT or PLT entries, etc., are handled in this file. 12 // 13 // Refer the ELF spec for the single letter varaibles, S, A or P, used 14 // in this file. SA is S+A. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #include "Target.h" 19 #include "Error.h" 20 #include "OutputSections.h" 21 #include "Symbols.h" 22 23 #include "llvm/ADT/ArrayRef.h" 24 #include "llvm/Object/ELF.h" 25 #include "llvm/Support/Endian.h" 26 #include "llvm/Support/ELF.h" 27 28 using namespace llvm; 29 using namespace llvm::object; 30 using namespace llvm::support::endian; 31 using namespace llvm::ELF; 32 33 namespace lld { 34 namespace elf2 { 35 36 std::unique_ptr<TargetInfo> Target; 37 38 template <endianness E> static void add32(void *P, int32_t V) { 39 write32<E>(P, read32<E>(P) + V); 40 } 41 42 static void add32le(uint8_t *P, int32_t V) { add32<support::little>(P, V); } 43 static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); } 44 45 template <unsigned N> static void checkInt(int64_t V, uint32_t Type) { 46 if (isInt<N>(V)) 47 return; 48 StringRef S = getELFRelocationTypeName(Config->EMachine, Type); 49 error("Relocation " + S + " out of range"); 50 } 51 52 template <unsigned N> static void checkUInt(uint64_t V, uint32_t Type) { 53 if (isUInt<N>(V)) 54 return; 55 StringRef S = getELFRelocationTypeName(Config->EMachine, Type); 56 error("Relocation " + S + " out of range"); 57 } 58 59 template <unsigned N> static void checkIntUInt(uint64_t V, uint32_t Type) { 60 if (isInt<N>(V) || isUInt<N>(V)) 61 return; 62 StringRef S = getELFRelocationTypeName(Config->EMachine, Type); 63 error("Relocation " + S + " out of range"); 64 } 65 66 template <unsigned N> static void checkAlignment(uint64_t V, uint32_t Type) { 67 if ((V & (N - 1)) == 0) 68 return; 69 StringRef S = getELFRelocationTypeName(Config->EMachine, Type); 70 error("Improper alignment for relocation " + S); 71 } 72 73 template <class ELFT> bool isGnuIFunc(const SymbolBody &S) { 74 if (auto *SS = dyn_cast<DefinedElf<ELFT>>(&S)) 75 return SS->Sym.getType() == STT_GNU_IFUNC; 76 return false; 77 } 78 79 template bool isGnuIFunc<ELF32LE>(const SymbolBody &S); 80 template bool isGnuIFunc<ELF32BE>(const SymbolBody &S); 81 template bool isGnuIFunc<ELF64LE>(const SymbolBody &S); 82 template bool isGnuIFunc<ELF64BE>(const SymbolBody &S); 83 84 namespace { 85 class X86TargetInfo final : public TargetInfo { 86 public: 87 X86TargetInfo(); 88 void writeGotPltHeaderEntries(uint8_t *Buf) const override; 89 unsigned getDynReloc(unsigned Type) const override; 90 unsigned getTlsGotReloc(unsigned Type) const override; 91 bool isTlsDynReloc(unsigned Type, const SymbolBody &S) const override; 92 void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; 93 void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 94 uint64_t PltEntryAddr) const override; 95 void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr, 96 uint64_t PltEntryAddr, int32_t Index, 97 unsigned RelOff) const override; 98 bool needsCopyRel(uint32_t Type, const SymbolBody &S) const override; 99 bool relocNeedsDynRelative(unsigned Type) const override; 100 bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; 101 bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; 102 void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, 103 uint64_t SA, uint64_t ZA = 0, 104 uint8_t *PairedLoc = nullptr) const override; 105 bool isTlsOptimized(unsigned Type, const SymbolBody *S) const override; 106 unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 107 uint64_t P, uint64_t SA, 108 const SymbolBody &S) const override; 109 bool isGotRelative(uint32_t Type) const override; 110 111 private: 112 void relocateTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 113 uint64_t SA) const; 114 void relocateTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 115 uint64_t SA) const; 116 void relocateTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 117 uint64_t SA) const; 118 void relocateTlsIeToLe(unsigned Type, uint8_t *Loc, uint8_t *BufEnd, 119 uint64_t P, uint64_t SA) const; 120 }; 121 122 class X86_64TargetInfo final : public TargetInfo { 123 public: 124 X86_64TargetInfo(); 125 bool isTlsDynReloc(unsigned Type, const SymbolBody &S) const override; 126 void writeGotPltHeaderEntries(uint8_t *Buf) const override; 127 void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; 128 void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 129 uint64_t PltEntryAddr) const override; 130 void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr, 131 uint64_t PltEntryAddr, int32_t Index, 132 unsigned RelOff) const override; 133 bool needsCopyRel(uint32_t Type, const SymbolBody &S) const override; 134 bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; 135 bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; 136 void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, 137 uint64_t SA, uint64_t ZA = 0, 138 uint8_t *PairedLoc = nullptr) const override; 139 bool isRelRelative(uint32_t Type) const override; 140 bool isTlsOptimized(unsigned Type, const SymbolBody *S) const override; 141 bool isSizeReloc(uint32_t Type) const override; 142 unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 143 uint64_t P, uint64_t SA, 144 const SymbolBody &S) const override; 145 146 private: 147 void relocateTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 148 uint64_t SA) const; 149 void relocateTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 150 uint64_t SA) const; 151 void relocateTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 152 uint64_t SA) const; 153 void relocateTlsIeToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 154 uint64_t SA) const; 155 }; 156 157 class PPCTargetInfo final : public TargetInfo { 158 public: 159 PPCTargetInfo(); 160 void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; 161 void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 162 uint64_t PltEntryAddr) const override; 163 void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr, 164 uint64_t PltEntryAddr, int32_t Index, 165 unsigned RelOff) const override; 166 bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; 167 bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; 168 void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, 169 uint64_t SA, uint64_t ZA = 0, 170 uint8_t *PairedLoc = nullptr) const override; 171 bool isRelRelative(uint32_t Type) const override; 172 }; 173 174 class PPC64TargetInfo final : public TargetInfo { 175 public: 176 PPC64TargetInfo(); 177 void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; 178 void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 179 uint64_t PltEntryAddr) const override; 180 void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr, 181 uint64_t PltEntryAddr, int32_t Index, 182 unsigned RelOff) const override; 183 bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; 184 bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; 185 void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, 186 uint64_t SA, uint64_t ZA = 0, 187 uint8_t *PairedLoc = nullptr) const override; 188 bool isRelRelative(uint32_t Type) const override; 189 }; 190 191 class AArch64TargetInfo final : public TargetInfo { 192 public: 193 AArch64TargetInfo(); 194 unsigned getDynReloc(unsigned Type) const override; 195 void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; 196 void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 197 uint64_t PltEntryAddr) const override; 198 void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr, 199 uint64_t PltEntryAddr, int32_t Index, 200 unsigned RelOff) const override; 201 bool needsCopyRel(uint32_t Type, const SymbolBody &S) const override; 202 bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; 203 bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; 204 void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, 205 uint64_t SA, uint64_t ZA = 0, 206 uint8_t *PairedLoc = nullptr) const override; 207 }; 208 209 class AMDGPUTargetInfo final : public TargetInfo { 210 public: 211 AMDGPUTargetInfo(); 212 void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; 213 void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 214 uint64_t PltEntryAddr) const override; 215 void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr, 216 uint64_t PltEntryAddr, int32_t Index, 217 unsigned RelOff) const override; 218 bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; 219 bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; 220 void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, 221 uint64_t SA, uint64_t ZA = 0, 222 uint8_t *PairedLoc = nullptr) const override; 223 }; 224 225 template <class ELFT> class MipsTargetInfo final : public TargetInfo { 226 public: 227 MipsTargetInfo(); 228 void writeGotHeaderEntries(uint8_t *Buf) const override; 229 void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; 230 void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 231 uint64_t PltEntryAddr) const override; 232 void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr, 233 uint64_t PltEntryAddr, int32_t Index, 234 unsigned RelOff) const override; 235 bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; 236 bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; 237 void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, 238 uint64_t SA, uint64_t ZA = 0, 239 uint8_t *PairedLoc = nullptr) const override; 240 bool isRelRelative(uint32_t Type) const override; 241 }; 242 } // anonymous namespace 243 244 TargetInfo *createTarget() { 245 switch (Config->EMachine) { 246 case EM_386: 247 return new X86TargetInfo(); 248 case EM_AARCH64: 249 return new AArch64TargetInfo(); 250 case EM_AMDGPU: 251 return new AMDGPUTargetInfo(); 252 case EM_MIPS: 253 switch (Config->EKind) { 254 case ELF32LEKind: 255 return new MipsTargetInfo<ELF32LE>(); 256 case ELF32BEKind: 257 return new MipsTargetInfo<ELF32BE>(); 258 default: 259 error("Unsupported MIPS target"); 260 } 261 case EM_PPC: 262 return new PPCTargetInfo(); 263 case EM_PPC64: 264 return new PPC64TargetInfo(); 265 case EM_X86_64: 266 return new X86_64TargetInfo(); 267 } 268 error("Unknown target machine"); 269 } 270 271 TargetInfo::~TargetInfo() {} 272 273 bool TargetInfo::isTlsOptimized(unsigned Type, const SymbolBody *S) const { 274 return false; 275 } 276 277 uint64_t TargetInfo::getVAStart() const { return Config->Shared ? 0 : VAStart; } 278 279 bool TargetInfo::needsCopyRel(uint32_t Type, const SymbolBody &S) const { 280 return false; 281 } 282 283 bool TargetInfo::isGotRelative(uint32_t Type) const { return false; } 284 285 bool TargetInfo::isRelRelative(uint32_t Type) const { return true; } 286 287 bool TargetInfo::isSizeReloc(uint32_t Type) const { return false; } 288 289 unsigned TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, 290 uint32_t Type, uint64_t P, uint64_t SA, 291 const SymbolBody &S) const { 292 return 0; 293 } 294 295 void TargetInfo::writeGotHeaderEntries(uint8_t *Buf) const {} 296 297 void TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {} 298 299 X86TargetInfo::X86TargetInfo() { 300 CopyReloc = R_386_COPY; 301 PCRelReloc = R_386_PC32; 302 GotReloc = R_386_GLOB_DAT; 303 PltReloc = R_386_JUMP_SLOT; 304 IRelativeReloc = R_386_IRELATIVE; 305 RelativeReloc = R_386_RELATIVE; 306 TlsGotReloc = R_386_TLS_TPOFF; 307 TlsGlobalDynamicReloc = R_386_TLS_GD; 308 TlsLocalDynamicReloc = R_386_TLS_LDM; 309 TlsModuleIndexReloc = R_386_TLS_DTPMOD32; 310 TlsOffsetReloc = R_386_TLS_DTPOFF32; 311 LazyRelocations = true; 312 PltEntrySize = 16; 313 PltZeroEntrySize = 16; 314 } 315 316 void X86TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const { 317 write32le(Buf, Out<ELF32LE>::Dynamic->getVA()); 318 } 319 320 void X86TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const { 321 // Skip 6 bytes of "pushl (GOT+4)" 322 write32le(Buf, Plt + 6); 323 } 324 325 unsigned X86TargetInfo::getDynReloc(unsigned Type) const { 326 if (Type == R_386_TLS_LE) 327 return R_386_TLS_TPOFF; 328 if (Type == R_386_TLS_LE_32) 329 return R_386_TLS_TPOFF32; 330 return Type; 331 } 332 333 unsigned X86TargetInfo::getTlsGotReloc(unsigned Type) const { 334 if (Type == R_386_TLS_IE) 335 return Type; 336 return TlsGotReloc; 337 } 338 339 bool X86TargetInfo::isTlsDynReloc(unsigned Type, const SymbolBody &S) const { 340 if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || 341 Type == R_386_TLS_GOTIE) 342 return Config->Shared; 343 if (Type == R_386_TLS_IE) 344 return canBePreempted(&S, true); 345 return Type == R_386_TLS_GD; 346 } 347 348 void X86TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 349 uint64_t PltEntryAddr) const { 350 // Executable files and shared object files have 351 // separate procedure linkage tables. 352 if (Config->Shared) { 353 const uint8_t V[] = { 354 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx) 355 0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx) 356 0x90, 0x90, 0x90, 0x90 // nop;nop;nop;nop 357 }; 358 memcpy(Buf, V, sizeof(V)); 359 return; 360 } 361 362 const uint8_t PltData[] = { 363 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushl (GOT+4) 364 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *(GOT+8) 365 0x90, 0x90, 0x90, 0x90 // nop;nop;nop;nop 366 }; 367 memcpy(Buf, PltData, sizeof(PltData)); 368 write32le(Buf + 2, GotEntryAddr + 4); // GOT+4 369 write32le(Buf + 8, GotEntryAddr + 8); // GOT+8 370 } 371 372 void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr, 373 uint64_t GotEntryAddr, uint64_t PltEntryAddr, 374 int32_t Index, unsigned RelOff) const { 375 const uint8_t Inst[] = { 376 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // jmp *foo_in_GOT|*foo@GOT(%ebx) 377 0x68, 0x00, 0x00, 0x00, 0x00, // pushl $reloc_offset 378 0xe9, 0x00, 0x00, 0x00, 0x00 // jmp .PLT0@PC 379 }; 380 memcpy(Buf, Inst, sizeof(Inst)); 381 // jmp *foo@GOT(%ebx) or jmp *foo_in_GOT 382 Buf[1] = Config->Shared ? 0xa3 : 0x25; 383 write32le(Buf + 2, Config->Shared ? (GotEntryAddr - GotAddr) : GotEntryAddr); 384 write32le(Buf + 7, RelOff); 385 write32le(Buf + 12, -Index * PltEntrySize - PltZeroEntrySize - 16); 386 } 387 388 bool X86TargetInfo::needsCopyRel(uint32_t Type, const SymbolBody &S) const { 389 if (Type == R_386_32 || Type == R_386_16 || Type == R_386_8) 390 if (auto *SS = dyn_cast<SharedSymbol<ELF32LE>>(&S)) 391 return SS->Sym.getType() == STT_OBJECT; 392 return false; 393 } 394 395 bool X86TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { 396 if (S.isTls() && Type == R_386_TLS_GD) 397 return Target->isTlsOptimized(Type, &S) && canBePreempted(&S, true); 398 if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE) 399 return !isTlsOptimized(Type, &S); 400 return Type == R_386_GOT32 || relocNeedsPlt(Type, S); 401 } 402 403 bool X86TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const { 404 return isGnuIFunc<ELF32LE>(S) || 405 (Type == R_386_PLT32 && canBePreempted(&S, true)) || 406 (Type == R_386_PC32 && S.isShared()); 407 } 408 409 bool X86TargetInfo::isGotRelative(uint32_t Type) const { 410 // This relocation does not require got entry, 411 // but it is relative to got and needs it to be created. 412 // Here we request for that. 413 return Type == R_386_GOTOFF; 414 } 415 416 void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 417 uint64_t P, uint64_t SA, uint64_t ZA, 418 uint8_t *PairedLoc) const { 419 switch (Type) { 420 case R_386_32: 421 add32le(Loc, SA); 422 break; 423 case R_386_GOT32: 424 case R_386_GOTOFF: 425 add32le(Loc, SA - Out<ELF32LE>::Got->getVA()); 426 break; 427 case R_386_GOTPC: 428 add32le(Loc, SA + Out<ELF32LE>::Got->getVA() - P); 429 break; 430 case R_386_PC32: 431 case R_386_PLT32: 432 add32le(Loc, SA - P); 433 break; 434 case R_386_TLS_GD: 435 case R_386_TLS_LDM: 436 case R_386_TLS_TPOFF: { 437 uint64_t V = SA - Out<ELF32LE>::Got->getVA() - 438 Out<ELF32LE>::Got->getNumEntries() * 4; 439 checkInt<32>(V, Type); 440 write32le(Loc, V); 441 break; 442 } 443 case R_386_TLS_IE: 444 case R_386_TLS_LDO_32: 445 write32le(Loc, SA); 446 break; 447 case R_386_TLS_LE: 448 write32le(Loc, SA - Out<ELF32LE>::TlsPhdr->p_memsz); 449 break; 450 case R_386_TLS_LE_32: 451 write32le(Loc, Out<ELF32LE>::TlsPhdr->p_memsz - SA); 452 break; 453 default: 454 error("unrecognized reloc " + Twine(Type)); 455 } 456 } 457 458 bool X86TargetInfo::isTlsOptimized(unsigned Type, const SymbolBody *S) const { 459 if (Config->Shared || (S && !S->isTls())) 460 return false; 461 return Type == R_386_TLS_LDO_32 || Type == R_386_TLS_LDM || 462 Type == R_386_TLS_GD || 463 (Type == R_386_TLS_IE && !canBePreempted(S, true)) || 464 (Type == R_386_TLS_GOTIE && !canBePreempted(S, true)); 465 } 466 467 bool X86TargetInfo::relocNeedsDynRelative(unsigned Type) const { 468 return Config->Shared && Type == R_386_TLS_IE; 469 } 470 471 unsigned X86TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, 472 uint32_t Type, uint64_t P, 473 uint64_t SA, 474 const SymbolBody &S) const { 475 switch (Type) { 476 case R_386_TLS_GD: 477 if (canBePreempted(&S, true)) 478 relocateTlsGdToIe(Loc, BufEnd, P, SA); 479 else 480 relocateTlsGdToLe(Loc, BufEnd, P, SA); 481 // The next relocation should be against __tls_get_addr, so skip it 482 return 1; 483 case R_386_TLS_GOTIE: 484 case R_386_TLS_IE: 485 relocateTlsIeToLe(Type, Loc, BufEnd, P, SA); 486 return 0; 487 case R_386_TLS_LDM: 488 relocateTlsLdToLe(Loc, BufEnd, P, SA); 489 // The next relocation should be against __tls_get_addr, so skip it 490 return 1; 491 case R_386_TLS_LDO_32: 492 relocateOne(Loc, BufEnd, R_386_TLS_LE, P, SA); 493 return 0; 494 } 495 llvm_unreachable("Unknown TLS optimization"); 496 } 497 498 // "Ulrich Drepper, ELF Handling For Thread-Local Storage" (5.1 499 // IA-32 Linker Optimizations, http://www.akkadia.org/drepper/tls.pdf) shows 500 // how GD can be optimized to IE: 501 // leal x@tlsgd(, %ebx, 1), 502 // call __tls_get_addr@plt 503 // Is converted to: 504 // movl %gs:0, %eax 505 // addl x@gotntpoff(%ebx), %eax 506 void X86TargetInfo::relocateTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 507 uint64_t SA) const { 508 const uint8_t Inst[] = { 509 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax 510 0x03, 0x83, 0x00, 0x00, 0x00, 0x00 // addl 0(%ebx), %eax 511 }; 512 memcpy(Loc - 3, Inst, sizeof(Inst)); 513 relocateOne(Loc + 5, BufEnd, R_386_32, P, 514 SA - Out<ELF32LE>::Got->getVA() - 515 Out<ELF32LE>::Got->getNumEntries() * 4); 516 } 517 518 // GD can be optimized to LE: 519 // leal x@tlsgd(, %ebx, 1), 520 // call __tls_get_addr@plt 521 // Can be converted to: 522 // movl %gs:0,%eax 523 // addl $x@ntpoff,%eax 524 // But gold emits subl $foo@tpoff,%eax instead of addl. 525 // These instructions are completely equal in behavior. 526 // This method generates subl to be consistent with gold. 527 void X86TargetInfo::relocateTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 528 uint64_t SA) const { 529 const uint8_t Inst[] = { 530 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax 531 0x81, 0xe8, 0x00, 0x00, 0x00, 0x00 // subl 0(%ebx), %eax 532 }; 533 memcpy(Loc - 3, Inst, sizeof(Inst)); 534 relocateOne(Loc + 5, BufEnd, R_386_32, P, 535 Out<ELF32LE>::TlsPhdr->p_memsz - SA); 536 } 537 538 // LD can be optimized to LE: 539 // leal foo(%reg),%eax 540 // call ___tls_get_addr 541 // Is converted to: 542 // movl %gs:0,%eax 543 // nop 544 // leal 0(%esi,1),%esi 545 void X86TargetInfo::relocateTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, 546 uint64_t SA) const { 547 const uint8_t Inst[] = { 548 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0,%eax 549 0x90, // nop 550 0x8d, 0x74, 0x26, 0x00 // leal 0(%esi,1),%esi 551 }; 552 memcpy(Loc - 2, Inst, sizeof(Inst)); 553 } 554 555 // In some conditions, relocations can be optimized to avoid using GOT. 556 // This function does that for Initial Exec to Local Exec case. 557 // Read "ELF Handling For Thread-Local Storage, 5.1 558 // IA-32 Linker Optimizations" (http://www.akkadia.org/drepper/tls.pdf) 559 // by Ulrich Drepper for details. 560 void X86TargetInfo::relocateTlsIeToLe(unsigned Type, uint8_t *Loc, 561 uint8_t *BufEnd, uint64_t P, 562 uint64_t SA) const { 563 // Ulrich's document section 6.2 says that @gotntpoff can 564 // be used with MOVL or ADDL instructions. 565 // @indntpoff is similar to @gotntpoff, but for use in 566 // position dependent code. 567 uint8_t *Inst = Loc - 2; 568 uint8_t *Op = Loc - 1; 569 uint8_t Reg = (Loc[-1] >> 3) & 7; 570 bool IsMov = *Inst == 0x8b; 571 if (Type == R_386_TLS_IE) { 572 // For R_386_TLS_IE relocation we perform the next transformations: 573 // MOVL foo@INDNTPOFF,%EAX is transformed to MOVL $foo,%EAX 574 // MOVL foo@INDNTPOFF,%REG is transformed to MOVL $foo,%REG 575 // ADDL foo@INDNTPOFF,%REG is transformed to ADDL $foo,%REG 576 // First one is special because when EAX is used the sequence is 5 bytes 577 // long, otherwise it is 6 bytes. 578 if (*Op == 0xa1) { 579 *Op = 0xb8; 580 } else { 581 *Inst = IsMov ? 0xc7 : 0x81; 582 *Op = 0xc0 | ((*Op >> 3) & 7); 583 } 584 } else { 585 // R_386_TLS_GOTIE relocation can be optimized to 586 // R_386_TLS_LE so that it does not use GOT. 587 // "MOVL foo@GOTTPOFF(%RIP), %REG" is transformed to "MOVL $foo, %REG". 588 // "ADDL foo@GOTNTPOFF(%RIP), %REG" is transformed to "LEAL foo(%REG), %REG" 589 // Note: gold converts to ADDL instead of LEAL. 590 *Inst = IsMov ? 0xc7 : 0x8d; 591 if (IsMov) 592 *Op = 0xc0 | ((*Op >> 3) & 7); 593 else 594 *Op = 0x80 | Reg | (Reg << 3); 595 } 596 relocateOne(Loc, BufEnd, R_386_TLS_LE, P, SA); 597 } 598 599 X86_64TargetInfo::X86_64TargetInfo() { 600 CopyReloc = R_X86_64_COPY; 601 PCRelReloc = R_X86_64_PC32; 602 GotReloc = R_X86_64_GLOB_DAT; 603 PltReloc = R_X86_64_JUMP_SLOT; 604 RelativeReloc = R_X86_64_RELATIVE; 605 IRelativeReloc = R_X86_64_IRELATIVE; 606 TlsGotReloc = R_X86_64_TPOFF64; 607 TlsLocalDynamicReloc = R_X86_64_TLSLD; 608 TlsGlobalDynamicReloc = R_X86_64_TLSGD; 609 TlsModuleIndexReloc = R_X86_64_DTPMOD64; 610 TlsOffsetReloc = R_X86_64_DTPOFF64; 611 LazyRelocations = true; 612 PltEntrySize = 16; 613 PltZeroEntrySize = 16; 614 } 615 616 void X86_64TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const { 617 write64le(Buf, Out<ELF64LE>::Dynamic->getVA()); 618 } 619 620 void X86_64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const { 621 // Skip 6 bytes of "jmpq *got(%rip)" 622 write32le(Buf, Plt + 6); 623 } 624 625 void X86_64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 626 uint64_t PltEntryAddr) const { 627 const uint8_t PltData[] = { 628 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip) 629 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip) 630 0x0f, 0x1f, 0x40, 0x00 // nopl 0x0(rax) 631 }; 632 memcpy(Buf, PltData, sizeof(PltData)); 633 write32le(Buf + 2, GotEntryAddr - PltEntryAddr + 2); // GOT+8 634 write32le(Buf + 8, GotEntryAddr - PltEntryAddr + 4); // GOT+16 635 } 636 637 void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr, 638 uint64_t GotEntryAddr, 639 uint64_t PltEntryAddr, int32_t Index, 640 unsigned RelOff) const { 641 const uint8_t Inst[] = { 642 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip) 643 0x68, 0x00, 0x00, 0x00, 0x00, // pushq <relocation index> 644 0xe9, 0x00, 0x00, 0x00, 0x00 // jmpq plt[0] 645 }; 646 memcpy(Buf, Inst, sizeof(Inst)); 647 648 write32le(Buf + 2, GotEntryAddr - PltEntryAddr - 6); 649 write32le(Buf + 7, Index); 650 write32le(Buf + 12, -Index * PltEntrySize - PltZeroEntrySize - 16); 651 } 652 653 bool X86_64TargetInfo::needsCopyRel(uint32_t Type, const SymbolBody &S) const { 654 if (Type == R_X86_64_32S || Type == R_X86_64_32 || Type == R_X86_64_PC32 || 655 Type == R_X86_64_64) 656 if (auto *SS = dyn_cast<SharedSymbol<ELF64LE>>(&S)) 657 return SS->Sym.getType() == STT_OBJECT; 658 return false; 659 } 660 661 bool X86_64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { 662 if (Type == R_X86_64_TLSGD) 663 return Target->isTlsOptimized(Type, &S) && canBePreempted(&S, true); 664 if (Type == R_X86_64_GOTTPOFF) 665 return !isTlsOptimized(Type, &S); 666 return Type == R_X86_64_GOTPCREL || relocNeedsPlt(Type, S); 667 } 668 669 bool X86_64TargetInfo::isTlsDynReloc(unsigned Type, const SymbolBody &S) const { 670 return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_TLSGD; 671 } 672 673 bool X86_64TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const { 674 if (needsCopyRel(Type, S)) 675 return false; 676 if (isGnuIFunc<ELF64LE>(S)) 677 return true; 678 679 switch (Type) { 680 default: 681 return false; 682 case R_X86_64_32: 683 case R_X86_64_64: 684 case R_X86_64_PC32: 685 // This relocation is defined to have a value of (S + A - P). 686 // The problems start when a non PIC program calls a function in a shared 687 // library. 688 // In an ideal world, we could just report an error saying the relocation 689 // can overflow at runtime. 690 // In the real world with glibc, crt1.o has a R_X86_64_PC32 pointing to 691 // libc.so. 692 // 693 // The general idea on how to handle such cases is to create a PLT entry 694 // and use that as the function value. 695 // 696 // For the static linking part, we just return true and everything else 697 // will use the the PLT entry as the address. 698 // 699 // The remaining (unimplemented) problem is making sure pointer equality 700 // still works. We need the help of the dynamic linker for that. We 701 // let it know that we have a direct reference to a so symbol by creating 702 // an undefined symbol with a non zero st_value. Seeing that, the 703 // dynamic linker resolves the symbol to the value of the symbol we created. 704 // This is true even for got entries, so pointer equality is maintained. 705 // To avoid an infinite loop, the only entry that points to the 706 // real function is a dedicated got entry used by the plt. That is 707 // identified by special relocation types (R_X86_64_JUMP_SLOT, 708 // R_386_JMP_SLOT, etc). 709 return S.isShared(); 710 case R_X86_64_PLT32: 711 return canBePreempted(&S, true); 712 } 713 } 714 715 bool X86_64TargetInfo::isRelRelative(uint32_t Type) const { 716 switch (Type) { 717 default: 718 return false; 719 case R_X86_64_DTPOFF32: 720 case R_X86_64_DTPOFF64: 721 case R_X86_64_PC8: 722 case R_X86_64_PC16: 723 case R_X86_64_PC32: 724 case R_X86_64_PC64: 725 case R_X86_64_PLT32: 726 return true; 727 } 728 } 729 730 bool X86_64TargetInfo::isSizeReloc(uint32_t Type) const { 731 return Type == R_X86_64_SIZE32 || Type == R_X86_64_SIZE64; 732 } 733 734 bool X86_64TargetInfo::isTlsOptimized(unsigned Type, 735 const SymbolBody *S) const { 736 if (Config->Shared || (S && !S->isTls())) 737 return false; 738 return Type == R_X86_64_TLSGD || Type == R_X86_64_TLSLD || 739 Type == R_X86_64_DTPOFF32 || 740 (Type == R_X86_64_GOTTPOFF && !canBePreempted(S, true)); 741 } 742 743 // "Ulrich Drepper, ELF Handling For Thread-Local Storage" (5.5 744 // x86-x64 linker optimizations, http://www.akkadia.org/drepper/tls.pdf) shows 745 // how LD can be optimized to LE: 746 // leaq bar@tlsld(%rip), %rdi 747 // callq __tls_get_addr@PLT 748 // leaq bar@dtpoff(%rax), %rcx 749 // Is converted to: 750 // .word 0x6666 751 // .byte 0x66 752 // mov %fs:0,%rax 753 // leaq bar@tpoff(%rax), %rcx 754 void X86_64TargetInfo::relocateTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd, 755 uint64_t P, uint64_t SA) const { 756 const uint8_t Inst[] = { 757 0x66, 0x66, //.word 0x6666 758 0x66, //.byte 0x66 759 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00 // mov %fs:0,%rax 760 }; 761 memcpy(Loc - 3, Inst, sizeof(Inst)); 762 } 763 764 // "Ulrich Drepper, ELF Handling For Thread-Local Storage" (5.5 765 // x86-x64 linker optimizations, http://www.akkadia.org/drepper/tls.pdf) shows 766 // how GD can be optimized to LE: 767 // .byte 0x66 768 // leaq x@tlsgd(%rip), %rdi 769 // .word 0x6666 770 // rex64 771 // call __tls_get_addr@plt 772 // Is converted to: 773 // mov %fs:0x0,%rax 774 // lea x@tpoff,%rax 775 void X86_64TargetInfo::relocateTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd, 776 uint64_t P, uint64_t SA) const { 777 const uint8_t Inst[] = { 778 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax 779 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00 // lea x@tpoff,%rax 780 }; 781 memcpy(Loc - 4, Inst, sizeof(Inst)); 782 relocateOne(Loc + 8, BufEnd, R_X86_64_TPOFF32, P, SA); 783 } 784 785 // "Ulrich Drepper, ELF Handling For Thread-Local Storage" (5.5 786 // x86-x64 linker optimizations, http://www.akkadia.org/drepper/tls.pdf) shows 787 // how GD can be optimized to IE: 788 // .byte 0x66 789 // leaq x@tlsgd(%rip), %rdi 790 // .word 0x6666 791 // rex64 792 // call __tls_get_addr@plt 793 // Is converted to: 794 // mov %fs:0x0,%rax 795 // addq x@tpoff,%rax 796 void X86_64TargetInfo::relocateTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd, 797 uint64_t P, uint64_t SA) const { 798 const uint8_t Inst[] = { 799 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax 800 0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00 // addq x@tpoff,%rax 801 }; 802 memcpy(Loc - 4, Inst, sizeof(Inst)); 803 relocateOne(Loc + 8, BufEnd, R_X86_64_TPOFF64, P + 12, SA); 804 } 805 806 // In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to 807 // R_X86_64_TPOFF32 so that it does not use GOT. 808 // This function does that. Read "ELF Handling For Thread-Local Storage, 809 // 5.5 x86-x64 linker optimizations" (http://www.akkadia.org/drepper/tls.pdf) 810 // by Ulrich Drepper for details. 811 void X86_64TargetInfo::relocateTlsIeToLe(uint8_t *Loc, uint8_t *BufEnd, 812 uint64_t P, uint64_t SA) const { 813 // Ulrich's document section 6.5 says that @gottpoff(%rip) must be 814 // used in MOVQ or ADDQ instructions only. 815 // "MOVQ foo@GOTTPOFF(%RIP), %REG" is transformed to "MOVQ $foo, %REG". 816 // "ADDQ foo@GOTTPOFF(%RIP), %REG" is transformed to "LEAQ foo(%REG), %REG" 817 // (if the register is not RSP/R12) or "ADDQ $foo, %RSP". 818 // Opcodes info can be found at http://ref.x86asm.net/coder64.html#x48. 819 uint8_t *Prefix = Loc - 3; 820 uint8_t *Inst = Loc - 2; 821 uint8_t *RegSlot = Loc - 1; 822 uint8_t Reg = Loc[-1] >> 3; 823 bool IsMov = *Inst == 0x8b; 824 bool RspAdd = !IsMov && Reg == 4; 825 // r12 and rsp registers requires special handling. 826 // Problem is that for other registers, for example leaq 0xXXXXXXXX(%r11),%r11 827 // result out is 7 bytes: 4d 8d 9b XX XX XX XX, 828 // but leaq 0xXXXXXXXX(%r12),%r12 is 8 bytes: 4d 8d a4 24 XX XX XX XX. 829 // The same true for rsp. So we convert to addq for them, saving 1 byte that 830 // we dont have. 831 if (RspAdd) 832 *Inst = 0x81; 833 else 834 *Inst = IsMov ? 0xc7 : 0x8d; 835 if (*Prefix == 0x4c) 836 *Prefix = (IsMov || RspAdd) ? 0x49 : 0x4d; 837 *RegSlot = (IsMov || RspAdd) ? (0xc0 | Reg) : (0x80 | Reg | (Reg << 3)); 838 relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA); 839 } 840 841 // This function applies a TLS relocation with an optimization as described 842 // in the Ulrich's document. As a result of rewriting instructions at the 843 // relocation target, relocations immediately follow the TLS relocation (which 844 // would be applied to rewritten instructions) may have to be skipped. 845 // This function returns a number of relocations that need to be skipped. 846 unsigned X86_64TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, 847 uint32_t Type, uint64_t P, 848 uint64_t SA, 849 const SymbolBody &S) const { 850 switch (Type) { 851 case R_X86_64_DTPOFF32: 852 relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA); 853 return 0; 854 case R_X86_64_GOTTPOFF: 855 relocateTlsIeToLe(Loc, BufEnd, P, SA); 856 return 0; 857 case R_X86_64_TLSGD: { 858 if (canBePreempted(&S, true)) 859 relocateTlsGdToIe(Loc, BufEnd, P, SA); 860 else 861 relocateTlsGdToLe(Loc, BufEnd, P, SA); 862 // The next relocation should be against __tls_get_addr, so skip it 863 return 1; 864 } 865 case R_X86_64_TLSLD: 866 relocateTlsLdToLe(Loc, BufEnd, P, SA); 867 // The next relocation should be against __tls_get_addr, so skip it 868 return 1; 869 } 870 llvm_unreachable("Unknown TLS optimization"); 871 } 872 873 void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 874 uint64_t P, uint64_t SA, uint64_t ZA, 875 uint8_t *PairedLoc) const { 876 switch (Type) { 877 case R_X86_64_32: 878 checkUInt<32>(SA, Type); 879 write32le(Loc, SA); 880 break; 881 case R_X86_64_32S: 882 checkInt<32>(SA, Type); 883 write32le(Loc, SA); 884 break; 885 case R_X86_64_64: 886 write64le(Loc, SA); 887 break; 888 case R_X86_64_DTPOFF32: 889 write32le(Loc, SA); 890 break; 891 case R_X86_64_DTPOFF64: 892 write64le(Loc, SA); 893 break; 894 case R_X86_64_GOTPCREL: 895 case R_X86_64_PC32: 896 case R_X86_64_PLT32: 897 case R_X86_64_TLSGD: 898 case R_X86_64_TLSLD: 899 write32le(Loc, SA - P); 900 break; 901 case R_X86_64_SIZE32: 902 write32le(Loc, ZA); 903 break; 904 case R_X86_64_SIZE64: 905 write64le(Loc, ZA); 906 break; 907 case R_X86_64_TPOFF32: { 908 uint64_t Val = SA - Out<ELF64LE>::TlsPhdr->p_memsz; 909 checkInt<32>(Val, Type); 910 write32le(Loc, Val); 911 break; 912 } 913 case R_X86_64_TPOFF64: 914 write32le(Loc, SA - P); 915 break; 916 default: 917 error("unrecognized reloc " + Twine(Type)); 918 } 919 } 920 921 // Relocation masks following the #lo(value), #hi(value), #ha(value), 922 // #higher(value), #highera(value), #highest(value), and #highesta(value) 923 // macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi 924 // document. 925 static uint16_t applyPPCLo(uint64_t V) { return V; } 926 static uint16_t applyPPCHi(uint64_t V) { return V >> 16; } 927 static uint16_t applyPPCHa(uint64_t V) { return (V + 0x8000) >> 16; } 928 static uint16_t applyPPCHigher(uint64_t V) { return V >> 32; } 929 static uint16_t applyPPCHighera(uint64_t V) { return (V + 0x8000) >> 32; } 930 static uint16_t applyPPCHighest(uint64_t V) { return V >> 48; } 931 static uint16_t applyPPCHighesta(uint64_t V) { return (V + 0x8000) >> 48; } 932 933 PPCTargetInfo::PPCTargetInfo() {} 934 void PPCTargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} 935 void PPCTargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 936 uint64_t PltEntryAddr) const {} 937 void PPCTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr, 938 uint64_t GotEntryAddr, 939 uint64_t PltEntryAddr, int32_t Index, 940 unsigned RelOff) const {} 941 bool PPCTargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { 942 return false; 943 } 944 bool PPCTargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const { 945 return false; 946 } 947 bool PPCTargetInfo::isRelRelative(uint32_t Type) const { return false; } 948 949 void PPCTargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 950 uint64_t P, uint64_t SA, uint64_t ZA, 951 uint8_t *PairedLoc) const { 952 switch (Type) { 953 case R_PPC_ADDR16_HA: 954 write16be(Loc, applyPPCHa(SA)); 955 break; 956 case R_PPC_ADDR16_LO: 957 write16be(Loc, applyPPCLo(SA)); 958 break; 959 default: 960 error("unrecognized reloc " + Twine(Type)); 961 } 962 } 963 964 PPC64TargetInfo::PPC64TargetInfo() { 965 PCRelReloc = R_PPC64_REL24; 966 GotReloc = R_PPC64_GLOB_DAT; 967 RelativeReloc = R_PPC64_RELATIVE; 968 PltEntrySize = 32; 969 970 // We need 64K pages (at least under glibc/Linux, the loader won't 971 // set different permissions on a finer granularity than that). 972 PageSize = 65536; 973 974 // The PPC64 ELF ABI v1 spec, says: 975 // 976 // It is normally desirable to put segments with different characteristics 977 // in separate 256 Mbyte portions of the address space, to give the 978 // operating system full paging flexibility in the 64-bit address space. 979 // 980 // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers 981 // use 0x10000000 as the starting address. 982 VAStart = 0x10000000; 983 } 984 985 uint64_t getPPC64TocBase() { 986 // The TOC consists of sections .got, .toc, .tocbss, .plt in that 987 // order. The TOC starts where the first of these sections starts. 988 989 // FIXME: This obviously does not do the right thing when there is no .got 990 // section, but there is a .toc or .tocbss section. 991 uint64_t TocVA = Out<ELF64BE>::Got->getVA(); 992 if (!TocVA) 993 TocVA = Out<ELF64BE>::Plt->getVA(); 994 995 // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000 996 // thus permitting a full 64 Kbytes segment. Note that the glibc startup 997 // code (crt1.o) assumes that you can get from the TOC base to the 998 // start of the .toc section with only a single (signed) 16-bit relocation. 999 return TocVA + 0x8000; 1000 } 1001 1002 void PPC64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} 1003 void PPC64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 1004 uint64_t PltEntryAddr) const {} 1005 void PPC64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr, 1006 uint64_t GotEntryAddr, 1007 uint64_t PltEntryAddr, int32_t Index, 1008 unsigned RelOff) const { 1009 uint64_t Off = GotEntryAddr - getPPC64TocBase(); 1010 1011 // FIXME: What we should do, in theory, is get the offset of the function 1012 // descriptor in the .opd section, and use that as the offset from %r2 (the 1013 // TOC-base pointer). Instead, we have the GOT-entry offset, and that will 1014 // be a pointer to the function descriptor in the .opd section. Using 1015 // this scheme is simpler, but requires an extra indirection per PLT dispatch. 1016 1017 write32be(Buf, 0xf8410028); // std %r2, 40(%r1) 1018 write32be(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha 1019 write32be(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11) 1020 write32be(Buf + 12, 0xe96c0000); // ld %r11,0(%r12) 1021 write32be(Buf + 16, 0x7d6903a6); // mtctr %r11 1022 write32be(Buf + 20, 0xe84c0008); // ld %r2,8(%r12) 1023 write32be(Buf + 24, 0xe96c0010); // ld %r11,16(%r12) 1024 write32be(Buf + 28, 0x4e800420); // bctr 1025 } 1026 1027 bool PPC64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { 1028 if (relocNeedsPlt(Type, S)) 1029 return true; 1030 1031 switch (Type) { 1032 default: return false; 1033 case R_PPC64_GOT16: 1034 case R_PPC64_GOT16_DS: 1035 case R_PPC64_GOT16_HA: 1036 case R_PPC64_GOT16_HI: 1037 case R_PPC64_GOT16_LO: 1038 case R_PPC64_GOT16_LO_DS: 1039 return true; 1040 } 1041 } 1042 1043 bool PPC64TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const { 1044 // These are function calls that need to be redirected through a PLT stub. 1045 return Type == R_PPC64_REL24 && canBePreempted(&S, false); 1046 } 1047 1048 bool PPC64TargetInfo::isRelRelative(uint32_t Type) const { 1049 switch (Type) { 1050 default: 1051 return true; 1052 case R_PPC64_ADDR64: 1053 case R_PPC64_TOC: 1054 return false; 1055 } 1056 } 1057 1058 void PPC64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 1059 uint64_t P, uint64_t SA, uint64_t ZA, 1060 uint8_t *PairedLoc) const { 1061 uint64_t TB = getPPC64TocBase(); 1062 1063 // For a TOC-relative relocation, adjust the addend and proceed in terms of 1064 // the corresponding ADDR16 relocation type. 1065 switch (Type) { 1066 case R_PPC64_TOC16: Type = R_PPC64_ADDR16; SA -= TB; break; 1067 case R_PPC64_TOC16_DS: Type = R_PPC64_ADDR16_DS; SA -= TB; break; 1068 case R_PPC64_TOC16_HA: Type = R_PPC64_ADDR16_HA; SA -= TB; break; 1069 case R_PPC64_TOC16_HI: Type = R_PPC64_ADDR16_HI; SA -= TB; break; 1070 case R_PPC64_TOC16_LO: Type = R_PPC64_ADDR16_LO; SA -= TB; break; 1071 case R_PPC64_TOC16_LO_DS: Type = R_PPC64_ADDR16_LO_DS; SA -= TB; break; 1072 default: break; 1073 } 1074 1075 switch (Type) { 1076 case R_PPC64_ADDR14: { 1077 checkAlignment<4>(SA, Type); 1078 // Preserve the AA/LK bits in the branch instruction 1079 uint8_t AALK = Loc[3]; 1080 write16be(Loc + 2, (AALK & 3) | (SA & 0xfffc)); 1081 break; 1082 } 1083 case R_PPC64_ADDR16: 1084 checkInt<16>(SA, Type); 1085 write16be(Loc, SA); 1086 break; 1087 case R_PPC64_ADDR16_DS: 1088 checkInt<16>(SA, Type); 1089 write16be(Loc, (read16be(Loc) & 3) | (SA & ~3)); 1090 break; 1091 case R_PPC64_ADDR16_HA: 1092 write16be(Loc, applyPPCHa(SA)); 1093 break; 1094 case R_PPC64_ADDR16_HI: 1095 write16be(Loc, applyPPCHi(SA)); 1096 break; 1097 case R_PPC64_ADDR16_HIGHER: 1098 write16be(Loc, applyPPCHigher(SA)); 1099 break; 1100 case R_PPC64_ADDR16_HIGHERA: 1101 write16be(Loc, applyPPCHighera(SA)); 1102 break; 1103 case R_PPC64_ADDR16_HIGHEST: 1104 write16be(Loc, applyPPCHighest(SA)); 1105 break; 1106 case R_PPC64_ADDR16_HIGHESTA: 1107 write16be(Loc, applyPPCHighesta(SA)); 1108 break; 1109 case R_PPC64_ADDR16_LO: 1110 write16be(Loc, applyPPCLo(SA)); 1111 break; 1112 case R_PPC64_ADDR16_LO_DS: 1113 write16be(Loc, (read16be(Loc) & 3) | (applyPPCLo(SA) & ~3)); 1114 break; 1115 case R_PPC64_ADDR32: 1116 checkInt<32>(SA, Type); 1117 write32be(Loc, SA); 1118 break; 1119 case R_PPC64_ADDR64: 1120 write64be(Loc, SA); 1121 break; 1122 case R_PPC64_REL16_HA: 1123 write16be(Loc, applyPPCHa(SA - P)); 1124 break; 1125 case R_PPC64_REL16_HI: 1126 write16be(Loc, applyPPCHi(SA - P)); 1127 break; 1128 case R_PPC64_REL16_LO: 1129 write16be(Loc, applyPPCLo(SA - P)); 1130 break; 1131 case R_PPC64_REL24: { 1132 // If we have an undefined weak symbol, we might get here with a symbol 1133 // address of zero. That could overflow, but the code must be unreachable, 1134 // so don't bother doing anything at all. 1135 if (!SA) 1136 break; 1137 1138 uint64_t PltStart = Out<ELF64BE>::Plt->getVA(); 1139 uint64_t PltEnd = PltStart + Out<ELF64BE>::Plt->getSize(); 1140 bool InPlt = PltStart <= SA && SA < PltEnd; 1141 1142 if (!InPlt && Out<ELF64BE>::Opd) { 1143 // If this is a local call, and we currently have the address of a 1144 // function-descriptor, get the underlying code address instead. 1145 uint64_t OpdStart = Out<ELF64BE>::Opd->getVA(); 1146 uint64_t OpdEnd = OpdStart + Out<ELF64BE>::Opd->getSize(); 1147 bool InOpd = OpdStart <= SA && SA < OpdEnd; 1148 1149 if (InOpd) 1150 SA = read64be(&Out<ELF64BE>::OpdBuf[SA - OpdStart]); 1151 } 1152 1153 uint32_t Mask = 0x03FFFFFC; 1154 checkInt<24>(SA - P, Type); 1155 write32be(Loc, (read32be(Loc) & ~Mask) | ((SA - P) & Mask)); 1156 1157 uint32_t Nop = 0x60000000; 1158 if (InPlt && Loc + 8 <= BufEnd && read32be(Loc + 4) == Nop) 1159 write32be(Loc + 4, 0xe8410028); // ld %r2, 40(%r1) 1160 break; 1161 } 1162 case R_PPC64_REL32: 1163 checkInt<32>(SA - P, Type); 1164 write32be(Loc, SA - P); 1165 break; 1166 case R_PPC64_REL64: 1167 write64be(Loc, SA - P); 1168 break; 1169 case R_PPC64_TOC: 1170 write64be(Loc, SA); 1171 break; 1172 default: 1173 error("unrecognized reloc " + Twine(Type)); 1174 } 1175 } 1176 1177 AArch64TargetInfo::AArch64TargetInfo() { 1178 CopyReloc = R_AARCH64_COPY; 1179 IRelativeReloc = R_AARCH64_IRELATIVE; 1180 GotReloc = R_AARCH64_GLOB_DAT; 1181 PltReloc = R_AARCH64_JUMP_SLOT; 1182 LazyRelocations = true; 1183 PltEntrySize = 16; 1184 PltZeroEntrySize = 32; 1185 } 1186 1187 unsigned AArch64TargetInfo::getDynReloc(unsigned Type) const { 1188 if (Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64) 1189 return Type; 1190 StringRef S = getELFRelocationTypeName(EM_AARCH64, Type); 1191 error("Relocation " + S + " cannot be used when making a shared object; " 1192 "recompile with -fPIC."); 1193 } 1194 1195 void AArch64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const { 1196 write64le(Buf, Out<ELF64LE>::Plt->getVA()); 1197 } 1198 1199 void AArch64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 1200 uint64_t PltEntryAddr) const { 1201 const uint8_t PltData[] = { 1202 0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]! 1203 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[2])) 1204 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[2]))] 1205 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[2])) 1206 0x20, 0x02, 0x1f, 0xd6, // br x17 1207 0x1f, 0x20, 0x03, 0xd5, // nop 1208 0x1f, 0x20, 0x03, 0xd5, // nop 1209 0x1f, 0x20, 0x03, 0xd5 // nop 1210 }; 1211 memcpy(Buf, PltData, sizeof(PltData)); 1212 1213 relocateOne(Buf + 4, Buf + 8, R_AARCH64_ADR_PREL_PG_HI21, PltEntryAddr + 4, 1214 GotEntryAddr + 16); 1215 relocateOne(Buf + 8, Buf + 12, R_AARCH64_LDST64_ABS_LO12_NC, PltEntryAddr + 8, 1216 GotEntryAddr + 16); 1217 relocateOne(Buf + 12, Buf + 16, R_AARCH64_ADD_ABS_LO12_NC, PltEntryAddr + 12, 1218 GotEntryAddr + 16); 1219 } 1220 1221 void AArch64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr, 1222 uint64_t GotEntryAddr, 1223 uint64_t PltEntryAddr, int32_t Index, 1224 unsigned RelOff) const { 1225 const uint8_t Inst[] = { 1226 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n])) 1227 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[n]))] 1228 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[n])) 1229 0x20, 0x02, 0x1f, 0xd6 // br x17 1230 }; 1231 memcpy(Buf, Inst, sizeof(Inst)); 1232 1233 relocateOne(Buf, Buf + 4, R_AARCH64_ADR_PREL_PG_HI21, PltEntryAddr, 1234 GotEntryAddr); 1235 relocateOne(Buf + 4, Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, PltEntryAddr + 4, 1236 GotEntryAddr); 1237 relocateOne(Buf + 8, Buf + 12, R_AARCH64_ADD_ABS_LO12_NC, PltEntryAddr + 8, 1238 GotEntryAddr); 1239 } 1240 1241 bool AArch64TargetInfo::needsCopyRel(uint32_t Type, const SymbolBody &S) const { 1242 if (Config->Shared) 1243 return false; 1244 switch (Type) { 1245 default: 1246 return false; 1247 case R_AARCH64_ABS16: 1248 case R_AARCH64_ABS32: 1249 case R_AARCH64_ABS64: 1250 case R_AARCH64_ADD_ABS_LO12_NC: 1251 case R_AARCH64_ADR_PREL_LO21: 1252 case R_AARCH64_ADR_PREL_PG_HI21: 1253 case R_AARCH64_LDST8_ABS_LO12_NC: 1254 case R_AARCH64_LDST32_ABS_LO12_NC: 1255 case R_AARCH64_LDST64_ABS_LO12_NC: 1256 if (auto *SS = dyn_cast<SharedSymbol<ELF64LE>>(&S)) 1257 return SS->Sym.getType() == STT_OBJECT; 1258 return false; 1259 } 1260 } 1261 1262 bool AArch64TargetInfo::relocNeedsGot(uint32_t Type, 1263 const SymbolBody &S) const { 1264 return Type == R_AARCH64_ADR_GOT_PAGE || Type == R_AARCH64_LD64_GOT_LO12_NC || 1265 relocNeedsPlt(Type, S); 1266 } 1267 1268 bool AArch64TargetInfo::relocNeedsPlt(uint32_t Type, 1269 const SymbolBody &S) const { 1270 if (isGnuIFunc<ELF64LE>(S)) 1271 return true; 1272 switch (Type) { 1273 default: 1274 return false; 1275 case R_AARCH64_CALL26: 1276 case R_AARCH64_CONDBR19: 1277 case R_AARCH64_JUMP26: 1278 case R_AARCH64_TSTBR14: 1279 return canBePreempted(&S, true); 1280 } 1281 } 1282 1283 static void updateAArch64Adr(uint8_t *L, uint64_t Imm) { 1284 uint32_t ImmLo = (Imm & 0x3) << 29; 1285 uint32_t ImmHi = ((Imm & 0x1FFFFC) >> 2) << 5; 1286 uint64_t Mask = (0x3 << 29) | (0x7FFFF << 5); 1287 write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi); 1288 } 1289 1290 // Page(Expr) is the page address of the expression Expr, defined 1291 // as (Expr & ~0xFFF). (This applies even if the machine page size 1292 // supported by the platform has a different value.) 1293 static uint64_t getAArch64Page(uint64_t Expr) { 1294 return Expr & (~static_cast<uint64_t>(0xFFF)); 1295 } 1296 1297 void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, 1298 uint32_t Type, uint64_t P, uint64_t SA, 1299 uint64_t ZA, uint8_t *PairedLoc) const { 1300 switch (Type) { 1301 case R_AARCH64_ABS16: 1302 checkIntUInt<16>(SA, Type); 1303 write16le(Loc, SA); 1304 break; 1305 case R_AARCH64_ABS32: 1306 checkIntUInt<32>(SA, Type); 1307 write32le(Loc, SA); 1308 break; 1309 case R_AARCH64_ABS64: 1310 write64le(Loc, SA); 1311 break; 1312 case R_AARCH64_ADD_ABS_LO12_NC: 1313 // This relocation stores 12 bits and there's no instruction 1314 // to do it. Instead, we do a 32 bits store of the value 1315 // of r_addend bitwise-or'ed Loc. This assumes that the addend 1316 // bits in Loc are zero. 1317 or32le(Loc, (SA & 0xFFF) << 10); 1318 break; 1319 case R_AARCH64_ADR_GOT_PAGE: { 1320 uint64_t X = getAArch64Page(SA) - getAArch64Page(P); 1321 checkInt<33>(X, Type); 1322 updateAArch64Adr(Loc, (X >> 12) & 0x1FFFFF); // X[32:12] 1323 break; 1324 } 1325 case R_AARCH64_ADR_PREL_LO21: { 1326 uint64_t X = SA - P; 1327 checkInt<21>(X, Type); 1328 updateAArch64Adr(Loc, X & 0x1FFFFF); 1329 break; 1330 } 1331 case R_AARCH64_ADR_PREL_PG_HI21: { 1332 uint64_t X = getAArch64Page(SA) - getAArch64Page(P); 1333 checkInt<33>(X, Type); 1334 updateAArch64Adr(Loc, (X >> 12) & 0x1FFFFF); // X[32:12] 1335 break; 1336 } 1337 case R_AARCH64_CALL26: 1338 case R_AARCH64_JUMP26: { 1339 uint64_t X = SA - P; 1340 checkInt<28>(X, Type); 1341 or32le(Loc, (X & 0x0FFFFFFC) >> 2); 1342 break; 1343 } 1344 case R_AARCH64_CONDBR19: { 1345 uint64_t X = SA - P; 1346 checkInt<21>(X, Type); 1347 or32le(Loc, (X & 0x1FFFFC) << 3); 1348 break; 1349 } 1350 case R_AARCH64_LD64_GOT_LO12_NC: 1351 checkAlignment<8>(SA, Type); 1352 or32le(Loc, (SA & 0xFF8) << 7); 1353 break; 1354 case R_AARCH64_LDST8_ABS_LO12_NC: 1355 or32le(Loc, (SA & 0xFFF) << 10); 1356 break; 1357 case R_AARCH64_LDST32_ABS_LO12_NC: 1358 or32le(Loc, (SA & 0xFFC) << 8); 1359 break; 1360 case R_AARCH64_LDST64_ABS_LO12_NC: 1361 or32le(Loc, (SA & 0xFF8) << 7); 1362 break; 1363 case R_AARCH64_PREL16: 1364 checkIntUInt<16>(SA - P, Type); 1365 write16le(Loc, SA - P); 1366 break; 1367 case R_AARCH64_PREL32: 1368 checkIntUInt<32>(SA - P, Type); 1369 write32le(Loc, SA - P); 1370 break; 1371 case R_AARCH64_PREL64: 1372 write64le(Loc, SA - P); 1373 break; 1374 case R_AARCH64_TSTBR14: { 1375 uint64_t X = SA - P; 1376 checkInt<16>(X, Type); 1377 or32le(Loc, (X & 0xFFFC) << 3); 1378 break; 1379 } 1380 default: 1381 error("unrecognized reloc " + Twine(Type)); 1382 } 1383 } 1384 1385 AMDGPUTargetInfo::AMDGPUTargetInfo() {} 1386 1387 void AMDGPUTargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const { 1388 llvm_unreachable("not implemented"); 1389 } 1390 1391 void AMDGPUTargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 1392 uint64_t PltEntryAddr) const { 1393 llvm_unreachable("not implemented"); 1394 } 1395 1396 void AMDGPUTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr, 1397 uint64_t GotEntryAddr, 1398 uint64_t PltEntryAddr, int32_t Index, 1399 unsigned RelOff) const { 1400 llvm_unreachable("not implemented"); 1401 } 1402 1403 bool AMDGPUTargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { 1404 return false; 1405 } 1406 1407 bool AMDGPUTargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const { 1408 return false; 1409 } 1410 1411 // Implementing relocations for AMDGPU is low priority since most 1412 // programs don't use relocations now. Thus, this function is not 1413 // actually called (relocateOne is called for each relocation). 1414 // That's why the AMDGPU port works without implementing this function. 1415 void AMDGPUTargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 1416 uint64_t P, uint64_t SA, uint64_t ZA, 1417 uint8_t *PairedLoc) const { 1418 llvm_unreachable("not implemented"); 1419 } 1420 1421 template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() { 1422 PageSize = 65536; 1423 GotHeaderEntriesNum = 2; 1424 } 1425 1426 template <class ELFT> 1427 void MipsTargetInfo<ELFT>::writeGotHeaderEntries(uint8_t *Buf) const { 1428 typedef typename ELFFile<ELFT>::Elf_Off Elf_Off; 1429 auto *P = reinterpret_cast<Elf_Off *>(Buf); 1430 // Module pointer 1431 P[1] = ELFT::Is64Bits ? 0x8000000000000000 : 0x80000000; 1432 } 1433 1434 template <class ELFT> 1435 void MipsTargetInfo<ELFT>::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} 1436 template <class ELFT> 1437 void MipsTargetInfo<ELFT>::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, 1438 uint64_t PltEntryAddr) const {} 1439 template <class ELFT> 1440 void MipsTargetInfo<ELFT>::writePltEntry(uint8_t *Buf, uint64_t GotAddr, 1441 uint64_t GotEntryAddr, 1442 uint64_t PltEntryAddr, int32_t Index, 1443 unsigned RelOff) const {} 1444 1445 template <class ELFT> 1446 bool MipsTargetInfo<ELFT>::relocNeedsGot(uint32_t Type, 1447 const SymbolBody &S) const { 1448 return Type == R_MIPS_GOT16 || Type == R_MIPS_CALL16; 1449 } 1450 1451 template <class ELFT> 1452 bool MipsTargetInfo<ELFT>::relocNeedsPlt(uint32_t Type, 1453 const SymbolBody &S) const { 1454 return false; 1455 } 1456 1457 static uint16_t mipsHigh(uint64_t V) { return (V + 0x8000) >> 16; } 1458 1459 template <endianness E, uint8_t BSIZE> 1460 static void applyMipsPcReloc(uint8_t *Loc, uint32_t Type, uint64_t P, 1461 uint64_t SA) { 1462 uint32_t Mask = ~(0xffffffff << BSIZE); 1463 uint32_t Instr = read32<E>(Loc); 1464 int64_t A = SignExtend64<BSIZE + 2>((Instr & Mask) << 2); 1465 checkAlignment<4>(SA + A, Type); 1466 int64_t V = SA + A - P; 1467 checkInt<BSIZE + 2>(V, Type); 1468 write32<E>(Loc, (Instr & ~Mask) | ((V >> 2) & Mask)); 1469 } 1470 1471 template <class ELFT> 1472 void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd, 1473 uint32_t Type, uint64_t P, uint64_t SA, 1474 uint64_t ZA, uint8_t *PairedLoc) const { 1475 const endianness E = ELFT::TargetEndianness; 1476 switch (Type) { 1477 case R_MIPS_32: 1478 add32<E>(Loc, SA); 1479 break; 1480 case R_MIPS_CALL16: 1481 case R_MIPS_GOT16: { 1482 int64_t V = SA - getMipsGpAddr<ELFT>(); 1483 if (Type == R_MIPS_GOT16) 1484 checkInt<16>(V, Type); 1485 write32<E>(Loc, (read32<E>(Loc) & 0xffff0000) | (V & 0xffff)); 1486 break; 1487 } 1488 case R_MIPS_GPREL16: { 1489 uint32_t Instr = read32<E>(Loc); 1490 int64_t V = SA + SignExtend64<16>(Instr & 0xffff) - getMipsGpAddr<ELFT>(); 1491 checkInt<16>(V, Type); 1492 write32<E>(Loc, (Instr & 0xffff0000) | (V & 0xffff)); 1493 break; 1494 } 1495 case R_MIPS_GPREL32: 1496 write32<E>(Loc, SA + int32_t(read32<E>(Loc)) - getMipsGpAddr<ELFT>()); 1497 break; 1498 case R_MIPS_HI16: { 1499 uint32_t Instr = read32<E>(Loc); 1500 if (PairedLoc) { 1501 uint64_t AHL = ((Instr & 0xffff) << 16) + 1502 SignExtend64<16>(read32<E>(PairedLoc) & 0xffff); 1503 write32<E>(Loc, (Instr & 0xffff0000) | mipsHigh(SA + AHL)); 1504 } else { 1505 warning("Can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16"); 1506 write32<E>(Loc, (Instr & 0xffff0000) | mipsHigh(SA)); 1507 } 1508 break; 1509 } 1510 case R_MIPS_JALR: 1511 // Ignore this optimization relocation for now 1512 break; 1513 case R_MIPS_LO16: { 1514 uint32_t Instr = read32<E>(Loc); 1515 int64_t AHL = SignExtend64<16>(Instr & 0xffff); 1516 write32<E>(Loc, (Instr & 0xffff0000) | ((SA + AHL) & 0xffff)); 1517 break; 1518 } 1519 case R_MIPS_PC16: 1520 applyMipsPcReloc<E, 16>(Loc, Type, P, SA); 1521 break; 1522 case R_MIPS_PC19_S2: 1523 applyMipsPcReloc<E, 19>(Loc, Type, P, SA); 1524 break; 1525 case R_MIPS_PC21_S2: 1526 applyMipsPcReloc<E, 21>(Loc, Type, P, SA); 1527 break; 1528 case R_MIPS_PC26_S2: 1529 applyMipsPcReloc<E, 26>(Loc, Type, P, SA); 1530 break; 1531 case R_MIPS_PCHI16: { 1532 uint32_t Instr = read32<E>(Loc); 1533 if (PairedLoc) { 1534 uint64_t AHL = ((Instr & 0xffff) << 16) + 1535 SignExtend64<16>(read32<E>(PairedLoc) & 0xffff); 1536 write32<E>(Loc, (Instr & 0xffff0000) | mipsHigh(SA + AHL - P)); 1537 } else { 1538 warning("Can't find matching R_MIPS_PCLO16 relocation for R_MIPS_PCHI16"); 1539 write32<E>(Loc, (Instr & 0xffff0000) | mipsHigh(SA - P)); 1540 } 1541 break; 1542 } 1543 case R_MIPS_PCLO16: { 1544 uint32_t Instr = read32<E>(Loc); 1545 int64_t AHL = SignExtend64<16>(Instr & 0xffff); 1546 write32<E>(Loc, (Instr & 0xffff0000) | ((SA + AHL - P) & 0xffff)); 1547 break; 1548 } 1549 default: 1550 error("unrecognized reloc " + Twine(Type)); 1551 } 1552 } 1553 1554 template <class ELFT> 1555 bool MipsTargetInfo<ELFT>::isRelRelative(uint32_t Type) const { 1556 switch (Type) { 1557 default: 1558 return false; 1559 case R_MIPS_PC16: 1560 case R_MIPS_PC19_S2: 1561 case R_MIPS_PC21_S2: 1562 case R_MIPS_PC26_S2: 1563 case R_MIPS_PCHI16: 1564 case R_MIPS_PCLO16: 1565 return true; 1566 } 1567 } 1568 1569 // _gp is a MIPS-specific ABI-defined symbol which points to 1570 // a location that is relative to GOT. This function returns 1571 // the value for the symbol. 1572 template <class ELFT> typename ELFFile<ELFT>::uintX_t getMipsGpAddr() { 1573 unsigned GPOffset = 0x7ff0; 1574 if (uint64_t V = Out<ELFT>::Got->getVA()) 1575 return V + GPOffset; 1576 return 0; 1577 } 1578 1579 template uint32_t getMipsGpAddr<ELF32LE>(); 1580 template uint32_t getMipsGpAddr<ELF32BE>(); 1581 template uint64_t getMipsGpAddr<ELF64LE>(); 1582 template uint64_t getMipsGpAddr<ELF64BE>(); 1583 } 1584 } 1585