Remove unused argument.
[oota-llvm.git] / lib / Target / X86 / MCTargetDesc / X86ELFObjectWriter.cpp
1 //===-- X86ELFObjectWriter.cpp - X86 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/X86FixupKinds.h"
11 #include "MCTargetDesc/X86MCTargetDesc.h"
12 #include "llvm/MC/MCELFObjectWriter.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCValue.h"
15 #include "llvm/Support/ELF.h"
16 #include "llvm/Support/ErrorHandling.h"
17
18 using namespace llvm;
19
20 namespace {
21   class X86ELFObjectWriter : public MCELFObjectTargetWriter {
22   public:
23     X86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine);
24
25     virtual ~X86ELFObjectWriter();
26   protected:
27     unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
28                           bool IsPCRel, bool IsRelocWithSymbol) const override;
29   };
30 }
31
32 X86ELFObjectWriter::X86ELFObjectWriter(bool IsELF64, uint8_t OSABI,
33                                        uint16_t EMachine)
34   : MCELFObjectTargetWriter(IsELF64, OSABI, EMachine,
35                             // Only i386 uses Rel instead of RelA.
36                             /*HasRelocationAddend*/ EMachine != ELF::EM_386) {}
37
38 X86ELFObjectWriter::~X86ELFObjectWriter()
39 {}
40
41 unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
42                                           const MCFixup &Fixup,
43                                           bool IsPCRel,
44                                           bool IsRelocWithSymbol) const {
45   // determine the type of the relocation
46
47   MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
48   unsigned Type;
49   if (getEMachine() == ELF::EM_X86_64) {
50     if (IsPCRel) {
51       switch ((unsigned)Fixup.getKind()) {
52       default: llvm_unreachable("invalid fixup kind!");
53
54       case FK_Data_8: Type = ELF::R_X86_64_PC64; break;
55       case FK_Data_4: Type = ELF::R_X86_64_PC32; break;
56       case FK_Data_2: Type = ELF::R_X86_64_PC16; break;
57       case FK_Data_1: Type = ELF::R_X86_64_PC8; break;
58
59       case FK_PCRel_8:
60         assert(Modifier == MCSymbolRefExpr::VK_None);
61         Type = ELF::R_X86_64_PC64;
62         break;
63       case X86::reloc_signed_4byte:
64       case X86::reloc_riprel_4byte_movq_load:
65       case X86::reloc_riprel_4byte:
66       case FK_PCRel_4:
67         switch (Modifier) {
68         default:
69           llvm_unreachable("Unimplemented");
70         case MCSymbolRefExpr::VK_None:
71           Type = ELF::R_X86_64_PC32;
72           break;
73         case MCSymbolRefExpr::VK_PLT:
74           Type = ELF::R_X86_64_PLT32;
75           break;
76         case MCSymbolRefExpr::VK_GOTPCREL:
77           Type = ELF::R_X86_64_GOTPCREL;
78           break;
79         case MCSymbolRefExpr::VK_GOTTPOFF:
80           Type = ELF::R_X86_64_GOTTPOFF;
81         break;
82         case MCSymbolRefExpr::VK_TLSGD:
83           Type = ELF::R_X86_64_TLSGD;
84           break;
85         case MCSymbolRefExpr::VK_TLSLD:
86           Type = ELF::R_X86_64_TLSLD;
87           break;
88         }
89         break;
90       case FK_PCRel_2:
91         assert(Modifier == MCSymbolRefExpr::VK_None);
92         Type = ELF::R_X86_64_PC16;
93         break;
94       case FK_PCRel_1:
95         assert(Modifier == MCSymbolRefExpr::VK_None);
96         Type = ELF::R_X86_64_PC8;
97         break;
98       }
99     } else {
100       switch ((unsigned)Fixup.getKind()) {
101       default: llvm_unreachable("invalid fixup kind!");
102       case FK_Data_8:
103         switch (Modifier) {
104         default:
105           llvm_unreachable("Unimplemented");
106         case MCSymbolRefExpr::VK_None:
107           Type = ELF::R_X86_64_64;
108           break;
109         case MCSymbolRefExpr::VK_GOT:
110           Type = ELF::R_X86_64_GOT64;
111           break;
112         case MCSymbolRefExpr::VK_GOTOFF:
113           Type = ELF::R_X86_64_GOTOFF64;
114           break;
115         case MCSymbolRefExpr::VK_TPOFF:
116           Type = ELF::R_X86_64_TPOFF64;
117           break;
118         case MCSymbolRefExpr::VK_DTPOFF:
119           Type = ELF::R_X86_64_DTPOFF64;
120           break;
121         }
122         break;
123       case X86::reloc_signed_4byte:
124         switch (Modifier) {
125         default:
126           llvm_unreachable("Unimplemented");
127         case MCSymbolRefExpr::VK_None:
128           Type = ELF::R_X86_64_32S;
129           break;
130         case MCSymbolRefExpr::VK_GOT:
131           Type = ELF::R_X86_64_GOT32;
132           break;
133         case MCSymbolRefExpr::VK_GOTPCREL:
134           Type = ELF::R_X86_64_GOTPCREL;
135           break;
136         case MCSymbolRefExpr::VK_TPOFF:
137           Type = ELF::R_X86_64_TPOFF32;
138           break;
139         case MCSymbolRefExpr::VK_DTPOFF:
140           Type = ELF::R_X86_64_DTPOFF32;
141           break;
142         }
143         break;
144       case FK_Data_4:
145         Type = ELF::R_X86_64_32;
146         break;
147       case FK_Data_2: Type = ELF::R_X86_64_16; break;
148       case FK_PCRel_1:
149       case FK_Data_1: Type = ELF::R_X86_64_8; break;
150       }
151     }
152   } else if (getEMachine() == ELF::EM_386) {
153     if (IsPCRel) {
154       switch ((unsigned)Fixup.getKind()) {
155       default: llvm_unreachable("invalid fixup kind!");
156
157       case X86::reloc_global_offset_table:
158         Type = ELF::R_386_GOTPC;
159         break;
160
161       case FK_PCRel_1:
162       case FK_Data_1:
163         switch (Modifier) {
164         default:
165           llvm_unreachable("Unimplemented");
166         case MCSymbolRefExpr::VK_None:
167           Type = ELF::R_386_PC8;
168           break;
169         }
170         break;
171
172       case FK_PCRel_2:
173       case FK_Data_2:
174         switch (Modifier) {
175         default:
176           llvm_unreachable("Unimplemented");
177         case MCSymbolRefExpr::VK_None:
178           Type = ELF::R_386_PC16;
179           break;
180         }
181         break;
182
183       case X86::reloc_signed_4byte:
184       case FK_PCRel_4:
185       case FK_Data_4:
186         switch (Modifier) {
187         default:
188           llvm_unreachable("Unimplemented");
189         case MCSymbolRefExpr::VK_None:
190           Type = ELF::R_386_PC32;
191           break;
192         case MCSymbolRefExpr::VK_PLT:
193           Type = ELF::R_386_PLT32;
194           break;
195         }
196         break;
197       }
198     } else {
199       switch ((unsigned)Fixup.getKind()) {
200       default: llvm_unreachable("invalid fixup kind!");
201
202       case X86::reloc_global_offset_table:
203         Type = ELF::R_386_GOTPC;
204         break;
205
206       // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
207       // instead?
208       case X86::reloc_signed_4byte:
209       case FK_PCRel_4:
210       case FK_Data_4:
211         switch (Modifier) {
212         default:
213           llvm_unreachable("Unimplemented");
214         case MCSymbolRefExpr::VK_None:
215           Type = ELF::R_386_32;
216           break;
217         case MCSymbolRefExpr::VK_GOT:
218           Type = ELF::R_386_GOT32;
219           break;
220         case MCSymbolRefExpr::VK_GOTOFF:
221           Type = ELF::R_386_GOTOFF;
222           break;
223         case MCSymbolRefExpr::VK_TLSGD:
224           Type = ELF::R_386_TLS_GD;
225           break;
226         case MCSymbolRefExpr::VK_TPOFF:
227           Type = ELF::R_386_TLS_LE_32;
228           break;
229         case MCSymbolRefExpr::VK_INDNTPOFF:
230           Type = ELF::R_386_TLS_IE;
231           break;
232         case MCSymbolRefExpr::VK_NTPOFF:
233           Type = ELF::R_386_TLS_LE;
234           break;
235         case MCSymbolRefExpr::VK_GOTNTPOFF:
236           Type = ELF::R_386_TLS_GOTIE;
237           break;
238         case MCSymbolRefExpr::VK_TLSLDM:
239           Type = ELF::R_386_TLS_LDM;
240           break;
241         case MCSymbolRefExpr::VK_DTPOFF:
242           Type = ELF::R_386_TLS_LDO_32;
243           break;
244         case MCSymbolRefExpr::VK_GOTTPOFF:
245           Type = ELF::R_386_TLS_IE_32;
246           break;
247         }
248         break;
249       case FK_Data_2: Type = ELF::R_386_16; break;
250       case FK_PCRel_1:
251       case FK_Data_1: Type = ELF::R_386_8; break;
252       }
253     }
254   } else
255     llvm_unreachable("Unsupported ELF machine type.");
256
257   return Type;
258 }
259
260 MCObjectWriter *llvm::createX86ELFObjectWriter(raw_ostream &OS,
261                                                bool IsELF64,
262                                                uint8_t OSABI,
263                                                uint16_t EMachine) {
264   MCELFObjectTargetWriter *MOTW =
265     new X86ELFObjectWriter(IsELF64, OSABI, EMachine);
266   return createELFObjectWriter(MOTW, OS,  /*IsLittleEndian=*/true);
267 }