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(); 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() { 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 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) + 174 ") against symbol " + toString(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, mainPart->dynamic->getVA()); 183 } 184 185 void SystemZ::writeGotPlt(uint8_t *buf, const Symbol &s) const { 186 write64be(buf, s.getPltVA() + 14); 187 } 188 189 void SystemZ::writeIgotPlt(uint8_t *buf, const Symbol &s) const { 190 if (config->writeAddends) 191 write64be(buf, s.getVA()); 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 = in.got->getVA(); 207 uint64_t plt = 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 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() - pltEntryAddr) >> 1); 231 write32be(buf + 24, (in.plt->getVA() - pltEntryAddr - 22) >> 1); 232 write32be(buf + 28, in.relaPlt->entsize * sym.getPltIdx()); 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 internalLinkerError(getErrorLocation(buf), 265 "cannot read addend for relocation " + toString(type)); 266 return 0; 267 } 268 } 269 270 RelType SystemZ::getDynRel(RelType type) const { 271 if (type == R_390_64 || type == R_390_PC64) 272 return type; 273 return R_390_NONE; 274 } 275 276 RelExpr SystemZ::adjustTlsExpr(RelType type, RelExpr expr) const { 277 if (expr == R_RELAX_TLS_GD_TO_IE) 278 return R_RELAX_TLS_GD_TO_IE_GOT_OFF; 279 return expr; 280 } 281 282 int SystemZ::getTlsGdRelaxSkip(RelType type) const { 283 // A __tls_get_offset call instruction is marked with 2 relocations: 284 // 285 // R_390_TLS_GDCALL / R_390_TLS_LDCALL: marker relocation 286 // R_390_PLT32DBL: __tls_get_offset 287 // 288 // After the relaxation we no longer call __tls_get_offset and should skip 289 // both relocations to not create a false dependence on __tls_get_offset 290 // being defined. 291 // 292 // Note that this mechanism only works correctly if the R_390_TLS_[GL]DCALL 293 // is seen immediately *before* the R_390_PLT32DBL. Unfortunately, current 294 // compilers on the platform will typically generate the inverse sequence. 295 // To fix this, we sort relocations by offset in RelocationScanner::scan; 296 // this ensures the correct sequence as the R_390_TLS_[GL]DCALL applies to 297 // the first byte of the brasl instruction, while the R_390_PLT32DBL applies 298 // to its third byte (the relative displacement). 299 300 if (type == R_390_TLS_GDCALL || type == R_390_TLS_LDCALL) 301 return 2; 302 return 1; 303 } 304 305 void SystemZ::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, 306 uint64_t val) const { 307 // The general-dynamic code sequence for a global `x`: 308 // 309 // Instruction Relocation Symbol 310 // ear %rX,%a0 311 // sllg %rX,%rX,32 312 // ear %rX,%a1 313 // larl %r12,_GLOBAL_OFFSET_TABLE_ R_390_GOTPCDBL _GLOBAL_OFFSET_TABLE_ 314 // lgrl %r2,.LC0 R_390_PC32DBL .LC0 315 // brasl %r14,__tls_get_offset@plt R_390_TLS_GDCALL x 316 // :tls_gdcall:x R_390_PLT32DBL __tls_get_offset 317 // la %r2,0(%r2,%rX) 318 // 319 // .LC0: 320 // .quad x@TLSGD R_390_TLS_GD64 x 321 // 322 // Relaxing to initial-exec entails: 323 // 1) Replacing the call by a load from the GOT. 324 // 2) Replacing the relocation on the constant LC0 by R_390_TLS_GOTIE64. 325 326 switch (rel.type) { 327 case R_390_TLS_GDCALL: 328 // brasl %r14,__tls_get_offset@plt -> lg %r2,0(%r2,%r12) 329 write16be(loc, 0xe322); 330 write32be(loc + 2, 0xc0000004); 331 break; 332 case R_390_TLS_GD64: 333 relocateNoSym(loc, R_390_TLS_GOTIE64, val); 334 break; 335 default: 336 llvm_unreachable("unsupported relocation for TLS GD to IE relaxation"); 337 } 338 } 339 340 void SystemZ::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, 341 uint64_t val) const { 342 // The general-dynamic code sequence for a global `x`: 343 // 344 // Instruction Relocation Symbol 345 // ear %rX,%a0 346 // sllg %rX,%rX,32 347 // ear %rX,%a1 348 // larl %r12,_GLOBAL_OFFSET_TABLE_ R_390_GOTPCDBL _GLOBAL_OFFSET_TABLE_ 349 // lgrl %r2,.LC0 R_390_PC32DBL .LC0 350 // brasl %r14,__tls_get_offset@plt R_390_TLS_GDCALL x 351 // :tls_gdcall:x R_390_PLT32DBL __tls_get_offset 352 // la %r2,0(%r2,%rX) 353 // 354 // .LC0: 355 // .quad x@tlsgd R_390_TLS_GD64 x 356 // 357 // Relaxing to local-exec entails: 358 // 1) Replacing the call by a nop. 359 // 2) Replacing the relocation on the constant LC0 by R_390_TLS_LE64. 360 361 switch (rel.type) { 362 case R_390_TLS_GDCALL: 363 // brasl %r14,__tls_get_offset@plt -> brcl 0,. 364 write16be(loc, 0xc004); 365 write32be(loc + 2, 0x00000000); 366 break; 367 case R_390_TLS_GD64: 368 relocateNoSym(loc, R_390_TLS_LE64, val); 369 break; 370 default: 371 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation"); 372 } 373 } 374 375 void SystemZ::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, 376 uint64_t val) const { 377 // The local-dynamic code sequence for a global `x`: 378 // 379 // Instruction Relocation Symbol 380 // ear %rX,%a0 381 // sllg %rX,%rX,32 382 // ear %rX,%a1 383 // larl %r12,_GLOBAL_OFFSET_TABLE_ R_390_GOTPCDBL _GLOBAL_OFFSET_TABLE_ 384 // lgrl %r2,.LC0 R_390_PC32DBL .LC0 385 // brasl %r14,__tls_get_offset@plt R_390_TLS_LDCALL <sym> 386 // :tls_ldcall:<sym> R_390_PLT32DBL __tls_get_offset 387 // la %r2,0(%r2,%rX) 388 // lgrl %rY,.LC1 R_390_PC32DBL .LC1 389 // la %r2,0(%r2,%rY) 390 // 391 // .LC0: 392 // .quad <sym>@tlsldm R_390_TLS_LDM64 <sym> 393 // .LC1: 394 // .quad x@dtpoff R_390_TLS_LDO64 x 395 // 396 // Relaxing to local-exec entails: 397 // 1) Replacing the call by a nop. 398 // 2) Replacing the constant LC0 by 0 (i.e. ignoring the relocation). 399 // 3) Replacing the relocation on the constant LC1 by R_390_TLS_LE64. 400 401 switch (rel.type) { 402 case R_390_TLS_LDCALL: 403 // brasl %r14,__tls_get_offset@plt -> brcl 0,. 404 write16be(loc, 0xc004); 405 write32be(loc + 2, 0x00000000); 406 break; 407 case R_390_TLS_LDM64: 408 break; 409 case R_390_TLS_LDO64: 410 relocateNoSym(loc, R_390_TLS_LE64, val); 411 break; 412 default: 413 llvm_unreachable("unsupported relocation for TLS LD to LE relaxation"); 414 } 415 } 416 417 RelExpr SystemZ::adjustGotPcExpr(RelType type, int64_t addend, 418 const uint8_t *loc) const { 419 // Only R_390_GOTENT with addend 2 can be relaxed. 420 if (!config->relax || addend != 2 || type != R_390_GOTENT) 421 return R_GOT_PC; 422 const uint16_t op = read16be(loc - 2); 423 424 // lgrl rx,sym@GOTENT -> larl rx, sym 425 // This relaxation is legal if "sym" binds locally (which was already 426 // verified by our caller) and is in-range and properly aligned for a 427 // LARL instruction. We cannot verify the latter constraint here, so 428 // we assume it is true and revert the decision later on in relaxOnce 429 // if necessary. 430 if ((op & 0xff0f) == 0xc408) 431 return R_RELAX_GOT_PC; 432 433 return R_GOT_PC; 434 } 435 436 bool SystemZ::relaxOnce(int pass) const { 437 // If we decided in adjustGotPcExpr to relax a R_390_GOTENT, 438 // we need to validate the target symbol is in-range and aligned. 439 SmallVector<InputSection *, 0> storage; 440 bool changed = false; 441 for (OutputSection *osec : outputSections) { 442 if (!(osec->flags & SHF_EXECINSTR)) 443 continue; 444 for (InputSection *sec : getInputSections(*osec, storage)) { 445 for (Relocation &rel : sec->relocs()) { 446 if (rel.expr != R_RELAX_GOT_PC) 447 continue; 448 449 uint64_t v = sec->getRelocTargetVA( 450 sec->file, rel.type, rel.addend, 451 sec->getOutputSection()->addr + rel.offset, *rel.sym, rel.expr); 452 if (isInt<33>(v) && !(v & 1)) 453 continue; 454 if (rel.sym->auxIdx == 0) { 455 rel.sym->allocateAux(); 456 addGotEntry(*rel.sym); 457 changed = true; 458 } 459 rel.expr = R_GOT_PC; 460 } 461 } 462 } 463 return changed; 464 } 465 466 void SystemZ::relaxGot(uint8_t *loc, const Relocation &rel, 467 uint64_t val) const { 468 assert(isInt<33>(val) && 469 "R_390_GOTENT should not have been relaxed if it overflows"); 470 assert(!(val & 1) && 471 "R_390_GOTENT should not have been relaxed if it is misaligned"); 472 const uint16_t op = read16be(loc - 2); 473 474 // lgrl rx,sym@GOTENT -> larl rx, sym 475 if ((op & 0xff0f) == 0xc408) { 476 write16be(loc - 2, 0xc000 | (op & 0x00f0)); 477 write32be(loc, val >> 1); 478 } 479 } 480 481 void SystemZ::relocate(uint8_t *loc, const Relocation &rel, 482 uint64_t val) const { 483 switch (rel.expr) { 484 case R_RELAX_GOT_PC: 485 return relaxGot(loc, rel, val); 486 case R_RELAX_TLS_GD_TO_IE_GOT_OFF: 487 return relaxTlsGdToIe(loc, rel, val); 488 case R_RELAX_TLS_GD_TO_LE: 489 return relaxTlsGdToLe(loc, rel, val); 490 case R_RELAX_TLS_LD_TO_LE: 491 return relaxTlsLdToLe(loc, rel, val); 492 default: 493 break; 494 } 495 switch (rel.type) { 496 case R_390_8: 497 checkIntUInt(loc, val, 8, rel); 498 *loc = val; 499 break; 500 case R_390_12: 501 case R_390_GOT12: 502 case R_390_GOTPLT12: 503 case R_390_TLS_GOTIE12: 504 checkUInt(loc, val, 12, rel); 505 write16be(loc, (read16be(loc) & 0xF000) | val); 506 break; 507 case R_390_PC12DBL: 508 case R_390_PLT12DBL: 509 checkInt(loc, val, 13, rel); 510 checkAlignment(loc, val, 2, rel); 511 write16be(loc, (read16be(loc) & 0xF000) | ((val >> 1) & 0x0FFF)); 512 break; 513 case R_390_16: 514 case R_390_GOT16: 515 case R_390_GOTPLT16: 516 case R_390_GOTOFF16: 517 case R_390_PLTOFF16: 518 checkIntUInt(loc, val, 16, rel); 519 write16be(loc, val); 520 break; 521 case R_390_PC16: 522 checkInt(loc, val, 16, rel); 523 write16be(loc, val); 524 break; 525 case R_390_PC16DBL: 526 case R_390_PLT16DBL: 527 checkInt(loc, val, 17, rel); 528 checkAlignment(loc, val, 2, rel); 529 write16be(loc, val >> 1); 530 break; 531 case R_390_20: 532 case R_390_GOT20: 533 case R_390_GOTPLT20: 534 case R_390_TLS_GOTIE20: 535 checkInt(loc, val, 20, rel); 536 write32be(loc, (read32be(loc) & 0xF00000FF) | ((val & 0xFFF) << 16) | 537 ((val & 0xFF000) >> 4)); 538 break; 539 case R_390_PC24DBL: 540 case R_390_PLT24DBL: 541 checkInt(loc, val, 25, rel); 542 checkAlignment(loc, val, 2, rel); 543 loc[0] = val >> 17; 544 loc[1] = val >> 9; 545 loc[2] = val >> 1; 546 break; 547 case R_390_32: 548 case R_390_GOT32: 549 case R_390_GOTPLT32: 550 case R_390_GOTOFF: 551 case R_390_PLTOFF32: 552 case R_390_TLS_IE32: 553 case R_390_TLS_GOTIE32: 554 case R_390_TLS_GD32: 555 case R_390_TLS_LDM32: 556 case R_390_TLS_LDO32: 557 case R_390_TLS_LE32: 558 checkIntUInt(loc, val, 32, rel); 559 write32be(loc, val); 560 break; 561 case R_390_PC32: 562 case R_390_PLT32: 563 checkInt(loc, val, 32, rel); 564 write32be(loc, val); 565 break; 566 case R_390_PC32DBL: 567 case R_390_PLT32DBL: 568 case R_390_GOTPCDBL: 569 case R_390_GOTENT: 570 case R_390_GOTPLTENT: 571 case R_390_TLS_IEENT: 572 checkInt(loc, val, 33, rel); 573 checkAlignment(loc, val, 2, rel); 574 write32be(loc, val >> 1); 575 break; 576 case R_390_64: 577 case R_390_PC64: 578 case R_390_PLT64: 579 case R_390_GOT64: 580 case R_390_GOTPLT64: 581 case R_390_GOTOFF64: 582 case R_390_PLTOFF64: 583 case R_390_GOTPC: 584 case R_390_TLS_IE64: 585 case R_390_TLS_GOTIE64: 586 case R_390_TLS_GD64: 587 case R_390_TLS_LDM64: 588 case R_390_TLS_LDO64: 589 case R_390_TLS_LE64: 590 case R_390_TLS_DTPMOD: 591 case R_390_TLS_DTPOFF: 592 case R_390_TLS_TPOFF: 593 write64be(loc, val); 594 break; 595 case R_390_TLS_LOAD: 596 case R_390_TLS_GDCALL: 597 case R_390_TLS_LDCALL: 598 break; 599 default: 600 llvm_unreachable("unknown relocation"); 601 } 602 } 603 604 TargetInfo *elf::getSystemZTargetInfo() { 605 static SystemZ t; 606 return &t; 607 } 608