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