[PowerPC] Support TLS on PPC32/ELF
[oota-llvm.git] / lib / Target / PowerPC / MCTargetDesc / PPCELFObjectWriter.cpp
1 //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MCTargetDesc/PPCMCTargetDesc.h"
11 #include "MCTargetDesc/PPCFixupKinds.h"
12 #include "MCTargetDesc/PPCMCExpr.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/MC/MCELF.h"
15 #include "llvm/MC/MCELFObjectWriter.h"
16 #include "llvm/MC/MCExpr.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     virtual ~PPCELFObjectWriter();
28   protected:
29     virtual unsigned getRelocTypeInner(const MCValue &Target,
30                                        const MCFixup &Fixup,
31                                        bool IsPCRel) const;
32     unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
33                           bool IsPCRel) const override;
34
35     bool needsRelocateWithSymbol(const MCSymbolData &SD,
36                                  unsigned Type) const override;
37   };
38 }
39
40 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
41   : MCELFObjectTargetWriter(Is64Bit, OSABI,
42                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
43                             /*HasRelocationAddend*/ true) {}
44
45 PPCELFObjectWriter::~PPCELFObjectWriter() {
46 }
47
48 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
49                                                      const MCFixup &Fixup) {
50   const MCExpr *Expr = Fixup.getValue();
51
52   if (Expr->getKind() != MCExpr::Target)
53     return Target.getAccessVariant();
54
55   switch (cast<PPCMCExpr>(Expr)->getKind()) {
56   case PPCMCExpr::VK_PPC_None:
57     return MCSymbolRefExpr::VK_None;
58   case PPCMCExpr::VK_PPC_LO:
59     return MCSymbolRefExpr::VK_PPC_LO;
60   case PPCMCExpr::VK_PPC_HI:
61     return MCSymbolRefExpr::VK_PPC_HI;
62   case PPCMCExpr::VK_PPC_HA:
63     return MCSymbolRefExpr::VK_PPC_HA;
64   case PPCMCExpr::VK_PPC_HIGHERA:
65     return MCSymbolRefExpr::VK_PPC_HIGHERA;
66   case PPCMCExpr::VK_PPC_HIGHER:
67     return MCSymbolRefExpr::VK_PPC_HIGHER;
68   case PPCMCExpr::VK_PPC_HIGHEST:
69     return MCSymbolRefExpr::VK_PPC_HIGHEST;
70   case PPCMCExpr::VK_PPC_HIGHESTA:
71     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
72   }
73   llvm_unreachable("unknown PPCMCExpr kind");
74 }
75
76 unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
77                                                const MCFixup &Fixup,
78                                                bool IsPCRel) const
79 {
80   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
81
82   // determine the type of the relocation
83   unsigned Type;
84   if (IsPCRel) {
85     switch ((unsigned)Fixup.getKind()) {
86     default:
87       llvm_unreachable("Unimplemented");
88     case PPC::fixup_ppc_br24:
89     case PPC::fixup_ppc_br24abs:
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       }
99       break;
100     case PPC::fixup_ppc_brcond14:
101     case PPC::fixup_ppc_brcond14abs:
102       Type = ELF::R_PPC_REL14;
103       break;
104     case PPC::fixup_ppc_half16:
105       switch (Modifier) {
106       default: llvm_unreachable("Unsupported Modifier");
107       case MCSymbolRefExpr::VK_None:
108         Type = ELF::R_PPC_REL16;
109         break;
110       case MCSymbolRefExpr::VK_PPC_LO:
111         Type = ELF::R_PPC_REL16_LO;
112         break;
113       case MCSymbolRefExpr::VK_PPC_HI:
114         Type = ELF::R_PPC_REL16_HI;
115         break;
116       case MCSymbolRefExpr::VK_PPC_HA:
117         Type = ELF::R_PPC_REL16_HA;
118         break;
119       }
120       break;
121     case FK_Data_4:
122     case FK_PCRel_4:
123       Type = ELF::R_PPC_REL32;
124       break;
125     case FK_Data_8:
126     case FK_PCRel_8:
127       Type = ELF::R_PPC64_REL64;
128       break;
129     }
130   } else {
131     switch ((unsigned)Fixup.getKind()) {
132       default: llvm_unreachable("invalid fixup kind!");
133     case PPC::fixup_ppc_br24abs:
134       Type = ELF::R_PPC_ADDR24;
135       break;
136     case PPC::fixup_ppc_brcond14abs:
137       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
138       break;
139     case PPC::fixup_ppc_half16:
140       switch (Modifier) {
141       default: llvm_unreachable("Unsupported Modifier");
142       case MCSymbolRefExpr::VK_None:
143         Type = ELF::R_PPC_ADDR16;
144         break;
145       case MCSymbolRefExpr::VK_PPC_LO:
146         Type = ELF::R_PPC_ADDR16_LO;
147         break;
148       case MCSymbolRefExpr::VK_PPC_HI:
149         Type = ELF::R_PPC_ADDR16_HI;
150         break;
151       case MCSymbolRefExpr::VK_PPC_HA:
152         Type = ELF::R_PPC_ADDR16_HA;
153         break;
154       case MCSymbolRefExpr::VK_PPC_HIGHER:
155         Type = ELF::R_PPC64_ADDR16_HIGHER;
156         break;
157       case MCSymbolRefExpr::VK_PPC_HIGHERA:
158         Type = ELF::R_PPC64_ADDR16_HIGHERA;
159         break;
160       case MCSymbolRefExpr::VK_PPC_HIGHEST:
161         Type = ELF::R_PPC64_ADDR16_HIGHEST;
162         break;
163       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
164         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
165         break;
166       case MCSymbolRefExpr::VK_GOT:
167         Type = ELF::R_PPC_GOT16;
168         break;
169       case MCSymbolRefExpr::VK_PPC_GOT_LO:
170         Type = ELF::R_PPC_GOT16_LO;
171         break;
172       case MCSymbolRefExpr::VK_PPC_GOT_HI:
173         Type = ELF::R_PPC_GOT16_HI;
174         break;
175       case MCSymbolRefExpr::VK_PPC_GOT_HA:
176         Type = ELF::R_PPC_GOT16_HA;
177         break;
178       case MCSymbolRefExpr::VK_PPC_TOC:
179         Type = ELF::R_PPC64_TOC16;
180         break;
181       case MCSymbolRefExpr::VK_PPC_TOC_LO:
182         Type = ELF::R_PPC64_TOC16_LO;
183         break;
184       case MCSymbolRefExpr::VK_PPC_TOC_HI:
185         Type = ELF::R_PPC64_TOC16_HI;
186         break;
187       case MCSymbolRefExpr::VK_PPC_TOC_HA:
188         Type = ELF::R_PPC64_TOC16_HA;
189         break;
190       case MCSymbolRefExpr::VK_PPC_TPREL:
191         Type = ELF::R_PPC_TPREL16;
192         break;
193       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
194         Type = ELF::R_PPC_TPREL16_LO;
195         break;
196       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
197         Type = ELF::R_PPC_TPREL16_HI;
198         break;
199       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
200         Type = ELF::R_PPC_TPREL16_HA;
201         break;
202       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
203         Type = ELF::R_PPC64_TPREL16_HIGHER;
204         break;
205       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
206         Type = ELF::R_PPC64_TPREL16_HIGHERA;
207         break;
208       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
209         Type = ELF::R_PPC64_TPREL16_HIGHEST;
210         break;
211       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
212         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
213         break;
214       case MCSymbolRefExpr::VK_PPC_DTPREL:
215         Type = ELF::R_PPC64_DTPREL16;
216         break;
217       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
218         Type = ELF::R_PPC64_DTPREL16_LO;
219         break;
220       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
221         Type = ELF::R_PPC64_DTPREL16_HI;
222         break;
223       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
224         Type = ELF::R_PPC64_DTPREL16_HA;
225         break;
226       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
227         Type = ELF::R_PPC64_DTPREL16_HIGHER;
228         break;
229       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
230         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
231         break;
232       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
233         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
234         break;
235       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
236         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
237         break;
238       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
239         if (is64Bit())
240           Type = ELF::R_PPC64_GOT_TLSGD16;
241         else
242           Type = ELF::R_PPC_GOT_TLSGD16;
243         break;
244       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
245         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
246         break;
247       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
248         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
249         break;
250       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
251         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
252         break;
253       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
254         if (is64Bit())
255           Type = ELF::R_PPC64_GOT_TLSLD16;
256         else
257           Type = ELF::R_PPC_GOT_TLSLD16;
258         break;
259       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
260         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
261         break;
262       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
263         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
264         break;
265       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
266         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
267         break;
268       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
269         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
270            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
271         Type = ELF::R_PPC64_GOT_TPREL16_DS;
272         break;
273       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
274         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
275            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
276         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
277         break;
278       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
279         Type = ELF::R_PPC64_GOT_TPREL16_HI;
280         break;
281       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
282         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
283            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
284         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
285         break;
286       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
287         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
288            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
289         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
290         break;
291       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
292         Type = ELF::R_PPC64_GOT_TPREL16_HA;
293         break;
294       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
295         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
296         break;
297       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
298         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
299         break;
300       }
301       break;
302     case PPC::fixup_ppc_half16ds:
303       switch (Modifier) {
304       default: llvm_unreachable("Unsupported Modifier");
305       case MCSymbolRefExpr::VK_None:
306         Type = ELF::R_PPC64_ADDR16_DS;
307         break;
308       case MCSymbolRefExpr::VK_PPC_LO:
309         Type = ELF::R_PPC64_ADDR16_LO_DS;
310         break;
311       case MCSymbolRefExpr::VK_GOT:
312         Type = ELF::R_PPC64_GOT16_DS;
313         break;
314       case MCSymbolRefExpr::VK_PPC_GOT_LO:
315         Type = ELF::R_PPC64_GOT16_LO_DS;
316         break;
317       case MCSymbolRefExpr::VK_PPC_TOC:
318         Type = ELF::R_PPC64_TOC16_DS;
319         break;
320       case MCSymbolRefExpr::VK_PPC_TOC_LO:
321         Type = ELF::R_PPC64_TOC16_LO_DS;
322         break;
323       case MCSymbolRefExpr::VK_PPC_TPREL:
324         Type = ELF::R_PPC64_TPREL16_DS;
325         break;
326       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
327         Type = ELF::R_PPC64_TPREL16_LO_DS;
328         break;
329       case MCSymbolRefExpr::VK_PPC_DTPREL:
330         Type = ELF::R_PPC64_DTPREL16_DS;
331         break;
332       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
333         Type = ELF::R_PPC64_DTPREL16_LO_DS;
334         break;
335       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
336         Type = ELF::R_PPC64_GOT_TPREL16_DS;
337         break;
338       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
339         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
340         break;
341       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
342         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
343         break;
344       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
345         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
346         break;
347       }
348       break;
349     case PPC::fixup_ppc_nofixup:
350       switch (Modifier) {
351       default: llvm_unreachable("Unsupported Modifier");
352       case MCSymbolRefExpr::VK_PPC_TLSGD:
353         if (is64Bit())
354           Type = ELF::R_PPC64_TLSGD;
355         else
356           Type = ELF::R_PPC_TLSGD;
357         break;
358       case MCSymbolRefExpr::VK_PPC_TLSLD:
359         if (is64Bit())
360           Type = ELF::R_PPC64_TLSLD;
361         else
362           Type = ELF::R_PPC_TLSLD;
363         break;
364       case MCSymbolRefExpr::VK_PPC_TLS:
365         if (is64Bit())
366           Type = ELF::R_PPC64_TLS;
367         else
368           Type = ELF::R_PPC_TLS;
369         break;
370       }
371       break;
372     case FK_Data_8:
373       switch (Modifier) {
374       default: llvm_unreachable("Unsupported Modifier");
375       case MCSymbolRefExpr::VK_PPC_TOCBASE:
376         Type = ELF::R_PPC64_TOC;
377         break;
378       case MCSymbolRefExpr::VK_None:
379         Type = ELF::R_PPC64_ADDR64;
380         break;
381       case MCSymbolRefExpr::VK_PPC_DTPMOD:
382         Type = ELF::R_PPC64_DTPMOD64;
383         break;
384       case MCSymbolRefExpr::VK_PPC_TPREL:
385         Type = ELF::R_PPC64_TPREL64;
386         break;
387       case MCSymbolRefExpr::VK_PPC_DTPREL:
388         Type = ELF::R_PPC64_DTPREL64;
389         break;
390       }
391       break;
392     case FK_Data_4:
393       Type = ELF::R_PPC_ADDR32;
394       break;
395     case FK_Data_2:
396       Type = ELF::R_PPC_ADDR16;
397       break;
398     }
399   }
400   return Type;
401 }
402
403 unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
404                                           const MCFixup &Fixup,
405                                           bool IsPCRel) const {
406   return getRelocTypeInner(Target, Fixup, IsPCRel);
407 }
408
409 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
410                                                  unsigned Type) const {
411   switch (Type) {
412     default:
413       return false;
414
415     case ELF::R_PPC_REL24:
416       // If the target symbol has a local entry point, we must keep the
417       // target symbol to preserve that information for the linker.
418       // The "other" values are stored in the last 6 bits of the second byte.
419       // The traditional defines for STO values assume the full byte and thus
420       // the shift to pack it.
421       unsigned Other = MCELF::getOther(SD) << 2;
422       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
423   }
424 }
425
426 MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,
427                                                bool Is64Bit,
428                                                bool IsLittleEndian,
429                                                uint8_t OSABI) {
430   MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI);
431   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
432 }