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"
12a4f89844SBill Schmidt #include "llvm/ADT/STLExtras.h"
1338a400dfSRafael Espindola #include "llvm/MC/MCELFObjectWriter.h"
14f2aceda8SAdhemerval Zanella #include "llvm/MC/MCExpr.h"
15f2aceda8SAdhemerval Zanella #include "llvm/MC/MCValue.h"
16ed0881b2SChandler Carruth #include "llvm/Support/ErrorHandling.h"
1738a400dfSRafael Espindola 
1838a400dfSRafael Espindola using namespace llvm;
1938a400dfSRafael Espindola 
2038a400dfSRafael Espindola namespace {
2138a400dfSRafael Espindola   class PPCELFObjectWriter : public MCELFObjectTargetWriter {
2238a400dfSRafael Espindola   public:
2338a400dfSRafael Espindola     PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
2438a400dfSRafael Espindola 
2538a400dfSRafael Espindola     virtual ~PPCELFObjectWriter();
2638a400dfSRafael Espindola   protected:
27f2aceda8SAdhemerval Zanella     virtual unsigned getRelocTypeInner(const MCValue &Target,
28f2aceda8SAdhemerval Zanella                                        const MCFixup &Fixup,
29f2aceda8SAdhemerval Zanella                                        bool IsPCRel) const;
3038a400dfSRafael Espindola     virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
3138a400dfSRafael Espindola                                   bool IsPCRel, bool IsRelocWithSymbol,
3238a400dfSRafael Espindola                                   int64_t Addend) const;
33*3a75861bSUlrich Weigand     virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
34*3a75861bSUlrich Weigand                                            const MCValue &Target,
35*3a75861bSUlrich Weigand                                            const MCFragment &F,
36*3a75861bSUlrich Weigand                                            const MCFixup &Fixup,
37*3a75861bSUlrich 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 
52f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
5338a400dfSRafael Espindola                                                const MCFixup &Fixup,
54f2aceda8SAdhemerval Zanella                                                bool IsPCRel) const
55f2aceda8SAdhemerval Zanella {
56f2aceda8SAdhemerval Zanella   MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
57f2aceda8SAdhemerval Zanella     MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
58f2aceda8SAdhemerval Zanella 
5938a400dfSRafael Espindola   // determine the type of the relocation
6038a400dfSRafael Espindola   unsigned Type;
6138a400dfSRafael Espindola   if (IsPCRel) {
6238a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
6338a400dfSRafael Espindola     default:
6438a400dfSRafael Espindola       llvm_unreachable("Unimplemented");
6538a400dfSRafael Espindola     case PPC::fixup_ppc_br24:
66b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
6738a400dfSRafael Espindola       Type = ELF::R_PPC_REL24;
6838a400dfSRafael Espindola       break;
6972a7dc0dSUlrich Weigand     case PPC::fixup_ppc_brcond14:
70b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
7172a7dc0dSUlrich Weigand       Type = ELF::R_PPC_REL14;
7272a7dc0dSUlrich Weigand       break;
7391add7dfSUlrich Weigand     case PPC::fixup_ppc_half16:
7491add7dfSUlrich Weigand       switch (Modifier) {
7591add7dfSUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
7691add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_None:
7791add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16;
7891add7dfSUlrich Weigand         break;
7991add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
8091add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_LO;
8191add7dfSUlrich Weigand         break;
8291add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
8391add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HI;
8491add7dfSUlrich Weigand         break;
8591add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
8691add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HA;
8791add7dfSUlrich Weigand         break;
8891add7dfSUlrich Weigand       }
8991add7dfSUlrich Weigand       break;
909b0b7813SAdhemerval Zanella     case FK_Data_4:
9138a400dfSRafael Espindola     case FK_PCRel_4:
9238a400dfSRafael Espindola       Type = ELF::R_PPC_REL32;
9338a400dfSRafael Espindola       break;
949b0b7813SAdhemerval Zanella     case FK_Data_8:
959b0b7813SAdhemerval Zanella     case FK_PCRel_8:
969b0b7813SAdhemerval Zanella       Type = ELF::R_PPC64_REL64;
979b0b7813SAdhemerval Zanella       break;
9838a400dfSRafael Espindola     }
9938a400dfSRafael Espindola   } else {
10038a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
10138a400dfSRafael Espindola       default: llvm_unreachable("invalid fixup kind!");
102b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
10338a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR24;
10438a400dfSRafael Espindola       break;
105b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
106f2aceda8SAdhemerval Zanella       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
10738a400dfSRafael Espindola       break;
1086e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16:
10985578500SUlrich Weigand       switch (Modifier) {
11085578500SUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
11185578500SUlrich Weigand       case MCSymbolRefExpr::VK_None:
112e462053fSUlrich Weigand         Type = ELF::R_PPC_ADDR16;
113e462053fSUlrich Weigand         break;
114d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
11538a400dfSRafael Espindola         Type = ELF::R_PPC_ADDR16_LO;
11638a400dfSRafael Espindola         break;
117e67c565dSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
118e67c565dSUlrich Weigand         Type = ELF::R_PPC_ADDR16_HI;
119e67c565dSUlrich Weigand         break;
120d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
1219e90b3c8SUlrich Weigand         Type = ELF::R_PPC_ADDR16_HA;
1229e90b3c8SUlrich Weigand         break;
123e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHER:
124e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHER;
125e9126f55SUlrich Weigand         break;
126e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHERA:
127e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHERA;
128e9126f55SUlrich Weigand         break;
129e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHEST:
130e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHEST;
131e9126f55SUlrich Weigand         break;
132e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
133e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
134e9126f55SUlrich Weigand         break;
13593372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
13693372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16;
13793372b45SUlrich Weigand         break;
13893372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
13993372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_LO;
14093372b45SUlrich Weigand         break;
14193372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HI:
14293372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HI;
14393372b45SUlrich Weigand         break;
14493372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HA:
14593372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HA;
14693372b45SUlrich Weigand         break;
147d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
1483e186015SUlrich Weigand         Type = ELF::R_PPC64_TOC16;
1493e186015SUlrich Weigand         break;
150d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
15134627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO;
15234627e34SBill Schmidt         break;
15372ddbd65SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HI:
15472ddbd65SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HI;
15572ddbd65SUlrich Weigand         break;
156d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HA:
1579e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HA;
1589e90b3c8SUlrich Weigand         break;
159876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
160876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16;
161876a0d01SUlrich Weigand         break;
162d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
1639e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_LO;
1649e90b3c8SUlrich Weigand         break;
165876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
166876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HI;
167876a0d01SUlrich Weigand         break;
168d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
1699e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HA;
1709e90b3c8SUlrich Weigand         break;
171876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
172876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHER;
173876a0d01SUlrich Weigand         break;
174876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
175876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHERA;
176876a0d01SUlrich Weigand         break;
177876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
178876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHEST;
179876a0d01SUlrich Weigand         break;
180876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
181876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
182876a0d01SUlrich Weigand         break;
183876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
184876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16;
185876a0d01SUlrich Weigand         break;
186d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
1879e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO;
1889e90b3c8SUlrich Weigand         break;
189876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
190876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HI;
191876a0d01SUlrich Weigand         break;
192d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
1939e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HA;
1949e90b3c8SUlrich Weigand         break;
195876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
196876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHER;
197876a0d01SUlrich Weigand         break;
198876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
199876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
200876a0d01SUlrich Weigand         break;
201876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
202876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
203876a0d01SUlrich Weigand         break;
204876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
205876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
206876a0d01SUlrich Weigand         break;
207876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
208876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16;
209876a0d01SUlrich Weigand         break;
210d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
211c56f1d34SBill Schmidt         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
212c56f1d34SBill Schmidt         break;
213876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
214876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
215876a0d01SUlrich Weigand         break;
216d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
2179e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
2189e90b3c8SUlrich Weigand         break;
219876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
220876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16;
221876a0d01SUlrich Weigand         break;
222d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
22324b8dd6eSBill Schmidt         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
22424b8dd6eSBill Schmidt         break;
225876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
226876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
227876a0d01SUlrich Weigand         break;
228d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
2299e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
2309e90b3c8SUlrich Weigand         break;
231876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
232876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HI;
233876a0d01SUlrich Weigand         break;
234d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
2359e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HA;
2369e90b3c8SUlrich Weigand         break;
237876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
238876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
239876a0d01SUlrich Weigand         break;
240876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
241876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
242876a0d01SUlrich Weigand         break;
24385578500SUlrich Weigand       }
24485578500SUlrich Weigand       break;
2456e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16ds:
2463822ef2cSBill Schmidt       switch (Modifier) {
2473822ef2cSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
2483822ef2cSBill Schmidt       case MCSymbolRefExpr::VK_None:
2493e186015SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_DS;
250f2aceda8SAdhemerval Zanella         break;
251d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
252e462053fSUlrich Weigand         Type = ELF::R_PPC64_ADDR16_LO_DS;
253e462053fSUlrich Weigand         break;
25493372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
25593372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_DS;
25693372b45SUlrich Weigand 	break;
25793372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
25893372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_LO_DS;
25993372b45SUlrich Weigand         break;
260d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
261f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC16_DS;
262f2aceda8SAdhemerval Zanella 	break;
263d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
26434627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO_DS;
26534627e34SBill Schmidt         break;
266876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL:
267876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_DS;
268876a0d01SUlrich Weigand         break;
269876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
270876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_LO_DS;
271876a0d01SUlrich Weigand         break;
272876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL:
273876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_DS;
274876a0d01SUlrich Weigand         break;
275876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
276876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO_DS;
277876a0d01SUlrich Weigand         break;
278876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
279876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
280876a0d01SUlrich Weigand         break;
281d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
2829f0b4ec0SBill Schmidt         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
283ca4a0c9dSBill Schmidt         break;
284876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
285876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
286876a0d01SUlrich Weigand         break;
287876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
288876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
289876a0d01SUlrich Weigand         break;
29034627e34SBill Schmidt       }
29134627e34SBill Schmidt       break;
292ca4a0c9dSBill Schmidt     case PPC::fixup_ppc_tlsreg:
293ca4a0c9dSBill Schmidt       Type = ELF::R_PPC64_TLS;
294ca4a0c9dSBill Schmidt       break;
29524b8dd6eSBill Schmidt     case PPC::fixup_ppc_nofixup:
29624b8dd6eSBill Schmidt       switch (Modifier) {
29724b8dd6eSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
29824b8dd6eSBill Schmidt       case MCSymbolRefExpr::VK_PPC_TLSGD:
299c56f1d34SBill Schmidt         Type = ELF::R_PPC64_TLSGD;
300c56f1d34SBill Schmidt         break;
30124b8dd6eSBill Schmidt       case MCSymbolRefExpr::VK_PPC_TLSLD:
30224b8dd6eSBill Schmidt         Type = ELF::R_PPC64_TLSLD;
30324b8dd6eSBill Schmidt         break;
30424b8dd6eSBill Schmidt       }
30524b8dd6eSBill Schmidt       break;
306f2aceda8SAdhemerval Zanella     case FK_Data_8:
307f2aceda8SAdhemerval Zanella       switch (Modifier) {
308f2aceda8SAdhemerval Zanella       default: llvm_unreachable("Unsupported Modifier");
30968e2e1b3SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOCBASE:
310f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC;
311f2aceda8SAdhemerval Zanella         break;
312f2aceda8SAdhemerval Zanella       case MCSymbolRefExpr::VK_None:
313f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_ADDR64;
314f2aceda8SAdhemerval Zanella 	break;
315f2aceda8SAdhemerval Zanella       }
316f2aceda8SAdhemerval Zanella       break;
31738a400dfSRafael Espindola     case FK_Data_4:
31838a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR32;
31938a400dfSRafael Espindola       break;
32038a400dfSRafael Espindola     case FK_Data_2:
32138a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR16;
32238a400dfSRafael Espindola       break;
32338a400dfSRafael Espindola     }
32438a400dfSRafael Espindola   }
32538a400dfSRafael Espindola   return Type;
32638a400dfSRafael Espindola }
32738a400dfSRafael Espindola 
328f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
329f2aceda8SAdhemerval Zanella                                           const MCFixup &Fixup,
330f2aceda8SAdhemerval Zanella                                           bool IsPCRel,
331f2aceda8SAdhemerval Zanella                                           bool IsRelocWithSymbol,
332f2aceda8SAdhemerval Zanella                                           int64_t Addend) const {
333f2aceda8SAdhemerval Zanella   return getRelocTypeInner(Target, Fixup, IsPCRel);
334f2aceda8SAdhemerval Zanella }
335f2aceda8SAdhemerval Zanella 
336*3a75861bSUlrich Weigand const MCSymbol *PPCELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
337*3a75861bSUlrich Weigand                                                    const MCValue &Target,
338*3a75861bSUlrich Weigand                                                    const MCFragment &F,
339*3a75861bSUlrich Weigand                                                    const MCFixup &Fixup,
340*3a75861bSUlrich Weigand                                                    bool IsPCRel) const {
341*3a75861bSUlrich Weigand   assert(Target.getSymA() && "SymA cannot be 0");
342*3a75861bSUlrich Weigand   MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
343*3a75861bSUlrich Weigand     MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
344*3a75861bSUlrich Weigand 
345*3a75861bSUlrich Weigand   bool EmitThisSym;
346*3a75861bSUlrich Weigand   switch (Modifier) {
347*3a75861bSUlrich Weigand   // GOT references always need a relocation, even if the
348*3a75861bSUlrich Weigand   // target symbol is local.
349*3a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_GOT:
350*3a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_PPC_GOT_LO:
351*3a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_PPC_GOT_HI:
352*3a75861bSUlrich Weigand   case MCSymbolRefExpr::VK_PPC_GOT_HA:
353*3a75861bSUlrich Weigand     EmitThisSym = true;
354*3a75861bSUlrich Weigand     break;
355*3a75861bSUlrich Weigand   default:
356*3a75861bSUlrich Weigand     EmitThisSym = false;
357*3a75861bSUlrich Weigand     break;
358*3a75861bSUlrich Weigand   }
359*3a75861bSUlrich Weigand 
360*3a75861bSUlrich Weigand   if (EmitThisSym)
361*3a75861bSUlrich Weigand     return &Target.getSymA()->getSymbol().AliasedSymbol();
362*3a75861bSUlrich Weigand   return NULL;
363*3a75861bSUlrich Weigand }
364*3a75861bSUlrich Weigand 
365f2aceda8SAdhemerval Zanella const MCSymbol *PPCELFObjectWriter::undefinedExplicitRelSym(const MCValue &Target,
366f2aceda8SAdhemerval Zanella                                                             const MCFixup &Fixup,
367f2aceda8SAdhemerval Zanella                                                             bool IsPCRel) const {
368f2aceda8SAdhemerval Zanella   assert(Target.getSymA() && "SymA cannot be 0");
369f2aceda8SAdhemerval Zanella   const MCSymbol &Symbol = Target.getSymA()->getSymbol().AliasedSymbol();
370f2aceda8SAdhemerval Zanella 
371f2aceda8SAdhemerval Zanella   unsigned RelocType = getRelocTypeInner(Target, Fixup, IsPCRel);
372f2aceda8SAdhemerval Zanella 
373f2aceda8SAdhemerval Zanella   // The .odp creation emits a relocation against the symbol ".TOC." which
374f2aceda8SAdhemerval Zanella   // create a R_PPC64_TOC relocation. However the relocation symbol name
375f2aceda8SAdhemerval Zanella   // in final object creation should be NULL, since the symbol does not
376f2aceda8SAdhemerval Zanella   // really exist, it is just the reference to TOC base for the current
377f2aceda8SAdhemerval Zanella   // object file.
378f2aceda8SAdhemerval Zanella   bool EmitThisSym = RelocType != ELF::R_PPC64_TOC;
379f2aceda8SAdhemerval Zanella 
380f2aceda8SAdhemerval Zanella   if (EmitThisSym && !Symbol.isTemporary())
381f2aceda8SAdhemerval Zanella     return &Symbol;
382f2aceda8SAdhemerval Zanella   return NULL;
383f2aceda8SAdhemerval Zanella }
384f2aceda8SAdhemerval Zanella 
38538a400dfSRafael Espindola MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,
38638a400dfSRafael Espindola                                                bool Is64Bit,
38738a400dfSRafael Espindola                                                uint8_t OSABI) {
38838a400dfSRafael Espindola   MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI);
38925009623SRafael Espindola   return createELFObjectWriter(MOTW, OS,  /*IsLittleEndian=*/false);
39038a400dfSRafael Espindola }
391