138a400dfSRafael Espindola //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
238a400dfSRafael Espindola //
338a400dfSRafael Espindola //                     The LLVM Compiler Infrastructure
438a400dfSRafael Espindola //
538a400dfSRafael Espindola // This file is distributed under the University of Illinois Open Source
638a400dfSRafael Espindola // License. See LICENSE.TXT for details.
738a400dfSRafael Espindola //
838a400dfSRafael Espindola //===----------------------------------------------------------------------===//
938a400dfSRafael Espindola 
1038a400dfSRafael Espindola #include "MCTargetDesc/PPCMCTargetDesc.h"
11ed0881b2SChandler Carruth #include "MCTargetDesc/PPCFixupKinds.h"
127fadc0eaSRafael Espindola #include "MCTargetDesc/PPCMCExpr.h"
13a4f89844SBill Schmidt #include "llvm/ADT/STLExtras.h"
1438a400dfSRafael Espindola #include "llvm/MC/MCELFObjectWriter.h"
15f2aceda8SAdhemerval Zanella #include "llvm/MC/MCExpr.h"
16f2aceda8SAdhemerval Zanella #include "llvm/MC/MCValue.h"
17ed0881b2SChandler Carruth #include "llvm/Support/ErrorHandling.h"
1838a400dfSRafael Espindola 
1938a400dfSRafael Espindola using namespace llvm;
2038a400dfSRafael Espindola 
2138a400dfSRafael Espindola namespace {
2238a400dfSRafael Espindola   class PPCELFObjectWriter : public MCELFObjectTargetWriter {
2338a400dfSRafael Espindola   public:
2438a400dfSRafael Espindola     PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
2538a400dfSRafael Espindola 
2638a400dfSRafael Espindola     virtual ~PPCELFObjectWriter();
2738a400dfSRafael Espindola   protected:
28f2aceda8SAdhemerval Zanella     virtual unsigned getRelocTypeInner(const MCValue &Target,
29f2aceda8SAdhemerval Zanella                                        const MCFixup &Fixup,
30f2aceda8SAdhemerval Zanella                                        bool IsPCRel) const;
319ab38012SRafael Espindola     unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
32c03f44caSRafael Espindola                           bool IsPCRel) const override;
33*bb68610dSUlrich Weigand 
34*bb68610dSUlrich Weigand     bool needsRelocateWithSymbol(unsigned Type) const override;
3538a400dfSRafael Espindola   };
3638a400dfSRafael Espindola }
3738a400dfSRafael Espindola 
3838a400dfSRafael Espindola PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
3938a400dfSRafael Espindola   : MCELFObjectTargetWriter(Is64Bit, OSABI,
4038a400dfSRafael Espindola                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
4125009623SRafael Espindola                             /*HasRelocationAddend*/ true) {}
4238a400dfSRafael Espindola 
4338a400dfSRafael Espindola PPCELFObjectWriter::~PPCELFObjectWriter() {
4438a400dfSRafael Espindola }
4538a400dfSRafael Espindola 
463d082fa5SRafael Espindola static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
473d082fa5SRafael Espindola                                                      const MCFixup &Fixup) {
487fadc0eaSRafael Espindola   const MCExpr *Expr = Fixup.getValue();
497fadc0eaSRafael Espindola 
507fadc0eaSRafael Espindola   if (Expr->getKind() != MCExpr::Target)
513d082fa5SRafael Espindola     return Target.getAccessVariant();
527fadc0eaSRafael Espindola 
537fadc0eaSRafael Espindola   switch (cast<PPCMCExpr>(Expr)->getKind()) {
547fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_None:
557fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_None;
567fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_LO:
577fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_LO;
587fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HI:
597fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HI;
607fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HA:
617fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HA;
627fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHERA:
637fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHERA;
647fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHER:
657fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHER;
667fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHEST:
677fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHEST;
687fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHESTA:
697fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
707fadc0eaSRafael Espindola   }
7194bc422dSAlexey Samsonov   llvm_unreachable("unknown PPCMCExpr kind");
727fadc0eaSRafael Espindola }
737fadc0eaSRafael Espindola 
74f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
7538a400dfSRafael Espindola                                                const MCFixup &Fixup,
76f2aceda8SAdhemerval Zanella                                                bool IsPCRel) const
77f2aceda8SAdhemerval Zanella {
783d082fa5SRafael Espindola   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
79f2aceda8SAdhemerval Zanella 
8038a400dfSRafael Espindola   // determine the type of the relocation
8138a400dfSRafael Espindola   unsigned Type;
8238a400dfSRafael Espindola   if (IsPCRel) {
8338a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
8438a400dfSRafael Espindola     default:
8538a400dfSRafael Espindola       llvm_unreachable("Unimplemented");
8638a400dfSRafael Espindola     case PPC::fixup_ppc_br24:
87b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
883ee2af7dSHal Finkel       switch (Modifier) {
893ee2af7dSHal Finkel       default: llvm_unreachable("Unsupported Modifier");
903ee2af7dSHal Finkel       case MCSymbolRefExpr::VK_None:
9138a400dfSRafael Espindola         Type = ELF::R_PPC_REL24;
9238a400dfSRafael Espindola         break;
933ee2af7dSHal Finkel       case MCSymbolRefExpr::VK_PLT:
943ee2af7dSHal Finkel         Type = ELF::R_PPC_PLTREL24;
953ee2af7dSHal Finkel         break;
963ee2af7dSHal Finkel       }
973ee2af7dSHal Finkel       break;
9872a7dc0dSUlrich Weigand     case PPC::fixup_ppc_brcond14:
99b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
10072a7dc0dSUlrich Weigand       Type = ELF::R_PPC_REL14;
10172a7dc0dSUlrich Weigand       break;
10291add7dfSUlrich Weigand     case PPC::fixup_ppc_half16:
10391add7dfSUlrich Weigand       switch (Modifier) {
10491add7dfSUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
10591add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_None:
10691add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16;
10791add7dfSUlrich Weigand         break;
10891add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
10991add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_LO;
11091add7dfSUlrich Weigand         break;
11191add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
11291add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HI;
11391add7dfSUlrich Weigand         break;
11491add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
11591add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HA;
11691add7dfSUlrich Weigand         break;
11791add7dfSUlrich Weigand       }
11891add7dfSUlrich Weigand       break;
1199b0b7813SAdhemerval Zanella     case FK_Data_4:
12038a400dfSRafael Espindola     case FK_PCRel_4:
12138a400dfSRafael Espindola       Type = ELF::R_PPC_REL32;
12238a400dfSRafael Espindola       break;
1239b0b7813SAdhemerval Zanella     case FK_Data_8:
1249b0b7813SAdhemerval Zanella     case FK_PCRel_8:
1259b0b7813SAdhemerval Zanella       Type = ELF::R_PPC64_REL64;
1269b0b7813SAdhemerval Zanella       break;
12738a400dfSRafael Espindola     }
12838a400dfSRafael Espindola   } else {
12938a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
13038a400dfSRafael Espindola       default: llvm_unreachable("invalid fixup kind!");
131b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
13238a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR24;
13338a400dfSRafael Espindola       break;
134b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
135f2aceda8SAdhemerval Zanella       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
13638a400dfSRafael Espindola       break;
1376e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16:
13885578500SUlrich Weigand       switch (Modifier) {
13985578500SUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
14085578500SUlrich Weigand       case MCSymbolRefExpr::VK_None:
141e462053fSUlrich Weigand         Type = ELF::R_PPC_ADDR16;
142e462053fSUlrich Weigand         break;
143d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
14438a400dfSRafael Espindola         Type = ELF::R_PPC_ADDR16_LO;
14538a400dfSRafael Espindola         break;
146e67c565dSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
147e67c565dSUlrich Weigand         Type = ELF::R_PPC_ADDR16_HI;
148e67c565dSUlrich Weigand         break;
149d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
1509e90b3c8SUlrich Weigand         Type = ELF::R_PPC_ADDR16_HA;
1519e90b3c8SUlrich Weigand         break;
152e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHER:
153e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHER;
154e9126f55SUlrich Weigand         break;
155e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHERA:
156e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHERA;
157e9126f55SUlrich Weigand         break;
158e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHEST:
159e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHEST;
160e9126f55SUlrich Weigand         break;
161e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
162e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
163e9126f55SUlrich Weigand         break;
16493372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
16593372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16;
16693372b45SUlrich Weigand         break;
16793372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
16893372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_LO;
16993372b45SUlrich Weigand         break;
17093372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HI:
17193372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HI;
17293372b45SUlrich Weigand         break;
17393372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HA:
17493372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HA;
17593372b45SUlrich Weigand         break;
176d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
1773e186015SUlrich Weigand         Type = ELF::R_PPC64_TOC16;
1783e186015SUlrich Weigand         break;
179d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
18034627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO;
18134627e34SBill Schmidt         break;
18272ddbd65SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HI:
18372ddbd65SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HI;
18472ddbd65SUlrich Weigand         break;
185d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HA:
1869e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HA;
1879e90b3c8SUlrich Weigand         break;
188876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
189876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16;
190876a0d01SUlrich Weigand         break;
191d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
1929e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_LO;
1939e90b3c8SUlrich Weigand         break;
194876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
195876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HI;
196876a0d01SUlrich Weigand         break;
197d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
1989e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HA;
1999e90b3c8SUlrich Weigand         break;
200876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
201876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHER;
202876a0d01SUlrich Weigand         break;
203876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
204876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHERA;
205876a0d01SUlrich Weigand         break;
206876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
207876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHEST;
208876a0d01SUlrich Weigand         break;
209876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
210876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
211876a0d01SUlrich Weigand         break;
212876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
213876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16;
214876a0d01SUlrich Weigand         break;
215d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
2169e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO;
2179e90b3c8SUlrich Weigand         break;
218876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
219876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HI;
220876a0d01SUlrich Weigand         break;
221d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
2229e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HA;
2239e90b3c8SUlrich Weigand         break;
224876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
225876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHER;
226876a0d01SUlrich Weigand         break;
227876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
228876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
229876a0d01SUlrich Weigand         break;
230876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
231876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
232876a0d01SUlrich Weigand         break;
233876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
234876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
235876a0d01SUlrich Weigand         break;
236876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
237876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16;
238876a0d01SUlrich Weigand         break;
239d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
240c56f1d34SBill Schmidt         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
241c56f1d34SBill Schmidt         break;
242876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
243876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
244876a0d01SUlrich Weigand         break;
245d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
2469e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
2479e90b3c8SUlrich Weigand         break;
248876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
249876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16;
250876a0d01SUlrich Weigand         break;
251d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
25224b8dd6eSBill Schmidt         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
25324b8dd6eSBill Schmidt         break;
254876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
255876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
256876a0d01SUlrich Weigand         break;
257d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
2589e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
2599e90b3c8SUlrich Weigand         break;
260b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
261b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
262b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
263b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
264b2044311SUlrich Weigand         break;
265b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
266b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
267b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
268b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
269b2044311SUlrich Weigand         break;
270876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
271876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HI;
272876a0d01SUlrich Weigand         break;
273b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
274b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
275b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
276b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
277b2044311SUlrich Weigand         break;
278b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
279b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
280b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
281b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
282b2044311SUlrich Weigand         break;
283d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
2849e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HA;
2859e90b3c8SUlrich Weigand         break;
286876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
287876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
288876a0d01SUlrich Weigand         break;
289876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
290876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
291876a0d01SUlrich Weigand         break;
29285578500SUlrich Weigand       }
29385578500SUlrich Weigand       break;
2946e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16ds:
2953822ef2cSBill Schmidt       switch (Modifier) {
2963822ef2cSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
2973822ef2cSBill Schmidt       case MCSymbolRefExpr::VK_None:
2983e186015SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_DS;
299f2aceda8SAdhemerval Zanella         break;
300d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
301e462053fSUlrich Weigand         Type = ELF::R_PPC64_ADDR16_LO_DS;
302e462053fSUlrich Weigand         break;
30393372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
30493372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_DS;
30593372b45SUlrich Weigand 	break;
30693372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
30793372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_LO_DS;
30893372b45SUlrich Weigand         break;
309d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
310f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC16_DS;
311f2aceda8SAdhemerval Zanella 	break;
312d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
31334627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO_DS;
31434627e34SBill Schmidt         break;
315876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
316876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_DS;
317876a0d01SUlrich Weigand         break;
318876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
319876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_LO_DS;
320876a0d01SUlrich Weigand         break;
321876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
322876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_DS;
323876a0d01SUlrich Weigand         break;
324876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
325876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO_DS;
326876a0d01SUlrich Weigand         break;
327876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
328876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
329876a0d01SUlrich Weigand         break;
330d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
3319f0b4ec0SBill Schmidt         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
332ca4a0c9dSBill Schmidt         break;
333876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
334876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
335876a0d01SUlrich Weigand         break;
336876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
337876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
338876a0d01SUlrich Weigand         break;
33934627e34SBill Schmidt       }
34034627e34SBill Schmidt       break;
34124b8dd6eSBill Schmidt     case PPC::fixup_ppc_nofixup:
34224b8dd6eSBill Schmidt       switch (Modifier) {
34324b8dd6eSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
34452cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSGD:
345c56f1d34SBill Schmidt         Type = ELF::R_PPC64_TLSGD;
346c56f1d34SBill Schmidt         break;
34752cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSLD:
34824b8dd6eSBill Schmidt         Type = ELF::R_PPC64_TLSLD;
34924b8dd6eSBill Schmidt         break;
3505b427591SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLS:
3515b427591SUlrich Weigand         Type = ELF::R_PPC64_TLS;
3525b427591SUlrich Weigand         break;
35324b8dd6eSBill Schmidt       }
35424b8dd6eSBill Schmidt       break;
355f2aceda8SAdhemerval Zanella     case FK_Data_8:
356f2aceda8SAdhemerval Zanella       switch (Modifier) {
357f2aceda8SAdhemerval Zanella       default: llvm_unreachable("Unsupported Modifier");
35868e2e1b3SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOCBASE:
359f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC;
360f2aceda8SAdhemerval Zanella         break;
361f2aceda8SAdhemerval Zanella       case MCSymbolRefExpr::VK_None:
362f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_ADDR64;
363f2aceda8SAdhemerval Zanella 	break;
364f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPMOD:
365f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPMOD64;
366f11efe7fSUlrich Weigand 	break;
367f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
368f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_TPREL64;
369f11efe7fSUlrich Weigand 	break;
370f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
371f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPREL64;
372f11efe7fSUlrich Weigand 	break;
373f2aceda8SAdhemerval Zanella       }
374f2aceda8SAdhemerval Zanella       break;
37538a400dfSRafael Espindola     case FK_Data_4:
37638a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR32;
37738a400dfSRafael Espindola       break;
37838a400dfSRafael Espindola     case FK_Data_2:
37938a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR16;
38038a400dfSRafael Espindola       break;
38138a400dfSRafael Espindola     }
38238a400dfSRafael Espindola   }
38338a400dfSRafael Espindola   return Type;
38438a400dfSRafael Espindola }
38538a400dfSRafael Espindola 
386f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
387f2aceda8SAdhemerval Zanella                                           const MCFixup &Fixup,
388c03f44caSRafael Espindola                                           bool IsPCRel) const {
389f2aceda8SAdhemerval Zanella   return getRelocTypeInner(Target, Fixup, IsPCRel);
390f2aceda8SAdhemerval Zanella }
391f2aceda8SAdhemerval Zanella 
392*bb68610dSUlrich Weigand bool PPCELFObjectWriter::needsRelocateWithSymbol(unsigned Type) const {
393*bb68610dSUlrich Weigand   switch (Type) {
394*bb68610dSUlrich Weigand     default:
395*bb68610dSUlrich Weigand       return false;
396*bb68610dSUlrich Weigand 
397*bb68610dSUlrich Weigand     case ELF::R_PPC_REL24:
398*bb68610dSUlrich Weigand       // FIXME: We only need to keep the target symbol of the relocation
399*bb68610dSUlrich Weigand       // if the symbol uses a local entry point.  Unfortunately, we do not
400*bb68610dSUlrich Weigand       // have access to the symbol here ...
401*bb68610dSUlrich Weigand       return true;
402*bb68610dSUlrich Weigand   }
403*bb68610dSUlrich Weigand }
404*bb68610dSUlrich Weigand 
40538a400dfSRafael Espindola MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,
40638a400dfSRafael Espindola                                                bool Is64Bit,
407cae3a17aSUlrich Weigand                                                bool IsLittleEndian,
40838a400dfSRafael Espindola                                                uint8_t OSABI) {
40938a400dfSRafael Espindola   MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI);
410cae3a17aSUlrich Weigand   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
41138a400dfSRafael Espindola }
412