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