xref: /aosp_15_r20/external/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/PPCMCTargetDesc.h"
11*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/PPCFixupKinds.h"
12*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/PPCMCExpr.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCELFObjectWriter.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbolELF.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCValue.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
19*9880d681SAndroid Build Coastguard Worker 
20*9880d681SAndroid Build Coastguard Worker using namespace llvm;
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker namespace {
23*9880d681SAndroid Build Coastguard Worker   class PPCELFObjectWriter : public MCELFObjectTargetWriter {
24*9880d681SAndroid Build Coastguard Worker   public:
25*9880d681SAndroid Build Coastguard Worker     PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
26*9880d681SAndroid Build Coastguard Worker 
27*9880d681SAndroid Build Coastguard Worker   protected:
28*9880d681SAndroid Build Coastguard Worker     unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
29*9880d681SAndroid Build Coastguard Worker                           const MCFixup &Fixup, bool IsPCRel) const override;
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker     bool needsRelocateWithSymbol(const MCSymbol &Sym,
32*9880d681SAndroid Build Coastguard Worker                                  unsigned Type) const override;
33*9880d681SAndroid Build Coastguard Worker   };
34*9880d681SAndroid Build Coastguard Worker }
35*9880d681SAndroid Build Coastguard Worker 
PPCELFObjectWriter(bool Is64Bit,uint8_t OSABI)36*9880d681SAndroid Build Coastguard Worker PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
37*9880d681SAndroid Build Coastguard Worker   : MCELFObjectTargetWriter(Is64Bit, OSABI,
38*9880d681SAndroid Build Coastguard Worker                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
39*9880d681SAndroid Build Coastguard Worker                             /*HasRelocationAddend*/ true) {}
40*9880d681SAndroid Build Coastguard Worker 
getAccessVariant(const MCValue & Target,const MCFixup & Fixup)41*9880d681SAndroid Build Coastguard Worker static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
42*9880d681SAndroid Build Coastguard Worker                                                      const MCFixup &Fixup) {
43*9880d681SAndroid Build Coastguard Worker   const MCExpr *Expr = Fixup.getValue();
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker   if (Expr->getKind() != MCExpr::Target)
46*9880d681SAndroid Build Coastguard Worker     return Target.getAccessVariant();
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker   switch (cast<PPCMCExpr>(Expr)->getKind()) {
49*9880d681SAndroid Build Coastguard Worker   case PPCMCExpr::VK_PPC_None:
50*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_None;
51*9880d681SAndroid Build Coastguard Worker   case PPCMCExpr::VK_PPC_LO:
52*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_PPC_LO;
53*9880d681SAndroid Build Coastguard Worker   case PPCMCExpr::VK_PPC_HI:
54*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_PPC_HI;
55*9880d681SAndroid Build Coastguard Worker   case PPCMCExpr::VK_PPC_HA:
56*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_PPC_HA;
57*9880d681SAndroid Build Coastguard Worker   case PPCMCExpr::VK_PPC_HIGHERA:
58*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_PPC_HIGHERA;
59*9880d681SAndroid Build Coastguard Worker   case PPCMCExpr::VK_PPC_HIGHER:
60*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_PPC_HIGHER;
61*9880d681SAndroid Build Coastguard Worker   case PPCMCExpr::VK_PPC_HIGHEST:
62*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_PPC_HIGHEST;
63*9880d681SAndroid Build Coastguard Worker   case PPCMCExpr::VK_PPC_HIGHESTA:
64*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
65*9880d681SAndroid Build Coastguard Worker   }
66*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("unknown PPCMCExpr kind");
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const69*9880d681SAndroid Build Coastguard Worker unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
70*9880d681SAndroid Build Coastguard Worker                                           const MCFixup &Fixup,
71*9880d681SAndroid Build Coastguard Worker                                           bool IsPCRel) const {
72*9880d681SAndroid Build Coastguard Worker   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker   // determine the type of the relocation
75*9880d681SAndroid Build Coastguard Worker   unsigned Type;
76*9880d681SAndroid Build Coastguard Worker   if (IsPCRel) {
77*9880d681SAndroid Build Coastguard Worker     switch ((unsigned)Fixup.getKind()) {
78*9880d681SAndroid Build Coastguard Worker     default:
79*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Unimplemented");
80*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_br24:
81*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_br24abs:
82*9880d681SAndroid Build Coastguard Worker       switch (Modifier) {
83*9880d681SAndroid Build Coastguard Worker       default: llvm_unreachable("Unsupported Modifier");
84*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_None:
85*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_REL24;
86*9880d681SAndroid Build Coastguard Worker         break;
87*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PLT:
88*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_PLTREL24;
89*9880d681SAndroid Build Coastguard Worker         break;
90*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_LOCAL:
91*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_LOCAL24PC;
92*9880d681SAndroid Build Coastguard Worker         break;
93*9880d681SAndroid Build Coastguard Worker       }
94*9880d681SAndroid Build Coastguard Worker       break;
95*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_brcond14:
96*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_brcond14abs:
97*9880d681SAndroid Build Coastguard Worker       Type = ELF::R_PPC_REL14;
98*9880d681SAndroid Build Coastguard Worker       break;
99*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_half16:
100*9880d681SAndroid Build Coastguard Worker       switch (Modifier) {
101*9880d681SAndroid Build Coastguard Worker       default: llvm_unreachable("Unsupported Modifier");
102*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_None:
103*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_REL16;
104*9880d681SAndroid Build Coastguard Worker         break;
105*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_LO:
106*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_REL16_LO;
107*9880d681SAndroid Build Coastguard Worker         break;
108*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_HI:
109*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_REL16_HI;
110*9880d681SAndroid Build Coastguard Worker         break;
111*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_HA:
112*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_REL16_HA;
113*9880d681SAndroid Build Coastguard Worker         break;
114*9880d681SAndroid Build Coastguard Worker       }
115*9880d681SAndroid Build Coastguard Worker       break;
116*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_half16ds:
117*9880d681SAndroid Build Coastguard Worker       Target.print(errs());
118*9880d681SAndroid Build Coastguard Worker       errs() << '\n';
119*9880d681SAndroid Build Coastguard Worker       report_fatal_error("Invalid PC-relative half16ds relocation");
120*9880d681SAndroid Build Coastguard Worker     case FK_Data_4:
121*9880d681SAndroid Build Coastguard Worker     case FK_PCRel_4:
122*9880d681SAndroid Build Coastguard Worker       Type = ELF::R_PPC_REL32;
123*9880d681SAndroid Build Coastguard Worker       break;
124*9880d681SAndroid Build Coastguard Worker     case FK_Data_8:
125*9880d681SAndroid Build Coastguard Worker     case FK_PCRel_8:
126*9880d681SAndroid Build Coastguard Worker       Type = ELF::R_PPC64_REL64;
127*9880d681SAndroid Build Coastguard Worker       break;
128*9880d681SAndroid Build Coastguard Worker     }
129*9880d681SAndroid Build Coastguard Worker   } else {
130*9880d681SAndroid Build Coastguard Worker     switch ((unsigned)Fixup.getKind()) {
131*9880d681SAndroid Build Coastguard Worker       default: llvm_unreachable("invalid fixup kind!");
132*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_br24abs:
133*9880d681SAndroid Build Coastguard Worker       Type = ELF::R_PPC_ADDR24;
134*9880d681SAndroid Build Coastguard Worker       break;
135*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_brcond14abs:
136*9880d681SAndroid Build Coastguard Worker       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
137*9880d681SAndroid Build Coastguard Worker       break;
138*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_half16:
139*9880d681SAndroid Build Coastguard Worker       switch (Modifier) {
140*9880d681SAndroid Build Coastguard Worker       default: llvm_unreachable("Unsupported Modifier");
141*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_None:
142*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_ADDR16;
143*9880d681SAndroid Build Coastguard Worker         break;
144*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_LO:
145*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_ADDR16_LO;
146*9880d681SAndroid Build Coastguard Worker         break;
147*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_HI:
148*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_ADDR16_HI;
149*9880d681SAndroid Build Coastguard Worker         break;
150*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_HA:
151*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_ADDR16_HA;
152*9880d681SAndroid Build Coastguard Worker         break;
153*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_HIGHER:
154*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_ADDR16_HIGHER;
155*9880d681SAndroid Build Coastguard Worker         break;
156*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_HIGHERA:
157*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_ADDR16_HIGHERA;
158*9880d681SAndroid Build Coastguard Worker         break;
159*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_HIGHEST:
160*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_ADDR16_HIGHEST;
161*9880d681SAndroid Build Coastguard Worker         break;
162*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
163*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
164*9880d681SAndroid Build Coastguard Worker         break;
165*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_GOT:
166*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_GOT16;
167*9880d681SAndroid Build Coastguard Worker         break;
168*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_LO:
169*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_GOT16_LO;
170*9880d681SAndroid Build Coastguard Worker         break;
171*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_HI:
172*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_GOT16_HI;
173*9880d681SAndroid Build Coastguard Worker         break;
174*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_HA:
175*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_GOT16_HA;
176*9880d681SAndroid Build Coastguard Worker         break;
177*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TOC:
178*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TOC16;
179*9880d681SAndroid Build Coastguard Worker         break;
180*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TOC_LO:
181*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TOC16_LO;
182*9880d681SAndroid Build Coastguard Worker         break;
183*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TOC_HI:
184*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TOC16_HI;
185*9880d681SAndroid Build Coastguard Worker         break;
186*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TOC_HA:
187*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TOC16_HA;
188*9880d681SAndroid Build Coastguard Worker         break;
189*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_TPREL:
190*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_TPREL16;
191*9880d681SAndroid Build Coastguard Worker         break;
192*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
193*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_TPREL16_LO;
194*9880d681SAndroid Build Coastguard Worker         break;
195*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
196*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_TPREL16_HI;
197*9880d681SAndroid Build Coastguard Worker         break;
198*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
199*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC_TPREL16_HA;
200*9880d681SAndroid Build Coastguard Worker         break;
201*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
202*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TPREL16_HIGHER;
203*9880d681SAndroid Build Coastguard Worker         break;
204*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
205*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TPREL16_HIGHERA;
206*9880d681SAndroid Build Coastguard Worker         break;
207*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
208*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TPREL16_HIGHEST;
209*9880d681SAndroid Build Coastguard Worker         break;
210*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
211*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
212*9880d681SAndroid Build Coastguard Worker         break;
213*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_DTPREL:
214*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16;
215*9880d681SAndroid Build Coastguard Worker         break;
216*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
217*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16_LO;
218*9880d681SAndroid Build Coastguard Worker         break;
219*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
220*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16_HI;
221*9880d681SAndroid Build Coastguard Worker         break;
222*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
223*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16_HA;
224*9880d681SAndroid Build Coastguard Worker         break;
225*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
226*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16_HIGHER;
227*9880d681SAndroid Build Coastguard Worker         break;
228*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
229*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
230*9880d681SAndroid Build Coastguard Worker         break;
231*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
232*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
233*9880d681SAndroid Build Coastguard Worker         break;
234*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
235*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
236*9880d681SAndroid Build Coastguard Worker         break;
237*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
238*9880d681SAndroid Build Coastguard Worker         if (is64Bit())
239*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC64_GOT_TLSGD16;
240*9880d681SAndroid Build Coastguard Worker         else
241*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC_GOT_TLSGD16;
242*9880d681SAndroid Build Coastguard Worker         break;
243*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
244*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
245*9880d681SAndroid Build Coastguard Worker         break;
246*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
247*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
248*9880d681SAndroid Build Coastguard Worker         break;
249*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
250*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
251*9880d681SAndroid Build Coastguard Worker         break;
252*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
253*9880d681SAndroid Build Coastguard Worker         if (is64Bit())
254*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC64_GOT_TLSLD16;
255*9880d681SAndroid Build Coastguard Worker         else
256*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC_GOT_TLSLD16;
257*9880d681SAndroid Build Coastguard Worker         break;
258*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
259*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
260*9880d681SAndroid Build Coastguard Worker         break;
261*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
262*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
263*9880d681SAndroid Build Coastguard Worker         break;
264*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
265*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
266*9880d681SAndroid Build Coastguard Worker         break;
267*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
268*9880d681SAndroid Build Coastguard Worker         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
269*9880d681SAndroid Build Coastguard Worker            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
270*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TPREL16_DS;
271*9880d681SAndroid Build Coastguard Worker         break;
272*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
273*9880d681SAndroid Build Coastguard Worker         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
274*9880d681SAndroid Build Coastguard Worker            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
275*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
276*9880d681SAndroid Build Coastguard Worker         break;
277*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
278*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TPREL16_HI;
279*9880d681SAndroid Build Coastguard Worker         break;
280*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
281*9880d681SAndroid Build Coastguard Worker         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
282*9880d681SAndroid Build Coastguard Worker            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
283*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
284*9880d681SAndroid Build Coastguard Worker         break;
285*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
286*9880d681SAndroid Build Coastguard Worker         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
287*9880d681SAndroid Build Coastguard Worker            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
288*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
289*9880d681SAndroid Build Coastguard Worker         break;
290*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
291*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TPREL16_HA;
292*9880d681SAndroid Build Coastguard Worker         break;
293*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
294*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
295*9880d681SAndroid Build Coastguard Worker         break;
296*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
297*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
298*9880d681SAndroid Build Coastguard Worker         break;
299*9880d681SAndroid Build Coastguard Worker       }
300*9880d681SAndroid Build Coastguard Worker       break;
301*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_half16ds:
302*9880d681SAndroid Build Coastguard Worker       switch (Modifier) {
303*9880d681SAndroid Build Coastguard Worker       default: llvm_unreachable("Unsupported Modifier");
304*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_None:
305*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_ADDR16_DS;
306*9880d681SAndroid Build Coastguard Worker         break;
307*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_LO:
308*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_ADDR16_LO_DS;
309*9880d681SAndroid Build Coastguard Worker         break;
310*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_GOT:
311*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT16_DS;
312*9880d681SAndroid Build Coastguard Worker         break;
313*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_LO:
314*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT16_LO_DS;
315*9880d681SAndroid Build Coastguard Worker         break;
316*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TOC:
317*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TOC16_DS;
318*9880d681SAndroid Build Coastguard Worker         break;
319*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TOC_LO:
320*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TOC16_LO_DS;
321*9880d681SAndroid Build Coastguard Worker         break;
322*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_TPREL:
323*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TPREL16_DS;
324*9880d681SAndroid Build Coastguard Worker         break;
325*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
326*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TPREL16_LO_DS;
327*9880d681SAndroid Build Coastguard Worker         break;
328*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_DTPREL:
329*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16_DS;
330*9880d681SAndroid Build Coastguard Worker         break;
331*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
332*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL16_LO_DS;
333*9880d681SAndroid Build Coastguard Worker         break;
334*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
335*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TPREL16_DS;
336*9880d681SAndroid Build Coastguard Worker         break;
337*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
338*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
339*9880d681SAndroid Build Coastguard Worker         break;
340*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
341*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
342*9880d681SAndroid Build Coastguard Worker         break;
343*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
344*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
345*9880d681SAndroid Build Coastguard Worker         break;
346*9880d681SAndroid Build Coastguard Worker       }
347*9880d681SAndroid Build Coastguard Worker       break;
348*9880d681SAndroid Build Coastguard Worker     case PPC::fixup_ppc_nofixup:
349*9880d681SAndroid Build Coastguard Worker       switch (Modifier) {
350*9880d681SAndroid Build Coastguard Worker       default: llvm_unreachable("Unsupported Modifier");
351*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TLSGD:
352*9880d681SAndroid Build Coastguard Worker         if (is64Bit())
353*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC64_TLSGD;
354*9880d681SAndroid Build Coastguard Worker         else
355*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC_TLSGD;
356*9880d681SAndroid Build Coastguard Worker         break;
357*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TLSLD:
358*9880d681SAndroid Build Coastguard Worker         if (is64Bit())
359*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC64_TLSLD;
360*9880d681SAndroid Build Coastguard Worker         else
361*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC_TLSLD;
362*9880d681SAndroid Build Coastguard Worker         break;
363*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TLS:
364*9880d681SAndroid Build Coastguard Worker         if (is64Bit())
365*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC64_TLS;
366*9880d681SAndroid Build Coastguard Worker         else
367*9880d681SAndroid Build Coastguard Worker           Type = ELF::R_PPC_TLS;
368*9880d681SAndroid Build Coastguard Worker         break;
369*9880d681SAndroid Build Coastguard Worker       }
370*9880d681SAndroid Build Coastguard Worker       break;
371*9880d681SAndroid Build Coastguard Worker     case FK_Data_8:
372*9880d681SAndroid Build Coastguard Worker       switch (Modifier) {
373*9880d681SAndroid Build Coastguard Worker       default: llvm_unreachable("Unsupported Modifier");
374*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_TOCBASE:
375*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TOC;
376*9880d681SAndroid Build Coastguard Worker         break;
377*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_None:
378*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_ADDR64;
379*9880d681SAndroid Build Coastguard Worker         break;
380*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_PPC_DTPMOD:
381*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPMOD64;
382*9880d681SAndroid Build Coastguard Worker         break;
383*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_TPREL:
384*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_TPREL64;
385*9880d681SAndroid Build Coastguard Worker         break;
386*9880d681SAndroid Build Coastguard Worker       case MCSymbolRefExpr::VK_DTPREL:
387*9880d681SAndroid Build Coastguard Worker         Type = ELF::R_PPC64_DTPREL64;
388*9880d681SAndroid Build Coastguard Worker         break;
389*9880d681SAndroid Build Coastguard Worker       }
390*9880d681SAndroid Build Coastguard Worker       break;
391*9880d681SAndroid Build Coastguard Worker     case FK_Data_4:
392*9880d681SAndroid Build Coastguard Worker       Type = ELF::R_PPC_ADDR32;
393*9880d681SAndroid Build Coastguard Worker       break;
394*9880d681SAndroid Build Coastguard Worker     case FK_Data_2:
395*9880d681SAndroid Build Coastguard Worker       Type = ELF::R_PPC_ADDR16;
396*9880d681SAndroid Build Coastguard Worker       break;
397*9880d681SAndroid Build Coastguard Worker     }
398*9880d681SAndroid Build Coastguard Worker   }
399*9880d681SAndroid Build Coastguard Worker   return Type;
400*9880d681SAndroid Build Coastguard Worker }
401*9880d681SAndroid Build Coastguard Worker 
needsRelocateWithSymbol(const MCSymbol & Sym,unsigned Type) const402*9880d681SAndroid Build Coastguard Worker bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
403*9880d681SAndroid Build Coastguard Worker                                                  unsigned Type) const {
404*9880d681SAndroid Build Coastguard Worker   switch (Type) {
405*9880d681SAndroid Build Coastguard Worker     default:
406*9880d681SAndroid Build Coastguard Worker       return false;
407*9880d681SAndroid Build Coastguard Worker 
408*9880d681SAndroid Build Coastguard Worker     case ELF::R_PPC_REL24:
409*9880d681SAndroid Build Coastguard Worker       // If the target symbol has a local entry point, we must keep the
410*9880d681SAndroid Build Coastguard Worker       // target symbol to preserve that information for the linker.
411*9880d681SAndroid Build Coastguard Worker       // The "other" values are stored in the last 6 bits of the second byte.
412*9880d681SAndroid Build Coastguard Worker       // The traditional defines for STO values assume the full byte and thus
413*9880d681SAndroid Build Coastguard Worker       // the shift to pack it.
414*9880d681SAndroid Build Coastguard Worker       unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
415*9880d681SAndroid Build Coastguard Worker       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
416*9880d681SAndroid Build Coastguard Worker   }
417*9880d681SAndroid Build Coastguard Worker }
418*9880d681SAndroid Build Coastguard Worker 
createPPCELFObjectWriter(raw_pwrite_stream & OS,bool Is64Bit,bool IsLittleEndian,uint8_t OSABI)419*9880d681SAndroid Build Coastguard Worker MCObjectWriter *llvm::createPPCELFObjectWriter(raw_pwrite_stream &OS,
420*9880d681SAndroid Build Coastguard Worker                                                bool Is64Bit,
421*9880d681SAndroid Build Coastguard Worker                                                bool IsLittleEndian,
422*9880d681SAndroid Build Coastguard Worker                                                uint8_t OSABI) {
423*9880d681SAndroid Build Coastguard Worker   MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI);
424*9880d681SAndroid Build Coastguard Worker   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
425*9880d681SAndroid Build Coastguard Worker }
426