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; 141e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL: 142e8d8bef9SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD_PCREL34; 143e8d8bef9SDimitry Andric break; 144e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL: 145e8d8bef9SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD_PCREL34; 146e8d8bef9SDimitry Andric break; 147e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL: 148e8d8bef9SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL_PCREL34; 149e8d8bef9SDimitry Andric break; 1505ffd83dbSDimitry Andric } 1515ffd83dbSDimitry Andric break; 152*0b57cec5SDimitry Andric case FK_Data_4: 153*0b57cec5SDimitry Andric case FK_PCRel_4: 154*0b57cec5SDimitry Andric Type = ELF::R_PPC_REL32; 155*0b57cec5SDimitry Andric break; 156*0b57cec5SDimitry Andric case FK_Data_8: 157*0b57cec5SDimitry Andric case FK_PCRel_8: 158*0b57cec5SDimitry Andric Type = ELF::R_PPC64_REL64; 159*0b57cec5SDimitry Andric break; 160*0b57cec5SDimitry Andric } 161*0b57cec5SDimitry Andric } else { 1628bcb0991SDimitry Andric switch (Fixup.getTargetKind()) { 163*0b57cec5SDimitry Andric default: llvm_unreachable("invalid fixup kind!"); 164*0b57cec5SDimitry Andric case PPC::fixup_ppc_br24abs: 165*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR24; 166*0b57cec5SDimitry Andric break; 167*0b57cec5SDimitry Andric case PPC::fixup_ppc_brcond14abs: 168*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ 169*0b57cec5SDimitry Andric break; 170*0b57cec5SDimitry Andric case PPC::fixup_ppc_half16: 171*0b57cec5SDimitry Andric switch (Modifier) { 172*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 173*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 174*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16; 175*0b57cec5SDimitry Andric break; 176*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO: 177*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16_LO; 178*0b57cec5SDimitry Andric break; 179*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HI: 180*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16_HI; 181*0b57cec5SDimitry Andric break; 182*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HA: 183*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16_HA; 184*0b57cec5SDimitry Andric break; 185*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGH: 186*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGH; 187*0b57cec5SDimitry Andric break; 188*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHA: 189*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHA; 190*0b57cec5SDimitry Andric break; 191*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHER: 192*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHER; 193*0b57cec5SDimitry Andric break; 194*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHERA: 195*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHERA; 196*0b57cec5SDimitry Andric break; 197*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHEST: 198*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHEST; 199*0b57cec5SDimitry Andric break; 200*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHESTA: 201*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHESTA; 202*0b57cec5SDimitry Andric break; 203*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT: 204*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16; 205*0b57cec5SDimitry Andric break; 206*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_LO: 207*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16_LO; 208*0b57cec5SDimitry Andric break; 209*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_HI: 210*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16_HI; 211*0b57cec5SDimitry Andric break; 212*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_HA: 213*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16_HA; 214*0b57cec5SDimitry Andric break; 215*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC: 216*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16; 217*0b57cec5SDimitry Andric break; 218*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_LO: 219*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_LO; 220*0b57cec5SDimitry Andric break; 221*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_HI: 222*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_HI; 223*0b57cec5SDimitry Andric break; 224*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_HA: 225*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_HA; 226*0b57cec5SDimitry Andric break; 227*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 228*0b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16; 229*0b57cec5SDimitry Andric break; 230*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_LO: 231*0b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16_LO; 232*0b57cec5SDimitry Andric break; 233*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HI: 234*0b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16_HI; 235*0b57cec5SDimitry Andric break; 236*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HA: 237*0b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16_HA; 238*0b57cec5SDimitry Andric break; 239*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: 240*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGH; 241*0b57cec5SDimitry Andric break; 242*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: 243*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHA; 244*0b57cec5SDimitry Andric break; 245*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: 246*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHER; 247*0b57cec5SDimitry Andric break; 248*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: 249*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHERA; 250*0b57cec5SDimitry Andric break; 251*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: 252*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHEST; 253*0b57cec5SDimitry Andric break; 254*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: 255*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHESTA; 256*0b57cec5SDimitry Andric break; 257*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 258*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16; 259*0b57cec5SDimitry Andric break; 260*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 261*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_LO; 262*0b57cec5SDimitry Andric break; 263*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HI: 264*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HI; 265*0b57cec5SDimitry Andric break; 266*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HA: 267*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HA; 268*0b57cec5SDimitry Andric break; 269*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: 270*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGH; 271*0b57cec5SDimitry Andric break; 272*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: 273*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHA; 274*0b57cec5SDimitry Andric break; 275*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: 276*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHER; 277*0b57cec5SDimitry Andric break; 278*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: 279*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHERA; 280*0b57cec5SDimitry Andric break; 281*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: 282*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHEST; 283*0b57cec5SDimitry Andric break; 284*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: 285*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHESTA; 286*0b57cec5SDimitry Andric break; 287*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: 288*0b57cec5SDimitry Andric if (is64Bit()) 289*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16; 290*0b57cec5SDimitry Andric else 291*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT_TLSGD16; 292*0b57cec5SDimitry Andric break; 293*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: 294*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16_LO; 295*0b57cec5SDimitry Andric break; 296*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: 297*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16_HI; 298*0b57cec5SDimitry Andric break; 299*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: 300*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16_HA; 301*0b57cec5SDimitry Andric break; 302*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: 303*0b57cec5SDimitry Andric if (is64Bit()) 304*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16; 305*0b57cec5SDimitry Andric else 306*0b57cec5SDimitry Andric Type = ELF::R_PPC_GOT_TLSLD16; 307*0b57cec5SDimitry Andric break; 308*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: 309*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16_LO; 310*0b57cec5SDimitry Andric break; 311*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: 312*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16_HI; 313*0b57cec5SDimitry Andric break; 314*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: 315*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16_HA; 316*0b57cec5SDimitry Andric break; 317*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 318*0b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets 319*0b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ 320*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_DS; 321*0b57cec5SDimitry Andric break; 322*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 323*0b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets 324*0b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ 325*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 326*0b57cec5SDimitry Andric break; 327*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: 328*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_HI; 329*0b57cec5SDimitry Andric break; 330*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 331*0b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets 332*0b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ 333*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_DS; 334*0b57cec5SDimitry Andric break; 335*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 336*0b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets 337*0b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ 338*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 339*0b57cec5SDimitry Andric break; 340*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: 341*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_HA; 342*0b57cec5SDimitry Andric break; 343*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: 344*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_HI; 345*0b57cec5SDimitry Andric break; 346*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: 347*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_HA; 348*0b57cec5SDimitry Andric break; 349*0b57cec5SDimitry Andric } 350*0b57cec5SDimitry Andric break; 351*0b57cec5SDimitry Andric case PPC::fixup_ppc_half16ds: 352*0b57cec5SDimitry Andric switch (Modifier) { 353*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 354*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 355*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_DS; 356*0b57cec5SDimitry Andric break; 357*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO: 358*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_LO_DS; 359*0b57cec5SDimitry Andric break; 360*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT: 361*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT16_DS; 362*0b57cec5SDimitry Andric break; 363*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_LO: 364*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT16_LO_DS; 365*0b57cec5SDimitry Andric break; 366*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC: 367*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_DS; 368*0b57cec5SDimitry Andric break; 369*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_LO: 370*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_LO_DS; 371*0b57cec5SDimitry Andric break; 372*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 373*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_DS; 374*0b57cec5SDimitry Andric break; 375*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_LO: 376*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_LO_DS; 377*0b57cec5SDimitry Andric break; 378*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 379*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_DS; 380*0b57cec5SDimitry Andric break; 381*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 382*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_LO_DS; 383*0b57cec5SDimitry Andric break; 384*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 385*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_DS; 386*0b57cec5SDimitry Andric break; 387*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 388*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 389*0b57cec5SDimitry Andric break; 390*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 391*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_DS; 392*0b57cec5SDimitry Andric break; 393*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 394*0b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 395*0b57cec5SDimitry Andric break; 396*0b57cec5SDimitry Andric } 397*0b57cec5SDimitry Andric break; 398*0b57cec5SDimitry Andric case PPC::fixup_ppc_nofixup: 399*0b57cec5SDimitry Andric switch (Modifier) { 400*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 401*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLSGD: 402*0b57cec5SDimitry Andric if (is64Bit()) 403*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TLSGD; 404*0b57cec5SDimitry Andric else 405*0b57cec5SDimitry Andric Type = ELF::R_PPC_TLSGD; 406*0b57cec5SDimitry Andric break; 407*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLSLD: 408*0b57cec5SDimitry Andric if (is64Bit()) 409*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TLSLD; 410*0b57cec5SDimitry Andric else 411*0b57cec5SDimitry Andric Type = ELF::R_PPC_TLSLD; 412*0b57cec5SDimitry Andric break; 413*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLS: 414*0b57cec5SDimitry Andric if (is64Bit()) 415*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TLS; 416*0b57cec5SDimitry Andric else 417*0b57cec5SDimitry Andric Type = ELF::R_PPC_TLS; 418*0b57cec5SDimitry Andric break; 419e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLS_PCREL: 420e8d8bef9SDimitry Andric Type = ELF::R_PPC64_TLS; 421e8d8bef9SDimitry Andric break; 422e8d8bef9SDimitry Andric } 423e8d8bef9SDimitry Andric break; 424e8d8bef9SDimitry Andric case PPC::fixup_ppc_imm34: 425e8d8bef9SDimitry Andric switch (Modifier) { 426e8d8bef9SDimitry Andric default: 427e8d8bef9SDimitry Andric report_fatal_error("Unsupported Modifier for fixup_ppc_imm34."); 428e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 429e8d8bef9SDimitry Andric Type = ELF::R_PPC64_DTPREL34; 430e8d8bef9SDimitry Andric break; 431e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 432e8d8bef9SDimitry Andric Type = ELF::R_PPC64_TPREL34; 433e8d8bef9SDimitry Andric break; 434*0b57cec5SDimitry Andric } 435*0b57cec5SDimitry Andric break; 436*0b57cec5SDimitry Andric case FK_Data_8: 437*0b57cec5SDimitry Andric switch (Modifier) { 438*0b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 439*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOCBASE: 440*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC; 441*0b57cec5SDimitry Andric break; 442*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 443*0b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR64; 444*0b57cec5SDimitry Andric break; 445*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPMOD: 446*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPMOD64; 447*0b57cec5SDimitry Andric break; 448*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 449*0b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL64; 450*0b57cec5SDimitry Andric break; 451*0b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 452*0b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL64; 453*0b57cec5SDimitry Andric break; 454*0b57cec5SDimitry Andric } 455*0b57cec5SDimitry Andric break; 456*0b57cec5SDimitry Andric case FK_Data_4: 457*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR32; 458*0b57cec5SDimitry Andric break; 459*0b57cec5SDimitry Andric case FK_Data_2: 460*0b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16; 461*0b57cec5SDimitry Andric break; 462*0b57cec5SDimitry Andric } 463*0b57cec5SDimitry Andric } 464*0b57cec5SDimitry Andric return Type; 465*0b57cec5SDimitry Andric } 466*0b57cec5SDimitry Andric 467*0b57cec5SDimitry Andric bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, 468*0b57cec5SDimitry Andric unsigned Type) const { 469*0b57cec5SDimitry Andric switch (Type) { 470*0b57cec5SDimitry Andric default: 471*0b57cec5SDimitry Andric return false; 472*0b57cec5SDimitry Andric 473*0b57cec5SDimitry Andric case ELF::R_PPC_REL24: 4745ffd83dbSDimitry Andric case ELF::R_PPC64_REL24_NOTOC: 475*0b57cec5SDimitry Andric // If the target symbol has a local entry point, we must keep the 476*0b57cec5SDimitry Andric // target symbol to preserve that information for the linker. 477*0b57cec5SDimitry Andric // The "other" values are stored in the last 6 bits of the second byte. 478*0b57cec5SDimitry Andric // The traditional defines for STO values assume the full byte and thus 479*0b57cec5SDimitry Andric // the shift to pack it. 480*0b57cec5SDimitry Andric unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2; 481*0b57cec5SDimitry Andric return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0; 482*0b57cec5SDimitry Andric } 483*0b57cec5SDimitry Andric } 484*0b57cec5SDimitry Andric 485*0b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter> 486*0b57cec5SDimitry Andric llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) { 4878bcb0991SDimitry Andric return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI); 488*0b57cec5SDimitry Andric } 489