[Github] Move agent container to separate tar archive
[llvm-project.git] / llvm / lib / Target / PowerPC / MCTargetDesc / PPCELFObjectWriter.cpp
blobd2fcb9766d7888268797e7bb9b96219c4097216f
1 //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/PPCFixupKinds.h"
10 #include "MCTargetDesc/PPCMCExpr.h"
11 #include "MCTargetDesc/PPCMCTargetDesc.h"
12 #include "llvm/MC/MCELFObjectWriter.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCObjectWriter.h"
15 #include "llvm/MC/MCSymbolELF.h"
16 #include "llvm/MC/MCValue.h"
17 #include "llvm/Support/ErrorHandling.h"
19 using namespace llvm;
21 namespace {
22 class PPCELFObjectWriter : public MCELFObjectTargetWriter {
23 public:
24 PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
26 protected:
27 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
28 const MCFixup &Fixup, bool IsPCRel) const override;
30 bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
31 unsigned Type) const override;
35 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
36 : MCELFObjectTargetWriter(Is64Bit, OSABI,
37 Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC,
38 /*HasRelocationAddend*/ true) {}
40 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
41 const MCFixup &Fixup) {
42 const MCExpr *Expr = Fixup.getValue();
44 if (Expr->getKind() != MCExpr::Target)
45 return Target.getAccessVariant();
47 switch (cast<PPCMCExpr>(Expr)->getKind()) {
48 case PPCMCExpr::VK_PPC_None:
49 return MCSymbolRefExpr::VK_None;
50 case PPCMCExpr::VK_PPC_LO:
51 return MCSymbolRefExpr::VK_PPC_LO;
52 case PPCMCExpr::VK_PPC_HI:
53 return MCSymbolRefExpr::VK_PPC_HI;
54 case PPCMCExpr::VK_PPC_HA:
55 return MCSymbolRefExpr::VK_PPC_HA;
56 case PPCMCExpr::VK_PPC_HIGH:
57 return MCSymbolRefExpr::VK_PPC_HIGH;
58 case PPCMCExpr::VK_PPC_HIGHA:
59 return MCSymbolRefExpr::VK_PPC_HIGHA;
60 case PPCMCExpr::VK_PPC_HIGHERA:
61 return MCSymbolRefExpr::VK_PPC_HIGHERA;
62 case PPCMCExpr::VK_PPC_HIGHER:
63 return MCSymbolRefExpr::VK_PPC_HIGHER;
64 case PPCMCExpr::VK_PPC_HIGHEST:
65 return MCSymbolRefExpr::VK_PPC_HIGHEST;
66 case PPCMCExpr::VK_PPC_HIGHESTA:
67 return MCSymbolRefExpr::VK_PPC_HIGHESTA;
69 llvm_unreachable("unknown PPCMCExpr kind");
72 unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
73 const MCFixup &Fixup,
74 bool IsPCRel) const {
75 MCFixupKind Kind = Fixup.getKind();
76 if (Kind >= FirstLiteralRelocationKind)
77 return Kind - FirstLiteralRelocationKind;
78 MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
80 // determine the type of the relocation
81 unsigned Type;
82 if (IsPCRel) {
83 switch (Fixup.getTargetKind()) {
84 default:
85 llvm_unreachable("Unimplemented");
86 case PPC::fixup_ppc_br24:
87 case PPC::fixup_ppc_br24abs:
88 case PPC::fixup_ppc_br24_notoc:
89 switch (Modifier) {
90 default: llvm_unreachable("Unsupported Modifier");
91 case MCSymbolRefExpr::VK_None:
92 Type = ELF::R_PPC_REL24;
93 break;
94 case MCSymbolRefExpr::VK_PLT:
95 Type = ELF::R_PPC_PLTREL24;
96 break;
97 case MCSymbolRefExpr::VK_PPC_LOCAL:
98 Type = ELF::R_PPC_LOCAL24PC;
99 break;
100 case MCSymbolRefExpr::VK_PPC_NOTOC:
101 Type = ELF::R_PPC64_REL24_NOTOC;
102 break;
104 break;
105 case PPC::fixup_ppc_brcond14:
106 case PPC::fixup_ppc_brcond14abs:
107 Type = ELF::R_PPC_REL14;
108 break;
109 case PPC::fixup_ppc_half16:
110 switch (Modifier) {
111 default: llvm_unreachable("Unsupported Modifier");
112 case MCSymbolRefExpr::VK_None:
113 Type = ELF::R_PPC_REL16;
114 break;
115 case MCSymbolRefExpr::VK_PPC_LO:
116 Type = ELF::R_PPC_REL16_LO;
117 break;
118 case MCSymbolRefExpr::VK_PPC_HI:
119 Type = ELF::R_PPC_REL16_HI;
120 break;
121 case MCSymbolRefExpr::VK_PPC_HA:
122 Type = ELF::R_PPC_REL16_HA;
123 break;
125 break;
126 case PPC::fixup_ppc_half16ds:
127 case PPC::fixup_ppc_half16dq:
128 Target.print(errs());
129 errs() << '\n';
130 report_fatal_error("Invalid PC-relative half16ds relocation");
131 case PPC::fixup_ppc_pcrel34:
132 switch (Modifier) {
133 default:
134 llvm_unreachable("Unsupported Modifier for fixup_ppc_pcrel34");
135 case MCSymbolRefExpr::VK_PCREL:
136 Type = ELF::R_PPC64_PCREL34;
137 break;
138 case MCSymbolRefExpr::VK_PPC_GOT_PCREL:
139 Type = ELF::R_PPC64_GOT_PCREL34;
140 break;
141 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
142 Type = ELF::R_PPC64_GOT_TLSGD_PCREL34;
143 break;
144 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL:
145 Type = ELF::R_PPC64_GOT_TLSLD_PCREL34;
146 break;
147 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
148 Type = ELF::R_PPC64_GOT_TPREL_PCREL34;
149 break;
151 break;
152 case FK_Data_4:
153 case FK_PCRel_4:
154 Type = ELF::R_PPC_REL32;
155 break;
156 case FK_Data_8:
157 case FK_PCRel_8:
158 Type = ELF::R_PPC64_REL64;
159 break;
161 } else {
162 switch (Fixup.getTargetKind()) {
163 default: llvm_unreachable("invalid fixup kind!");
164 case PPC::fixup_ppc_br24abs:
165 Type = ELF::R_PPC_ADDR24;
166 break;
167 case PPC::fixup_ppc_brcond14abs:
168 Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
169 break;
170 case PPC::fixup_ppc_half16:
171 switch (Modifier) {
172 default: llvm_unreachable("Unsupported Modifier");
173 case MCSymbolRefExpr::VK_None:
174 Type = ELF::R_PPC_ADDR16;
175 break;
176 case MCSymbolRefExpr::VK_PPC_LO:
177 Type = ELF::R_PPC_ADDR16_LO;
178 break;
179 case MCSymbolRefExpr::VK_PPC_HI:
180 Type = ELF::R_PPC_ADDR16_HI;
181 break;
182 case MCSymbolRefExpr::VK_PPC_HA:
183 Type = ELF::R_PPC_ADDR16_HA;
184 break;
185 case MCSymbolRefExpr::VK_PPC_HIGH:
186 Type = ELF::R_PPC64_ADDR16_HIGH;
187 break;
188 case MCSymbolRefExpr::VK_PPC_HIGHA:
189 Type = ELF::R_PPC64_ADDR16_HIGHA;
190 break;
191 case MCSymbolRefExpr::VK_PPC_HIGHER:
192 Type = ELF::R_PPC64_ADDR16_HIGHER;
193 break;
194 case MCSymbolRefExpr::VK_PPC_HIGHERA:
195 Type = ELF::R_PPC64_ADDR16_HIGHERA;
196 break;
197 case MCSymbolRefExpr::VK_PPC_HIGHEST:
198 Type = ELF::R_PPC64_ADDR16_HIGHEST;
199 break;
200 case MCSymbolRefExpr::VK_PPC_HIGHESTA:
201 Type = ELF::R_PPC64_ADDR16_HIGHESTA;
202 break;
203 case MCSymbolRefExpr::VK_GOT:
204 Type = ELF::R_PPC_GOT16;
205 break;
206 case MCSymbolRefExpr::VK_PPC_GOT_LO:
207 Type = ELF::R_PPC_GOT16_LO;
208 break;
209 case MCSymbolRefExpr::VK_PPC_GOT_HI:
210 Type = ELF::R_PPC_GOT16_HI;
211 break;
212 case MCSymbolRefExpr::VK_PPC_GOT_HA:
213 Type = ELF::R_PPC_GOT16_HA;
214 break;
215 case MCSymbolRefExpr::VK_PPC_TOC:
216 Type = ELF::R_PPC64_TOC16;
217 break;
218 case MCSymbolRefExpr::VK_PPC_TOC_LO:
219 Type = ELF::R_PPC64_TOC16_LO;
220 break;
221 case MCSymbolRefExpr::VK_PPC_TOC_HI:
222 Type = ELF::R_PPC64_TOC16_HI;
223 break;
224 case MCSymbolRefExpr::VK_PPC_TOC_HA:
225 Type = ELF::R_PPC64_TOC16_HA;
226 break;
227 case MCSymbolRefExpr::VK_TPREL:
228 Type = ELF::R_PPC_TPREL16;
229 break;
230 case MCSymbolRefExpr::VK_PPC_TPREL_LO:
231 Type = ELF::R_PPC_TPREL16_LO;
232 break;
233 case MCSymbolRefExpr::VK_PPC_TPREL_HI:
234 Type = ELF::R_PPC_TPREL16_HI;
235 break;
236 case MCSymbolRefExpr::VK_PPC_TPREL_HA:
237 Type = ELF::R_PPC_TPREL16_HA;
238 break;
239 case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
240 Type = ELF::R_PPC64_TPREL16_HIGH;
241 break;
242 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
243 Type = ELF::R_PPC64_TPREL16_HIGHA;
244 break;
245 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
246 Type = ELF::R_PPC64_TPREL16_HIGHER;
247 break;
248 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
249 Type = ELF::R_PPC64_TPREL16_HIGHERA;
250 break;
251 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
252 Type = ELF::R_PPC64_TPREL16_HIGHEST;
253 break;
254 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
255 Type = ELF::R_PPC64_TPREL16_HIGHESTA;
256 break;
257 case MCSymbolRefExpr::VK_DTPREL:
258 Type = ELF::R_PPC64_DTPREL16;
259 break;
260 case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
261 Type = ELF::R_PPC64_DTPREL16_LO;
262 break;
263 case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
264 Type = ELF::R_PPC64_DTPREL16_HI;
265 break;
266 case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
267 Type = ELF::R_PPC64_DTPREL16_HA;
268 break;
269 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
270 Type = ELF::R_PPC64_DTPREL16_HIGH;
271 break;
272 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
273 Type = ELF::R_PPC64_DTPREL16_HIGHA;
274 break;
275 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
276 Type = ELF::R_PPC64_DTPREL16_HIGHER;
277 break;
278 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
279 Type = ELF::R_PPC64_DTPREL16_HIGHERA;
280 break;
281 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
282 Type = ELF::R_PPC64_DTPREL16_HIGHEST;
283 break;
284 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
285 Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
286 break;
287 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
288 if (is64Bit())
289 Type = ELF::R_PPC64_GOT_TLSGD16;
290 else
291 Type = ELF::R_PPC_GOT_TLSGD16;
292 break;
293 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
294 Type = ELF::R_PPC64_GOT_TLSGD16_LO;
295 break;
296 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
297 Type = ELF::R_PPC64_GOT_TLSGD16_HI;
298 break;
299 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
300 Type = ELF::R_PPC64_GOT_TLSGD16_HA;
301 break;
302 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
303 if (is64Bit())
304 Type = ELF::R_PPC64_GOT_TLSLD16;
305 else
306 Type = ELF::R_PPC_GOT_TLSLD16;
307 break;
308 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
309 Type = ELF::R_PPC64_GOT_TLSLD16_LO;
310 break;
311 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
312 Type = ELF::R_PPC64_GOT_TLSLD16_HI;
313 break;
314 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
315 Type = ELF::R_PPC64_GOT_TLSLD16_HA;
316 break;
317 case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
318 /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
319 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */
320 Type = ELF::R_PPC64_GOT_TPREL16_DS;
321 break;
322 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
323 /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
324 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */
325 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
326 break;
327 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
328 Type = ELF::R_PPC64_GOT_TPREL16_HI;
329 break;
330 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
331 /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
332 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */
333 Type = ELF::R_PPC64_GOT_DTPREL16_DS;
334 break;
335 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
336 /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
337 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */
338 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
339 break;
340 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
341 Type = ELF::R_PPC64_GOT_TPREL16_HA;
342 break;
343 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
344 Type = ELF::R_PPC64_GOT_DTPREL16_HI;
345 break;
346 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
347 Type = ELF::R_PPC64_GOT_DTPREL16_HA;
348 break;
350 break;
351 case PPC::fixup_ppc_half16ds:
352 case PPC::fixup_ppc_half16dq:
353 switch (Modifier) {
354 default: llvm_unreachable("Unsupported Modifier");
355 case MCSymbolRefExpr::VK_None:
356 Type = ELF::R_PPC64_ADDR16_DS;
357 break;
358 case MCSymbolRefExpr::VK_PPC_LO:
359 Type = ELF::R_PPC64_ADDR16_LO_DS;
360 break;
361 case MCSymbolRefExpr::VK_GOT:
362 Type = ELF::R_PPC64_GOT16_DS;
363 break;
364 case MCSymbolRefExpr::VK_PPC_GOT_LO:
365 Type = ELF::R_PPC64_GOT16_LO_DS;
366 break;
367 case MCSymbolRefExpr::VK_PPC_TOC:
368 Type = ELF::R_PPC64_TOC16_DS;
369 break;
370 case MCSymbolRefExpr::VK_PPC_TOC_LO:
371 Type = ELF::R_PPC64_TOC16_LO_DS;
372 break;
373 case MCSymbolRefExpr::VK_TPREL:
374 Type = ELF::R_PPC64_TPREL16_DS;
375 break;
376 case MCSymbolRefExpr::VK_PPC_TPREL_LO:
377 Type = ELF::R_PPC64_TPREL16_LO_DS;
378 break;
379 case MCSymbolRefExpr::VK_DTPREL:
380 Type = ELF::R_PPC64_DTPREL16_DS;
381 break;
382 case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
383 Type = ELF::R_PPC64_DTPREL16_LO_DS;
384 break;
385 case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
386 Type = ELF::R_PPC64_GOT_TPREL16_DS;
387 break;
388 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
389 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
390 break;
391 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
392 Type = ELF::R_PPC64_GOT_DTPREL16_DS;
393 break;
394 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
395 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
396 break;
398 break;
399 case PPC::fixup_ppc_nofixup:
400 switch (Modifier) {
401 default: llvm_unreachable("Unsupported Modifier");
402 case MCSymbolRefExpr::VK_PPC_TLSGD:
403 if (is64Bit())
404 Type = ELF::R_PPC64_TLSGD;
405 else
406 Type = ELF::R_PPC_TLSGD;
407 break;
408 case MCSymbolRefExpr::VK_PPC_TLSLD:
409 if (is64Bit())
410 Type = ELF::R_PPC64_TLSLD;
411 else
412 Type = ELF::R_PPC_TLSLD;
413 break;
414 case MCSymbolRefExpr::VK_PPC_TLS:
415 if (is64Bit())
416 Type = ELF::R_PPC64_TLS;
417 else
418 Type = ELF::R_PPC_TLS;
419 break;
420 case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
421 Type = ELF::R_PPC64_TLS;
422 break;
424 break;
425 case PPC::fixup_ppc_imm34:
426 switch (Modifier) {
427 default:
428 report_fatal_error("Unsupported Modifier for fixup_ppc_imm34.");
429 case MCSymbolRefExpr::VK_DTPREL:
430 Type = ELF::R_PPC64_DTPREL34;
431 break;
432 case MCSymbolRefExpr::VK_TPREL:
433 Type = ELF::R_PPC64_TPREL34;
434 break;
436 break;
437 case FK_Data_8:
438 switch (Modifier) {
439 default: llvm_unreachable("Unsupported Modifier");
440 case MCSymbolRefExpr::VK_PPC_TOCBASE:
441 Type = ELF::R_PPC64_TOC;
442 break;
443 case MCSymbolRefExpr::VK_None:
444 Type = ELF::R_PPC64_ADDR64;
445 break;
446 case MCSymbolRefExpr::VK_PPC_DTPMOD:
447 Type = ELF::R_PPC64_DTPMOD64;
448 break;
449 case MCSymbolRefExpr::VK_TPREL:
450 Type = ELF::R_PPC64_TPREL64;
451 break;
452 case MCSymbolRefExpr::VK_DTPREL:
453 Type = ELF::R_PPC64_DTPREL64;
454 break;
456 break;
457 case FK_Data_4:
458 switch (Modifier) {
459 case MCSymbolRefExpr::VK_DTPREL:
460 Type = ELF::R_PPC_DTPREL32;
461 break;
462 default:
463 Type = ELF::R_PPC_ADDR32;
465 break;
466 case FK_Data_2:
467 Type = ELF::R_PPC_ADDR16;
468 break;
471 return Type;
474 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
475 const MCSymbol &Sym,
476 unsigned Type) const {
477 switch (Type) {
478 default:
479 return false;
481 case ELF::R_PPC_REL24:
482 case ELF::R_PPC64_REL24_NOTOC:
483 // If the target symbol has a local entry point, we must keep the
484 // target symbol to preserve that information for the linker.
485 // The "other" values are stored in the last 6 bits of the second byte.
486 // The traditional defines for STO values assume the full byte and thus
487 // the shift to pack it.
488 unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
489 return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
493 std::unique_ptr<MCObjectTargetWriter>
494 llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
495 return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);