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