1dff0c46cSDimitry Andric //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
2dff0c46cSDimitry Andric //
3dff0c46cSDimitry Andric //                     The LLVM Compiler Infrastructure
4dff0c46cSDimitry Andric //
5dff0c46cSDimitry Andric // This file is distributed under the University of Illinois Open Source
6dff0c46cSDimitry Andric // License. See LICENSE.TXT for details.
7dff0c46cSDimitry Andric //
8dff0c46cSDimitry Andric //===----------------------------------------------------------------------===//
9dff0c46cSDimitry Andric 
10139f7f9bSDimitry Andric #include "MCTargetDesc/PPCFixupKinds.h"
1191bc56edSDimitry Andric #include "MCTargetDesc/PPCMCExpr.h"
12db17bf38SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
13139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h"
14dff0c46cSDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
153861d79fSDimitry Andric #include "llvm/MC/MCExpr.h"
162cab237bSDimitry Andric #include "llvm/MC/MCObjectWriter.h"
1797bc6c73SDimitry Andric #include "llvm/MC/MCSymbolELF.h"
183861d79fSDimitry Andric #include "llvm/MC/MCValue.h"
19139f7f9bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
20dff0c46cSDimitry Andric 
21dff0c46cSDimitry Andric using namespace llvm;
22dff0c46cSDimitry Andric 
23dff0c46cSDimitry Andric namespace {
24dff0c46cSDimitry Andric   class PPCELFObjectWriter : public MCELFObjectTargetWriter {
25dff0c46cSDimitry Andric   public:
26dff0c46cSDimitry Andric     PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
27dff0c46cSDimitry Andric 
28dff0c46cSDimitry Andric   protected:
293ca95b02SDimitry Andric     unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
303ca95b02SDimitry Andric                           const MCFixup &Fixup, bool IsPCRel) const override;
3191bc56edSDimitry Andric 
3297bc6c73SDimitry Andric     bool needsRelocateWithSymbol(const MCSymbol &Sym,
3391bc56edSDimitry Andric                                  unsigned Type) const override;
34dff0c46cSDimitry Andric   };
353dac3a9bSDimitry Andric }
36dff0c46cSDimitry Andric 
PPCELFObjectWriter(bool Is64Bit,uint8_t OSABI)37dff0c46cSDimitry Andric PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
38dff0c46cSDimitry Andric   : MCELFObjectTargetWriter(Is64Bit, OSABI,
39dff0c46cSDimitry Andric                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
40dff0c46cSDimitry Andric                             /*HasRelocationAddend*/ true) {}
41dff0c46cSDimitry Andric 
getAccessVariant(const MCValue & Target,const MCFixup & Fixup)4291bc56edSDimitry Andric static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
4391bc56edSDimitry Andric                                                      const MCFixup &Fixup) {
4491bc56edSDimitry Andric   const MCExpr *Expr = Fixup.getValue();
4591bc56edSDimitry Andric 
4691bc56edSDimitry Andric   if (Expr->getKind() != MCExpr::Target)
4791bc56edSDimitry Andric     return Target.getAccessVariant();
4891bc56edSDimitry Andric 
4991bc56edSDimitry Andric   switch (cast<PPCMCExpr>(Expr)->getKind()) {
5091bc56edSDimitry Andric   case PPCMCExpr::VK_PPC_None:
5191bc56edSDimitry Andric     return MCSymbolRefExpr::VK_None;
5291bc56edSDimitry Andric   case PPCMCExpr::VK_PPC_LO:
5391bc56edSDimitry Andric     return MCSymbolRefExpr::VK_PPC_LO;
5491bc56edSDimitry Andric   case PPCMCExpr::VK_PPC_HI:
5591bc56edSDimitry Andric     return MCSymbolRefExpr::VK_PPC_HI;
5691bc56edSDimitry Andric   case PPCMCExpr::VK_PPC_HA:
5791bc56edSDimitry Andric     return MCSymbolRefExpr::VK_PPC_HA;
58*4ba319b5SDimitry Andric   case PPCMCExpr::VK_PPC_HIGH:
59*4ba319b5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGH;
60*4ba319b5SDimitry Andric   case PPCMCExpr::VK_PPC_HIGHA:
61*4ba319b5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHA;
6291bc56edSDimitry Andric   case PPCMCExpr::VK_PPC_HIGHERA:
6391bc56edSDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHERA;
6491bc56edSDimitry Andric   case PPCMCExpr::VK_PPC_HIGHER:
6591bc56edSDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHER;
6691bc56edSDimitry Andric   case PPCMCExpr::VK_PPC_HIGHEST:
6791bc56edSDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHEST;
6891bc56edSDimitry Andric   case PPCMCExpr::VK_PPC_HIGHESTA:
6991bc56edSDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
7091bc56edSDimitry Andric   }
7191bc56edSDimitry Andric   llvm_unreachable("unknown PPCMCExpr kind");
7291bc56edSDimitry Andric }
7391bc56edSDimitry Andric 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const743ca95b02SDimitry Andric unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
75dff0c46cSDimitry Andric                                           const MCFixup &Fixup,
7639d628a0SDimitry Andric                                           bool IsPCRel) const {
7791bc56edSDimitry Andric   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
783861d79fSDimitry Andric 
79dff0c46cSDimitry Andric   // determine the type of the relocation
80dff0c46cSDimitry Andric   unsigned Type;
81dff0c46cSDimitry Andric   if (IsPCRel) {
82dff0c46cSDimitry Andric     switch ((unsigned)Fixup.getKind()) {
83dff0c46cSDimitry Andric     default:
84dff0c46cSDimitry Andric       llvm_unreachable("Unimplemented");
85dff0c46cSDimitry Andric     case PPC::fixup_ppc_br24:
86f785676fSDimitry Andric     case PPC::fixup_ppc_br24abs:
8726e25074SRoman Divacky       switch (Modifier) {
8826e25074SRoman Divacky       default: llvm_unreachable("Unsupported Modifier");
8926e25074SRoman Divacky       case MCSymbolRefExpr::VK_None:
90dff0c46cSDimitry Andric         Type = ELF::R_PPC_REL24;
91dff0c46cSDimitry Andric         break;
9226e25074SRoman Divacky       case MCSymbolRefExpr::VK_PLT:
9326e25074SRoman Divacky         Type = ELF::R_PPC_PLTREL24;
9426e25074SRoman Divacky         break;
95404df5bbSDimitry Andric       case MCSymbolRefExpr::VK_PPC_LOCAL:
96404df5bbSDimitry Andric         Type = ELF::R_PPC_LOCAL24PC;
97404df5bbSDimitry Andric         break;
9826e25074SRoman Divacky       }
9926e25074SRoman Divacky       break;
100284c1978SDimitry Andric     case PPC::fixup_ppc_brcond14:
101f785676fSDimitry Andric     case PPC::fixup_ppc_brcond14abs:
102284c1978SDimitry Andric       Type = ELF::R_PPC_REL14;
103284c1978SDimitry Andric       break;
104f785676fSDimitry Andric     case PPC::fixup_ppc_half16:
105f785676fSDimitry Andric       switch (Modifier) {
106f785676fSDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
107f785676fSDimitry Andric       case MCSymbolRefExpr::VK_None:
108f785676fSDimitry Andric         Type = ELF::R_PPC_REL16;
109f785676fSDimitry Andric         break;
110f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_LO:
111f785676fSDimitry Andric         Type = ELF::R_PPC_REL16_LO;
112f785676fSDimitry Andric         break;
113f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_HI:
114f785676fSDimitry Andric         Type = ELF::R_PPC_REL16_HI;
115f785676fSDimitry Andric         break;
116f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_HA:
117f785676fSDimitry Andric         Type = ELF::R_PPC_REL16_HA;
118f785676fSDimitry Andric         break;
119f785676fSDimitry Andric       }
120f785676fSDimitry Andric       break;
1217d523365SDimitry Andric     case PPC::fixup_ppc_half16ds:
1227d523365SDimitry Andric       Target.print(errs());
1237d523365SDimitry Andric       errs() << '\n';
1247d523365SDimitry Andric       report_fatal_error("Invalid PC-relative half16ds relocation");
125139f7f9bSDimitry Andric     case FK_Data_4:
126dff0c46cSDimitry Andric     case FK_PCRel_4:
127dff0c46cSDimitry Andric       Type = ELF::R_PPC_REL32;
128dff0c46cSDimitry Andric       break;
129139f7f9bSDimitry Andric     case FK_Data_8:
130139f7f9bSDimitry Andric     case FK_PCRel_8:
131139f7f9bSDimitry Andric       Type = ELF::R_PPC64_REL64;
132139f7f9bSDimitry Andric       break;
133dff0c46cSDimitry Andric     }
134dff0c46cSDimitry Andric   } else {
135dff0c46cSDimitry Andric     switch ((unsigned)Fixup.getKind()) {
136dff0c46cSDimitry Andric       default: llvm_unreachable("invalid fixup kind!");
137f785676fSDimitry Andric     case PPC::fixup_ppc_br24abs:
138dff0c46cSDimitry Andric       Type = ELF::R_PPC_ADDR24;
139dff0c46cSDimitry Andric       break;
140f785676fSDimitry Andric     case PPC::fixup_ppc_brcond14abs:
1413861d79fSDimitry Andric       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
142dff0c46cSDimitry Andric       break;
143f785676fSDimitry Andric     case PPC::fixup_ppc_half16:
1443861d79fSDimitry Andric       switch (Modifier) {
1453861d79fSDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
1463861d79fSDimitry Andric       case MCSymbolRefExpr::VK_None:
147284c1978SDimitry Andric         Type = ELF::R_PPC_ADDR16;
148284c1978SDimitry Andric         break;
149f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_LO:
150dff0c46cSDimitry Andric         Type = ELF::R_PPC_ADDR16_LO;
151dff0c46cSDimitry Andric         break;
152f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_HI:
153f785676fSDimitry Andric         Type = ELF::R_PPC_ADDR16_HI;
154f785676fSDimitry Andric         break;
155f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_HA:
156f785676fSDimitry Andric         Type = ELF::R_PPC_ADDR16_HA;
157f785676fSDimitry Andric         break;
158*4ba319b5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGH:
159*4ba319b5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGH;
160*4ba319b5SDimitry Andric         break;
161*4ba319b5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHA:
162*4ba319b5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHA;
163*4ba319b5SDimitry Andric         break;
164f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHER:
165f785676fSDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHER;
166f785676fSDimitry Andric         break;
167f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHERA:
168f785676fSDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHERA;
169f785676fSDimitry Andric         break;
170f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHEST:
171f785676fSDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHEST;
172f785676fSDimitry Andric         break;
173f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
174f785676fSDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
175f785676fSDimitry Andric         break;
176f785676fSDimitry Andric       case MCSymbolRefExpr::VK_GOT:
177f785676fSDimitry Andric         Type = ELF::R_PPC_GOT16;
178f785676fSDimitry Andric         break;
179f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_LO:
180f785676fSDimitry Andric         Type = ELF::R_PPC_GOT16_LO;
181f785676fSDimitry Andric         break;
182f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_HI:
183f785676fSDimitry Andric         Type = ELF::R_PPC_GOT16_HI;
184f785676fSDimitry Andric         break;
185f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_HA:
186f785676fSDimitry Andric         Type = ELF::R_PPC_GOT16_HA;
187f785676fSDimitry Andric         break;
188f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC:
1893861d79fSDimitry Andric         Type = ELF::R_PPC64_TOC16;
1903861d79fSDimitry Andric         break;
191f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC_LO:
192139f7f9bSDimitry Andric         Type = ELF::R_PPC64_TOC16_LO;
193139f7f9bSDimitry Andric         break;
194f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC_HI:
195f785676fSDimitry Andric         Type = ELF::R_PPC64_TOC16_HI;
196f785676fSDimitry Andric         break;
197f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC_HA:
198f785676fSDimitry Andric         Type = ELF::R_PPC64_TOC16_HA;
199f785676fSDimitry Andric         break;
2003ca95b02SDimitry Andric       case MCSymbolRefExpr::VK_TPREL:
201f785676fSDimitry Andric         Type = ELF::R_PPC_TPREL16;
202f785676fSDimitry Andric         break;
203f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
204f785676fSDimitry Andric         Type = ELF::R_PPC_TPREL16_LO;
205f785676fSDimitry Andric         break;
206f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
207f785676fSDimitry Andric         Type = ELF::R_PPC_TPREL16_HI;
208f785676fSDimitry Andric         break;
209f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
210f785676fSDimitry Andric         Type = ELF::R_PPC_TPREL16_HA;
211f785676fSDimitry Andric         break;
212*4ba319b5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
213*4ba319b5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGH;
214*4ba319b5SDimitry Andric         break;
215*4ba319b5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
216*4ba319b5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHA;
217*4ba319b5SDimitry Andric         break;
218f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
219f785676fSDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHER;
220f785676fSDimitry Andric         break;
221f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
222f785676fSDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHERA;
223f785676fSDimitry Andric         break;
224f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
225f785676fSDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHEST;
226f785676fSDimitry Andric         break;
227f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
228f785676fSDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
229f785676fSDimitry Andric         break;
2303ca95b02SDimitry Andric       case MCSymbolRefExpr::VK_DTPREL:
231f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16;
232f785676fSDimitry Andric         break;
233f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
234f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16_LO;
235f785676fSDimitry Andric         break;
236f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
237f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HI;
238f785676fSDimitry Andric         break;
239f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
240f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HA;
241f785676fSDimitry Andric         break;
242*4ba319b5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
243*4ba319b5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGH;
244*4ba319b5SDimitry Andric         break;
245*4ba319b5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
246*4ba319b5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHA;
247*4ba319b5SDimitry Andric         break;
248f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
249f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHER;
250f785676fSDimitry Andric         break;
251f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
252f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
253f785676fSDimitry Andric         break;
254f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
255f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
256f785676fSDimitry Andric         break;
257f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
258f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
259f785676fSDimitry Andric         break;
260f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
26126e25074SRoman Divacky         if (is64Bit())
262f785676fSDimitry Andric           Type = ELF::R_PPC64_GOT_TLSGD16;
26326e25074SRoman Divacky         else
26426e25074SRoman Divacky           Type = ELF::R_PPC_GOT_TLSGD16;
265f785676fSDimitry Andric         break;
266f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
267139f7f9bSDimitry Andric         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
268139f7f9bSDimitry Andric         break;
269f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
270f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
271f785676fSDimitry Andric         break;
272f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
273f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
274f785676fSDimitry Andric         break;
275f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
27626e25074SRoman Divacky         if (is64Bit())
277f785676fSDimitry Andric           Type = ELF::R_PPC64_GOT_TLSLD16;
27826e25074SRoman Divacky         else
27926e25074SRoman Divacky           Type = ELF::R_PPC_GOT_TLSLD16;
280f785676fSDimitry Andric         break;
281f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
282139f7f9bSDimitry Andric         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
283139f7f9bSDimitry Andric         break;
284f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
285f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
286f785676fSDimitry Andric         break;
287f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
288f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
289f785676fSDimitry Andric         break;
290f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
291f785676fSDimitry Andric         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
292f785676fSDimitry Andric            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
293f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_DS;
294f785676fSDimitry Andric         break;
295f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
296f785676fSDimitry Andric         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
297f785676fSDimitry Andric            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
298f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
299f785676fSDimitry Andric         break;
300f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
301f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_HI;
302f785676fSDimitry Andric         break;
303f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
304f785676fSDimitry Andric         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
305f785676fSDimitry Andric            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
306f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
307f785676fSDimitry Andric         break;
308f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
309f785676fSDimitry Andric         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
310f785676fSDimitry Andric            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
311f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
312f785676fSDimitry Andric         break;
313f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
314f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_HA;
315f785676fSDimitry Andric         break;
316f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
317f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
318f785676fSDimitry Andric         break;
319f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
320f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
321f785676fSDimitry Andric         break;
322139f7f9bSDimitry Andric       }
323139f7f9bSDimitry Andric       break;
324f785676fSDimitry Andric     case PPC::fixup_ppc_half16ds:
325139f7f9bSDimitry Andric       switch (Modifier) {
326139f7f9bSDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
327139f7f9bSDimitry Andric       case MCSymbolRefExpr::VK_None:
328139f7f9bSDimitry Andric         Type = ELF::R_PPC64_ADDR16_DS;
329139f7f9bSDimitry Andric         break;
330f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_LO:
331284c1978SDimitry Andric         Type = ELF::R_PPC64_ADDR16_LO_DS;
332284c1978SDimitry Andric         break;
333f785676fSDimitry Andric       case MCSymbolRefExpr::VK_GOT:
334f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT16_DS;
335f785676fSDimitry Andric         break;
336f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_LO:
337f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT16_LO_DS;
338f785676fSDimitry Andric         break;
339f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC:
3403861d79fSDimitry Andric         Type = ELF::R_PPC64_TOC16_DS;
3413861d79fSDimitry Andric         break;
342f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC_LO:
343139f7f9bSDimitry Andric         Type = ELF::R_PPC64_TOC16_LO_DS;
344139f7f9bSDimitry Andric         break;
3453ca95b02SDimitry Andric       case MCSymbolRefExpr::VK_TPREL:
346f785676fSDimitry Andric         Type = ELF::R_PPC64_TPREL16_DS;
347f785676fSDimitry Andric         break;
348f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
349f785676fSDimitry Andric         Type = ELF::R_PPC64_TPREL16_LO_DS;
350f785676fSDimitry Andric         break;
3513ca95b02SDimitry Andric       case MCSymbolRefExpr::VK_DTPREL:
352f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16_DS;
353f785676fSDimitry Andric         break;
354f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
355f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL16_LO_DS;
356f785676fSDimitry Andric         break;
357f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
358f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_DS;
359f785676fSDimitry Andric         break;
360f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
361139f7f9bSDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
362139f7f9bSDimitry Andric         break;
363f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
364f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
365139f7f9bSDimitry Andric         break;
366f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
367f785676fSDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
368f785676fSDimitry Andric         break;
369f785676fSDimitry Andric       }
370139f7f9bSDimitry Andric       break;
371139f7f9bSDimitry Andric     case PPC::fixup_ppc_nofixup:
372139f7f9bSDimitry Andric       switch (Modifier) {
373139f7f9bSDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
374139f7f9bSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TLSGD:
37526e25074SRoman Divacky         if (is64Bit())
376139f7f9bSDimitry Andric           Type = ELF::R_PPC64_TLSGD;
37726e25074SRoman Divacky         else
37826e25074SRoman Divacky           Type = ELF::R_PPC_TLSGD;
379139f7f9bSDimitry Andric         break;
380139f7f9bSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TLSLD:
38126e25074SRoman Divacky         if (is64Bit())
382139f7f9bSDimitry Andric           Type = ELF::R_PPC64_TLSLD;
38326e25074SRoman Divacky         else
38426e25074SRoman Divacky           Type = ELF::R_PPC_TLSLD;
385139f7f9bSDimitry Andric         break;
386f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TLS:
38726e25074SRoman Divacky         if (is64Bit())
388f785676fSDimitry Andric           Type = ELF::R_PPC64_TLS;
38926e25074SRoman Divacky         else
39026e25074SRoman Divacky           Type = ELF::R_PPC_TLS;
391f785676fSDimitry Andric         break;
392139f7f9bSDimitry Andric       }
393139f7f9bSDimitry Andric       break;
3943861d79fSDimitry Andric     case FK_Data_8:
3953861d79fSDimitry Andric       switch (Modifier) {
3963861d79fSDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
397f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOCBASE:
3983861d79fSDimitry Andric         Type = ELF::R_PPC64_TOC;
3993861d79fSDimitry Andric         break;
4003861d79fSDimitry Andric       case MCSymbolRefExpr::VK_None:
4013861d79fSDimitry Andric         Type = ELF::R_PPC64_ADDR64;
4023861d79fSDimitry Andric         break;
403f785676fSDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPMOD:
404f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPMOD64;
405f785676fSDimitry Andric         break;
4063ca95b02SDimitry Andric       case MCSymbolRefExpr::VK_TPREL:
407f785676fSDimitry Andric         Type = ELF::R_PPC64_TPREL64;
408f785676fSDimitry Andric         break;
4093ca95b02SDimitry Andric       case MCSymbolRefExpr::VK_DTPREL:
410f785676fSDimitry Andric         Type = ELF::R_PPC64_DTPREL64;
411f785676fSDimitry Andric         break;
4123861d79fSDimitry Andric       }
4133861d79fSDimitry Andric       break;
414dff0c46cSDimitry Andric     case FK_Data_4:
415dff0c46cSDimitry Andric       Type = ELF::R_PPC_ADDR32;
416dff0c46cSDimitry Andric       break;
417dff0c46cSDimitry Andric     case FK_Data_2:
418dff0c46cSDimitry Andric       Type = ELF::R_PPC_ADDR16;
419dff0c46cSDimitry Andric       break;
420dff0c46cSDimitry Andric     }
421dff0c46cSDimitry Andric   }
422dff0c46cSDimitry Andric   return Type;
423dff0c46cSDimitry Andric }
424dff0c46cSDimitry Andric 
needsRelocateWithSymbol(const MCSymbol & Sym,unsigned Type) const42597bc6c73SDimitry Andric bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
42691bc56edSDimitry Andric                                                  unsigned Type) const {
42791bc56edSDimitry Andric   switch (Type) {
428f785676fSDimitry Andric     default:
42991bc56edSDimitry Andric       return false;
43091bc56edSDimitry Andric 
43191bc56edSDimitry Andric     case ELF::R_PPC_REL24:
43291bc56edSDimitry Andric       // If the target symbol has a local entry point, we must keep the
43391bc56edSDimitry Andric       // target symbol to preserve that information for the linker.
43491bc56edSDimitry Andric       // The "other" values are stored in the last 6 bits of the second byte.
43591bc56edSDimitry Andric       // The traditional defines for STO values assume the full byte and thus
43691bc56edSDimitry Andric       // the shift to pack it.
43797bc6c73SDimitry Andric       unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
43891bc56edSDimitry Andric       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
439f785676fSDimitry Andric   }
4403861d79fSDimitry Andric }
4413861d79fSDimitry Andric 
442*4ba319b5SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
createPPCELFObjectWriter(bool Is64Bit,uint8_t OSABI)443*4ba319b5SDimitry Andric llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
444*4ba319b5SDimitry Andric   return llvm::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);
445dff0c46cSDimitry Andric }
446