xref: /openbsd-src/gnu/llvm/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick 
909467b48Spatrick #include "MCTargetDesc/PPCFixupKinds.h"
1009467b48Spatrick #include "MCTargetDesc/PPCMCExpr.h"
1109467b48Spatrick #include "MCTargetDesc/PPCMCTargetDesc.h"
1209467b48Spatrick #include "llvm/ADT/STLExtras.h"
1309467b48Spatrick #include "llvm/MC/MCELFObjectWriter.h"
1409467b48Spatrick #include "llvm/MC/MCExpr.h"
1509467b48Spatrick #include "llvm/MC/MCObjectWriter.h"
1609467b48Spatrick #include "llvm/MC/MCSymbolELF.h"
1709467b48Spatrick #include "llvm/MC/MCValue.h"
1809467b48Spatrick #include "llvm/Support/ErrorHandling.h"
1909467b48Spatrick 
2009467b48Spatrick using namespace llvm;
2109467b48Spatrick 
2209467b48Spatrick namespace {
2309467b48Spatrick   class PPCELFObjectWriter : public MCELFObjectTargetWriter {
2409467b48Spatrick   public:
2509467b48Spatrick     PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
2609467b48Spatrick 
2709467b48Spatrick   protected:
2809467b48Spatrick     unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
2909467b48Spatrick                           const MCFixup &Fixup, bool IsPCRel) const override;
3009467b48Spatrick 
3109467b48Spatrick     bool needsRelocateWithSymbol(const MCSymbol &Sym,
3209467b48Spatrick                                  unsigned Type) const override;
3309467b48Spatrick   };
3409467b48Spatrick }
3509467b48Spatrick 
PPCELFObjectWriter(bool Is64Bit,uint8_t OSABI)3609467b48Spatrick PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
3709467b48Spatrick   : MCELFObjectTargetWriter(Is64Bit, OSABI,
3809467b48Spatrick                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
3909467b48Spatrick                             /*HasRelocationAddend*/ true) {}
4009467b48Spatrick 
getAccessVariant(const MCValue & Target,const MCFixup & Fixup)4109467b48Spatrick static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
4209467b48Spatrick                                                      const MCFixup &Fixup) {
4309467b48Spatrick   const MCExpr *Expr = Fixup.getValue();
4409467b48Spatrick 
4509467b48Spatrick   if (Expr->getKind() != MCExpr::Target)
4609467b48Spatrick     return Target.getAccessVariant();
4709467b48Spatrick 
4809467b48Spatrick   switch (cast<PPCMCExpr>(Expr)->getKind()) {
4909467b48Spatrick   case PPCMCExpr::VK_PPC_None:
5009467b48Spatrick     return MCSymbolRefExpr::VK_None;
5109467b48Spatrick   case PPCMCExpr::VK_PPC_LO:
5209467b48Spatrick     return MCSymbolRefExpr::VK_PPC_LO;
5309467b48Spatrick   case PPCMCExpr::VK_PPC_HI:
5409467b48Spatrick     return MCSymbolRefExpr::VK_PPC_HI;
5509467b48Spatrick   case PPCMCExpr::VK_PPC_HA:
5609467b48Spatrick     return MCSymbolRefExpr::VK_PPC_HA;
5709467b48Spatrick   case PPCMCExpr::VK_PPC_HIGH:
5809467b48Spatrick     return MCSymbolRefExpr::VK_PPC_HIGH;
5909467b48Spatrick   case PPCMCExpr::VK_PPC_HIGHA:
6009467b48Spatrick     return MCSymbolRefExpr::VK_PPC_HIGHA;
6109467b48Spatrick   case PPCMCExpr::VK_PPC_HIGHERA:
6209467b48Spatrick     return MCSymbolRefExpr::VK_PPC_HIGHERA;
6309467b48Spatrick   case PPCMCExpr::VK_PPC_HIGHER:
6409467b48Spatrick     return MCSymbolRefExpr::VK_PPC_HIGHER;
6509467b48Spatrick   case PPCMCExpr::VK_PPC_HIGHEST:
6609467b48Spatrick     return MCSymbolRefExpr::VK_PPC_HIGHEST;
6709467b48Spatrick   case PPCMCExpr::VK_PPC_HIGHESTA:
6809467b48Spatrick     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
6909467b48Spatrick   }
7009467b48Spatrick   llvm_unreachable("unknown PPCMCExpr kind");
7109467b48Spatrick }
7209467b48Spatrick 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const7309467b48Spatrick unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
7409467b48Spatrick                                           const MCFixup &Fixup,
7509467b48Spatrick                                           bool IsPCRel) const {
76097a140dSpatrick   MCFixupKind Kind = Fixup.getKind();
77097a140dSpatrick   if (Kind >= FirstLiteralRelocationKind)
78097a140dSpatrick     return Kind - FirstLiteralRelocationKind;
7909467b48Spatrick   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
8009467b48Spatrick 
8109467b48Spatrick   // determine the type of the relocation
8209467b48Spatrick   unsigned Type;
8309467b48Spatrick   if (IsPCRel) {
8409467b48Spatrick     switch (Fixup.getTargetKind()) {
8509467b48Spatrick     default:
8609467b48Spatrick       llvm_unreachable("Unimplemented");
8709467b48Spatrick     case PPC::fixup_ppc_br24:
8809467b48Spatrick     case PPC::fixup_ppc_br24abs:
89097a140dSpatrick     case PPC::fixup_ppc_br24_notoc:
9009467b48Spatrick       switch (Modifier) {
9109467b48Spatrick       default: llvm_unreachable("Unsupported Modifier");
9209467b48Spatrick       case MCSymbolRefExpr::VK_None:
9309467b48Spatrick         Type = ELF::R_PPC_REL24;
9409467b48Spatrick         break;
9509467b48Spatrick       case MCSymbolRefExpr::VK_PLT:
9609467b48Spatrick         Type = ELF::R_PPC_PLTREL24;
9709467b48Spatrick         break;
9809467b48Spatrick       case MCSymbolRefExpr::VK_PPC_LOCAL:
9909467b48Spatrick         Type = ELF::R_PPC_LOCAL24PC;
10009467b48Spatrick         break;
101097a140dSpatrick       case MCSymbolRefExpr::VK_PPC_NOTOC:
102097a140dSpatrick         Type = ELF::R_PPC64_REL24_NOTOC;
103097a140dSpatrick         break;
10409467b48Spatrick       }
10509467b48Spatrick       break;
10609467b48Spatrick     case PPC::fixup_ppc_brcond14:
10709467b48Spatrick     case PPC::fixup_ppc_brcond14abs:
10809467b48Spatrick       Type = ELF::R_PPC_REL14;
10909467b48Spatrick       break;
11009467b48Spatrick     case PPC::fixup_ppc_half16:
11109467b48Spatrick       switch (Modifier) {
11209467b48Spatrick       default: llvm_unreachable("Unsupported Modifier");
11309467b48Spatrick       case MCSymbolRefExpr::VK_None:
11409467b48Spatrick         Type = ELF::R_PPC_REL16;
11509467b48Spatrick         break;
11609467b48Spatrick       case MCSymbolRefExpr::VK_PPC_LO:
11709467b48Spatrick         Type = ELF::R_PPC_REL16_LO;
11809467b48Spatrick         break;
11909467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HI:
12009467b48Spatrick         Type = ELF::R_PPC_REL16_HI;
12109467b48Spatrick         break;
12209467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HA:
12309467b48Spatrick         Type = ELF::R_PPC_REL16_HA;
12409467b48Spatrick         break;
12509467b48Spatrick       }
12609467b48Spatrick       break;
12709467b48Spatrick     case PPC::fixup_ppc_half16ds:
128*d415bd75Srobert     case PPC::fixup_ppc_half16dq:
12909467b48Spatrick       Target.print(errs());
13009467b48Spatrick       errs() << '\n';
13109467b48Spatrick       report_fatal_error("Invalid PC-relative half16ds relocation");
132097a140dSpatrick     case PPC::fixup_ppc_pcrel34:
133097a140dSpatrick       switch (Modifier) {
134097a140dSpatrick       default:
135097a140dSpatrick         llvm_unreachable("Unsupported Modifier for fixup_ppc_pcrel34");
136097a140dSpatrick       case MCSymbolRefExpr::VK_PCREL:
137097a140dSpatrick         Type = ELF::R_PPC64_PCREL34;
138097a140dSpatrick         break;
139097a140dSpatrick       case MCSymbolRefExpr::VK_PPC_GOT_PCREL:
140097a140dSpatrick         Type = ELF::R_PPC64_GOT_PCREL34;
141097a140dSpatrick         break;
14273471bf0Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
14373471bf0Spatrick         Type = ELF::R_PPC64_GOT_TLSGD_PCREL34;
14473471bf0Spatrick         break;
14573471bf0Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL:
14673471bf0Spatrick         Type = ELF::R_PPC64_GOT_TLSLD_PCREL34;
14773471bf0Spatrick         break;
14873471bf0Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
14973471bf0Spatrick         Type = ELF::R_PPC64_GOT_TPREL_PCREL34;
15073471bf0Spatrick         break;
151097a140dSpatrick       }
152097a140dSpatrick       break;
15309467b48Spatrick     case FK_Data_4:
15409467b48Spatrick     case FK_PCRel_4:
15509467b48Spatrick       Type = ELF::R_PPC_REL32;
15609467b48Spatrick       break;
15709467b48Spatrick     case FK_Data_8:
15809467b48Spatrick     case FK_PCRel_8:
15909467b48Spatrick       Type = ELF::R_PPC64_REL64;
16009467b48Spatrick       break;
16109467b48Spatrick     }
16209467b48Spatrick   } else {
16309467b48Spatrick     switch (Fixup.getTargetKind()) {
16409467b48Spatrick       default: llvm_unreachable("invalid fixup kind!");
16509467b48Spatrick     case PPC::fixup_ppc_br24abs:
16609467b48Spatrick       Type = ELF::R_PPC_ADDR24;
16709467b48Spatrick       break;
16809467b48Spatrick     case PPC::fixup_ppc_brcond14abs:
16909467b48Spatrick       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
17009467b48Spatrick       break;
17109467b48Spatrick     case PPC::fixup_ppc_half16:
17209467b48Spatrick       switch (Modifier) {
17309467b48Spatrick       default: llvm_unreachable("Unsupported Modifier");
17409467b48Spatrick       case MCSymbolRefExpr::VK_None:
17509467b48Spatrick         Type = ELF::R_PPC_ADDR16;
17609467b48Spatrick         break;
17709467b48Spatrick       case MCSymbolRefExpr::VK_PPC_LO:
17809467b48Spatrick         Type = ELF::R_PPC_ADDR16_LO;
17909467b48Spatrick         break;
18009467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HI:
18109467b48Spatrick         Type = ELF::R_PPC_ADDR16_HI;
18209467b48Spatrick         break;
18309467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HA:
18409467b48Spatrick         Type = ELF::R_PPC_ADDR16_HA;
18509467b48Spatrick         break;
18609467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HIGH:
18709467b48Spatrick         Type = ELF::R_PPC64_ADDR16_HIGH;
18809467b48Spatrick         break;
18909467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HIGHA:
19009467b48Spatrick         Type = ELF::R_PPC64_ADDR16_HIGHA;
19109467b48Spatrick         break;
19209467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HIGHER:
19309467b48Spatrick         Type = ELF::R_PPC64_ADDR16_HIGHER;
19409467b48Spatrick         break;
19509467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HIGHERA:
19609467b48Spatrick         Type = ELF::R_PPC64_ADDR16_HIGHERA;
19709467b48Spatrick         break;
19809467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HIGHEST:
19909467b48Spatrick         Type = ELF::R_PPC64_ADDR16_HIGHEST;
20009467b48Spatrick         break;
20109467b48Spatrick       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
20209467b48Spatrick         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
20309467b48Spatrick         break;
20409467b48Spatrick       case MCSymbolRefExpr::VK_GOT:
20509467b48Spatrick         Type = ELF::R_PPC_GOT16;
20609467b48Spatrick         break;
20709467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_LO:
20809467b48Spatrick         Type = ELF::R_PPC_GOT16_LO;
20909467b48Spatrick         break;
21009467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_HI:
21109467b48Spatrick         Type = ELF::R_PPC_GOT16_HI;
21209467b48Spatrick         break;
21309467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_HA:
21409467b48Spatrick         Type = ELF::R_PPC_GOT16_HA;
21509467b48Spatrick         break;
21609467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TOC:
21709467b48Spatrick         Type = ELF::R_PPC64_TOC16;
21809467b48Spatrick         break;
21909467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TOC_LO:
22009467b48Spatrick         Type = ELF::R_PPC64_TOC16_LO;
22109467b48Spatrick         break;
22209467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TOC_HI:
22309467b48Spatrick         Type = ELF::R_PPC64_TOC16_HI;
22409467b48Spatrick         break;
22509467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TOC_HA:
22609467b48Spatrick         Type = ELF::R_PPC64_TOC16_HA;
22709467b48Spatrick         break;
22809467b48Spatrick       case MCSymbolRefExpr::VK_TPREL:
22909467b48Spatrick         Type = ELF::R_PPC_TPREL16;
23009467b48Spatrick         break;
23109467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
23209467b48Spatrick         Type = ELF::R_PPC_TPREL16_LO;
23309467b48Spatrick         break;
23409467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
23509467b48Spatrick         Type = ELF::R_PPC_TPREL16_HI;
23609467b48Spatrick         break;
23709467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
23809467b48Spatrick         Type = ELF::R_PPC_TPREL16_HA;
23909467b48Spatrick         break;
24009467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
24109467b48Spatrick         Type = ELF::R_PPC64_TPREL16_HIGH;
24209467b48Spatrick         break;
24309467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
24409467b48Spatrick         Type = ELF::R_PPC64_TPREL16_HIGHA;
24509467b48Spatrick         break;
24609467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
24709467b48Spatrick         Type = ELF::R_PPC64_TPREL16_HIGHER;
24809467b48Spatrick         break;
24909467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
25009467b48Spatrick         Type = ELF::R_PPC64_TPREL16_HIGHERA;
25109467b48Spatrick         break;
25209467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
25309467b48Spatrick         Type = ELF::R_PPC64_TPREL16_HIGHEST;
25409467b48Spatrick         break;
25509467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
25609467b48Spatrick         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
25709467b48Spatrick         break;
25809467b48Spatrick       case MCSymbolRefExpr::VK_DTPREL:
25909467b48Spatrick         Type = ELF::R_PPC64_DTPREL16;
26009467b48Spatrick         break;
26109467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
26209467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_LO;
26309467b48Spatrick         break;
26409467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
26509467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_HI;
26609467b48Spatrick         break;
26709467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
26809467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_HA;
26909467b48Spatrick         break;
27009467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
27109467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_HIGH;
27209467b48Spatrick         break;
27309467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
27409467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_HIGHA;
27509467b48Spatrick         break;
27609467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
27709467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_HIGHER;
27809467b48Spatrick         break;
27909467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
28009467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
28109467b48Spatrick         break;
28209467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
28309467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
28409467b48Spatrick         break;
28509467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
28609467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
28709467b48Spatrick         break;
28809467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
28909467b48Spatrick         if (is64Bit())
29009467b48Spatrick           Type = ELF::R_PPC64_GOT_TLSGD16;
29109467b48Spatrick         else
29209467b48Spatrick           Type = ELF::R_PPC_GOT_TLSGD16;
29309467b48Spatrick         break;
29409467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
29509467b48Spatrick         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
29609467b48Spatrick         break;
29709467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
29809467b48Spatrick         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
29909467b48Spatrick         break;
30009467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
30109467b48Spatrick         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
30209467b48Spatrick         break;
30309467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
30409467b48Spatrick         if (is64Bit())
30509467b48Spatrick           Type = ELF::R_PPC64_GOT_TLSLD16;
30609467b48Spatrick         else
30709467b48Spatrick           Type = ELF::R_PPC_GOT_TLSLD16;
30809467b48Spatrick         break;
30909467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
31009467b48Spatrick         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
31109467b48Spatrick         break;
31209467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
31309467b48Spatrick         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
31409467b48Spatrick         break;
31509467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
31609467b48Spatrick         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
31709467b48Spatrick         break;
31809467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
31909467b48Spatrick         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
32009467b48Spatrick            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
32109467b48Spatrick         Type = ELF::R_PPC64_GOT_TPREL16_DS;
32209467b48Spatrick         break;
32309467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
32409467b48Spatrick         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
32509467b48Spatrick            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
32609467b48Spatrick         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
32709467b48Spatrick         break;
32809467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
32909467b48Spatrick         Type = ELF::R_PPC64_GOT_TPREL16_HI;
33009467b48Spatrick         break;
33109467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
33209467b48Spatrick         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
33309467b48Spatrick            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
33409467b48Spatrick         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
33509467b48Spatrick         break;
33609467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
33709467b48Spatrick         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
33809467b48Spatrick            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
33909467b48Spatrick         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
34009467b48Spatrick         break;
34109467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
34209467b48Spatrick         Type = ELF::R_PPC64_GOT_TPREL16_HA;
34309467b48Spatrick         break;
34409467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
34509467b48Spatrick         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
34609467b48Spatrick         break;
34709467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
34809467b48Spatrick         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
34909467b48Spatrick         break;
35009467b48Spatrick       }
35109467b48Spatrick       break;
35209467b48Spatrick     case PPC::fixup_ppc_half16ds:
353*d415bd75Srobert     case PPC::fixup_ppc_half16dq:
35409467b48Spatrick       switch (Modifier) {
35509467b48Spatrick       default: llvm_unreachable("Unsupported Modifier");
35609467b48Spatrick       case MCSymbolRefExpr::VK_None:
35709467b48Spatrick         Type = ELF::R_PPC64_ADDR16_DS;
35809467b48Spatrick         break;
35909467b48Spatrick       case MCSymbolRefExpr::VK_PPC_LO:
36009467b48Spatrick         Type = ELF::R_PPC64_ADDR16_LO_DS;
36109467b48Spatrick         break;
36209467b48Spatrick       case MCSymbolRefExpr::VK_GOT:
36309467b48Spatrick         Type = ELF::R_PPC64_GOT16_DS;
36409467b48Spatrick         break;
36509467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_LO:
36609467b48Spatrick         Type = ELF::R_PPC64_GOT16_LO_DS;
36709467b48Spatrick         break;
36809467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TOC:
36909467b48Spatrick         Type = ELF::R_PPC64_TOC16_DS;
37009467b48Spatrick         break;
37109467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TOC_LO:
37209467b48Spatrick         Type = ELF::R_PPC64_TOC16_LO_DS;
37309467b48Spatrick         break;
37409467b48Spatrick       case MCSymbolRefExpr::VK_TPREL:
37509467b48Spatrick         Type = ELF::R_PPC64_TPREL16_DS;
37609467b48Spatrick         break;
37709467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
37809467b48Spatrick         Type = ELF::R_PPC64_TPREL16_LO_DS;
37909467b48Spatrick         break;
38009467b48Spatrick       case MCSymbolRefExpr::VK_DTPREL:
38109467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_DS;
38209467b48Spatrick         break;
38309467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
38409467b48Spatrick         Type = ELF::R_PPC64_DTPREL16_LO_DS;
38509467b48Spatrick         break;
38609467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
38709467b48Spatrick         Type = ELF::R_PPC64_GOT_TPREL16_DS;
38809467b48Spatrick         break;
38909467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
39009467b48Spatrick         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
39109467b48Spatrick         break;
39209467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
39309467b48Spatrick         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
39409467b48Spatrick         break;
39509467b48Spatrick       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
39609467b48Spatrick         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
39709467b48Spatrick         break;
39809467b48Spatrick       }
39909467b48Spatrick       break;
40009467b48Spatrick     case PPC::fixup_ppc_nofixup:
40109467b48Spatrick       switch (Modifier) {
40209467b48Spatrick       default: llvm_unreachable("Unsupported Modifier");
40309467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TLSGD:
40409467b48Spatrick         if (is64Bit())
40509467b48Spatrick           Type = ELF::R_PPC64_TLSGD;
40609467b48Spatrick         else
40709467b48Spatrick           Type = ELF::R_PPC_TLSGD;
40809467b48Spatrick         break;
40909467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TLSLD:
41009467b48Spatrick         if (is64Bit())
41109467b48Spatrick           Type = ELF::R_PPC64_TLSLD;
41209467b48Spatrick         else
41309467b48Spatrick           Type = ELF::R_PPC_TLSLD;
41409467b48Spatrick         break;
41509467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TLS:
41609467b48Spatrick         if (is64Bit())
41709467b48Spatrick           Type = ELF::R_PPC64_TLS;
41809467b48Spatrick         else
41909467b48Spatrick           Type = ELF::R_PPC_TLS;
42009467b48Spatrick         break;
42173471bf0Spatrick       case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
42273471bf0Spatrick         Type = ELF::R_PPC64_TLS;
42373471bf0Spatrick         break;
42473471bf0Spatrick       }
42573471bf0Spatrick       break;
42673471bf0Spatrick     case PPC::fixup_ppc_imm34:
42773471bf0Spatrick       switch (Modifier) {
42873471bf0Spatrick       default:
42973471bf0Spatrick         report_fatal_error("Unsupported Modifier for fixup_ppc_imm34.");
43073471bf0Spatrick       case MCSymbolRefExpr::VK_DTPREL:
43173471bf0Spatrick         Type = ELF::R_PPC64_DTPREL34;
43273471bf0Spatrick         break;
43373471bf0Spatrick       case MCSymbolRefExpr::VK_TPREL:
43473471bf0Spatrick         Type = ELF::R_PPC64_TPREL34;
43573471bf0Spatrick         break;
43609467b48Spatrick       }
43709467b48Spatrick       break;
43809467b48Spatrick     case FK_Data_8:
43909467b48Spatrick       switch (Modifier) {
44009467b48Spatrick       default: llvm_unreachable("Unsupported Modifier");
44109467b48Spatrick       case MCSymbolRefExpr::VK_PPC_TOCBASE:
44209467b48Spatrick         Type = ELF::R_PPC64_TOC;
44309467b48Spatrick         break;
44409467b48Spatrick       case MCSymbolRefExpr::VK_None:
44509467b48Spatrick         Type = ELF::R_PPC64_ADDR64;
44609467b48Spatrick         break;
44709467b48Spatrick       case MCSymbolRefExpr::VK_PPC_DTPMOD:
44809467b48Spatrick         Type = ELF::R_PPC64_DTPMOD64;
44909467b48Spatrick         break;
45009467b48Spatrick       case MCSymbolRefExpr::VK_TPREL:
45109467b48Spatrick         Type = ELF::R_PPC64_TPREL64;
45209467b48Spatrick         break;
45309467b48Spatrick       case MCSymbolRefExpr::VK_DTPREL:
45409467b48Spatrick         Type = ELF::R_PPC64_DTPREL64;
45509467b48Spatrick         break;
45609467b48Spatrick       }
45709467b48Spatrick       break;
45809467b48Spatrick     case FK_Data_4:
45909467b48Spatrick       Type = ELF::R_PPC_ADDR32;
46009467b48Spatrick       break;
46109467b48Spatrick     case FK_Data_2:
46209467b48Spatrick       Type = ELF::R_PPC_ADDR16;
46309467b48Spatrick       break;
46409467b48Spatrick     }
46509467b48Spatrick   }
46609467b48Spatrick   return Type;
46709467b48Spatrick }
46809467b48Spatrick 
needsRelocateWithSymbol(const MCSymbol & Sym,unsigned Type) const46909467b48Spatrick bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
47009467b48Spatrick                                                  unsigned Type) const {
47109467b48Spatrick   switch (Type) {
47209467b48Spatrick     default:
47309467b48Spatrick       return false;
47409467b48Spatrick 
47509467b48Spatrick     case ELF::R_PPC_REL24:
476097a140dSpatrick     case ELF::R_PPC64_REL24_NOTOC:
47709467b48Spatrick       // If the target symbol has a local entry point, we must keep the
47809467b48Spatrick       // target symbol to preserve that information for the linker.
47909467b48Spatrick       // The "other" values are stored in the last 6 bits of the second byte.
48009467b48Spatrick       // The traditional defines for STO values assume the full byte and thus
48109467b48Spatrick       // the shift to pack it.
48209467b48Spatrick       unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
48309467b48Spatrick       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
48409467b48Spatrick   }
48509467b48Spatrick }
48609467b48Spatrick 
48709467b48Spatrick std::unique_ptr<MCObjectTargetWriter>
createPPCELFObjectWriter(bool Is64Bit,uint8_t OSABI)48809467b48Spatrick llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
48909467b48Spatrick   return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);
49009467b48Spatrick }
491