1 //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
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
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"
22 class PPCELFObjectWriter
: public MCELFObjectTargetWriter
{
24 PPCELFObjectWriter(bool Is64Bit
, uint8_t OSABI
);
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
,
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
83 switch (Fixup
.getTargetKind()) {
85 llvm_unreachable("Unimplemented");
86 case PPC::fixup_ppc_br24
:
87 case PPC::fixup_ppc_br24abs
:
88 case PPC::fixup_ppc_br24_notoc
:
90 default: llvm_unreachable("Unsupported Modifier");
91 case MCSymbolRefExpr::VK_None
:
92 Type
= ELF::R_PPC_REL24
;
94 case MCSymbolRefExpr::VK_PLT
:
95 Type
= ELF::R_PPC_PLTREL24
;
97 case MCSymbolRefExpr::VK_PPC_LOCAL
:
98 Type
= ELF::R_PPC_LOCAL24PC
;
100 case MCSymbolRefExpr::VK_PPC_NOTOC
:
101 Type
= ELF::R_PPC64_REL24_NOTOC
;
105 case PPC::fixup_ppc_brcond14
:
106 case PPC::fixup_ppc_brcond14abs
:
107 Type
= ELF::R_PPC_REL14
;
109 case PPC::fixup_ppc_half16
:
111 default: llvm_unreachable("Unsupported Modifier");
112 case MCSymbolRefExpr::VK_None
:
113 Type
= ELF::R_PPC_REL16
;
115 case MCSymbolRefExpr::VK_PPC_LO
:
116 Type
= ELF::R_PPC_REL16_LO
;
118 case MCSymbolRefExpr::VK_PPC_HI
:
119 Type
= ELF::R_PPC_REL16_HI
;
121 case MCSymbolRefExpr::VK_PPC_HA
:
122 Type
= ELF::R_PPC_REL16_HA
;
126 case PPC::fixup_ppc_half16ds
:
127 case PPC::fixup_ppc_half16dq
:
128 Target
.print(errs());
130 report_fatal_error("Invalid PC-relative half16ds relocation");
131 case PPC::fixup_ppc_pcrel34
:
134 llvm_unreachable("Unsupported Modifier for fixup_ppc_pcrel34");
135 case MCSymbolRefExpr::VK_PCREL
:
136 Type
= ELF::R_PPC64_PCREL34
;
138 case MCSymbolRefExpr::VK_PPC_GOT_PCREL
:
139 Type
= ELF::R_PPC64_GOT_PCREL34
;
141 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL
:
142 Type
= ELF::R_PPC64_GOT_TLSGD_PCREL34
;
144 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL
:
145 Type
= ELF::R_PPC64_GOT_TLSLD_PCREL34
;
147 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL
:
148 Type
= ELF::R_PPC64_GOT_TPREL_PCREL34
;
154 Type
= ELF::R_PPC_REL32
;
158 Type
= ELF::R_PPC64_REL64
;
162 switch (Fixup
.getTargetKind()) {
163 default: llvm_unreachable("invalid fixup kind!");
164 case PPC::fixup_ppc_br24abs
:
165 Type
= ELF::R_PPC_ADDR24
;
167 case PPC::fixup_ppc_brcond14abs
:
168 Type
= ELF::R_PPC_ADDR14
; // XXX: or BRNTAKEN?_
170 case PPC::fixup_ppc_half16
:
172 default: llvm_unreachable("Unsupported Modifier");
173 case MCSymbolRefExpr::VK_None
:
174 Type
= ELF::R_PPC_ADDR16
;
176 case MCSymbolRefExpr::VK_PPC_LO
:
177 Type
= ELF::R_PPC_ADDR16_LO
;
179 case MCSymbolRefExpr::VK_PPC_HI
:
180 Type
= ELF::R_PPC_ADDR16_HI
;
182 case MCSymbolRefExpr::VK_PPC_HA
:
183 Type
= ELF::R_PPC_ADDR16_HA
;
185 case MCSymbolRefExpr::VK_PPC_HIGH
:
186 Type
= ELF::R_PPC64_ADDR16_HIGH
;
188 case MCSymbolRefExpr::VK_PPC_HIGHA
:
189 Type
= ELF::R_PPC64_ADDR16_HIGHA
;
191 case MCSymbolRefExpr::VK_PPC_HIGHER
:
192 Type
= ELF::R_PPC64_ADDR16_HIGHER
;
194 case MCSymbolRefExpr::VK_PPC_HIGHERA
:
195 Type
= ELF::R_PPC64_ADDR16_HIGHERA
;
197 case MCSymbolRefExpr::VK_PPC_HIGHEST
:
198 Type
= ELF::R_PPC64_ADDR16_HIGHEST
;
200 case MCSymbolRefExpr::VK_PPC_HIGHESTA
:
201 Type
= ELF::R_PPC64_ADDR16_HIGHESTA
;
203 case MCSymbolRefExpr::VK_GOT
:
204 Type
= ELF::R_PPC_GOT16
;
206 case MCSymbolRefExpr::VK_PPC_GOT_LO
:
207 Type
= ELF::R_PPC_GOT16_LO
;
209 case MCSymbolRefExpr::VK_PPC_GOT_HI
:
210 Type
= ELF::R_PPC_GOT16_HI
;
212 case MCSymbolRefExpr::VK_PPC_GOT_HA
:
213 Type
= ELF::R_PPC_GOT16_HA
;
215 case MCSymbolRefExpr::VK_PPC_TOC
:
216 Type
= ELF::R_PPC64_TOC16
;
218 case MCSymbolRefExpr::VK_PPC_TOC_LO
:
219 Type
= ELF::R_PPC64_TOC16_LO
;
221 case MCSymbolRefExpr::VK_PPC_TOC_HI
:
222 Type
= ELF::R_PPC64_TOC16_HI
;
224 case MCSymbolRefExpr::VK_PPC_TOC_HA
:
225 Type
= ELF::R_PPC64_TOC16_HA
;
227 case MCSymbolRefExpr::VK_TPREL
:
228 Type
= ELF::R_PPC_TPREL16
;
230 case MCSymbolRefExpr::VK_PPC_TPREL_LO
:
231 Type
= ELF::R_PPC_TPREL16_LO
;
233 case MCSymbolRefExpr::VK_PPC_TPREL_HI
:
234 Type
= ELF::R_PPC_TPREL16_HI
;
236 case MCSymbolRefExpr::VK_PPC_TPREL_HA
:
237 Type
= ELF::R_PPC_TPREL16_HA
;
239 case MCSymbolRefExpr::VK_PPC_TPREL_HIGH
:
240 Type
= ELF::R_PPC64_TPREL16_HIGH
;
242 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA
:
243 Type
= ELF::R_PPC64_TPREL16_HIGHA
;
245 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER
:
246 Type
= ELF::R_PPC64_TPREL16_HIGHER
;
248 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA
:
249 Type
= ELF::R_PPC64_TPREL16_HIGHERA
;
251 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST
:
252 Type
= ELF::R_PPC64_TPREL16_HIGHEST
;
254 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA
:
255 Type
= ELF::R_PPC64_TPREL16_HIGHESTA
;
257 case MCSymbolRefExpr::VK_DTPREL
:
258 Type
= ELF::R_PPC64_DTPREL16
;
260 case MCSymbolRefExpr::VK_PPC_DTPREL_LO
:
261 Type
= ELF::R_PPC64_DTPREL16_LO
;
263 case MCSymbolRefExpr::VK_PPC_DTPREL_HI
:
264 Type
= ELF::R_PPC64_DTPREL16_HI
;
266 case MCSymbolRefExpr::VK_PPC_DTPREL_HA
:
267 Type
= ELF::R_PPC64_DTPREL16_HA
;
269 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH
:
270 Type
= ELF::R_PPC64_DTPREL16_HIGH
;
272 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA
:
273 Type
= ELF::R_PPC64_DTPREL16_HIGHA
;
275 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER
:
276 Type
= ELF::R_PPC64_DTPREL16_HIGHER
;
278 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA
:
279 Type
= ELF::R_PPC64_DTPREL16_HIGHERA
;
281 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST
:
282 Type
= ELF::R_PPC64_DTPREL16_HIGHEST
;
284 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA
:
285 Type
= ELF::R_PPC64_DTPREL16_HIGHESTA
;
287 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD
:
289 Type
= ELF::R_PPC64_GOT_TLSGD16
;
291 Type
= ELF::R_PPC_GOT_TLSGD16
;
293 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
:
294 Type
= ELF::R_PPC64_GOT_TLSGD16_LO
;
296 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI
:
297 Type
= ELF::R_PPC64_GOT_TLSGD16_HI
;
299 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA
:
300 Type
= ELF::R_PPC64_GOT_TLSGD16_HA
;
302 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD
:
304 Type
= ELF::R_PPC64_GOT_TLSLD16
;
306 Type
= ELF::R_PPC_GOT_TLSLD16
;
308 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
:
309 Type
= ELF::R_PPC64_GOT_TLSLD16_LO
;
311 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI
:
312 Type
= ELF::R_PPC64_GOT_TLSLD16_HI
;
314 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA
:
315 Type
= ELF::R_PPC64_GOT_TLSLD16_HA
;
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
;
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
;
327 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI
:
328 Type
= ELF::R_PPC64_GOT_TPREL16_HI
;
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
;
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
;
340 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA
:
341 Type
= ELF::R_PPC64_GOT_TPREL16_HA
;
343 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI
:
344 Type
= ELF::R_PPC64_GOT_DTPREL16_HI
;
346 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA
:
347 Type
= ELF::R_PPC64_GOT_DTPREL16_HA
;
351 case PPC::fixup_ppc_half16ds
:
352 case PPC::fixup_ppc_half16dq
:
354 default: llvm_unreachable("Unsupported Modifier");
355 case MCSymbolRefExpr::VK_None
:
356 Type
= ELF::R_PPC64_ADDR16_DS
;
358 case MCSymbolRefExpr::VK_PPC_LO
:
359 Type
= ELF::R_PPC64_ADDR16_LO_DS
;
361 case MCSymbolRefExpr::VK_GOT
:
362 Type
= ELF::R_PPC64_GOT16_DS
;
364 case MCSymbolRefExpr::VK_PPC_GOT_LO
:
365 Type
= ELF::R_PPC64_GOT16_LO_DS
;
367 case MCSymbolRefExpr::VK_PPC_TOC
:
368 Type
= ELF::R_PPC64_TOC16_DS
;
370 case MCSymbolRefExpr::VK_PPC_TOC_LO
:
371 Type
= ELF::R_PPC64_TOC16_LO_DS
;
373 case MCSymbolRefExpr::VK_TPREL
:
374 Type
= ELF::R_PPC64_TPREL16_DS
;
376 case MCSymbolRefExpr::VK_PPC_TPREL_LO
:
377 Type
= ELF::R_PPC64_TPREL16_LO_DS
;
379 case MCSymbolRefExpr::VK_DTPREL
:
380 Type
= ELF::R_PPC64_DTPREL16_DS
;
382 case MCSymbolRefExpr::VK_PPC_DTPREL_LO
:
383 Type
= ELF::R_PPC64_DTPREL16_LO_DS
;
385 case MCSymbolRefExpr::VK_PPC_GOT_TPREL
:
386 Type
= ELF::R_PPC64_GOT_TPREL16_DS
;
388 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO
:
389 Type
= ELF::R_PPC64_GOT_TPREL16_LO_DS
;
391 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL
:
392 Type
= ELF::R_PPC64_GOT_DTPREL16_DS
;
394 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO
:
395 Type
= ELF::R_PPC64_GOT_DTPREL16_LO_DS
;
399 case PPC::fixup_ppc_nofixup
:
401 default: llvm_unreachable("Unsupported Modifier");
402 case MCSymbolRefExpr::VK_PPC_TLSGD
:
404 Type
= ELF::R_PPC64_TLSGD
;
406 Type
= ELF::R_PPC_TLSGD
;
408 case MCSymbolRefExpr::VK_PPC_TLSLD
:
410 Type
= ELF::R_PPC64_TLSLD
;
412 Type
= ELF::R_PPC_TLSLD
;
414 case MCSymbolRefExpr::VK_PPC_TLS
:
416 Type
= ELF::R_PPC64_TLS
;
418 Type
= ELF::R_PPC_TLS
;
420 case MCSymbolRefExpr::VK_PPC_TLS_PCREL
:
421 Type
= ELF::R_PPC64_TLS
;
425 case PPC::fixup_ppc_imm34
:
428 report_fatal_error("Unsupported Modifier for fixup_ppc_imm34.");
429 case MCSymbolRefExpr::VK_DTPREL
:
430 Type
= ELF::R_PPC64_DTPREL34
;
432 case MCSymbolRefExpr::VK_TPREL
:
433 Type
= ELF::R_PPC64_TPREL34
;
439 default: llvm_unreachable("Unsupported Modifier");
440 case MCSymbolRefExpr::VK_PPC_TOCBASE
:
441 Type
= ELF::R_PPC64_TOC
;
443 case MCSymbolRefExpr::VK_None
:
444 Type
= ELF::R_PPC64_ADDR64
;
446 case MCSymbolRefExpr::VK_PPC_DTPMOD
:
447 Type
= ELF::R_PPC64_DTPMOD64
;
449 case MCSymbolRefExpr::VK_TPREL
:
450 Type
= ELF::R_PPC64_TPREL64
;
452 case MCSymbolRefExpr::VK_DTPREL
:
453 Type
= ELF::R_PPC64_DTPREL64
;
459 case MCSymbolRefExpr::VK_DTPREL
:
460 Type
= ELF::R_PPC_DTPREL32
;
463 Type
= ELF::R_PPC_ADDR32
;
467 Type
= ELF::R_PPC_ADDR16
;
474 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCValue
&,
476 unsigned Type
) const {
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
);