1 //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/PPCFixupKinds.h"
11 #include "MCTargetDesc/PPCMCExpr.h"
12 #include "MCTargetDesc/PPCMCTargetDesc.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/MC/MCELFObjectWriter.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCObjectWriter.h"
17 #include "llvm/MC/MCSymbolELF.h"
18 #include "llvm/MC/MCValue.h"
19 #include "llvm/Support/ErrorHandling.h"
24 class PPCELFObjectWriter : public MCELFObjectTargetWriter {
26 PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
29 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
30 const MCFixup &Fixup, bool IsPCRel) const override;
32 bool needsRelocateWithSymbol(const MCSymbol &Sym,
33 unsigned Type) const override;
37 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
38 : MCELFObjectTargetWriter(Is64Bit, OSABI,
39 Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC,
40 /*HasRelocationAddend*/ true) {}
42 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
43 const MCFixup &Fixup) {
44 const MCExpr *Expr = Fixup.getValue();
46 if (Expr->getKind() != MCExpr::Target)
47 return Target.getAccessVariant();
49 switch (cast<PPCMCExpr>(Expr)->getKind()) {
50 case PPCMCExpr::VK_PPC_None:
51 return MCSymbolRefExpr::VK_None;
52 case PPCMCExpr::VK_PPC_LO:
53 return MCSymbolRefExpr::VK_PPC_LO;
54 case PPCMCExpr::VK_PPC_HI:
55 return MCSymbolRefExpr::VK_PPC_HI;
56 case PPCMCExpr::VK_PPC_HA:
57 return MCSymbolRefExpr::VK_PPC_HA;
58 case PPCMCExpr::VK_PPC_HIGH:
59 return MCSymbolRefExpr::VK_PPC_HIGH;
60 case PPCMCExpr::VK_PPC_HIGHA:
61 return MCSymbolRefExpr::VK_PPC_HIGHA;
62 case PPCMCExpr::VK_PPC_HIGHERA:
63 return MCSymbolRefExpr::VK_PPC_HIGHERA;
64 case PPCMCExpr::VK_PPC_HIGHER:
65 return MCSymbolRefExpr::VK_PPC_HIGHER;
66 case PPCMCExpr::VK_PPC_HIGHEST:
67 return MCSymbolRefExpr::VK_PPC_HIGHEST;
68 case PPCMCExpr::VK_PPC_HIGHESTA:
69 return MCSymbolRefExpr::VK_PPC_HIGHESTA;
71 llvm_unreachable("unknown PPCMCExpr kind");
74 unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
77 MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
79 // determine the type of the relocation
82 switch ((unsigned)Fixup.getKind()) {
84 llvm_unreachable("Unimplemented");
85 case PPC::fixup_ppc_br24:
86 case PPC::fixup_ppc_br24abs:
88 default: llvm_unreachable("Unsupported Modifier");
89 case MCSymbolRefExpr::VK_None:
90 Type = ELF::R_PPC_REL24;
92 case MCSymbolRefExpr::VK_PLT:
93 Type = ELF::R_PPC_PLTREL24;
95 case MCSymbolRefExpr::VK_PPC_LOCAL:
96 Type = ELF::R_PPC_LOCAL24PC;
100 case PPC::fixup_ppc_brcond14:
101 case PPC::fixup_ppc_brcond14abs:
102 Type = ELF::R_PPC_REL14;
104 case PPC::fixup_ppc_half16:
106 default: llvm_unreachable("Unsupported Modifier");
107 case MCSymbolRefExpr::VK_None:
108 Type = ELF::R_PPC_REL16;
110 case MCSymbolRefExpr::VK_PPC_LO:
111 Type = ELF::R_PPC_REL16_LO;
113 case MCSymbolRefExpr::VK_PPC_HI:
114 Type = ELF::R_PPC_REL16_HI;
116 case MCSymbolRefExpr::VK_PPC_HA:
117 Type = ELF::R_PPC_REL16_HA;
121 case PPC::fixup_ppc_half16ds:
122 Target.print(errs());
124 report_fatal_error("Invalid PC-relative half16ds relocation");
127 Type = ELF::R_PPC_REL32;
131 Type = ELF::R_PPC64_REL64;
135 switch ((unsigned)Fixup.getKind()) {
136 default: llvm_unreachable("invalid fixup kind!");
137 case PPC::fixup_ppc_br24abs:
138 Type = ELF::R_PPC_ADDR24;
140 case PPC::fixup_ppc_brcond14abs:
141 Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
143 case PPC::fixup_ppc_half16:
145 default: llvm_unreachable("Unsupported Modifier");
146 case MCSymbolRefExpr::VK_None:
147 Type = ELF::R_PPC_ADDR16;
149 case MCSymbolRefExpr::VK_PPC_LO:
150 Type = ELF::R_PPC_ADDR16_LO;
152 case MCSymbolRefExpr::VK_PPC_HI:
153 Type = ELF::R_PPC_ADDR16_HI;
155 case MCSymbolRefExpr::VK_PPC_HA:
156 Type = ELF::R_PPC_ADDR16_HA;
158 case MCSymbolRefExpr::VK_PPC_HIGH:
159 Type = ELF::R_PPC64_ADDR16_HIGH;
161 case MCSymbolRefExpr::VK_PPC_HIGHA:
162 Type = ELF::R_PPC64_ADDR16_HIGHA;
164 case MCSymbolRefExpr::VK_PPC_HIGHER:
165 Type = ELF::R_PPC64_ADDR16_HIGHER;
167 case MCSymbolRefExpr::VK_PPC_HIGHERA:
168 Type = ELF::R_PPC64_ADDR16_HIGHERA;
170 case MCSymbolRefExpr::VK_PPC_HIGHEST:
171 Type = ELF::R_PPC64_ADDR16_HIGHEST;
173 case MCSymbolRefExpr::VK_PPC_HIGHESTA:
174 Type = ELF::R_PPC64_ADDR16_HIGHESTA;
176 case MCSymbolRefExpr::VK_GOT:
177 Type = ELF::R_PPC_GOT16;
179 case MCSymbolRefExpr::VK_PPC_GOT_LO:
180 Type = ELF::R_PPC_GOT16_LO;
182 case MCSymbolRefExpr::VK_PPC_GOT_HI:
183 Type = ELF::R_PPC_GOT16_HI;
185 case MCSymbolRefExpr::VK_PPC_GOT_HA:
186 Type = ELF::R_PPC_GOT16_HA;
188 case MCSymbolRefExpr::VK_PPC_TOC:
189 Type = ELF::R_PPC64_TOC16;
191 case MCSymbolRefExpr::VK_PPC_TOC_LO:
192 Type = ELF::R_PPC64_TOC16_LO;
194 case MCSymbolRefExpr::VK_PPC_TOC_HI:
195 Type = ELF::R_PPC64_TOC16_HI;
197 case MCSymbolRefExpr::VK_PPC_TOC_HA:
198 Type = ELF::R_PPC64_TOC16_HA;
200 case MCSymbolRefExpr::VK_TPREL:
201 Type = ELF::R_PPC_TPREL16;
203 case MCSymbolRefExpr::VK_PPC_TPREL_LO:
204 Type = ELF::R_PPC_TPREL16_LO;
206 case MCSymbolRefExpr::VK_PPC_TPREL_HI:
207 Type = ELF::R_PPC_TPREL16_HI;
209 case MCSymbolRefExpr::VK_PPC_TPREL_HA:
210 Type = ELF::R_PPC_TPREL16_HA;
212 case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
213 Type = ELF::R_PPC64_TPREL16_HIGH;
215 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
216 Type = ELF::R_PPC64_TPREL16_HIGHA;
218 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
219 Type = ELF::R_PPC64_TPREL16_HIGHER;
221 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
222 Type = ELF::R_PPC64_TPREL16_HIGHERA;
224 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
225 Type = ELF::R_PPC64_TPREL16_HIGHEST;
227 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
228 Type = ELF::R_PPC64_TPREL16_HIGHESTA;
230 case MCSymbolRefExpr::VK_DTPREL:
231 Type = ELF::R_PPC64_DTPREL16;
233 case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
234 Type = ELF::R_PPC64_DTPREL16_LO;
236 case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
237 Type = ELF::R_PPC64_DTPREL16_HI;
239 case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
240 Type = ELF::R_PPC64_DTPREL16_HA;
242 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
243 Type = ELF::R_PPC64_DTPREL16_HIGH;
245 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
246 Type = ELF::R_PPC64_DTPREL16_HIGHA;
248 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
249 Type = ELF::R_PPC64_DTPREL16_HIGHER;
251 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
252 Type = ELF::R_PPC64_DTPREL16_HIGHERA;
254 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
255 Type = ELF::R_PPC64_DTPREL16_HIGHEST;
257 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
258 Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
260 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
262 Type = ELF::R_PPC64_GOT_TLSGD16;
264 Type = ELF::R_PPC_GOT_TLSGD16;
266 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
267 Type = ELF::R_PPC64_GOT_TLSGD16_LO;
269 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
270 Type = ELF::R_PPC64_GOT_TLSGD16_HI;
272 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
273 Type = ELF::R_PPC64_GOT_TLSGD16_HA;
275 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
277 Type = ELF::R_PPC64_GOT_TLSLD16;
279 Type = ELF::R_PPC_GOT_TLSLD16;
281 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
282 Type = ELF::R_PPC64_GOT_TLSLD16_LO;
284 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
285 Type = ELF::R_PPC64_GOT_TLSLD16_HI;
287 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
288 Type = ELF::R_PPC64_GOT_TLSLD16_HA;
290 case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
291 /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
292 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */
293 Type = ELF::R_PPC64_GOT_TPREL16_DS;
295 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
296 /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
297 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */
298 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
300 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
301 Type = ELF::R_PPC64_GOT_TPREL16_HI;
303 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
304 /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
305 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */
306 Type = ELF::R_PPC64_GOT_DTPREL16_DS;
308 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
309 /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
310 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */
311 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
313 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
314 Type = ELF::R_PPC64_GOT_TPREL16_HA;
316 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
317 Type = ELF::R_PPC64_GOT_DTPREL16_HI;
319 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
320 Type = ELF::R_PPC64_GOT_DTPREL16_HA;
324 case PPC::fixup_ppc_half16ds:
326 default: llvm_unreachable("Unsupported Modifier");
327 case MCSymbolRefExpr::VK_None:
328 Type = ELF::R_PPC64_ADDR16_DS;
330 case MCSymbolRefExpr::VK_PPC_LO:
331 Type = ELF::R_PPC64_ADDR16_LO_DS;
333 case MCSymbolRefExpr::VK_GOT:
334 Type = ELF::R_PPC64_GOT16_DS;
336 case MCSymbolRefExpr::VK_PPC_GOT_LO:
337 Type = ELF::R_PPC64_GOT16_LO_DS;
339 case MCSymbolRefExpr::VK_PPC_TOC:
340 Type = ELF::R_PPC64_TOC16_DS;
342 case MCSymbolRefExpr::VK_PPC_TOC_LO:
343 Type = ELF::R_PPC64_TOC16_LO_DS;
345 case MCSymbolRefExpr::VK_TPREL:
346 Type = ELF::R_PPC64_TPREL16_DS;
348 case MCSymbolRefExpr::VK_PPC_TPREL_LO:
349 Type = ELF::R_PPC64_TPREL16_LO_DS;
351 case MCSymbolRefExpr::VK_DTPREL:
352 Type = ELF::R_PPC64_DTPREL16_DS;
354 case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
355 Type = ELF::R_PPC64_DTPREL16_LO_DS;
357 case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
358 Type = ELF::R_PPC64_GOT_TPREL16_DS;
360 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
361 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
363 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
364 Type = ELF::R_PPC64_GOT_DTPREL16_DS;
366 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
367 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
371 case PPC::fixup_ppc_nofixup:
373 default: llvm_unreachable("Unsupported Modifier");
374 case MCSymbolRefExpr::VK_PPC_TLSGD:
376 Type = ELF::R_PPC64_TLSGD;
378 Type = ELF::R_PPC_TLSGD;
380 case MCSymbolRefExpr::VK_PPC_TLSLD:
382 Type = ELF::R_PPC64_TLSLD;
384 Type = ELF::R_PPC_TLSLD;
386 case MCSymbolRefExpr::VK_PPC_TLS:
388 Type = ELF::R_PPC64_TLS;
390 Type = ELF::R_PPC_TLS;
396 default: llvm_unreachable("Unsupported Modifier");
397 case MCSymbolRefExpr::VK_PPC_TOCBASE:
398 Type = ELF::R_PPC64_TOC;
400 case MCSymbolRefExpr::VK_None:
401 Type = ELF::R_PPC64_ADDR64;
403 case MCSymbolRefExpr::VK_PPC_DTPMOD:
404 Type = ELF::R_PPC64_DTPMOD64;
406 case MCSymbolRefExpr::VK_TPREL:
407 Type = ELF::R_PPC64_TPREL64;
409 case MCSymbolRefExpr::VK_DTPREL:
410 Type = ELF::R_PPC64_DTPREL64;
415 Type = ELF::R_PPC_ADDR32;
418 Type = ELF::R_PPC_ADDR16;
425 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
426 unsigned Type) const {
431 case ELF::R_PPC_REL24:
432 // If the target symbol has a local entry point, we must keep the
433 // target symbol to preserve that information for the linker.
434 // The "other" values are stored in the last 6 bits of the second byte.
435 // The traditional defines for STO values assume the full byte and thus
436 // the shift to pack it.
437 unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
438 return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
442 std::unique_ptr<MCObjectTargetWriter>
443 llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
444 return llvm::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);