xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
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/PPCMCAsmInfo.h"
11 #include "MCTargetDesc/PPCMCTargetDesc.h"
12 #include "llvm/MC/MCContext.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(const MCFixup &Fixup, const MCValue &Target,
29                           bool IsPCRel) const override;
30 
31     bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;
32   };
33 }
34 
35 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
36   : MCELFObjectTargetWriter(Is64Bit, OSABI,
37                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
38                             /*HasRelocationAddend*/ true) {}
39 
40 unsigned PPCELFObjectWriter::getRelocType(const MCFixup &Fixup,
41                                           const MCValue &Target,
42                                           bool IsPCRel) const {
43   SMLoc Loc = Fixup.getValue()->getLoc();
44   auto Spec = static_cast<PPCMCExpr::Specifier>(Target.getSpecifier());
45   switch (Spec) {
46   case PPC::S_DTPMOD:
47   case PPC::S_DTPREL:
48   case PPC::S_DTPREL_HA:
49   case PPC::S_DTPREL_HI:
50   case PPC::S_DTPREL_HIGH:
51   case PPC::S_DTPREL_HIGHA:
52   case PPC::S_DTPREL_HIGHER:
53   case PPC::S_DTPREL_HIGHERA:
54   case PPC::S_DTPREL_HIGHEST:
55   case PPC::S_DTPREL_HIGHESTA:
56   case PPC::S_DTPREL_LO:
57   case PPC::S_GOT_DTPREL:
58   case PPC::S_GOT_DTPREL_HA:
59   case PPC::S_GOT_DTPREL_HI:
60   case PPC::S_GOT_DTPREL_LO:
61   case PPC::S_GOT_TLSGD:
62   case PPC::S_GOT_TLSGD_HA:
63   case PPC::S_GOT_TLSGD_HI:
64   case PPC::S_GOT_TLSGD_LO:
65   case PPC::S_GOT_TLSGD_PCREL:
66   case PPC::S_GOT_TLSLD:
67   case PPC::S_GOT_TLSLD_HA:
68   case PPC::S_GOT_TLSLD_HI:
69   case PPC::S_GOT_TLSLD_LO:
70   case PPC::S_GOT_TPREL:
71   case PPC::S_GOT_TPREL_HA:
72   case PPC::S_GOT_TPREL_HI:
73   case PPC::S_GOT_TPREL_LO:
74   case PPC::S_GOT_TPREL_PCREL:
75   case PPC::S_TLS:
76   case PPC::S_TLSGD:
77   case PPC::S_TLSLD:
78   case PPC::S_TLS_PCREL:
79   case PPC::S_TPREL:
80   case PPC::S_TPREL_HA:
81   case PPC::S_TPREL_HI:
82   case PPC::S_TPREL_HIGH:
83   case PPC::S_TPREL_HIGHA:
84   case PPC::S_TPREL_HIGHER:
85   case PPC::S_TPREL_HIGHERA:
86   case PPC::S_TPREL_HIGHEST:
87   case PPC::S_TPREL_HIGHESTA:
88   case PPC::S_TPREL_LO:
89     if (auto *SA = Target.getAddSym())
90       cast<MCSymbolELF>(SA)->setType(ELF::STT_TLS);
91     break;
92   default:
93     break;
94   }
95 
96   // determine the type of the relocation
97   unsigned Type = 0;
98   if (IsPCRel) {
99     switch (Fixup.getKind()) {
100     default:
101       llvm_unreachable("Unimplemented");
102     case PPC::fixup_ppc_br24:
103     case PPC::fixup_ppc_br24abs:
104     case PPC::fixup_ppc_br24_notoc:
105       switch (Spec) {
106       default:
107         reportError(Loc, "unsupported relocation type");
108         break;
109       case PPC::S_None:
110         Type = ELF::R_PPC_REL24;
111         break;
112       case PPC::S_PLT:
113         Type = ELF::R_PPC_PLTREL24;
114         break;
115       case PPC::S_LOCAL:
116         Type = ELF::R_PPC_LOCAL24PC;
117         break;
118       case PPC::S_NOTOC:
119         Type = ELF::R_PPC64_REL24_NOTOC;
120         break;
121       }
122       break;
123     case PPC::fixup_ppc_brcond14:
124     case PPC::fixup_ppc_brcond14abs:
125       Type = ELF::R_PPC_REL14;
126       break;
127     case PPC::fixup_ppc_half16:
128       switch (Spec) {
129       default:
130         reportError(Loc, "unsupported relocation type");
131         return ELF::R_PPC_NONE;
132       case PPC::S_None:
133         return ELF::R_PPC_REL16;
134       case PPC::S_LO:
135         return ELF::R_PPC_REL16_LO;
136       case PPC::S_HI:
137         return ELF::R_PPC_REL16_HI;
138       case PPC::S_HA:
139         return ELF::R_PPC_REL16_HA;
140       }
141       break;
142     case PPC::fixup_ppc_half16ds:
143     case PPC::fixup_ppc_half16dq:
144       reportError(Loc, "unsupported relocation type");
145       break;
146     case PPC::fixup_ppc_pcrel34:
147       switch (Spec) {
148       default:
149         reportError(Loc, "unsupported relocation type");
150         break;
151       case PPC::S_PCREL:
152         Type = ELF::R_PPC64_PCREL34;
153         break;
154       case PPC::S_GOT_PCREL:
155         Type = ELF::R_PPC64_GOT_PCREL34;
156         break;
157       case PPC::S_GOT_TLSGD_PCREL:
158         Type = ELF::R_PPC64_GOT_TLSGD_PCREL34;
159         break;
160       case PPC::S_GOT_TLSLD_PCREL:
161         Type = ELF::R_PPC64_GOT_TLSLD_PCREL34;
162         break;
163       case PPC::S_GOT_TPREL_PCREL:
164         Type = ELF::R_PPC64_GOT_TPREL_PCREL34;
165         break;
166       }
167       break;
168     case FK_Data_4:
169       Type = ELF::R_PPC_REL32;
170       break;
171     case FK_Data_8:
172       Type = ELF::R_PPC64_REL64;
173       break;
174     }
175   } else {
176     switch (Fixup.getKind()) {
177     default:
178       llvm_unreachable("invalid fixup kind!");
179     case PPC::fixup_ppc_br24abs:
180       Type = ELF::R_PPC_ADDR24;
181       break;
182     case PPC::fixup_ppc_brcond14abs:
183       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
184       break;
185     case PPC::fixup_ppc_half16:
186       switch (Spec) {
187       default:
188         reportError(Loc, "unsupported relocation type");
189         break;
190       case PPC::S_LO:
191         return ELF::R_PPC_ADDR16_LO;
192       case PPC::S_HI:
193         return ELF::R_PPC_ADDR16_HI;
194       case PPC::S_HA:
195         return ELF::R_PPC_ADDR16_HA;
196       case PPC::S_HIGH:
197         return ELF::R_PPC64_ADDR16_HIGH;
198       case PPC::S_HIGHA:
199         return ELF::R_PPC64_ADDR16_HIGHA;
200       case PPC::S_HIGHER:
201         return ELF::R_PPC64_ADDR16_HIGHER;
202       case PPC::S_HIGHERA:
203         return ELF::R_PPC64_ADDR16_HIGHERA;
204       case PPC::S_HIGHEST:
205         return ELF::R_PPC64_ADDR16_HIGHEST;
206       case PPC::S_HIGHESTA:
207         return ELF::R_PPC64_ADDR16_HIGHESTA;
208 
209       case PPC::S_None:
210         Type = ELF::R_PPC_ADDR16;
211         break;
212       case PPC::S_GOT:
213         Type = ELF::R_PPC_GOT16;
214         break;
215       case PPC::S_GOT_LO:
216         Type = ELF::R_PPC_GOT16_LO;
217         break;
218       case PPC::S_GOT_HI:
219         Type = ELF::R_PPC_GOT16_HI;
220         break;
221       case PPC::S_GOT_HA:
222         Type = ELF::R_PPC_GOT16_HA;
223         break;
224       case PPC::S_TOC:
225         Type = ELF::R_PPC64_TOC16;
226         break;
227       case PPC::S_TOC_LO:
228         Type = ELF::R_PPC64_TOC16_LO;
229         break;
230       case PPC::S_TOC_HI:
231         Type = ELF::R_PPC64_TOC16_HI;
232         break;
233       case PPC::S_TOC_HA:
234         Type = ELF::R_PPC64_TOC16_HA;
235         break;
236       case PPC::S_TPREL:
237         Type = ELF::R_PPC_TPREL16;
238         break;
239       case PPC::S_TPREL_LO:
240         Type = ELF::R_PPC_TPREL16_LO;
241         break;
242       case PPC::S_TPREL_HI:
243         Type = ELF::R_PPC_TPREL16_HI;
244         break;
245       case PPC::S_TPREL_HA:
246         Type = ELF::R_PPC_TPREL16_HA;
247         break;
248       case PPC::S_TPREL_HIGH:
249         Type = ELF::R_PPC64_TPREL16_HIGH;
250         break;
251       case PPC::S_TPREL_HIGHA:
252         Type = ELF::R_PPC64_TPREL16_HIGHA;
253         break;
254       case PPC::S_TPREL_HIGHER:
255         Type = ELF::R_PPC64_TPREL16_HIGHER;
256         break;
257       case PPC::S_TPREL_HIGHERA:
258         Type = ELF::R_PPC64_TPREL16_HIGHERA;
259         break;
260       case PPC::S_TPREL_HIGHEST:
261         Type = ELF::R_PPC64_TPREL16_HIGHEST;
262         break;
263       case PPC::S_TPREL_HIGHESTA:
264         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
265         break;
266       case PPC::S_DTPREL:
267         Type = ELF::R_PPC64_DTPREL16;
268         break;
269       case PPC::S_DTPREL_LO:
270         Type = ELF::R_PPC64_DTPREL16_LO;
271         break;
272       case PPC::S_DTPREL_HI:
273         Type = ELF::R_PPC64_DTPREL16_HI;
274         break;
275       case PPC::S_DTPREL_HA:
276         Type = ELF::R_PPC64_DTPREL16_HA;
277         break;
278       case PPC::S_DTPREL_HIGH:
279         Type = ELF::R_PPC64_DTPREL16_HIGH;
280         break;
281       case PPC::S_DTPREL_HIGHA:
282         Type = ELF::R_PPC64_DTPREL16_HIGHA;
283         break;
284       case PPC::S_DTPREL_HIGHER:
285         Type = ELF::R_PPC64_DTPREL16_HIGHER;
286         break;
287       case PPC::S_DTPREL_HIGHERA:
288         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
289         break;
290       case PPC::S_DTPREL_HIGHEST:
291         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
292         break;
293       case PPC::S_DTPREL_HIGHESTA:
294         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
295         break;
296       case PPC::S_GOT_TLSGD:
297         if (is64Bit())
298           Type = ELF::R_PPC64_GOT_TLSGD16;
299         else
300           Type = ELF::R_PPC_GOT_TLSGD16;
301         break;
302       case PPC::S_GOT_TLSGD_LO:
303         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
304         break;
305       case PPC::S_GOT_TLSGD_HI:
306         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
307         break;
308       case PPC::S_GOT_TLSGD_HA:
309         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
310         break;
311       case PPC::S_GOT_TLSLD:
312         if (is64Bit())
313           Type = ELF::R_PPC64_GOT_TLSLD16;
314         else
315           Type = ELF::R_PPC_GOT_TLSLD16;
316         break;
317       case PPC::S_GOT_TLSLD_LO:
318         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
319         break;
320       case PPC::S_GOT_TLSLD_HI:
321         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
322         break;
323       case PPC::S_GOT_TLSLD_HA:
324         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
325         break;
326       case PPC::S_GOT_TPREL:
327         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
328            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
329         Type = ELF::R_PPC64_GOT_TPREL16_DS;
330         break;
331       case PPC::S_GOT_TPREL_LO:
332         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
333            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
334         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
335         break;
336       case PPC::S_GOT_TPREL_HI:
337         Type = ELF::R_PPC64_GOT_TPREL16_HI;
338         break;
339       case PPC::S_GOT_DTPREL:
340         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
341            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
342         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
343         break;
344       case PPC::S_GOT_DTPREL_LO:
345         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
346            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
347         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
348         break;
349       case PPC::S_GOT_TPREL_HA:
350         Type = ELF::R_PPC64_GOT_TPREL16_HA;
351         break;
352       case PPC::S_GOT_DTPREL_HI:
353         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
354         break;
355       case PPC::S_GOT_DTPREL_HA:
356         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
357         break;
358       }
359       break;
360     case PPC::fixup_ppc_half16ds:
361     case PPC::fixup_ppc_half16dq:
362       switch (Spec) {
363       default:
364         reportError(Loc, "unsupported relocation type");
365         break;
366       case PPC::S_LO:
367         return ELF::R_PPC64_ADDR16_LO_DS;
368       case PPC::S_None:
369         Type = ELF::R_PPC64_ADDR16_DS;
370         break;
371       case PPC::S_GOT:
372         Type = ELF::R_PPC64_GOT16_DS;
373         break;
374       case PPC::S_GOT_LO:
375         Type = ELF::R_PPC64_GOT16_LO_DS;
376         break;
377       case PPC::S_TOC:
378         Type = ELF::R_PPC64_TOC16_DS;
379         break;
380       case PPC::S_TOC_LO:
381         Type = ELF::R_PPC64_TOC16_LO_DS;
382         break;
383       case PPC::S_TPREL:
384         Type = ELF::R_PPC64_TPREL16_DS;
385         break;
386       case PPC::S_TPREL_LO:
387         Type = ELF::R_PPC64_TPREL16_LO_DS;
388         break;
389       case PPC::S_DTPREL:
390         Type = ELF::R_PPC64_DTPREL16_DS;
391         break;
392       case PPC::S_DTPREL_LO:
393         Type = ELF::R_PPC64_DTPREL16_LO_DS;
394         break;
395       case PPC::S_GOT_TPREL:
396         Type = ELF::R_PPC64_GOT_TPREL16_DS;
397         break;
398       case PPC::S_GOT_TPREL_LO:
399         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
400         break;
401       case PPC::S_GOT_DTPREL:
402         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
403         break;
404       case PPC::S_GOT_DTPREL_LO:
405         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
406         break;
407       }
408       break;
409     case PPC::fixup_ppc_nofixup:
410       switch (Spec) {
411       default:
412         reportError(Loc, "unsupported relocation type");
413         break;
414       case PPC::S_TLSGD:
415         if (is64Bit())
416           Type = ELF::R_PPC64_TLSGD;
417         else
418           Type = ELF::R_PPC_TLSGD;
419         break;
420       case PPC::S_TLSLD:
421         if (is64Bit())
422           Type = ELF::R_PPC64_TLSLD;
423         else
424           Type = ELF::R_PPC_TLSLD;
425         break;
426       case PPC::S_TLS:
427         if (is64Bit())
428           Type = ELF::R_PPC64_TLS;
429         else
430           Type = ELF::R_PPC_TLS;
431         break;
432       case PPC::S_TLS_PCREL:
433         Type = ELF::R_PPC64_TLS;
434         break;
435       }
436       break;
437     case PPC::fixup_ppc_imm34:
438       switch (Spec) {
439       default:
440         reportError(Loc, "unsupported relocation type");
441         break;
442       case PPC::S_DTPREL:
443         Type = ELF::R_PPC64_DTPREL34;
444         break;
445       case PPC::S_TPREL:
446         Type = ELF::R_PPC64_TPREL34;
447         break;
448       }
449       break;
450     case FK_Data_8:
451       switch (Spec) {
452       default:
453         reportError(Loc, "unsupported relocation type");
454         break;
455       case PPC::S_TOCBASE:
456         Type = ELF::R_PPC64_TOC;
457         break;
458       case PPC::S_None:
459         Type = ELF::R_PPC64_ADDR64;
460         break;
461       case PPC::S_DTPMOD:
462         Type = ELF::R_PPC64_DTPMOD64;
463         break;
464       case PPC::S_TPREL:
465         Type = ELF::R_PPC64_TPREL64;
466         break;
467       case PPC::S_DTPREL:
468         Type = ELF::R_PPC64_DTPREL64;
469         break;
470       }
471       break;
472     case FK_Data_4:
473       switch (Spec) {
474       case PPC::S_DTPREL:
475         Type = ELF::R_PPC_DTPREL32;
476         break;
477       default:
478         Type = ELF::R_PPC_ADDR32;
479       }
480       break;
481     case FK_Data_2:
482       Type = ELF::R_PPC_ADDR16;
483       break;
484     }
485   }
486   return Type;
487 }
488 
489 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCValue &V,
490                                                  unsigned Type) const {
491   switch (Type) {
492     default:
493       return false;
494 
495     case ELF::R_PPC_REL24:
496     case ELF::R_PPC64_REL24_NOTOC: {
497       // If the target symbol has a local entry point, we must keep the
498       // target symbol to preserve that information for the linker.
499       // The "other" values are stored in the last 6 bits of the second byte.
500       // The traditional defines for STO values assume the full byte and thus
501       // the shift to pack it.
502       unsigned Other = cast<MCSymbolELF>(V.getAddSym())->getOther() << 2;
503       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
504     }
505 
506     case ELF::R_PPC64_GOT16:
507     case ELF::R_PPC64_GOT16_DS:
508     case ELF::R_PPC64_GOT16_LO:
509     case ELF::R_PPC64_GOT16_LO_DS:
510     case ELF::R_PPC64_GOT16_HI:
511     case ELF::R_PPC64_GOT16_HA:
512       return true;
513     }
514 }
515 
516 std::unique_ptr<MCObjectTargetWriter>
517 llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
518   return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);
519 }
520