Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lld/ELF/Arch/SystemZ.cpp
34878 views
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
609