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