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,
32*c03f44caSRafael Espindola                           bool IsPCRel) const override;
333a75861bSUlrich Weigand     virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
343a75861bSUlrich Weigand                                            const MCValue &Target,
353a75861bSUlrich Weigand                                            const MCFragment &F,
363a75861bSUlrich Weigand                                            const MCFixup &Fixup,
373a75861bSUlrich Weigand                                            bool IsPCRel) const;
38f2aceda8SAdhemerval Zanella     virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
39f2aceda8SAdhemerval Zanella                                                     const MCFixup &Fixup,
40f2aceda8SAdhemerval Zanella                                                     bool IsPCRel) const;
4138a400dfSRafael Espindola   };
4238a400dfSRafael Espindola }
4338a400dfSRafael Espindola 
4438a400dfSRafael Espindola PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
4538a400dfSRafael Espindola   : MCELFObjectTargetWriter(Is64Bit, OSABI,
4638a400dfSRafael Espindola                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
4725009623SRafael Espindola                             /*HasRelocationAddend*/ true) {}
4838a400dfSRafael Espindola 
4938a400dfSRafael Espindola PPCELFObjectWriter::~PPCELFObjectWriter() {
5038a400dfSRafael Espindola }
5138a400dfSRafael Espindola 
527fadc0eaSRafael Espindola static MCSymbolRefExpr::VariantKind getAccessVariant(const MCFixup &Fixup) {
537fadc0eaSRafael Espindola   const MCExpr *Expr = Fixup.getValue();
547fadc0eaSRafael Espindola 
557fadc0eaSRafael Espindola   if (Expr->getKind() != MCExpr::Target)
567fadc0eaSRafael Espindola     return Fixup.getAccessVariant();
577fadc0eaSRafael Espindola 
587fadc0eaSRafael Espindola   switch (cast<PPCMCExpr>(Expr)->getKind()) {
597fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_None:
607fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_None;
617fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_LO:
627fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_LO;
637fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HI:
647fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HI;
657fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HA:
667fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HA;
677fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHERA:
687fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHERA;
697fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHER:
707fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHER;
717fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHEST:
727fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHEST;
737fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHESTA:
747fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
757fadc0eaSRafael Espindola   }
7694bc422dSAlexey Samsonov   llvm_unreachable("unknown PPCMCExpr kind");
777fadc0eaSRafael Espindola }
787fadc0eaSRafael Espindola 
79f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
8038a400dfSRafael Espindola                                                const MCFixup &Fixup,
81f2aceda8SAdhemerval Zanella                                                bool IsPCRel) const
82f2aceda8SAdhemerval Zanella {
837fadc0eaSRafael Espindola   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Fixup);
84f2aceda8SAdhemerval Zanella 
8538a400dfSRafael Espindola   // determine the type of the relocation
8638a400dfSRafael Espindola   unsigned Type;
8738a400dfSRafael Espindola   if (IsPCRel) {
8838a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
8938a400dfSRafael Espindola     default:
9038a400dfSRafael Espindola       llvm_unreachable("Unimplemented");
9138a400dfSRafael Espindola     case PPC::fixup_ppc_br24:
92b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
9338a400dfSRafael Espindola       Type = ELF::R_PPC_REL24;
9438a400dfSRafael Espindola       break;
9572a7dc0dSUlrich Weigand     case PPC::fixup_ppc_brcond14:
96b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
9772a7dc0dSUlrich Weigand       Type = ELF::R_PPC_REL14;
9872a7dc0dSUlrich Weigand       break;
9991add7dfSUlrich Weigand     case PPC::fixup_ppc_half16:
10091add7dfSUlrich Weigand       switch (Modifier) {
10191add7dfSUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
10291add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_None:
10391add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16;
10491add7dfSUlrich Weigand         break;
10591add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
10691add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_LO;
10791add7dfSUlrich Weigand         break;
10891add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
10991add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HI;
11091add7dfSUlrich Weigand         break;
11191add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
11291add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HA;
11391add7dfSUlrich Weigand         break;
11491add7dfSUlrich Weigand       }
11591add7dfSUlrich Weigand       break;
1169b0b7813SAdhemerval Zanella     case FK_Data_4:
11738a400dfSRafael Espindola     case FK_PCRel_4:
11838a400dfSRafael Espindola       Type = ELF::R_PPC_REL32;
11938a400dfSRafael Espindola       break;
1209b0b7813SAdhemerval Zanella     case FK_Data_8:
1219b0b7813SAdhemerval Zanella     case FK_PCRel_8:
1229b0b7813SAdhemerval Zanella       Type = ELF::R_PPC64_REL64;
1239b0b7813SAdhemerval Zanella       break;
12438a400dfSRafael Espindola     }
12538a400dfSRafael Espindola   } else {
12638a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
12738a400dfSRafael Espindola       default: llvm_unreachable("invalid fixup kind!");
128b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
12938a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR24;
13038a400dfSRafael Espindola       break;
131b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
132f2aceda8SAdhemerval Zanella       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
13338a400dfSRafael Espindola       break;
1346e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16:
13585578500SUlrich Weigand       switch (Modifier) {
13685578500SUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
13785578500SUlrich Weigand       case MCSymbolRefExpr::VK_None:
138e462053fSUlrich Weigand         Type = ELF::R_PPC_ADDR16;
139e462053fSUlrich Weigand         break;
140d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
14138a400dfSRafael Espindola         Type = ELF::R_PPC_ADDR16_LO;
14238a400dfSRafael Espindola         break;
143e67c565dSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
144e67c565dSUlrich Weigand         Type = ELF::R_PPC_ADDR16_HI;
145e67c565dSUlrich Weigand         break;
146d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
1479e90b3c8SUlrich Weigand         Type = ELF::R_PPC_ADDR16_HA;
1489e90b3c8SUlrich Weigand         break;
149e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHER:
150e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHER;
151e9126f55SUlrich Weigand         break;
152e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHERA:
153e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHERA;
154e9126f55SUlrich Weigand         break;
155e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHEST:
156e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHEST;
157e9126f55SUlrich Weigand         break;
158e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
159e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
160e9126f55SUlrich Weigand         break;
16193372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
16293372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16;
16393372b45SUlrich Weigand         break;
16493372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
16593372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_LO;
16693372b45SUlrich Weigand         break;
16793372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HI:
16893372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HI;
16993372b45SUlrich Weigand         break;
17093372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HA:
17193372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HA;
17293372b45SUlrich Weigand         break;
173d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
1743e186015SUlrich Weigand         Type = ELF::R_PPC64_TOC16;
1753e186015SUlrich Weigand         break;
176d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
17734627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO;
17834627e34SBill Schmidt         break;
17972ddbd65SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HI:
18072ddbd65SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HI;
18172ddbd65SUlrich Weigand         break;
182d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HA:
1839e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HA;
1849e90b3c8SUlrich Weigand         break;
185876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
186876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16;
187876a0d01SUlrich Weigand         break;
188d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
1899e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_LO;
1909e90b3c8SUlrich Weigand         break;
191876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
192876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HI;
193876a0d01SUlrich Weigand         break;
194d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
1959e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HA;
1969e90b3c8SUlrich Weigand         break;
197876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
198876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHER;
199876a0d01SUlrich Weigand         break;
200876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
201876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHERA;
202876a0d01SUlrich Weigand         break;
203876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
204876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHEST;
205876a0d01SUlrich Weigand         break;
206876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
207876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
208876a0d01SUlrich Weigand         break;
209876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
210876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16;
211876a0d01SUlrich Weigand         break;
212d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
2139e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO;
2149e90b3c8SUlrich Weigand         break;
215876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
216876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HI;
217876a0d01SUlrich Weigand         break;
218d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
2199e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HA;
2209e90b3c8SUlrich Weigand         break;
221876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
222876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHER;
223876a0d01SUlrich Weigand         break;
224876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
225876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
226876a0d01SUlrich Weigand         break;
227876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
228876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
229876a0d01SUlrich Weigand         break;
230876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
231876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
232876a0d01SUlrich Weigand         break;
233876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
234876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16;
235876a0d01SUlrich Weigand         break;
236d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
237c56f1d34SBill Schmidt         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
238c56f1d34SBill Schmidt         break;
239876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
240876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
241876a0d01SUlrich Weigand         break;
242d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
2439e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
2449e90b3c8SUlrich Weigand         break;
245876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
246876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16;
247876a0d01SUlrich Weigand         break;
248d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
24924b8dd6eSBill Schmidt         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
25024b8dd6eSBill Schmidt         break;
251876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
252876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
253876a0d01SUlrich Weigand         break;
254d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
2559e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
2569e90b3c8SUlrich Weigand         break;
257b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
258b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
259b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
260b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
261b2044311SUlrich Weigand         break;
262b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
263b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
264b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
265b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
266b2044311SUlrich Weigand         break;
267876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
268876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HI;
269876a0d01SUlrich Weigand         break;
270b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
271b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
272b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
273b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
274b2044311SUlrich Weigand         break;
275b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
276b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
277b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
278b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
279b2044311SUlrich Weigand         break;
280d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
2819e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HA;
2829e90b3c8SUlrich Weigand         break;
283876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
284876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
285876a0d01SUlrich Weigand         break;
286876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
287876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
288876a0d01SUlrich Weigand         break;
28985578500SUlrich Weigand       }
29085578500SUlrich Weigand       break;
2916e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16ds:
2923822ef2cSBill Schmidt       switch (Modifier) {
2933822ef2cSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
2943822ef2cSBill Schmidt       case MCSymbolRefExpr::VK_None:
2953e186015SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_DS;
296f2aceda8SAdhemerval Zanella         break;
297d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
298e462053fSUlrich Weigand         Type = ELF::R_PPC64_ADDR16_LO_DS;
299e462053fSUlrich Weigand         break;
30093372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
30193372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_DS;
30293372b45SUlrich Weigand 	break;
30393372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
30493372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_LO_DS;
30593372b45SUlrich Weigand         break;
306d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
307f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC16_DS;
308f2aceda8SAdhemerval Zanella 	break;
309d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
31034627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO_DS;
31134627e34SBill Schmidt         break;
312876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
313876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_DS;
314876a0d01SUlrich Weigand         break;
315876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
316876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_LO_DS;
317876a0d01SUlrich Weigand         break;
318876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
319876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_DS;
320876a0d01SUlrich Weigand         break;
321876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
322876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO_DS;
323876a0d01SUlrich Weigand         break;
324876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
325876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
326876a0d01SUlrich Weigand         break;
327d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
3289f0b4ec0SBill Schmidt         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
329ca4a0c9dSBill Schmidt         break;
330876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
331876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
332876a0d01SUlrich Weigand         break;
333876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
334876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
335876a0d01SUlrich Weigand         break;
33634627e34SBill Schmidt       }
33734627e34SBill Schmidt       break;
33824b8dd6eSBill Schmidt     case PPC::fixup_ppc_nofixup:
33924b8dd6eSBill Schmidt       switch (Modifier) {
34024b8dd6eSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
34152cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSGD:
342c56f1d34SBill Schmidt         Type = ELF::R_PPC64_TLSGD;
343c56f1d34SBill Schmidt         break;
34452cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSLD:
34524b8dd6eSBill Schmidt         Type = ELF::R_PPC64_TLSLD;
34624b8dd6eSBill Schmidt         break;
3475b427591SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLS:
3485b427591SUlrich Weigand         Type = ELF::R_PPC64_TLS;
3495b427591SUlrich Weigand         break;
35024b8dd6eSBill Schmidt       }
35124b8dd6eSBill Schmidt       break;
352f2aceda8SAdhemerval Zanella     case FK_Data_8:
353f2aceda8SAdhemerval Zanella       switch (Modifier) {
354f2aceda8SAdhemerval Zanella       default: llvm_unreachable("Unsupported Modifier");
35568e2e1b3SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOCBASE:
356f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC;
357f2aceda8SAdhemerval Zanella         break;
358f2aceda8SAdhemerval Zanella       case MCSymbolRefExpr::VK_None:
359f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_ADDR64;
360f2aceda8SAdhemerval Zanella 	break;
361f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPMOD:
362f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPMOD64;
363f11efe7fSUlrich Weigand 	break;
364f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
365f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_TPREL64;
366f11efe7fSUlrich Weigand 	break;
367f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
368f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPREL64;
369f11efe7fSUlrich Weigand 	break;
370f2aceda8SAdhemerval Zanella       }
371f2aceda8SAdhemerval Zanella       break;
37238a400dfSRafael Espindola     case FK_Data_4:
37338a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR32;
37438a400dfSRafael Espindola       break;
37538a400dfSRafael Espindola     case FK_Data_2:
37638a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR16;
37738a400dfSRafael Espindola       break;
37838a400dfSRafael Espindola     }
37938a400dfSRafael Espindola   }
38038a400dfSRafael Espindola   return Type;
38138a400dfSRafael Espindola }
38238a400dfSRafael Espindola 
383f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
384f2aceda8SAdhemerval Zanella                                           const MCFixup &Fixup,
385*c03f44caSRafael Espindola                                           bool IsPCRel) const {
386f2aceda8SAdhemerval Zanella   return getRelocTypeInner(Target, Fixup, IsPCRel);
387f2aceda8SAdhemerval Zanella }
388f2aceda8SAdhemerval Zanella 
3893a75861bSUlrich Weigand const MCSymbol *PPCELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
3903a75861bSUlrich Weigand                                                    const MCValue &Target,
3913a75861bSUlrich Weigand                                                    const MCFragment &F,
3923a75861bSUlrich Weigand                                                    const MCFixup &Fixup,
3933a75861bSUlrich Weigand                                                    bool IsPCRel) const {
3943a75861bSUlrich Weigand   assert(Target.getSymA() && "SymA cannot be 0");
3957fadc0eaSRafael Espindola   MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
3963a75861bSUlrich Weigand 
3973a75861bSUlrich Weigand   bool EmitThisSym;
3983a75861bSUlrich Weigand   switch (Modifier) {
3993a75861bSUlrich Weigand   // GOT references always need a relocation, even if the
4003a75861bSUlrich Weigand   // target symbol is local.
4013a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_GOT:
4023a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_PPC_GOT_LO:
4033a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_PPC_GOT_HI:
4043a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_PPC_GOT_HA:
4053a75861bSUlrich Weigand     EmitThisSym = true;
4063a75861bSUlrich Weigand     break;
4073a75861bSUlrich Weigand   default:
4083a75861bSUlrich Weigand     EmitThisSym = false;
4093a75861bSUlrich Weigand     break;
4103a75861bSUlrich Weigand   }
4113a75861bSUlrich Weigand 
4123a75861bSUlrich Weigand   if (EmitThisSym)
4133a75861bSUlrich Weigand     return &Target.getSymA()->getSymbol().AliasedSymbol();
4143a75861bSUlrich Weigand   return NULL;
4153a75861bSUlrich Weigand }
4163a75861bSUlrich Weigand 
417f2aceda8SAdhemerval Zanella const MCSymbol *PPCELFObjectWriter::undefinedExplicitRelSym(const MCValue &Target,
418f2aceda8SAdhemerval Zanella                                                             const MCFixup &Fixup,
419f2aceda8SAdhemerval Zanella                                                             bool IsPCRel) const {
420f2aceda8SAdhemerval Zanella   assert(Target.getSymA() && "SymA cannot be 0");
421f2aceda8SAdhemerval Zanella   const MCSymbol &Symbol = Target.getSymA()->getSymbol().AliasedSymbol();
422f2aceda8SAdhemerval Zanella 
423f2aceda8SAdhemerval Zanella   unsigned RelocType = getRelocTypeInner(Target, Fixup, IsPCRel);
424f2aceda8SAdhemerval Zanella 
425f2aceda8SAdhemerval Zanella   // The .odp creation emits a relocation against the symbol ".TOC." which
426f2aceda8SAdhemerval Zanella   // create a R_PPC64_TOC relocation. However the relocation symbol name
427f2aceda8SAdhemerval Zanella   // in final object creation should be NULL, since the symbol does not
428f2aceda8SAdhemerval Zanella   // really exist, it is just the reference to TOC base for the current
429f2aceda8SAdhemerval Zanella   // object file.
430f2aceda8SAdhemerval Zanella   bool EmitThisSym = RelocType != ELF::R_PPC64_TOC;
431f2aceda8SAdhemerval Zanella 
432f2aceda8SAdhemerval Zanella   if (EmitThisSym && !Symbol.isTemporary())
433f2aceda8SAdhemerval Zanella     return &Symbol;
434f2aceda8SAdhemerval Zanella   return NULL;
435f2aceda8SAdhemerval Zanella }
436f2aceda8SAdhemerval Zanella 
43738a400dfSRafael Espindola MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,
43838a400dfSRafael Espindola                                                bool Is64Bit,
439cae3a17aSUlrich Weigand                                                bool IsLittleEndian,
44038a400dfSRafael Espindola                                                uint8_t OSABI) {
44138a400dfSRafael Espindola   MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI);
442cae3a17aSUlrich Weigand   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
44338a400dfSRafael Espindola }
444