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;
3138a400dfSRafael Espindola     virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
3238a400dfSRafael Espindola                                   bool IsPCRel, bool IsRelocWithSymbol,
3338a400dfSRafael Espindola                                   int64_t Addend) const;
343a75861bSUlrich Weigand     virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
353a75861bSUlrich Weigand                                            const MCValue &Target,
363a75861bSUlrich Weigand                                            const MCFragment &F,
373a75861bSUlrich Weigand                                            const MCFixup &Fixup,
383a75861bSUlrich Weigand                                            bool IsPCRel) const;
39f2aceda8SAdhemerval Zanella     virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
40f2aceda8SAdhemerval Zanella                                                     const MCFixup &Fixup,
41f2aceda8SAdhemerval Zanella                                                     bool IsPCRel) const;
4238a400dfSRafael Espindola   };
4338a400dfSRafael Espindola }
4438a400dfSRafael Espindola 
4538a400dfSRafael Espindola PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
4638a400dfSRafael Espindola   : MCELFObjectTargetWriter(Is64Bit, OSABI,
4738a400dfSRafael Espindola                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
4825009623SRafael Espindola                             /*HasRelocationAddend*/ true) {}
4938a400dfSRafael Espindola 
5038a400dfSRafael Espindola PPCELFObjectWriter::~PPCELFObjectWriter() {
5138a400dfSRafael Espindola }
5238a400dfSRafael Espindola 
537fadc0eaSRafael Espindola static MCSymbolRefExpr::VariantKind getAccessVariant(const MCFixup &Fixup) {
547fadc0eaSRafael Espindola   const MCExpr *Expr = Fixup.getValue();
557fadc0eaSRafael Espindola 
567fadc0eaSRafael Espindola   if (Expr->getKind() != MCExpr::Target)
577fadc0eaSRafael Espindola     return Fixup.getAccessVariant();
587fadc0eaSRafael Espindola 
597fadc0eaSRafael Espindola   switch (cast<PPCMCExpr>(Expr)->getKind()) {
607fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_None:
617fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_None;
627fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_LO:
637fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_LO;
647fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HI:
657fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HI;
667fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HA:
677fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HA;
687fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHERA:
697fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHERA;
707fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHER:
717fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHER;
727fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHEST:
737fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHEST;
747fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHESTA:
757fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
767fadc0eaSRafael Espindola   }
7794bc422dSAlexey Samsonov   llvm_unreachable("unknown PPCMCExpr kind");
787fadc0eaSRafael Espindola }
797fadc0eaSRafael Espindola 
80f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
8138a400dfSRafael Espindola                                                const MCFixup &Fixup,
82f2aceda8SAdhemerval Zanella                                                bool IsPCRel) const
83f2aceda8SAdhemerval Zanella {
847fadc0eaSRafael Espindola   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Fixup);
85f2aceda8SAdhemerval Zanella 
8638a400dfSRafael Espindola   // determine the type of the relocation
8738a400dfSRafael Espindola   unsigned Type;
8838a400dfSRafael Espindola   if (IsPCRel) {
8938a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
9038a400dfSRafael Espindola     default:
9138a400dfSRafael Espindola       llvm_unreachable("Unimplemented");
9238a400dfSRafael Espindola     case PPC::fixup_ppc_br24:
93b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
9438a400dfSRafael Espindola       Type = ELF::R_PPC_REL24;
9538a400dfSRafael Espindola       break;
9672a7dc0dSUlrich Weigand     case PPC::fixup_ppc_brcond14:
97b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
9872a7dc0dSUlrich Weigand       Type = ELF::R_PPC_REL14;
9972a7dc0dSUlrich Weigand       break;
10091add7dfSUlrich Weigand     case PPC::fixup_ppc_half16:
10191add7dfSUlrich Weigand       switch (Modifier) {
10291add7dfSUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
10391add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_None:
10491add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16;
10591add7dfSUlrich Weigand         break;
10691add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
10791add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_LO;
10891add7dfSUlrich Weigand         break;
10991add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
11091add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HI;
11191add7dfSUlrich Weigand         break;
11291add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
11391add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HA;
11491add7dfSUlrich Weigand         break;
11591add7dfSUlrich Weigand       }
11691add7dfSUlrich Weigand       break;
1179b0b7813SAdhemerval Zanella     case FK_Data_4:
11838a400dfSRafael Espindola     case FK_PCRel_4:
11938a400dfSRafael Espindola       Type = ELF::R_PPC_REL32;
12038a400dfSRafael Espindola       break;
1219b0b7813SAdhemerval Zanella     case FK_Data_8:
1229b0b7813SAdhemerval Zanella     case FK_PCRel_8:
1239b0b7813SAdhemerval Zanella       Type = ELF::R_PPC64_REL64;
1249b0b7813SAdhemerval Zanella       break;
12538a400dfSRafael Espindola     }
12638a400dfSRafael Espindola   } else {
12738a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
12838a400dfSRafael Espindola       default: llvm_unreachable("invalid fixup kind!");
129b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
13038a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR24;
13138a400dfSRafael Espindola       break;
132b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
133f2aceda8SAdhemerval Zanella       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
13438a400dfSRafael Espindola       break;
1356e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16:
13685578500SUlrich Weigand       switch (Modifier) {
13785578500SUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
13885578500SUlrich Weigand       case MCSymbolRefExpr::VK_None:
139e462053fSUlrich Weigand         Type = ELF::R_PPC_ADDR16;
140e462053fSUlrich Weigand         break;
141d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
14238a400dfSRafael Espindola         Type = ELF::R_PPC_ADDR16_LO;
14338a400dfSRafael Espindola         break;
144e67c565dSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
145e67c565dSUlrich Weigand         Type = ELF::R_PPC_ADDR16_HI;
146e67c565dSUlrich Weigand         break;
147d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
1489e90b3c8SUlrich Weigand         Type = ELF::R_PPC_ADDR16_HA;
1499e90b3c8SUlrich Weigand         break;
150e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHER:
151e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHER;
152e9126f55SUlrich Weigand         break;
153e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHERA:
154e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHERA;
155e9126f55SUlrich Weigand         break;
156e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHEST:
157e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHEST;
158e9126f55SUlrich Weigand         break;
159e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
160e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
161e9126f55SUlrich Weigand         break;
16293372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
16393372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16;
16493372b45SUlrich Weigand         break;
16593372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
16693372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_LO;
16793372b45SUlrich Weigand         break;
16893372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HI:
16993372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HI;
17093372b45SUlrich Weigand         break;
17193372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HA:
17293372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HA;
17393372b45SUlrich Weigand         break;
174d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
1753e186015SUlrich Weigand         Type = ELF::R_PPC64_TOC16;
1763e186015SUlrich Weigand         break;
177d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
17834627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO;
17934627e34SBill Schmidt         break;
18072ddbd65SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HI:
18172ddbd65SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HI;
18272ddbd65SUlrich Weigand         break;
183d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HA:
1849e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HA;
1859e90b3c8SUlrich Weigand         break;
186876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
187876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16;
188876a0d01SUlrich Weigand         break;
189d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
1909e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_LO;
1919e90b3c8SUlrich Weigand         break;
192876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
193876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HI;
194876a0d01SUlrich Weigand         break;
195d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
1969e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HA;
1979e90b3c8SUlrich Weigand         break;
198876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
199876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHER;
200876a0d01SUlrich Weigand         break;
201876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
202876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHERA;
203876a0d01SUlrich Weigand         break;
204876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
205876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHEST;
206876a0d01SUlrich Weigand         break;
207876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
208876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
209876a0d01SUlrich Weigand         break;
210876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
211876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16;
212876a0d01SUlrich Weigand         break;
213d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
2149e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO;
2159e90b3c8SUlrich Weigand         break;
216876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
217876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HI;
218876a0d01SUlrich Weigand         break;
219d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
2209e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HA;
2219e90b3c8SUlrich Weigand         break;
222876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
223876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHER;
224876a0d01SUlrich Weigand         break;
225876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
226876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
227876a0d01SUlrich Weigand         break;
228876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
229876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
230876a0d01SUlrich Weigand         break;
231876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
232876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
233876a0d01SUlrich Weigand         break;
234876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
235876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16;
236876a0d01SUlrich Weigand         break;
237d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
238c56f1d34SBill Schmidt         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
239c56f1d34SBill Schmidt         break;
240876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
241876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
242876a0d01SUlrich Weigand         break;
243d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
2449e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
2459e90b3c8SUlrich Weigand         break;
246876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
247876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16;
248876a0d01SUlrich Weigand         break;
249d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
25024b8dd6eSBill Schmidt         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
25124b8dd6eSBill Schmidt         break;
252876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
253876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
254876a0d01SUlrich Weigand         break;
255d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
2569e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
2579e90b3c8SUlrich Weigand         break;
258b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
259b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
260b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
261b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
262b2044311SUlrich Weigand         break;
263b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
264b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
265b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
266b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
267b2044311SUlrich Weigand         break;
268876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
269876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HI;
270876a0d01SUlrich Weigand         break;
271b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
272b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
273b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
274b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
275b2044311SUlrich Weigand         break;
276b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
277b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
278b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
279b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
280b2044311SUlrich Weigand         break;
281d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
2829e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HA;
2839e90b3c8SUlrich Weigand         break;
284876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
285876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
286876a0d01SUlrich Weigand         break;
287876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
288876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
289876a0d01SUlrich Weigand         break;
29085578500SUlrich Weigand       }
29185578500SUlrich Weigand       break;
2926e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16ds:
2933822ef2cSBill Schmidt       switch (Modifier) {
2943822ef2cSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
2953822ef2cSBill Schmidt       case MCSymbolRefExpr::VK_None:
2963e186015SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_DS;
297f2aceda8SAdhemerval Zanella         break;
298d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
299e462053fSUlrich Weigand         Type = ELF::R_PPC64_ADDR16_LO_DS;
300e462053fSUlrich Weigand         break;
30193372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
30293372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_DS;
30393372b45SUlrich Weigand 	break;
30493372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
30593372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_LO_DS;
30693372b45SUlrich Weigand         break;
307d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
308f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC16_DS;
309f2aceda8SAdhemerval Zanella 	break;
310d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
31134627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO_DS;
31234627e34SBill Schmidt         break;
313876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
314876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_DS;
315876a0d01SUlrich Weigand         break;
316876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
317876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_LO_DS;
318876a0d01SUlrich Weigand         break;
319876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
320876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_DS;
321876a0d01SUlrich Weigand         break;
322876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
323876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO_DS;
324876a0d01SUlrich Weigand         break;
325876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
326876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
327876a0d01SUlrich Weigand         break;
328d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
3299f0b4ec0SBill Schmidt         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
330ca4a0c9dSBill Schmidt         break;
331876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
332876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
333876a0d01SUlrich Weigand         break;
334876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
335876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
336876a0d01SUlrich Weigand         break;
33734627e34SBill Schmidt       }
33834627e34SBill Schmidt       break;
33924b8dd6eSBill Schmidt     case PPC::fixup_ppc_nofixup:
34024b8dd6eSBill Schmidt       switch (Modifier) {
34124b8dd6eSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
34252cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSGD:
343c56f1d34SBill Schmidt         Type = ELF::R_PPC64_TLSGD;
344c56f1d34SBill Schmidt         break;
34552cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSLD:
34624b8dd6eSBill Schmidt         Type = ELF::R_PPC64_TLSLD;
34724b8dd6eSBill Schmidt         break;
3485b427591SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLS:
3495b427591SUlrich Weigand         Type = ELF::R_PPC64_TLS;
3505b427591SUlrich Weigand         break;
35124b8dd6eSBill Schmidt       }
35224b8dd6eSBill Schmidt       break;
353f2aceda8SAdhemerval Zanella     case FK_Data_8:
354f2aceda8SAdhemerval Zanella       switch (Modifier) {
355f2aceda8SAdhemerval Zanella       default: llvm_unreachable("Unsupported Modifier");
35668e2e1b3SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOCBASE:
357f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC;
358f2aceda8SAdhemerval Zanella         break;
359f2aceda8SAdhemerval Zanella       case MCSymbolRefExpr::VK_None:
360f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_ADDR64;
361f2aceda8SAdhemerval Zanella 	break;
362f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPMOD:
363f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPMOD64;
364f11efe7fSUlrich Weigand 	break;
365f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
366f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_TPREL64;
367f11efe7fSUlrich Weigand 	break;
368f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
369f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPREL64;
370f11efe7fSUlrich Weigand 	break;
371f2aceda8SAdhemerval Zanella       }
372f2aceda8SAdhemerval Zanella       break;
37338a400dfSRafael Espindola     case FK_Data_4:
37438a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR32;
37538a400dfSRafael Espindola       break;
37638a400dfSRafael Espindola     case FK_Data_2:
37738a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR16;
37838a400dfSRafael Espindola       break;
37938a400dfSRafael Espindola     }
38038a400dfSRafael Espindola   }
38138a400dfSRafael Espindola   return Type;
38238a400dfSRafael Espindola }
38338a400dfSRafael Espindola 
384f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
385f2aceda8SAdhemerval Zanella                                           const MCFixup &Fixup,
386f2aceda8SAdhemerval Zanella                                           bool IsPCRel,
387f2aceda8SAdhemerval Zanella                                           bool IsRelocWithSymbol,
388f2aceda8SAdhemerval Zanella                                           int64_t Addend) const {
389f2aceda8SAdhemerval Zanella   return getRelocTypeInner(Target, Fixup, IsPCRel);
390f2aceda8SAdhemerval Zanella }
391f2aceda8SAdhemerval Zanella 
3923a75861bSUlrich Weigand const MCSymbol *PPCELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
3933a75861bSUlrich Weigand                                                    const MCValue &Target,
3943a75861bSUlrich Weigand                                                    const MCFragment &F,
3953a75861bSUlrich Weigand                                                    const MCFixup &Fixup,
3963a75861bSUlrich Weigand                                                    bool IsPCRel) const {
3973a75861bSUlrich Weigand   assert(Target.getSymA() && "SymA cannot be 0");
3987fadc0eaSRafael Espindola   MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
3993a75861bSUlrich Weigand 
4003a75861bSUlrich Weigand   bool EmitThisSym;
4013a75861bSUlrich Weigand   switch (Modifier) {
4023a75861bSUlrich Weigand   // GOT references always need a relocation, even if the
4033a75861bSUlrich Weigand   // target symbol is local.
4043a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_GOT:
4053a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_PPC_GOT_LO:
4063a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_PPC_GOT_HI:
4073a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_PPC_GOT_HA:
4083a75861bSUlrich Weigand     EmitThisSym = true;
4093a75861bSUlrich Weigand     break;
4103a75861bSUlrich Weigand   default:
4113a75861bSUlrich Weigand     EmitThisSym = false;
4123a75861bSUlrich Weigand     break;
4133a75861bSUlrich Weigand   }
4143a75861bSUlrich Weigand 
4153a75861bSUlrich Weigand   if (EmitThisSym)
4163a75861bSUlrich Weigand     return &Target.getSymA()->getSymbol().AliasedSymbol();
4173a75861bSUlrich Weigand   return NULL;
4183a75861bSUlrich Weigand }
4193a75861bSUlrich Weigand 
420f2aceda8SAdhemerval Zanella const MCSymbol *PPCELFObjectWriter::undefinedExplicitRelSym(const MCValue &Target,
421f2aceda8SAdhemerval Zanella                                                             const MCFixup &Fixup,
422f2aceda8SAdhemerval Zanella                                                             bool IsPCRel) const {
423f2aceda8SAdhemerval Zanella   assert(Target.getSymA() && "SymA cannot be 0");
424f2aceda8SAdhemerval Zanella   const MCSymbol &Symbol = Target.getSymA()->getSymbol().AliasedSymbol();
425f2aceda8SAdhemerval Zanella 
426f2aceda8SAdhemerval Zanella   unsigned RelocType = getRelocTypeInner(Target, Fixup, IsPCRel);
427f2aceda8SAdhemerval Zanella 
428f2aceda8SAdhemerval Zanella   // The .odp creation emits a relocation against the symbol ".TOC." which
429f2aceda8SAdhemerval Zanella   // create a R_PPC64_TOC relocation. However the relocation symbol name
430f2aceda8SAdhemerval Zanella   // in final object creation should be NULL, since the symbol does not
431f2aceda8SAdhemerval Zanella   // really exist, it is just the reference to TOC base for the current
432f2aceda8SAdhemerval Zanella   // object file.
433f2aceda8SAdhemerval Zanella   bool EmitThisSym = RelocType != ELF::R_PPC64_TOC;
434f2aceda8SAdhemerval Zanella 
435f2aceda8SAdhemerval Zanella   if (EmitThisSym && !Symbol.isTemporary())
436f2aceda8SAdhemerval Zanella     return &Symbol;
437f2aceda8SAdhemerval Zanella   return NULL;
438f2aceda8SAdhemerval Zanella }
439f2aceda8SAdhemerval Zanella 
44038a400dfSRafael Espindola MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,
44138a400dfSRafael Espindola                                                bool Is64Bit,
442*cae3a17aSUlrich Weigand                                                bool IsLittleEndian,
44338a400dfSRafael Espindola                                                uint8_t OSABI) {
44438a400dfSRafael Espindola   MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI);
445*cae3a17aSUlrich Weigand   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
44638a400dfSRafael Espindola }
447