[MC] Pass MCSymbolData to needsRelocateWithSymbol
[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         Type = ELF::R_PPC64_GOT_TLSGD16;
240         break;
241       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
242         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
243         break;
244       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
245         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
246         break;
247       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
248         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
249         break;
250       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
251         Type = ELF::R_PPC64_GOT_TLSLD16;
252         break;
253       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
254         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
255         break;
256       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
257         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
258         break;
259       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
260         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
261         break;
262       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
263         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
264            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
265         Type = ELF::R_PPC64_GOT_TPREL16_DS;
266         break;
267       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
268         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
269            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
270         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
271         break;
272       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
273         Type = ELF::R_PPC64_GOT_TPREL16_HI;
274         break;
275       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
276         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
277            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
278         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
279         break;
280       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
281         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
282            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
283         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
284         break;
285       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
286         Type = ELF::R_PPC64_GOT_TPREL16_HA;
287         break;
288       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
289         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
290         break;
291       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
292         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
293         break;
294       }
295       break;
296     case PPC::fixup_ppc_half16ds:
297       switch (Modifier) {
298       default: llvm_unreachable("Unsupported Modifier");
299       case MCSymbolRefExpr::VK_None:
300         Type = ELF::R_PPC64_ADDR16_DS;
301         break;
302       case MCSymbolRefExpr::VK_PPC_LO:
303         Type = ELF::R_PPC64_ADDR16_LO_DS;
304         break;
305       case MCSymbolRefExpr::VK_GOT:
306         Type = ELF::R_PPC64_GOT16_DS;
307         break;
308       case MCSymbolRefExpr::VK_PPC_GOT_LO:
309         Type = ELF::R_PPC64_GOT16_LO_DS;
310         break;
311       case MCSymbolRefExpr::VK_PPC_TOC:
312         Type = ELF::R_PPC64_TOC16_DS;
313         break;
314       case MCSymbolRefExpr::VK_PPC_TOC_LO:
315         Type = ELF::R_PPC64_TOC16_LO_DS;
316         break;
317       case MCSymbolRefExpr::VK_PPC_TPREL:
318         Type = ELF::R_PPC64_TPREL16_DS;
319         break;
320       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
321         Type = ELF::R_PPC64_TPREL16_LO_DS;
322         break;
323       case MCSymbolRefExpr::VK_PPC_DTPREL:
324         Type = ELF::R_PPC64_DTPREL16_DS;
325         break;
326       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
327         Type = ELF::R_PPC64_DTPREL16_LO_DS;
328         break;
329       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
330         Type = ELF::R_PPC64_GOT_TPREL16_DS;
331         break;
332       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
333         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
334         break;
335       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
336         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
337         break;
338       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
339         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
340         break;
341       }
342       break;
343     case PPC::fixup_ppc_nofixup:
344       switch (Modifier) {
345       default: llvm_unreachable("Unsupported Modifier");
346       case MCSymbolRefExpr::VK_PPC_TLSGD:
347         Type = ELF::R_PPC64_TLSGD;
348         break;
349       case MCSymbolRefExpr::VK_PPC_TLSLD:
350         Type = ELF::R_PPC64_TLSLD;
351         break;
352       case MCSymbolRefExpr::VK_PPC_TLS:
353         Type = ELF::R_PPC64_TLS;
354         break;
355       }
356       break;
357     case FK_Data_8:
358       switch (Modifier) {
359       default: llvm_unreachable("Unsupported Modifier");
360       case MCSymbolRefExpr::VK_PPC_TOCBASE:
361         Type = ELF::R_PPC64_TOC;
362         break;
363       case MCSymbolRefExpr::VK_None:
364         Type = ELF::R_PPC64_ADDR64;
365         break;
366       case MCSymbolRefExpr::VK_PPC_DTPMOD:
367         Type = ELF::R_PPC64_DTPMOD64;
368         break;
369       case MCSymbolRefExpr::VK_PPC_TPREL:
370         Type = ELF::R_PPC64_TPREL64;
371         break;
372       case MCSymbolRefExpr::VK_PPC_DTPREL:
373         Type = ELF::R_PPC64_DTPREL64;
374         break;
375       }
376       break;
377     case FK_Data_4:
378       Type = ELF::R_PPC_ADDR32;
379       break;
380     case FK_Data_2:
381       Type = ELF::R_PPC_ADDR16;
382       break;
383     }
384   }
385   return Type;
386 }
387
388 unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
389                                           const MCFixup &Fixup,
390                                           bool IsPCRel) const {
391   return getRelocTypeInner(Target, Fixup, IsPCRel);
392 }
393
394 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
395                                                  unsigned Type) const {
396   switch (Type) {
397     default:
398       return false;
399
400     case ELF::R_PPC_REL24:
401       // If the target symbol has a local entry point, we must keep the
402       // target symbol to preserve that information for the linker.
403       // The "other" values are stored in the last 6 bits of the second byte.
404       // The traditional defines for STO values assume the full byte and thus
405       // the shift to pack it.
406       unsigned Other = MCELF::getOther(SD) << 2;
407       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
408   }
409 }
410
411 MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,
412                                                bool Is64Bit,
413                                                bool IsLittleEndian,
414                                                uint8_t OSABI) {
415   MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI);
416   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
417 }