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 { 765ffd83dbSDimitry Andric MCFixupKind Kind = Fixup.getKind(); 775ffd83dbSDimitry Andric if (Kind >= FirstLiteralRelocationKind) 785ffd83dbSDimitry Andric return Kind - FirstLiteralRelocationKind; 79*0b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup); 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric // determine the type of the relocation 82*0b57cec5SDimitry Andric unsigned Type; 83*0b57cec5SDimitry Andric if (IsPCRel) { 848bcb0991SDimitry Andric switch (Fixup.getTargetKind()) { 85*0b57cec5SDimitry Andric default: 86*0b57cec5SDimitry Andric llvm_unreachable("Unimplemented"); 87*0b57cec5SDimitry Andric case PPC::fixup_ppc_br24: 88*0b57cec5SDimitry Andric case PPC::fixup_ppc_br24abs: 895ffd83dbSDimitry Andric case PPC::fixup_ppc_br24_notoc: 90*0b57cec5SDimitry Andric switch (Modifier) { 91*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 92*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 93*0b57cec5SDimitry Andric Type = ELF::R_PPC_REL24; 94*0b57cec5SDimitry Andric break; 95*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PLT: 96*0b57cec5SDimitry Andric Type = ELF::R_PPC_PLTREL24; 97*0b57cec5SDimitry Andric break; 98*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LOCAL: 99*0b57cec5SDimitry Andric Type = ELF::R_PPC_LOCAL24PC; 100*0b57cec5SDimitry Andric break; 1015ffd83dbSDimitry Andric case MCSymbolRefExpr::VK_PPC_NOTOC: 1025ffd83dbSDimitry Andric Type = ELF::R_PPC64_REL24_NOTOC; 1035ffd83dbSDimitry Andric break; 104*0b57cec5SDimitry Andric } 105*0b57cec5SDimitry Andric break; 106*0b57cec5SDimitry Andric case PPC::fixup_ppc_brcond14: 107*0b57cec5SDimitry Andric case PPC::fixup_ppc_brcond14abs: 108*0b57cec5SDimitry Andric Type = ELF::R_PPC_REL14; 109*0b57cec5SDimitry Andric break; 110*0b57cec5SDimitry Andric case PPC::fixup_ppc_half16: 111*0b57cec5SDimitry Andric switch (Modifier) { 112*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 113*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 114*0b57cec5SDimitry Andric Type = ELF::R_PPC_REL16; 115*0b57cec5SDimitry Andric break; 116*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO: 117*0b57cec5SDimitry Andric Type = ELF::R_PPC_REL16_LO; 118*0b57cec5SDimitry Andric break; 119*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HI: 120*0b57cec5SDimitry Andric Type = ELF::R_PPC_REL16_HI; 121*0b57cec5SDimitry Andric break; 122*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HA: 123*0b57cec5SDimitry Andric Type = ELF::R_PPC_REL16_HA; 124*0b57cec5SDimitry Andric break; 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric break; 127*0b57cec5SDimitry Andric case PPC::fixup_ppc_half16ds: 128*0b57cec5SDimitry Andric Target.print(errs()); 129*0b57cec5SDimitry Andric errs() << '\n'; 130*0b57cec5SDimitry Andric report_fatal_error("Invalid PC-relative half16ds relocation"); 1315ffd83dbSDimitry Andric case PPC::fixup_ppc_pcrel34: 1325ffd83dbSDimitry Andric switch (Modifier) { 1335ffd83dbSDimitry Andric default: 1345ffd83dbSDimitry Andric llvm_unreachable("Unsupported Modifier for fixup_ppc_pcrel34"); 1355ffd83dbSDimitry Andric case MCSymbolRefExpr::VK_PCREL: 1365ffd83dbSDimitry Andric Type = ELF::R_PPC64_PCREL34; 1375ffd83dbSDimitry Andric break; 1385ffd83dbSDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_PCREL: 1395ffd83dbSDimitry Andric Type = ELF::R_PPC64_GOT_PCREL34; 1405ffd83dbSDimitry Andric break; 1415ffd83dbSDimitry Andric } 1425ffd83dbSDimitry Andric break; 143*0b57cec5SDimitry Andric case FK_Data_4: 144*0b57cec5SDimitry Andric case FK_PCRel_4: 145*0b57cec5SDimitry Andric Type = ELF::R_PPC_REL32; 146*0b57cec5SDimitry Andric break; 147*0b57cec5SDimitry Andric case FK_Data_8: 148*0b57cec5SDimitry Andric case FK_PCRel_8: 149*0b57cec5SDimitry Andric Type = ELF::R_PPC64_REL64; 150*0b57cec5SDimitry Andric break; 151*0b57cec5SDimitry Andric } 152*0b57cec5SDimitry Andric } else { 1538bcb0991SDimitry Andric switch (Fixup.getTargetKind()) { 154*0b57cec5SDimitry Andric default: llvm_unreachable("invalid fixup kind!"); 155*0b57cec5SDimitry Andric case PPC::fixup_ppc_br24abs: 156*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR24; 157*0b57cec5SDimitry Andric break; 158*0b57cec5SDimitry Andric case PPC::fixup_ppc_brcond14abs: 159*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ 160*0b57cec5SDimitry Andric break; 161*0b57cec5SDimitry Andric case PPC::fixup_ppc_half16: 162*0b57cec5SDimitry Andric switch (Modifier) { 163*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 164*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 165*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16; 166*0b57cec5SDimitry Andric break; 167*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO: 168*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16_LO; 169*0b57cec5SDimitry Andric break; 170*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HI: 171*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16_HI; 172*0b57cec5SDimitry Andric break; 173*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HA: 174*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16_HA; 175*0b57cec5SDimitry Andric break; 176*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGH: 177*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGH; 178*0b57cec5SDimitry Andric break; 179*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHA: 180*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHA; 181*0b57cec5SDimitry Andric break; 182*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHER: 183*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHER; 184*0b57cec5SDimitry Andric break; 185*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHERA: 186*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHERA; 187*0b57cec5SDimitry Andric break; 188*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHEST: 189*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHEST; 190*0b57cec5SDimitry Andric break; 191*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHESTA: 192*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHESTA; 193*0b57cec5SDimitry Andric break; 194*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT: 195*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16; 196*0b57cec5SDimitry Andric break; 197*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_LO: 198*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16_LO; 199*0b57cec5SDimitry Andric break; 200*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_HI: 201*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16_HI; 202*0b57cec5SDimitry Andric break; 203*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_HA: 204*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16_HA; 205*0b57cec5SDimitry Andric break; 206*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC: 207*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16; 208*0b57cec5SDimitry Andric break; 209*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_LO: 210*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_LO; 211*0b57cec5SDimitry Andric break; 212*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_HI: 213*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_HI; 214*0b57cec5SDimitry Andric break; 215*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_HA: 216*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_HA; 217*0b57cec5SDimitry Andric break; 218*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 219*0b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16; 220*0b57cec5SDimitry Andric break; 221*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_LO: 222*0b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16_LO; 223*0b57cec5SDimitry Andric break; 224*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HI: 225*0b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16_HI; 226*0b57cec5SDimitry Andric break; 227*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HA: 228*0b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16_HA; 229*0b57cec5SDimitry Andric break; 230*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: 231*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGH; 232*0b57cec5SDimitry Andric break; 233*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: 234*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHA; 235*0b57cec5SDimitry Andric break; 236*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: 237*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHER; 238*0b57cec5SDimitry Andric break; 239*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: 240*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHERA; 241*0b57cec5SDimitry Andric break; 242*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: 243*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHEST; 244*0b57cec5SDimitry Andric break; 245*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: 246*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHESTA; 247*0b57cec5SDimitry Andric break; 248*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 249*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16; 250*0b57cec5SDimitry Andric break; 251*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 252*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_LO; 253*0b57cec5SDimitry Andric break; 254*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HI: 255*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HI; 256*0b57cec5SDimitry Andric break; 257*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HA: 258*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HA; 259*0b57cec5SDimitry Andric break; 260*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: 261*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGH; 262*0b57cec5SDimitry Andric break; 263*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: 264*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHA; 265*0b57cec5SDimitry Andric break; 266*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: 267*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHER; 268*0b57cec5SDimitry Andric break; 269*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: 270*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHERA; 271*0b57cec5SDimitry Andric break; 272*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: 273*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHEST; 274*0b57cec5SDimitry Andric break; 275*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: 276*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHESTA; 277*0b57cec5SDimitry Andric break; 278*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: 279*0b57cec5SDimitry Andric if (is64Bit()) 280*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16; 281*0b57cec5SDimitry Andric else 282*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT_TLSGD16; 283*0b57cec5SDimitry Andric break; 284*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: 285*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16_LO; 286*0b57cec5SDimitry Andric break; 287*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: 288*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16_HI; 289*0b57cec5SDimitry Andric break; 290*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: 291*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16_HA; 292*0b57cec5SDimitry Andric break; 293*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: 294*0b57cec5SDimitry Andric if (is64Bit()) 295*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16; 296*0b57cec5SDimitry Andric else 297*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT_TLSLD16; 298*0b57cec5SDimitry Andric break; 299*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: 300*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16_LO; 301*0b57cec5SDimitry Andric break; 302*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: 303*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16_HI; 304*0b57cec5SDimitry Andric break; 305*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: 306*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16_HA; 307*0b57cec5SDimitry Andric break; 308*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 309*0b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets 310*0b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ 311*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_DS; 312*0b57cec5SDimitry Andric break; 313*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 314*0b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets 315*0b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ 316*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 317*0b57cec5SDimitry Andric break; 318*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: 319*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_HI; 320*0b57cec5SDimitry Andric break; 321*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 322*0b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets 323*0b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ 324*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_DS; 325*0b57cec5SDimitry Andric break; 326*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 327*0b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets 328*0b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ 329*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 330*0b57cec5SDimitry Andric break; 331*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: 332*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_HA; 333*0b57cec5SDimitry Andric break; 334*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: 335*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_HI; 336*0b57cec5SDimitry Andric break; 337*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: 338*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_HA; 339*0b57cec5SDimitry Andric break; 340*0b57cec5SDimitry Andric } 341*0b57cec5SDimitry Andric break; 342*0b57cec5SDimitry Andric case PPC::fixup_ppc_half16ds: 343*0b57cec5SDimitry Andric switch (Modifier) { 344*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 345*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 346*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_DS; 347*0b57cec5SDimitry Andric break; 348*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO: 349*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_LO_DS; 350*0b57cec5SDimitry Andric break; 351*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT: 352*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT16_DS; 353*0b57cec5SDimitry Andric break; 354*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_LO: 355*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT16_LO_DS; 356*0b57cec5SDimitry Andric break; 357*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC: 358*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_DS; 359*0b57cec5SDimitry Andric break; 360*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_LO: 361*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_LO_DS; 362*0b57cec5SDimitry Andric break; 363*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 364*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_DS; 365*0b57cec5SDimitry Andric break; 366*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_LO: 367*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_LO_DS; 368*0b57cec5SDimitry Andric break; 369*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 370*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_DS; 371*0b57cec5SDimitry Andric break; 372*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 373*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_LO_DS; 374*0b57cec5SDimitry Andric break; 375*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 376*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_DS; 377*0b57cec5SDimitry Andric break; 378*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 379*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 380*0b57cec5SDimitry Andric break; 381*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 382*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_DS; 383*0b57cec5SDimitry Andric break; 384*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 385*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 386*0b57cec5SDimitry Andric break; 387*0b57cec5SDimitry Andric } 388*0b57cec5SDimitry Andric break; 389*0b57cec5SDimitry Andric case PPC::fixup_ppc_nofixup: 390*0b57cec5SDimitry Andric switch (Modifier) { 391*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 392*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLSGD: 393*0b57cec5SDimitry Andric if (is64Bit()) 394*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TLSGD; 395*0b57cec5SDimitry Andric else 396*0b57cec5SDimitry Andric Type = ELF::R_PPC_TLSGD; 397*0b57cec5SDimitry Andric break; 398*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLSLD: 399*0b57cec5SDimitry Andric if (is64Bit()) 400*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TLSLD; 401*0b57cec5SDimitry Andric else 402*0b57cec5SDimitry Andric Type = ELF::R_PPC_TLSLD; 403*0b57cec5SDimitry Andric break; 404*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLS: 405*0b57cec5SDimitry Andric if (is64Bit()) 406*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TLS; 407*0b57cec5SDimitry Andric else 408*0b57cec5SDimitry Andric Type = ELF::R_PPC_TLS; 409*0b57cec5SDimitry Andric break; 410*0b57cec5SDimitry Andric } 411*0b57cec5SDimitry Andric break; 412*0b57cec5SDimitry Andric case FK_Data_8: 413*0b57cec5SDimitry Andric switch (Modifier) { 414*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 415*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOCBASE: 416*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC; 417*0b57cec5SDimitry Andric break; 418*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 419*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR64; 420*0b57cec5SDimitry Andric break; 421*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPMOD: 422*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPMOD64; 423*0b57cec5SDimitry Andric break; 424*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 425*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL64; 426*0b57cec5SDimitry Andric break; 427*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 428*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL64; 429*0b57cec5SDimitry Andric break; 430*0b57cec5SDimitry Andric } 431*0b57cec5SDimitry Andric break; 432*0b57cec5SDimitry Andric case FK_Data_4: 433*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR32; 434*0b57cec5SDimitry Andric break; 435*0b57cec5SDimitry Andric case FK_Data_2: 436*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16; 437*0b57cec5SDimitry Andric break; 438*0b57cec5SDimitry Andric } 439*0b57cec5SDimitry Andric } 440*0b57cec5SDimitry Andric return Type; 441*0b57cec5SDimitry Andric } 442*0b57cec5SDimitry Andric 443*0b57cec5SDimitry Andric bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, 444*0b57cec5SDimitry Andric unsigned Type) const { 445*0b57cec5SDimitry Andric switch (Type) { 446*0b57cec5SDimitry Andric default: 447*0b57cec5SDimitry Andric return false; 448*0b57cec5SDimitry Andric 449*0b57cec5SDimitry Andric case ELF::R_PPC_REL24: 4505ffd83dbSDimitry Andric case ELF::R_PPC64_REL24_NOTOC: 451*0b57cec5SDimitry Andric // If the target symbol has a local entry point, we must keep the 452*0b57cec5SDimitry Andric // target symbol to preserve that information for the linker. 453*0b57cec5SDimitry Andric // The "other" values are stored in the last 6 bits of the second byte. 454*0b57cec5SDimitry Andric // The traditional defines for STO values assume the full byte and thus 455*0b57cec5SDimitry Andric // the shift to pack it. 456*0b57cec5SDimitry Andric unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2; 457*0b57cec5SDimitry Andric return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0; 458*0b57cec5SDimitry Andric } 459*0b57cec5SDimitry Andric } 460*0b57cec5SDimitry Andric 461*0b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter> 462*0b57cec5SDimitry Andric llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) { 4638bcb0991SDimitry Andric return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI); 464*0b57cec5SDimitry Andric } 465