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
17using namespace llvm;
18using namespace llvm::support::endian;
19using namespace llvm::ELF;
20using namespace lld;
21using namespace lld::elf;
22
23namespace {
24class SystemZ : public TargetInfo {
25public:
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
46private:
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
54SystemZ::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
83RelExpr 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
179void 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
185void SystemZ::writeGotPlt(uint8_t *buf, const Symbol &s) const {
186  write64be(buf, s.getPltVA() + 14);
187}
188
189void SystemZ::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
190  if (config->writeAddends)
191    write64be(buf, s.getVA());
192}
193
194void 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
211void 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
217void 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
235int64_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
270RelType 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
276RelExpr 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
282int 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
305void 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
340void 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
375void 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
417RelExpr 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
436bool 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
466void 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
481void 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
604TargetInfo *elf::getSystemZTargetInfo() {
605  static SystemZ t;
606  return &t;
607}
608