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