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