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 
PPCELFObjectWriter(bool Is64Bit,uint8_t OSABI)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 
getAccessVariant(const MCValue & Target,const MCFixup & Fixup)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 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const738340f94dSRafael Espindola unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
7438a400dfSRafael Espindola                                           const MCFixup &Fixup,
758c90fd71SBenjamin Kramer                                           bool IsPCRel) const {
76fc93787dSFangrui Song   MCFixupKind Kind = Fixup.getKind();
77fc93787dSFangrui Song   if (Kind >= FirstLiteralRelocationKind)
78fc93787dSFangrui Song     return Kind - FirstLiteralRelocationKind;
793d082fa5SRafael Espindola   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
80f2aceda8SAdhemerval Zanella 
8138a400dfSRafael Espindola   // determine the type of the relocation
8238a400dfSRafael Espindola   unsigned Type;
8338a400dfSRafael Espindola   if (IsPCRel) {
8490b6bb75SSam Clegg     switch (Fixup.getTargetKind()) {
8538a400dfSRafael Espindola     default:
8638a400dfSRafael Espindola       llvm_unreachable("Unimplemented");
8738a400dfSRafael Espindola     case PPC::fixup_ppc_br24:
88b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
896c4b40deSStefan Pintilie     case PPC::fixup_ppc_br24_notoc:
903ee2af7dSHal Finkel       switch (Modifier) {
913ee2af7dSHal Finkel       default: llvm_unreachable("Unsupported Modifier");
923ee2af7dSHal Finkel       case MCSymbolRefExpr::VK_None:
9338a400dfSRafael Espindola         Type = ELF::R_PPC_REL24;
9438a400dfSRafael Espindola         break;
953ee2af7dSHal Finkel       case MCSymbolRefExpr::VK_PLT:
963ee2af7dSHal Finkel         Type = ELF::R_PPC_PLTREL24;
973ee2af7dSHal Finkel         break;
98a88b6057SJustin Hibbits       case MCSymbolRefExpr::VK_PPC_LOCAL:
99a88b6057SJustin Hibbits         Type = ELF::R_PPC_LOCAL24PC;
100a88b6057SJustin Hibbits         break;
1016c4b40deSStefan Pintilie       case MCSymbolRefExpr::VK_PPC_NOTOC:
1026c4b40deSStefan Pintilie         Type = ELF::R_PPC64_REL24_NOTOC;
1036c4b40deSStefan Pintilie         break;
1043ee2af7dSHal Finkel       }
1053ee2af7dSHal Finkel       break;
10672a7dc0dSUlrich Weigand     case PPC::fixup_ppc_brcond14:
107b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
10872a7dc0dSUlrich Weigand       Type = ELF::R_PPC_REL14;
10972a7dc0dSUlrich Weigand       break;
11091add7dfSUlrich Weigand     case PPC::fixup_ppc_half16:
11191add7dfSUlrich Weigand       switch (Modifier) {
11291add7dfSUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
11391add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_None:
11491add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16;
11591add7dfSUlrich Weigand         break;
11691add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
11791add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_LO;
11891add7dfSUlrich Weigand         break;
11991add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
12091add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HI;
12191add7dfSUlrich Weigand         break;
12291add7dfSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
12391add7dfSUlrich Weigand         Type = ELF::R_PPC_REL16_HA;
12491add7dfSUlrich Weigand         break;
12591add7dfSUlrich Weigand       }
12691add7dfSUlrich Weigand       break;
127850ba46dSRafael Espindola     case PPC::fixup_ppc_half16ds:
128*2aaba44bSNemanja Ivanovic     case PPC::fixup_ppc_half16dq:
129850ba46dSRafael Espindola       Target.print(errs());
130850ba46dSRafael Espindola       errs() << '\n';
131de1dc9c9SBill Schmidt       report_fatal_error("Invalid PC-relative half16ds relocation");
13275828ef6SStefan Pintilie     case PPC::fixup_ppc_pcrel34:
133b771c4a8SStefan Pintilie       switch (Modifier) {
134b771c4a8SStefan Pintilie       default:
135b771c4a8SStefan Pintilie         llvm_unreachable("Unsupported Modifier for fixup_ppc_pcrel34");
136b771c4a8SStefan Pintilie       case MCSymbolRefExpr::VK_PCREL:
13775828ef6SStefan Pintilie         Type = ELF::R_PPC64_PCREL34;
13875828ef6SStefan Pintilie         break;
139b771c4a8SStefan Pintilie       case MCSymbolRefExpr::VK_PPC_GOT_PCREL:
140b771c4a8SStefan Pintilie         Type = ELF::R_PPC64_GOT_PCREL34;
141b771c4a8SStefan Pintilie         break;
142b74b80bbSKamau Bridgeman       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
143b74b80bbSKamau Bridgeman         Type = ELF::R_PPC64_GOT_TLSGD_PCREL34;
144b74b80bbSKamau Bridgeman         break;
145652a8f15SVictor Huang       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL:
146652a8f15SVictor Huang         Type = ELF::R_PPC64_GOT_TLSLD_PCREL34;
147652a8f15SVictor Huang         break;
148365f861cSKamau Bridgeman       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
149365f861cSKamau Bridgeman         Type = ELF::R_PPC64_GOT_TPREL_PCREL34;
150365f861cSKamau Bridgeman         break;
151b771c4a8SStefan Pintilie       }
152b771c4a8SStefan Pintilie       break;
1539b0b7813SAdhemerval Zanella     case FK_Data_4:
15438a400dfSRafael Espindola     case FK_PCRel_4:
15538a400dfSRafael Espindola       Type = ELF::R_PPC_REL32;
15638a400dfSRafael Espindola       break;
1579b0b7813SAdhemerval Zanella     case FK_Data_8:
1589b0b7813SAdhemerval Zanella     case FK_PCRel_8:
1599b0b7813SAdhemerval Zanella       Type = ELF::R_PPC64_REL64;
1609b0b7813SAdhemerval Zanella       break;
16138a400dfSRafael Espindola     }
16238a400dfSRafael Espindola   } else {
16390b6bb75SSam Clegg     switch (Fixup.getTargetKind()) {
16438a400dfSRafael Espindola       default: llvm_unreachable("invalid fixup kind!");
165b6a30d15SUlrich Weigand     case PPC::fixup_ppc_br24abs:
16638a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR24;
16738a400dfSRafael Espindola       break;
168b6a30d15SUlrich Weigand     case PPC::fixup_ppc_brcond14abs:
169f2aceda8SAdhemerval Zanella       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
17038a400dfSRafael Espindola       break;
1716e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16:
17285578500SUlrich Weigand       switch (Modifier) {
17385578500SUlrich Weigand       default: llvm_unreachable("Unsupported Modifier");
17485578500SUlrich Weigand       case MCSymbolRefExpr::VK_None:
175e462053fSUlrich Weigand         Type = ELF::R_PPC_ADDR16;
176e462053fSUlrich Weigand         break;
177d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
17838a400dfSRafael Espindola         Type = ELF::R_PPC_ADDR16_LO;
17938a400dfSRafael Espindola         break;
180e67c565dSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HI:
181e67c565dSUlrich Weigand         Type = ELF::R_PPC_ADDR16_HI;
182e67c565dSUlrich Weigand         break;
183d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HA:
1849e90b3c8SUlrich Weigand         Type = ELF::R_PPC_ADDR16_HA;
1859e90b3c8SUlrich Weigand         break;
18680b8f82fSSean Fertile       case MCSymbolRefExpr::VK_PPC_HIGH:
18780b8f82fSSean Fertile         Type = ELF::R_PPC64_ADDR16_HIGH;
18880b8f82fSSean Fertile         break;
18980b8f82fSSean Fertile       case MCSymbolRefExpr::VK_PPC_HIGHA:
19080b8f82fSSean Fertile         Type = ELF::R_PPC64_ADDR16_HIGHA;
19180b8f82fSSean Fertile         break;
192e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHER:
193e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHER;
194e9126f55SUlrich Weigand         break;
195e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHERA:
196e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHERA;
197e9126f55SUlrich Weigand         break;
198e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHEST:
199e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHEST;
200e9126f55SUlrich Weigand         break;
201e9126f55SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
202e9126f55SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
203e9126f55SUlrich Weigand         break;
20493372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
20593372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16;
20693372b45SUlrich Weigand         break;
20793372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
20893372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_LO;
20993372b45SUlrich Weigand         break;
21093372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HI:
21193372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HI;
21293372b45SUlrich Weigand         break;
21393372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_HA:
21493372b45SUlrich Weigand         Type = ELF::R_PPC_GOT16_HA;
21593372b45SUlrich Weigand         break;
216d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
2173e186015SUlrich Weigand         Type = ELF::R_PPC64_TOC16;
2183e186015SUlrich Weigand         break;
219d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
22034627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO;
22134627e34SBill Schmidt         break;
22272ddbd65SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HI:
22372ddbd65SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HI;
22472ddbd65SUlrich Weigand         break;
225d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_HA:
2269e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_TOC16_HA;
2279e90b3c8SUlrich Weigand         break;
2280e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_TPREL:
229876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16;
230876a0d01SUlrich Weigand         break;
231d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
2329e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_LO;
2339e90b3c8SUlrich Weigand         break;
234876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
235876a0d01SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HI;
236876a0d01SUlrich Weigand         break;
237d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
2389e90b3c8SUlrich Weigand         Type = ELF::R_PPC_TPREL16_HA;
2399e90b3c8SUlrich Weigand         break;
240cac28aebSSean Fertile       case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
241cac28aebSSean Fertile         Type = ELF::R_PPC64_TPREL16_HIGH;
242cac28aebSSean Fertile         break;
243cac28aebSSean Fertile       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
244cac28aebSSean Fertile         Type = ELF::R_PPC64_TPREL16_HIGHA;
245cac28aebSSean Fertile         break;
246876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
247876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHER;
248876a0d01SUlrich Weigand         break;
249876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
250876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHERA;
251876a0d01SUlrich Weigand         break;
252876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
253876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHEST;
254876a0d01SUlrich Weigand         break;
255876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
256876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
257876a0d01SUlrich Weigand         break;
2580e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_DTPREL:
259876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16;
260876a0d01SUlrich Weigand         break;
261d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
2629e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO;
2639e90b3c8SUlrich Weigand         break;
264876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
265876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HI;
266876a0d01SUlrich Weigand         break;
267d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
2689e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HA;
2699e90b3c8SUlrich Weigand         break;
270cac28aebSSean Fertile       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
271cac28aebSSean Fertile         Type = ELF::R_PPC64_DTPREL16_HIGH;
272cac28aebSSean Fertile         break;
273cac28aebSSean Fertile       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
274cac28aebSSean Fertile         Type = ELF::R_PPC64_DTPREL16_HIGHA;
275cac28aebSSean Fertile         break;
276876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
277876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHER;
278876a0d01SUlrich Weigand         break;
279876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
280876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
281876a0d01SUlrich Weigand         break;
282876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
283876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
284876a0d01SUlrich Weigand         break;
285876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
286876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
287876a0d01SUlrich Weigand         break;
288876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
2897c8ae535SHal Finkel         if (is64Bit())
290876a0d01SUlrich Weigand           Type = ELF::R_PPC64_GOT_TLSGD16;
2917c8ae535SHal Finkel         else
2927c8ae535SHal Finkel           Type = ELF::R_PPC_GOT_TLSGD16;
293876a0d01SUlrich Weigand         break;
294d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
295c56f1d34SBill Schmidt         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
296c56f1d34SBill Schmidt         break;
297876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
298876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
299876a0d01SUlrich Weigand         break;
300d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
3019e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
3029e90b3c8SUlrich Weigand         break;
303876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
3047c8ae535SHal Finkel         if (is64Bit())
305876a0d01SUlrich Weigand           Type = ELF::R_PPC64_GOT_TLSLD16;
3067c8ae535SHal Finkel         else
3077c8ae535SHal Finkel           Type = ELF::R_PPC_GOT_TLSLD16;
308876a0d01SUlrich Weigand         break;
309d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
31024b8dd6eSBill Schmidt         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
31124b8dd6eSBill Schmidt         break;
312876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
313876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
314876a0d01SUlrich Weigand         break;
315d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
3169e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
3179e90b3c8SUlrich Weigand         break;
318b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
319b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
320b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
321b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
322b2044311SUlrich Weigand         break;
323b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
324b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
325b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
326b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
327b2044311SUlrich Weigand         break;
328876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
329876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HI;
330876a0d01SUlrich Weigand         break;
331b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
332b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
333b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
334b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
335b2044311SUlrich Weigand         break;
336b2044311SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
337b2044311SUlrich Weigand         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
338b2044311SUlrich Weigand            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
339b2044311SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
340b2044311SUlrich Weigand         break;
341d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
3429e90b3c8SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_HA;
3439e90b3c8SUlrich Weigand         break;
344876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
345876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
346876a0d01SUlrich Weigand         break;
347876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
348876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
349876a0d01SUlrich Weigand         break;
35085578500SUlrich Weigand       }
35185578500SUlrich Weigand       break;
3526e23ac60SUlrich Weigand     case PPC::fixup_ppc_half16ds:
353*2aaba44bSNemanja Ivanovic     case PPC::fixup_ppc_half16dq:
3543822ef2cSBill Schmidt       switch (Modifier) {
3553822ef2cSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
3563822ef2cSBill Schmidt       case MCSymbolRefExpr::VK_None:
3573e186015SUlrich Weigand         Type = ELF::R_PPC64_ADDR16_DS;
358f2aceda8SAdhemerval Zanella         break;
359d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_LO:
360e462053fSUlrich Weigand         Type = ELF::R_PPC64_ADDR16_LO_DS;
361e462053fSUlrich Weigand         break;
36293372b45SUlrich Weigand       case MCSymbolRefExpr::VK_GOT:
36393372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_DS;
36493372b45SUlrich Weigand         break;
36593372b45SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_LO:
36693372b45SUlrich Weigand         Type = ELF::R_PPC64_GOT16_LO_DS;
36793372b45SUlrich Weigand         break;
368d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC:
369f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC16_DS;
370f2aceda8SAdhemerval Zanella         break;
371d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOC_LO:
37234627e34SBill Schmidt         Type = ELF::R_PPC64_TOC16_LO_DS;
37334627e34SBill Schmidt         break;
3740e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_TPREL:
375876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_DS;
376876a0d01SUlrich Weigand         break;
377876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
378876a0d01SUlrich Weigand         Type = ELF::R_PPC64_TPREL16_LO_DS;
379876a0d01SUlrich Weigand         break;
3800e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_DTPREL:
381876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_DS;
382876a0d01SUlrich Weigand         break;
383876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
384876a0d01SUlrich Weigand         Type = ELF::R_PPC64_DTPREL16_LO_DS;
385876a0d01SUlrich Weigand         break;
386876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
387876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_TPREL16_DS;
388876a0d01SUlrich Weigand         break;
389d51c09f5SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
3909f0b4ec0SBill Schmidt         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
391ca4a0c9dSBill Schmidt         break;
392876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
393876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
394876a0d01SUlrich Weigand         break;
395876a0d01SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
396876a0d01SUlrich Weigand         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
397876a0d01SUlrich Weigand         break;
39834627e34SBill Schmidt       }
39934627e34SBill Schmidt       break;
40024b8dd6eSBill Schmidt     case PPC::fixup_ppc_nofixup:
40124b8dd6eSBill Schmidt       switch (Modifier) {
40224b8dd6eSBill Schmidt       default: llvm_unreachable("Unsupported Modifier");
40352cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSGD:
4047c8ae535SHal Finkel         if (is64Bit())
405c56f1d34SBill Schmidt           Type = ELF::R_PPC64_TLSGD;
4067c8ae535SHal Finkel         else
4077c8ae535SHal Finkel           Type = ELF::R_PPC_TLSGD;
408c56f1d34SBill Schmidt         break;
40952cf8e44SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLSLD:
4107c8ae535SHal Finkel         if (is64Bit())
41124b8dd6eSBill Schmidt           Type = ELF::R_PPC64_TLSLD;
4127c8ae535SHal Finkel         else
4137c8ae535SHal Finkel           Type = ELF::R_PPC_TLSLD;
41424b8dd6eSBill Schmidt         break;
4155b427591SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TLS:
4167c8ae535SHal Finkel         if (is64Bit())
4175b427591SUlrich Weigand           Type = ELF::R_PPC64_TLS;
4187c8ae535SHal Finkel         else
4197c8ae535SHal Finkel           Type = ELF::R_PPC_TLS;
4205b427591SUlrich Weigand         break;
421365f861cSKamau Bridgeman       case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
422365f861cSKamau Bridgeman         Type = ELF::R_PPC64_TLS;
423365f861cSKamau Bridgeman         break;
42424b8dd6eSBill Schmidt       }
42524b8dd6eSBill Schmidt       break;
42697470897SStefan Pintilie     case PPC::fixup_ppc_imm34:
427c0f199e5SKamau Bridgeman       switch (Modifier) {
428c0f199e5SKamau Bridgeman       default:
42997470897SStefan Pintilie         report_fatal_error("Unsupported Modifier for fixup_ppc_imm34.");
430652a8f15SVictor Huang       case MCSymbolRefExpr::VK_DTPREL:
431652a8f15SVictor Huang         Type = ELF::R_PPC64_DTPREL34;
432652a8f15SVictor Huang         break;
433c0f199e5SKamau Bridgeman       case MCSymbolRefExpr::VK_TPREL:
434c0f199e5SKamau Bridgeman         Type = ELF::R_PPC64_TPREL34;
435c0f199e5SKamau Bridgeman         break;
436c0f199e5SKamau Bridgeman       }
43797470897SStefan Pintilie       break;
438f2aceda8SAdhemerval Zanella     case FK_Data_8:
439f2aceda8SAdhemerval Zanella       switch (Modifier) {
440f2aceda8SAdhemerval Zanella       default: llvm_unreachable("Unsupported Modifier");
44168e2e1b3SUlrich Weigand       case MCSymbolRefExpr::VK_PPC_TOCBASE:
442f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_TOC;
443f2aceda8SAdhemerval Zanella         break;
444f2aceda8SAdhemerval Zanella       case MCSymbolRefExpr::VK_None:
445f2aceda8SAdhemerval Zanella         Type = ELF::R_PPC64_ADDR64;
446f2aceda8SAdhemerval Zanella         break;
447f11efe7fSUlrich Weigand       case MCSymbolRefExpr::VK_PPC_DTPMOD:
448f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPMOD64;
449f11efe7fSUlrich Weigand         break;
4500e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_TPREL:
451f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_TPREL64;
452f11efe7fSUlrich Weigand         break;
4530e05192dSColin LeMahieu       case MCSymbolRefExpr::VK_DTPREL:
454f11efe7fSUlrich Weigand         Type = ELF::R_PPC64_DTPREL64;
455f11efe7fSUlrich Weigand         break;
456f2aceda8SAdhemerval Zanella       }
457f2aceda8SAdhemerval Zanella       break;
45838a400dfSRafael Espindola     case FK_Data_4:
45938a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR32;
46038a400dfSRafael Espindola       break;
46138a400dfSRafael Espindola     case FK_Data_2:
46238a400dfSRafael Espindola       Type = ELF::R_PPC_ADDR16;
46338a400dfSRafael Espindola       break;
46438a400dfSRafael Espindola     }
46538a400dfSRafael Espindola   }
46638a400dfSRafael Espindola   return Type;
46738a400dfSRafael Espindola }
46838a400dfSRafael Espindola 
needsRelocateWithSymbol(const MCSymbol & Sym,unsigned Type) const469ece40ca4SRafael Espindola bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
47046797c69SUlrich Weigand                                                  unsigned Type) const {
471bb68610dSUlrich Weigand   switch (Type) {
472bb68610dSUlrich Weigand     default:
473bb68610dSUlrich Weigand       return false;
474bb68610dSUlrich Weigand 
475bb68610dSUlrich Weigand     case ELF::R_PPC_REL24:
4766c4b40deSStefan Pintilie     case ELF::R_PPC64_REL24_NOTOC:
47746797c69SUlrich Weigand       // If the target symbol has a local entry point, we must keep the
47846797c69SUlrich Weigand       // target symbol to preserve that information for the linker.
47946797c69SUlrich Weigand       // The "other" values are stored in the last 6 bits of the second byte.
48046797c69SUlrich Weigand       // The traditional defines for STO values assume the full byte and thus
48146797c69SUlrich Weigand       // the shift to pack it.
48295fb9b93SRafael Espindola       unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
48346797c69SUlrich Weigand       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
484bb68610dSUlrich Weigand   }
485bb68610dSUlrich Weigand }
486bb68610dSUlrich Weigand 
487dcd7d6c3SPeter Collingbourne std::unique_ptr<MCObjectTargetWriter>
createPPCELFObjectWriter(bool Is64Bit,uint8_t OSABI)488dcd7d6c3SPeter Collingbourne llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
4890eaee545SJonas Devlieghere   return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);
49038a400dfSRafael Espindola }
491