138a400dfSRafael Espindola //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
238a400dfSRafael Espindola //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
638a400dfSRafael Espindola //
738a400dfSRafael Espindola //===----------------------------------------------------------------------===//
838a400dfSRafael Espindola 
9ed0881b2SChandler Carruth #include "MCTargetDesc/PPCFixupKinds.h"
107fadc0eaSRafael Espindola #include "MCTargetDesc/PPCMCExpr.h"
116bda14b3SChandler Carruth #include "MCTargetDesc/PPCMCTargetDesc.h"
12a4f89844SBill Schmidt #include "llvm/ADT/STLExtras.h"
1338a400dfSRafael Espindola #include "llvm/MC/MCELFObjectWriter.h"
14f2aceda8SAdhemerval Zanella #include "llvm/MC/MCExpr.h"
1560fbc7ccSLang Hames #include "llvm/MC/MCObjectWriter.h"
1695fb9b93SRafael Espindola #include "llvm/MC/MCSymbolELF.h"
17f2aceda8SAdhemerval Zanella #include "llvm/MC/MCValue.h"
18ed0881b2SChandler Carruth #include "llvm/Support/ErrorHandling.h"
1938a400dfSRafael Espindola 
2038a400dfSRafael Espindola using namespace llvm;
2138a400dfSRafael Espindola 
2238a400dfSRafael Espindola namespace {
2338a400dfSRafael Espindola   class PPCELFObjectWriter : public MCELFObjectTargetWriter {
2438a400dfSRafael Espindola   public:
2538a400dfSRafael Espindola     PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
2638a400dfSRafael Espindola 
2738a400dfSRafael Espindola   protected:
288340f94dSRafael Espindola     unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
298340f94dSRafael Espindola                           const MCFixup &Fixup, bool IsPCRel) const override;
30bb68610dSUlrich Weigand 
31ece40ca4SRafael Espindola     bool needsRelocateWithSymbol(const MCSymbol &Sym,
3246797c69SUlrich Weigand                                  unsigned Type) const override;
3338a400dfSRafael Espindola   };
34f00654e3SAlexander Kornienko }
3538a400dfSRafael Espindola 
3638a400dfSRafael Espindola PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
3738a400dfSRafael Espindola   : MCELFObjectTargetWriter(Is64Bit, OSABI,
3838a400dfSRafael Espindola                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
3925009623SRafael Espindola                             /*HasRelocationAddend*/ true) {}
4038a400dfSRafael Espindola 
413d082fa5SRafael Espindola static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
423d082fa5SRafael Espindola                                                      const MCFixup &Fixup) {
437fadc0eaSRafael Espindola   const MCExpr *Expr = Fixup.getValue();
447fadc0eaSRafael Espindola 
457fadc0eaSRafael Espindola   if (Expr->getKind() != MCExpr::Target)
463d082fa5SRafael Espindola     return Target.getAccessVariant();
477fadc0eaSRafael Espindola 
487fadc0eaSRafael Espindola   switch (cast<PPCMCExpr>(Expr)->getKind()) {
497fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_None:
507fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_None;
517fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_LO:
527fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_LO;
537fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HI:
547fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HI;
557fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HA:
567fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HA;
5780b8f82fSSean Fertile   case PPCMCExpr::VK_PPC_HIGH:
5880b8f82fSSean Fertile     return MCSymbolRefExpr::VK_PPC_HIGH;
5980b8f82fSSean Fertile   case PPCMCExpr::VK_PPC_HIGHA:
6080b8f82fSSean Fertile     return MCSymbolRefExpr::VK_PPC_HIGHA;
617fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHERA:
627fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHERA;
637fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHER:
647fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHER;
657fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHEST:
667fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHEST;
677fadc0eaSRafael Espindola   case PPCMCExpr::VK_PPC_HIGHESTA:
687fadc0eaSRafael Espindola     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
697fadc0eaSRafael Espindola   }
7094bc422dSAlexey Samsonov   llvm_unreachable("unknown PPCMCExpr kind");
717fadc0eaSRafael Espindola }
727fadc0eaSRafael Espindola 
738340f94dSRafael Espindola unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
7438a400dfSRafael Espindola                                           const MCFixup &Fixup,
758c90fd71SBenjamin Kramer                                           bool IsPCRel) const {
763d082fa5SRafael Espindola   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
77f2aceda8SAdhemerval Zanella 
7838a400dfSRafael Espindola   // determine the type of the relocation
7938a400dfSRafael Espindola   unsigned Type;
8038a400dfSRafael Espindola   if (IsPCRel) {
8138a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
8238a400dfSRafael Espindola     default:
8338a400dfSRafael Espindola       llvm_unreachable("Unimplemented");
8438a400dfSRafael Espindola     case PPC::fixup_ppc_br24:
85b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
863ee2af7dSHal Finkel       switch (Modifier) {
873ee2af7dSHal Finkel       default: llvm_unreachable("Unsupported Modifier");
883ee2af7dSHal Finkel       case MCSymbolRefExpr::VK_None:
8938a400dfSRafael Espindola         Type = ELF::R_PPC_REL24;
9038a400dfSRafael Espindola         break;
913ee2af7dSHal Finkel       case MCSymbolRefExpr::VK_PLT:
923ee2af7dSHal Finkel         Type = ELF::R_PPC_PLTREL24;
933ee2af7dSHal Finkel         break;
94a88b6057SJustin Hibbits       case MCSymbolRefExpr::VK_PPC_LOCAL:
95a88b6057SJustin Hibbits         Type = ELF::R_PPC_LOCAL24PC;
96a88b6057SJustin Hibbits         break;
973ee2af7dSHal Finkel       }
983ee2af7dSHal Finkel       break;
9972a7dc0dSUlrich Weigand     case PPC::fixup_ppc_brcond14:
100b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
10172a7dc0dSUlrich Weigand       Type = ELF::R_PPC_REL14;
10272a7dc0dSUlrich Weigand       break;
10391add7dfSUlrich Weigand     case PPC::fixup_ppc_half16:
10491add7dfSUlrich Weigand       switch (Modifier) {
10591add7dfSUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
10691add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_None:
10791add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16;
10891add7dfSUlrich Weigand         break;
10991add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
11091add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_LO;
11191add7dfSUlrich Weigand         break;
11291add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
11391add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HI;
11491add7dfSUlrich Weigand         break;
11591add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
11691add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HA;
11791add7dfSUlrich Weigand         break;
11891add7dfSUlrich Weigand       }
11991add7dfSUlrich Weigand       break;
120850ba46dSRafael Espindola     case PPC::fixup_ppc_half16ds:
121850ba46dSRafael Espindola       Target.print(errs());
122850ba46dSRafael Espindola       errs() << '\n';
123de1dc9c9SBill Schmidt       report_fatal_error("Invalid PC-relative half16ds relocation");
1249b0b7813SAdhemerval Zanella     case FK_Data_4:
12538a400dfSRafael Espindola     case FK_PCRel_4:
12638a400dfSRafael Espindola       Type = ELF::R_PPC_REL32;
12738a400dfSRafael Espindola       break;
1289b0b7813SAdhemerval Zanella     case FK_Data_8:
1299b0b7813SAdhemerval Zanella     case FK_PCRel_8:
1309b0b7813SAdhemerval Zanella       Type = ELF::R_PPC64_REL64;
1319b0b7813SAdhemerval Zanella       break;
13238a400dfSRafael Espindola     }
13338a400dfSRafael Espindola   } else {
13438a400dfSRafael Espindola     switch ((unsigned)Fixup.getKind()) {
13538a400dfSRafael Espindola       default: llvm_unreachable("invalid fixup kind!");
136*ad7199f3SFangrui Song     case FK_NONE:
137*ad7199f3SFangrui Song       Type = ELF::R_PPC_NONE;
138*ad7199f3SFangrui Song       break;
139b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
14038a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR24;
14138a400dfSRafael Espindola       break;
142b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
143f2aceda8SAdhemerval Zanella       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
14438a400dfSRafael Espindola       break;
1456e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16:
14685578500SUlrich Weigand       switch (Modifier) {
14785578500SUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
14885578500SUlrich Weigand       case MCSymbolRefExpr::VK_None:
149e462053fSUlrich Weigand         Type = ELF::R_PPC_ADDR16;
150e462053fSUlrich Weigand         break;
151d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
15238a400dfSRafael Espindola         Type = ELF::R_PPC_ADDR16_LO;
15338a400dfSRafael Espindola         break;
154e67c565dSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
155e67c565dSUlrich Weigand         Type = ELF::R_PPC_ADDR16_HI;
156e67c565dSUlrich Weigand         break;
157d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
1589e90b3c8SUlrich Weigand         Type = ELF::R_PPC_ADDR16_HA;
1599e90b3c8SUlrich Weigand         break;
16080b8f82fSSean Fertile       case MCSymbolRefExpr::VK_PPC_HIGH:
16180b8f82fSSean Fertile         Type = ELF::R_PPC64_ADDR16_HIGH;
16280b8f82fSSean Fertile         break;
16380b8f82fSSean Fertile       case MCSymbolRefExpr::VK_PPC_HIGHA:
16480b8f82fSSean Fertile         Type = ELF::R_PPC64_ADDR16_HIGHA;
16580b8f82fSSean Fertile         break;
166e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHER:
167e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHER;
168e9126f55SUlrich Weigand         break;
169e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHERA:
170e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHERA;
171e9126f55SUlrich Weigand         break;
172e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHEST:
173e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHEST;
174e9126f55SUlrich Weigand         break;
175e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
176e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
177e9126f55SUlrich Weigand         break;
17893372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
17993372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16;
18093372b45SUlrich Weigand         break;
18193372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
18293372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_LO;
18393372b45SUlrich Weigand         break;
18493372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HI:
18593372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HI;
18693372b45SUlrich Weigand         break;
18793372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HA:
18893372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HA;
18993372b45SUlrich Weigand         break;
190d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
1913e186015SUlrich Weigand         Type = ELF::R_PPC64_TOC16;
1923e186015SUlrich Weigand         break;
193d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
19434627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO;
19534627e34SBill Schmidt         break;
19672ddbd65SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HI:
19772ddbd65SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HI;
19872ddbd65SUlrich Weigand         break;
199d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HA:
2009e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HA;
2019e90b3c8SUlrich Weigand         break;
2020e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_TPREL:
203876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16;
204876a0d01SUlrich Weigand         break;
205d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
2069e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_LO;
2079e90b3c8SUlrich Weigand         break;
208876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
209876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HI;
210876a0d01SUlrich Weigand         break;
211d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
2129e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HA;
2139e90b3c8SUlrich Weigand         break;
214cac28aebSSean Fertile       case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
215cac28aebSSean Fertile         Type = ELF::R_PPC64_TPREL16_HIGH;
216cac28aebSSean Fertile         break;
217cac28aebSSean Fertile       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
218cac28aebSSean Fertile         Type = ELF::R_PPC64_TPREL16_HIGHA;
219cac28aebSSean Fertile         break;
220876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
221876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHER;
222876a0d01SUlrich Weigand         break;
223876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
224876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHERA;
225876a0d01SUlrich Weigand         break;
226876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
227876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHEST;
228876a0d01SUlrich Weigand         break;
229876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
230876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
231876a0d01SUlrich Weigand         break;
2320e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_DTPREL:
233876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16;
234876a0d01SUlrich Weigand         break;
235d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
2369e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO;
2379e90b3c8SUlrich Weigand         break;
238876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
239876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HI;
240876a0d01SUlrich Weigand         break;
241d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
2429e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HA;
2439e90b3c8SUlrich Weigand         break;
244cac28aebSSean Fertile       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
245cac28aebSSean Fertile         Type = ELF::R_PPC64_DTPREL16_HIGH;
246cac28aebSSean Fertile         break;
247cac28aebSSean Fertile       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
248cac28aebSSean Fertile         Type = ELF::R_PPC64_DTPREL16_HIGHA;
249cac28aebSSean Fertile         break;
250876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
251876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHER;
252876a0d01SUlrich Weigand         break;
253876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
254876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
255876a0d01SUlrich Weigand         break;
256876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
257876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
258876a0d01SUlrich Weigand         break;
259876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
260876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
261876a0d01SUlrich Weigand         break;
262876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
2637c8ae535SHal Finkel         if (is64Bit())
264876a0d01SUlrich Weigand           Type = ELF::R_PPC64_GOT_TLSGD16;
2657c8ae535SHal Finkel         else
2667c8ae535SHal Finkel           Type = ELF::R_PPC_GOT_TLSGD16;
267876a0d01SUlrich Weigand         break;
268d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
269c56f1d34SBill Schmidt         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
270c56f1d34SBill Schmidt         break;
271876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
272876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
273876a0d01SUlrich Weigand         break;
274d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
2759e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
2769e90b3c8SUlrich Weigand         break;
277876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
2787c8ae535SHal Finkel         if (is64Bit())
279876a0d01SUlrich Weigand           Type = ELF::R_PPC64_GOT_TLSLD16;
2807c8ae535SHal Finkel         else
2817c8ae535SHal Finkel           Type = ELF::R_PPC_GOT_TLSLD16;
282876a0d01SUlrich Weigand         break;
283d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
28424b8dd6eSBill Schmidt         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
28524b8dd6eSBill Schmidt         break;
286876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
287876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
288876a0d01SUlrich Weigand         break;
289d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
2909e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
2919e90b3c8SUlrich Weigand         break;
292b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
293b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
294b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
295b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
296b2044311SUlrich Weigand         break;
297b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
298b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
299b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
300b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
301b2044311SUlrich Weigand         break;
302876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
303876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HI;
304876a0d01SUlrich Weigand         break;
305b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
306b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
307b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
308b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
309b2044311SUlrich Weigand         break;
310b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
311b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
312b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
313b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
314b2044311SUlrich Weigand         break;
315d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
3169e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HA;
3179e90b3c8SUlrich Weigand         break;
318876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
319876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
320876a0d01SUlrich Weigand         break;
321876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
322876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
323876a0d01SUlrich Weigand         break;
32485578500SUlrich Weigand       }
32585578500SUlrich Weigand       break;
3266e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16ds:
3273822ef2cSBill Schmidt       switch (Modifier) {
3283822ef2cSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
3293822ef2cSBill Schmidt       case MCSymbolRefExpr::VK_None:
3303e186015SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_DS;
331f2aceda8SAdhemerval Zanella         break;
332d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
333e462053fSUlrich Weigand         Type = ELF::R_PPC64_ADDR16_LO_DS;
334e462053fSUlrich Weigand         break;
33593372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
33693372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_DS;
33793372b45SUlrich Weigand         break;
33893372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
33993372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_LO_DS;
34093372b45SUlrich Weigand         break;
341d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
342f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC16_DS;
343f2aceda8SAdhemerval Zanella         break;
344d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
34534627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO_DS;
34634627e34SBill Schmidt         break;
3470e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_TPREL:
348876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_DS;
349876a0d01SUlrich Weigand         break;
350876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
351876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_LO_DS;
352876a0d01SUlrich Weigand         break;
3530e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_DTPREL:
354876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_DS;
355876a0d01SUlrich Weigand         break;
356876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
357876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO_DS;
358876a0d01SUlrich Weigand         break;
359876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
360876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
361876a0d01SUlrich Weigand         break;
362d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
3639f0b4ec0SBill Schmidt         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
364ca4a0c9dSBill Schmidt         break;
365876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
366876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
367876a0d01SUlrich Weigand         break;
368876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
369876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
370876a0d01SUlrich Weigand         break;
37134627e34SBill Schmidt       }
37234627e34SBill Schmidt       break;
37324b8dd6eSBill Schmidt     case PPC::fixup_ppc_nofixup:
37424b8dd6eSBill Schmidt       switch (Modifier) {
37524b8dd6eSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
37652cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSGD:
3777c8ae535SHal Finkel         if (is64Bit())
378c56f1d34SBill Schmidt           Type = ELF::R_PPC64_TLSGD;
3797c8ae535SHal Finkel         else
3807c8ae535SHal Finkel           Type = ELF::R_PPC_TLSGD;
381c56f1d34SBill Schmidt         break;
38252cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSLD:
3837c8ae535SHal Finkel         if (is64Bit())
38424b8dd6eSBill Schmidt           Type = ELF::R_PPC64_TLSLD;
3857c8ae535SHal Finkel         else
3867c8ae535SHal Finkel           Type = ELF::R_PPC_TLSLD;
38724b8dd6eSBill Schmidt         break;
3885b427591SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLS:
3897c8ae535SHal Finkel         if (is64Bit())
3905b427591SUlrich Weigand           Type = ELF::R_PPC64_TLS;
3917c8ae535SHal Finkel         else
3927c8ae535SHal Finkel           Type = ELF::R_PPC_TLS;
3935b427591SUlrich Weigand         break;
39424b8dd6eSBill Schmidt       }
39524b8dd6eSBill Schmidt       break;
396f2aceda8SAdhemerval Zanella     case FK_Data_8:
397f2aceda8SAdhemerval Zanella       switch (Modifier) {
398f2aceda8SAdhemerval Zanella       default: llvm_unreachable("Unsupported Modifier");
39968e2e1b3SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOCBASE:
400f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC;
401f2aceda8SAdhemerval Zanella         break;
402f2aceda8SAdhemerval Zanella       case MCSymbolRefExpr::VK_None:
403f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_ADDR64;
404f2aceda8SAdhemerval Zanella         break;
405f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPMOD:
406f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPMOD64;
407f11efe7fSUlrich Weigand         break;
4080e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_TPREL:
409f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_TPREL64;
410f11efe7fSUlrich Weigand         break;
4110e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_DTPREL:
412f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPREL64;
413f11efe7fSUlrich Weigand         break;
414f2aceda8SAdhemerval Zanella       }
415f2aceda8SAdhemerval Zanella       break;
41638a400dfSRafael Espindola     case FK_Data_4:
41738a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR32;
41838a400dfSRafael Espindola       break;
41938a400dfSRafael Espindola     case FK_Data_2:
42038a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR16;
42138a400dfSRafael Espindola       break;
42238a400dfSRafael Espindola     }
42338a400dfSRafael Espindola   }
42438a400dfSRafael Espindola   return Type;
42538a400dfSRafael Espindola }
42638a400dfSRafael Espindola 
427ece40ca4SRafael Espindola bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
42846797c69SUlrich Weigand                                                  unsigned Type) const {
429bb68610dSUlrich Weigand   switch (Type) {
430bb68610dSUlrich Weigand     default:
431bb68610dSUlrich Weigand       return false;
432bb68610dSUlrich Weigand 
433bb68610dSUlrich Weigand     case ELF::R_PPC_REL24:
43446797c69SUlrich Weigand       // If the target symbol has a local entry point, we must keep the
43546797c69SUlrich Weigand       // target symbol to preserve that information for the linker.
43646797c69SUlrich Weigand       // The "other" values are stored in the last 6 bits of the second byte.
43746797c69SUlrich Weigand       // The traditional defines for STO values assume the full byte and thus
43846797c69SUlrich Weigand       // the shift to pack it.
43995fb9b93SRafael Espindola       unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
44046797c69SUlrich Weigand       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
441bb68610dSUlrich Weigand   }
442bb68610dSUlrich Weigand }
443bb68610dSUlrich Weigand 
444dcd7d6c3SPeter Collingbourne std::unique_ptr<MCObjectTargetWriter>
445dcd7d6c3SPeter Collingbourne llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
446dcd7d6c3SPeter Collingbourne   return llvm::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);
44738a400dfSRafael Espindola }
448