1 //===- SystemZ.cpp --------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "OutputSections.h" 10 #include "Symbols.h" 11 #include "SyntheticSections.h" 12 #include "Target.h" 13 #include "lld/Common/ErrorHandler.h" 14 #include "llvm/BinaryFormat/ELF.h" 15 #include "llvm/Support/Endian.h" 16 17 using namespace llvm; 18 using namespace llvm::support::endian; 19 using namespace llvm::ELF; 20 using namespace lld; 21 using namespace lld::elf; 22 23 namespace { 24 class SystemZ : public TargetInfo { 25 public: 26 SystemZ(Ctx &); 27 int getTlsGdRelaxSkip(RelType type) const override; 28 RelExpr getRelExpr(RelType type, const Symbol &s, 29 const uint8_t *loc) const override; 30 RelType getDynRel(RelType type) const override; 31 void writeGotHeader(uint8_t *buf) const override; 32 void writeGotPlt(uint8_t *buf, const Symbol &s) const override; 33 void writeIgotPlt(uint8_t *buf, const Symbol &s) const override; 34 void writePltHeader(uint8_t *buf) const override; 35 void addPltHeaderSymbols(InputSection &isd) const override; 36 void writePlt(uint8_t *buf, const Symbol &sym, 37 uint64_t pltEntryAddr) const override; 38 RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override; 39 RelExpr adjustGotPcExpr(RelType type, int64_t addend, 40 const uint8_t *loc) const override; 41 bool relaxOnce(int pass) const override; 42 void relocate(uint8_t *loc, const Relocation &rel, 43 uint64_t val) const override; 44 int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override; 45 46 private: 47 void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const; 48 void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) const; 49 void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const; 50 void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const; 51 }; 52 } // namespace 53 54 SystemZ::SystemZ(Ctx &ctx) : TargetInfo(ctx) { 55 copyRel = R_390_COPY; 56 gotRel = R_390_GLOB_DAT; 57 pltRel = R_390_JMP_SLOT; 58 relativeRel = R_390_RELATIVE; 59 iRelativeRel = R_390_IRELATIVE; 60 symbolicRel = R_390_64; 61 tlsGotRel = R_390_TLS_TPOFF; 62 tlsModuleIndexRel = R_390_TLS_DTPMOD; 63 tlsOffsetRel = R_390_TLS_DTPOFF; 64 gotHeaderEntriesNum = 3; 65 gotPltHeaderEntriesNum = 0; 66 gotEntrySize = 8; 67 pltHeaderSize = 32; 68 pltEntrySize = 32; 69 ipltEntrySize = 32; 70 71 // This "trap instruction" is used to fill gaps between sections. 72 // On SystemZ, the behavior of the GNU ld is to fill those gaps 73 // with nop instructions instead - and unfortunately the default 74 // glibc crt object files (used to) rely on that behavior since 75 // they use an alignment on the .init section fragments that causes 76 // gaps which must be filled with nops as they are being executed. 77 // Therefore, we provide a nop instruction as "trapInstr" here. 78 trapInstr = {0x07, 0x07, 0x07, 0x07}; 79 80 defaultImageBase = 0x1000000; 81 } 82 83 RelExpr SystemZ::getRelExpr(RelType type, const Symbol &s, 84 const uint8_t *loc) const { 85 switch (type) { 86 case R_390_NONE: 87 return R_NONE; 88 // Relocations targeting the symbol value. 89 case R_390_8: 90 case R_390_12: 91 case R_390_16: 92 case R_390_20: 93 case R_390_32: 94 case R_390_64: 95 return R_ABS; 96 case R_390_PC16: 97 case R_390_PC32: 98 case R_390_PC64: 99 case R_390_PC12DBL: 100 case R_390_PC16DBL: 101 case R_390_PC24DBL: 102 case R_390_PC32DBL: 103 return R_PC; 104 case R_390_GOTOFF16: 105 case R_390_GOTOFF: // a.k.a. R_390_GOTOFF32 106 case R_390_GOTOFF64: 107 return R_GOTREL; 108 // Relocations targeting the PLT associated with the symbol. 109 case R_390_PLT32: 110 case R_390_PLT64: 111 case R_390_PLT12DBL: 112 case R_390_PLT16DBL: 113 case R_390_PLT24DBL: 114 case R_390_PLT32DBL: 115 return R_PLT_PC; 116 case R_390_PLTOFF16: 117 case R_390_PLTOFF32: 118 case R_390_PLTOFF64: 119 return R_PLT_GOTREL; 120 // Relocations targeting the GOT entry associated with the symbol. 121 case R_390_GOTENT: 122 return R_GOT_PC; 123 case R_390_GOT12: 124 case R_390_GOT16: 125 case R_390_GOT20: 126 case R_390_GOT32: 127 case R_390_GOT64: 128 return R_GOT_OFF; 129 // Relocations targeting the GOTPLT entry associated with the symbol. 130 case R_390_GOTPLTENT: 131 return R_GOTPLT_PC; 132 case R_390_GOTPLT12: 133 case R_390_GOTPLT16: 134 case R_390_GOTPLT20: 135 case R_390_GOTPLT32: 136 case R_390_GOTPLT64: 137 return R_GOTPLT_GOTREL; 138 // Relocations targeting _GLOBAL_OFFSET_TABLE_. 139 case R_390_GOTPC: 140 case R_390_GOTPCDBL: 141 return R_GOTONLY_PC; 142 // TLS-related relocations. 143 case R_390_TLS_LOAD: 144 return R_NONE; 145 case R_390_TLS_GDCALL: 146 return R_TLSGD_PC; 147 case R_390_TLS_LDCALL: 148 return R_TLSLD_PC; 149 case R_390_TLS_GD32: 150 case R_390_TLS_GD64: 151 return R_TLSGD_GOT; 152 case R_390_TLS_LDM32: 153 case R_390_TLS_LDM64: 154 return R_TLSLD_GOT; 155 case R_390_TLS_LDO32: 156 case R_390_TLS_LDO64: 157 return R_DTPREL; 158 case R_390_TLS_LE32: 159 case R_390_TLS_LE64: 160 return R_TPREL; 161 case R_390_TLS_IE32: 162 case R_390_TLS_IE64: 163 return R_GOT; 164 case R_390_TLS_GOTIE12: 165 case R_390_TLS_GOTIE20: 166 case R_390_TLS_GOTIE32: 167 case R_390_TLS_GOTIE64: 168 return R_GOT_OFF; 169 case R_390_TLS_IEENT: 170 return R_GOT_PC; 171 172 default: 173 Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v 174 << ") against symbol " << &s; 175 return R_NONE; 176 } 177 } 178 179 void SystemZ::writeGotHeader(uint8_t *buf) const { 180 // _GLOBAL_OFFSET_TABLE_[0] holds the value of _DYNAMIC. 181 // _GLOBAL_OFFSET_TABLE_[1] and [2] are reserved. 182 write64be(buf, ctx.mainPart->dynamic->getVA()); 183 } 184 185 void SystemZ::writeGotPlt(uint8_t *buf, const Symbol &s) const { 186 write64be(buf, s.getPltVA(ctx) + 14); 187 } 188 189 void SystemZ::writeIgotPlt(uint8_t *buf, const Symbol &s) const { 190 if (ctx.arg.writeAddends) 191 write64be(buf, s.getVA(ctx)); 192 } 193 194 void SystemZ::writePltHeader(uint8_t *buf) const { 195 const uint8_t pltData[] = { 196 0xe3, 0x10, 0xf0, 0x38, 0x00, 0x24, // stg %r1,56(%r15) 197 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, // larl %r1,_GLOBAL_OFFSET_TABLE_ 198 0xd2, 0x07, 0xf0, 0x30, 0x10, 0x08, // mvc 48(8,%r15),8(%r1) 199 0xe3, 0x10, 0x10, 0x10, 0x00, 0x04, // lg %r1,16(%r1) 200 0x07, 0xf1, // br %r1 201 0x07, 0x00, // nopr 202 0x07, 0x00, // nopr 203 0x07, 0x00, // nopr 204 }; 205 memcpy(buf, pltData, sizeof(pltData)); 206 uint64_t got = ctx.in.got->getVA(); 207 uint64_t plt = ctx.in.plt->getVA(); 208 write32be(buf + 8, (got - plt - 6) >> 1); 209 } 210 211 void SystemZ::addPltHeaderSymbols(InputSection &isec) const { 212 // The PLT header needs a reference to _GLOBAL_OFFSET_TABLE_, so we 213 // must ensure the .got section is created even if otherwise unused. 214 ctx.in.got->hasGotOffRel.store(true, std::memory_order_relaxed); 215 } 216 217 void SystemZ::writePlt(uint8_t *buf, const Symbol &sym, 218 uint64_t pltEntryAddr) const { 219 const uint8_t inst[] = { 220 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, // larl %r1,<.got.plt slot> 221 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, // lg %r1,0(%r1) 222 0x07, 0xf1, // br %r1 223 0x0d, 0x10, // basr %r1,%r0 224 0xe3, 0x10, 0x10, 0x0c, 0x00, 0x14, // lgf %r1,12(%r1) 225 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, // jg <plt header> 226 0x00, 0x00, 0x00, 0x00, // <relocation offset> 227 }; 228 memcpy(buf, inst, sizeof(inst)); 229 230 write32be(buf + 2, (sym.getGotPltVA(ctx) - pltEntryAddr) >> 1); 231 write32be(buf + 24, (ctx.in.plt->getVA() - pltEntryAddr - 22) >> 1); 232 write32be(buf + 28, ctx.in.relaPlt->entsize * sym.getPltIdx(ctx)); 233 } 234 235 int64_t SystemZ::getImplicitAddend(const uint8_t *buf, RelType type) const { 236 switch (type) { 237 case R_390_8: 238 return SignExtend64<8>(*buf); 239 case R_390_16: 240 case R_390_PC16: 241 return SignExtend64<16>(read16be(buf)); 242 case R_390_PC16DBL: 243 return SignExtend64<16>(read16be(buf)) << 1; 244 case R_390_32: 245 case R_390_PC32: 246 return SignExtend64<32>(read32be(buf)); 247 case R_390_PC32DBL: 248 return SignExtend64<32>(read32be(buf)) << 1; 249 case R_390_64: 250 case R_390_PC64: 251 case R_390_TLS_DTPMOD: 252 case R_390_TLS_DTPOFF: 253 case R_390_TLS_TPOFF: 254 case R_390_GLOB_DAT: 255 case R_390_RELATIVE: 256 case R_390_IRELATIVE: 257 return read64be(buf); 258 case R_390_COPY: 259 case R_390_JMP_SLOT: 260 case R_390_NONE: 261 // These relocations are defined as not having an implicit addend. 262 return 0; 263 default: 264 InternalErr(ctx, buf) << "cannot read addend for relocation " << type; 265 return 0; 266 } 267 } 268 269 RelType SystemZ::getDynRel(RelType type) const { 270 if (type == R_390_64 || type == R_390_PC64) 271 return type; 272 return R_390_NONE; 273 } 274 275 RelExpr SystemZ::adjustTlsExpr(RelType type, RelExpr expr) const { 276 if (expr == R_RELAX_TLS_GD_TO_IE) 277 return R_RELAX_TLS_GD_TO_IE_GOT_OFF; 278 return expr; 279 } 280 281 int SystemZ::getTlsGdRelaxSkip(RelType type) const { 282 // A __tls_get_offset call instruction is marked with 2 relocations: 283 // 284 // R_390_TLS_GDCALL / R_390_TLS_LDCALL: marker relocation 285 // R_390_PLT32DBL: __tls_get_offset 286 // 287 // After the relaxation we no longer call __tls_get_offset and should skip 288 // both relocations to not create a false dependence on __tls_get_offset 289 // being defined. 290 // 291 // Note that this mechanism only works correctly if the R_390_TLS_[GL]DCALL 292 // is seen immediately *before* the R_390_PLT32DBL. Unfortunately, current 293 // compilers on the platform will typically generate the inverse sequence. 294 // To fix this, we sort relocations by offset in RelocationScanner::scan; 295 // this ensures the correct sequence as the R_390_TLS_[GL]DCALL applies to 296 // the first byte of the brasl instruction, while the R_390_PLT32DBL applies 297 // to its third byte (the relative displacement). 298 299 if (type == R_390_TLS_GDCALL || type == R_390_TLS_LDCALL) 300 return 2; 301 return 1; 302 } 303 304 void SystemZ::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, 305 uint64_t val) const { 306 // The general-dynamic code sequence for a global `x`: 307 // 308 // Instruction Relocation Symbol 309 // ear %rX,%a0 310 // sllg %rX,%rX,32 311 // ear %rX,%a1 312 // larl %r12,_GLOBAL_OFFSET_TABLE_ R_390_GOTPCDBL _GLOBAL_OFFSET_TABLE_ 313 // lgrl %r2,.LC0 R_390_PC32DBL .LC0 314 // brasl %r14,__tls_get_offset@plt R_390_TLS_GDCALL x 315 // :tls_gdcall:x R_390_PLT32DBL __tls_get_offset 316 // la %r2,0(%r2,%rX) 317 // 318 // .LC0: 319 // .quad x@TLSGD R_390_TLS_GD64 x 320 // 321 // Relaxing to initial-exec entails: 322 // 1) Replacing the call by a load from the GOT. 323 // 2) Replacing the relocation on the constant LC0 by R_390_TLS_GOTIE64. 324 325 switch (rel.type) { 326 case R_390_TLS_GDCALL: 327 // brasl %r14,__tls_get_offset@plt -> lg %r2,0(%r2,%r12) 328 write16be(loc, 0xe322); 329 write32be(loc + 2, 0xc0000004); 330 break; 331 case R_390_TLS_GD64: 332 relocateNoSym(loc, R_390_TLS_GOTIE64, val); 333 break; 334 default: 335 llvm_unreachable("unsupported relocation for TLS GD to IE relaxation"); 336 } 337 } 338 339 void SystemZ::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, 340 uint64_t val) const { 341 // The general-dynamic code sequence for a global `x`: 342 // 343 // Instruction Relocation Symbol 344 // ear %rX,%a0 345 // sllg %rX,%rX,32 346 // ear %rX,%a1 347 // larl %r12,_GLOBAL_OFFSET_TABLE_ R_390_GOTPCDBL _GLOBAL_OFFSET_TABLE_ 348 // lgrl %r2,.LC0 R_390_PC32DBL .LC0 349 // brasl %r14,__tls_get_offset@plt R_390_TLS_GDCALL x 350 // :tls_gdcall:x R_390_PLT32DBL __tls_get_offset 351 // la %r2,0(%r2,%rX) 352 // 353 // .LC0: 354 // .quad x@tlsgd R_390_TLS_GD64 x 355 // 356 // Relaxing to local-exec entails: 357 // 1) Replacing the call by a nop. 358 // 2) Replacing the relocation on the constant LC0 by R_390_TLS_LE64. 359 360 switch (rel.type) { 361 case R_390_TLS_GDCALL: 362 // brasl %r14,__tls_get_offset@plt -> brcl 0,. 363 write16be(loc, 0xc004); 364 write32be(loc + 2, 0x00000000); 365 break; 366 case R_390_TLS_GD64: 367 relocateNoSym(loc, R_390_TLS_LE64, val); 368 break; 369 default: 370 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation"); 371 } 372 } 373 374 void SystemZ::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, 375 uint64_t val) const { 376 // The local-dynamic code sequence for a global `x`: 377 // 378 // Instruction Relocation Symbol 379 // ear %rX,%a0 380 // sllg %rX,%rX,32 381 // ear %rX,%a1 382 // larl %r12,_GLOBAL_OFFSET_TABLE_ R_390_GOTPCDBL _GLOBAL_OFFSET_TABLE_ 383 // lgrl %r2,.LC0 R_390_PC32DBL .LC0 384 // brasl %r14,__tls_get_offset@plt R_390_TLS_LDCALL <sym> 385 // :tls_ldcall:<sym> R_390_PLT32DBL __tls_get_offset 386 // la %r2,0(%r2,%rX) 387 // lgrl %rY,.LC1 R_390_PC32DBL .LC1 388 // la %r2,0(%r2,%rY) 389 // 390 // .LC0: 391 // .quad <sym>@tlsldm R_390_TLS_LDM64 <sym> 392 // .LC1: 393 // .quad x@dtpoff R_390_TLS_LDO64 x 394 // 395 // Relaxing to local-exec entails: 396 // 1) Replacing the call by a nop. 397 // 2) Replacing the constant LC0 by 0 (i.e. ignoring the relocation). 398 // 3) Replacing the relocation on the constant LC1 by R_390_TLS_LE64. 399 400 switch (rel.type) { 401 case R_390_TLS_LDCALL: 402 // brasl %r14,__tls_get_offset@plt -> brcl 0,. 403 write16be(loc, 0xc004); 404 write32be(loc + 2, 0x00000000); 405 break; 406 case R_390_TLS_LDM64: 407 break; 408 case R_390_TLS_LDO64: 409 relocateNoSym(loc, R_390_TLS_LE64, val); 410 break; 411 default: 412 llvm_unreachable("unsupported relocation for TLS LD to LE relaxation"); 413 } 414 } 415 416 RelExpr SystemZ::adjustGotPcExpr(RelType type, int64_t addend, 417 const uint8_t *loc) const { 418 // Only R_390_GOTENT with addend 2 can be relaxed. 419 if (!ctx.arg.relax || addend != 2 || type != R_390_GOTENT) 420 return R_GOT_PC; 421 const uint16_t op = read16be(loc - 2); 422 423 // lgrl rx,sym@GOTENT -> larl rx, sym 424 // This relaxation is legal if "sym" binds locally (which was already 425 // verified by our caller) and is in-range and properly aligned for a 426 // LARL instruction. We cannot verify the latter constraint here, so 427 // we assume it is true and revert the decision later on in relaxOnce 428 // if necessary. 429 if ((op & 0xff0f) == 0xc408) 430 return R_RELAX_GOT_PC; 431 432 return R_GOT_PC; 433 } 434 435 bool SystemZ::relaxOnce(int pass) const { 436 // If we decided in adjustGotPcExpr to relax a R_390_GOTENT, 437 // we need to validate the target symbol is in-range and aligned. 438 SmallVector<InputSection *, 0> storage; 439 bool changed = false; 440 for (OutputSection *osec : ctx.outputSections) { 441 if (!(osec->flags & SHF_EXECINSTR)) 442 continue; 443 for (InputSection *sec : getInputSections(*osec, storage)) { 444 for (Relocation &rel : sec->relocs()) { 445 if (rel.expr != R_RELAX_GOT_PC) 446 continue; 447 448 uint64_t v = sec->getRelocTargetVA( 449 ctx, rel, sec->getOutputSection()->addr + rel.offset); 450 if (isInt<33>(v) && !(v & 1)) 451 continue; 452 if (rel.sym->auxIdx == 0) { 453 rel.sym->allocateAux(ctx); 454 addGotEntry(ctx, *rel.sym); 455 changed = true; 456 } 457 rel.expr = R_GOT_PC; 458 } 459 } 460 } 461 return changed; 462 } 463 464 void SystemZ::relaxGot(uint8_t *loc, const Relocation &rel, 465 uint64_t val) const { 466 assert(isInt<33>(val) && 467 "R_390_GOTENT should not have been relaxed if it overflows"); 468 assert(!(val & 1) && 469 "R_390_GOTENT should not have been relaxed if it is misaligned"); 470 const uint16_t op = read16be(loc - 2); 471 472 // lgrl rx,sym@GOTENT -> larl rx, sym 473 if ((op & 0xff0f) == 0xc408) { 474 write16be(loc - 2, 0xc000 | (op & 0x00f0)); 475 write32be(loc, val >> 1); 476 } 477 } 478 479 void SystemZ::relocate(uint8_t *loc, const Relocation &rel, 480 uint64_t val) const { 481 switch (rel.expr) { 482 case R_RELAX_GOT_PC: 483 return relaxGot(loc, rel, val); 484 case R_RELAX_TLS_GD_TO_IE_GOT_OFF: 485 return relaxTlsGdToIe(loc, rel, val); 486 case R_RELAX_TLS_GD_TO_LE: 487 return relaxTlsGdToLe(loc, rel, val); 488 case R_RELAX_TLS_LD_TO_LE: 489 return relaxTlsLdToLe(loc, rel, val); 490 default: 491 break; 492 } 493 switch (rel.type) { 494 case R_390_8: 495 checkIntUInt(ctx, loc, val, 8, rel); 496 *loc = val; 497 break; 498 case R_390_12: 499 case R_390_GOT12: 500 case R_390_GOTPLT12: 501 case R_390_TLS_GOTIE12: 502 checkUInt(ctx, loc, val, 12, rel); 503 write16be(loc, (read16be(loc) & 0xF000) | val); 504 break; 505 case R_390_PC12DBL: 506 case R_390_PLT12DBL: 507 checkInt(ctx, loc, val, 13, rel); 508 checkAlignment(ctx, loc, val, 2, rel); 509 write16be(loc, (read16be(loc) & 0xF000) | ((val >> 1) & 0x0FFF)); 510 break; 511 case R_390_16: 512 case R_390_GOT16: 513 case R_390_GOTPLT16: 514 case R_390_GOTOFF16: 515 case R_390_PLTOFF16: 516 checkIntUInt(ctx, loc, val, 16, rel); 517 write16be(loc, val); 518 break; 519 case R_390_PC16: 520 checkInt(ctx, loc, val, 16, rel); 521 write16be(loc, val); 522 break; 523 case R_390_PC16DBL: 524 case R_390_PLT16DBL: 525 checkInt(ctx, loc, val, 17, rel); 526 checkAlignment(ctx, loc, val, 2, rel); 527 write16be(loc, val >> 1); 528 break; 529 case R_390_20: 530 case R_390_GOT20: 531 case R_390_GOTPLT20: 532 case R_390_TLS_GOTIE20: 533 checkInt(ctx, loc, val, 20, rel); 534 write32be(loc, (read32be(loc) & 0xF00000FF) | ((val & 0xFFF) << 16) | 535 ((val & 0xFF000) >> 4)); 536 break; 537 case R_390_PC24DBL: 538 case R_390_PLT24DBL: 539 checkInt(ctx, loc, val, 25, rel); 540 checkAlignment(ctx, loc, val, 2, rel); 541 loc[0] = val >> 17; 542 loc[1] = val >> 9; 543 loc[2] = val >> 1; 544 break; 545 case R_390_32: 546 case R_390_GOT32: 547 case R_390_GOTPLT32: 548 case R_390_GOTOFF: 549 case R_390_PLTOFF32: 550 case R_390_TLS_IE32: 551 case R_390_TLS_GOTIE32: 552 case R_390_TLS_GD32: 553 case R_390_TLS_LDM32: 554 case R_390_TLS_LDO32: 555 case R_390_TLS_LE32: 556 checkIntUInt(ctx, loc, val, 32, rel); 557 write32be(loc, val); 558 break; 559 case R_390_PC32: 560 case R_390_PLT32: 561 checkInt(ctx, loc, val, 32, rel); 562 write32be(loc, val); 563 break; 564 case R_390_PC32DBL: 565 case R_390_PLT32DBL: 566 case R_390_GOTPCDBL: 567 case R_390_GOTENT: 568 case R_390_GOTPLTENT: 569 case R_390_TLS_IEENT: 570 checkInt(ctx, loc, val, 33, rel); 571 checkAlignment(ctx, loc, val, 2, rel); 572 write32be(loc, val >> 1); 573 break; 574 case R_390_64: 575 case R_390_PC64: 576 case R_390_PLT64: 577 case R_390_GOT64: 578 case R_390_GOTPLT64: 579 case R_390_GOTOFF64: 580 case R_390_PLTOFF64: 581 case R_390_GOTPC: 582 case R_390_TLS_IE64: 583 case R_390_TLS_GOTIE64: 584 case R_390_TLS_GD64: 585 case R_390_TLS_LDM64: 586 case R_390_TLS_LDO64: 587 case R_390_TLS_LE64: 588 case R_390_TLS_DTPMOD: 589 case R_390_TLS_DTPOFF: 590 case R_390_TLS_TPOFF: 591 write64be(loc, val); 592 break; 593 case R_390_TLS_LOAD: 594 case R_390_TLS_GDCALL: 595 case R_390_TLS_LDCALL: 596 break; 597 default: 598 llvm_unreachable("unknown relocation"); 599 } 600 } 601 602 void elf::setSystemZTargetInfo(Ctx &ctx) { ctx.target.reset(new SystemZ(ctx)); } 603