10b57cec5SDimitry Andric //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "MCTargetDesc/PPCFixupKinds.h" 100b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCExpr.h" 110b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h" 120b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 130b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 140b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 180b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric using namespace llvm; 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace { 230b57cec5SDimitry Andric class PPCELFObjectWriter : public MCELFObjectTargetWriter { 240b57cec5SDimitry Andric public: 250b57cec5SDimitry Andric PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI); 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric protected: 280b57cec5SDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 290b57cec5SDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override; 300b57cec5SDimitry Andric 31*5f757f3fSDimitry Andric bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, 320b57cec5SDimitry Andric unsigned Type) const override; 330b57cec5SDimitry Andric }; 340b57cec5SDimitry Andric } 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) 370b57cec5SDimitry Andric : MCELFObjectTargetWriter(Is64Bit, OSABI, 380b57cec5SDimitry Andric Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, 390b57cec5SDimitry Andric /*HasRelocationAddend*/ true) {} 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, 420b57cec5SDimitry Andric const MCFixup &Fixup) { 430b57cec5SDimitry Andric const MCExpr *Expr = Fixup.getValue(); 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric if (Expr->getKind() != MCExpr::Target) 460b57cec5SDimitry Andric return Target.getAccessVariant(); 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric switch (cast<PPCMCExpr>(Expr)->getKind()) { 490b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_None: 500b57cec5SDimitry Andric return MCSymbolRefExpr::VK_None; 510b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_LO: 520b57cec5SDimitry Andric return MCSymbolRefExpr::VK_PPC_LO; 530b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_HI: 540b57cec5SDimitry Andric return MCSymbolRefExpr::VK_PPC_HI; 550b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_HA: 560b57cec5SDimitry Andric return MCSymbolRefExpr::VK_PPC_HA; 570b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_HIGH: 580b57cec5SDimitry Andric return MCSymbolRefExpr::VK_PPC_HIGH; 590b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_HIGHA: 600b57cec5SDimitry Andric return MCSymbolRefExpr::VK_PPC_HIGHA; 610b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_HIGHERA: 620b57cec5SDimitry Andric return MCSymbolRefExpr::VK_PPC_HIGHERA; 630b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_HIGHER: 640b57cec5SDimitry Andric return MCSymbolRefExpr::VK_PPC_HIGHER; 650b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_HIGHEST: 660b57cec5SDimitry Andric return MCSymbolRefExpr::VK_PPC_HIGHEST; 670b57cec5SDimitry Andric case PPCMCExpr::VK_PPC_HIGHESTA: 680b57cec5SDimitry Andric return MCSymbolRefExpr::VK_PPC_HIGHESTA; 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric llvm_unreachable("unknown PPCMCExpr kind"); 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, 740b57cec5SDimitry Andric const MCFixup &Fixup, 750b57cec5SDimitry Andric bool IsPCRel) const { 765ffd83dbSDimitry Andric MCFixupKind Kind = Fixup.getKind(); 775ffd83dbSDimitry Andric if (Kind >= FirstLiteralRelocationKind) 785ffd83dbSDimitry Andric return Kind - FirstLiteralRelocationKind; 790b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup); 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric // determine the type of the relocation 820b57cec5SDimitry Andric unsigned Type; 830b57cec5SDimitry Andric if (IsPCRel) { 848bcb0991SDimitry Andric switch (Fixup.getTargetKind()) { 850b57cec5SDimitry Andric default: 860b57cec5SDimitry Andric llvm_unreachable("Unimplemented"); 870b57cec5SDimitry Andric case PPC::fixup_ppc_br24: 880b57cec5SDimitry Andric case PPC::fixup_ppc_br24abs: 895ffd83dbSDimitry Andric case PPC::fixup_ppc_br24_notoc: 900b57cec5SDimitry Andric switch (Modifier) { 910b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 920b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 930b57cec5SDimitry Andric Type = ELF::R_PPC_REL24; 940b57cec5SDimitry Andric break; 950b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PLT: 960b57cec5SDimitry Andric Type = ELF::R_PPC_PLTREL24; 970b57cec5SDimitry Andric break; 980b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LOCAL: 990b57cec5SDimitry Andric Type = ELF::R_PPC_LOCAL24PC; 1000b57cec5SDimitry Andric break; 1015ffd83dbSDimitry Andric case MCSymbolRefExpr::VK_PPC_NOTOC: 1025ffd83dbSDimitry Andric Type = ELF::R_PPC64_REL24_NOTOC; 1035ffd83dbSDimitry Andric break; 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric break; 1060b57cec5SDimitry Andric case PPC::fixup_ppc_brcond14: 1070b57cec5SDimitry Andric case PPC::fixup_ppc_brcond14abs: 1080b57cec5SDimitry Andric Type = ELF::R_PPC_REL14; 1090b57cec5SDimitry Andric break; 1100b57cec5SDimitry Andric case PPC::fixup_ppc_half16: 1110b57cec5SDimitry Andric switch (Modifier) { 1120b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 1130b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 1140b57cec5SDimitry Andric Type = ELF::R_PPC_REL16; 1150b57cec5SDimitry Andric break; 1160b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO: 1170b57cec5SDimitry Andric Type = ELF::R_PPC_REL16_LO; 1180b57cec5SDimitry Andric break; 1190b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HI: 1200b57cec5SDimitry Andric Type = ELF::R_PPC_REL16_HI; 1210b57cec5SDimitry Andric break; 1220b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HA: 1230b57cec5SDimitry Andric Type = ELF::R_PPC_REL16_HA; 1240b57cec5SDimitry Andric break; 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric break; 1270b57cec5SDimitry Andric case PPC::fixup_ppc_half16ds: 1283a9a9c0cSDimitry Andric case PPC::fixup_ppc_half16dq: 1290b57cec5SDimitry Andric Target.print(errs()); 1300b57cec5SDimitry Andric errs() << '\n'; 1310b57cec5SDimitry 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; 1530b57cec5SDimitry Andric case FK_Data_4: 1540b57cec5SDimitry Andric case FK_PCRel_4: 1550b57cec5SDimitry Andric Type = ELF::R_PPC_REL32; 1560b57cec5SDimitry Andric break; 1570b57cec5SDimitry Andric case FK_Data_8: 1580b57cec5SDimitry Andric case FK_PCRel_8: 1590b57cec5SDimitry Andric Type = ELF::R_PPC64_REL64; 1600b57cec5SDimitry Andric break; 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric } else { 1638bcb0991SDimitry Andric switch (Fixup.getTargetKind()) { 1640b57cec5SDimitry Andric default: llvm_unreachable("invalid fixup kind!"); 1650b57cec5SDimitry Andric case PPC::fixup_ppc_br24abs: 1660b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR24; 1670b57cec5SDimitry Andric break; 1680b57cec5SDimitry Andric case PPC::fixup_ppc_brcond14abs: 1690b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ 1700b57cec5SDimitry Andric break; 1710b57cec5SDimitry Andric case PPC::fixup_ppc_half16: 1720b57cec5SDimitry Andric switch (Modifier) { 1730b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 1740b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 1750b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16; 1760b57cec5SDimitry Andric break; 1770b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO: 1780b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16_LO; 1790b57cec5SDimitry Andric break; 1800b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HI: 1810b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16_HI; 1820b57cec5SDimitry Andric break; 1830b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HA: 1840b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16_HA; 1850b57cec5SDimitry Andric break; 1860b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGH: 1870b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGH; 1880b57cec5SDimitry Andric break; 1890b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHA: 1900b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHA; 1910b57cec5SDimitry Andric break; 1920b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHER: 1930b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHER; 1940b57cec5SDimitry Andric break; 1950b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHERA: 1960b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHERA; 1970b57cec5SDimitry Andric break; 1980b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHEST: 1990b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHEST; 2000b57cec5SDimitry Andric break; 2010b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHESTA: 2020b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_HIGHESTA; 2030b57cec5SDimitry Andric break; 2040b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT: 2050b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16; 2060b57cec5SDimitry Andric break; 2070b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_LO: 2080b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16_LO; 2090b57cec5SDimitry Andric break; 2100b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_HI: 2110b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16_HI; 2120b57cec5SDimitry Andric break; 2130b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_HA: 2140b57cec5SDimitry Andric Type = ELF::R_PPC_GOT16_HA; 2150b57cec5SDimitry Andric break; 2160b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC: 2170b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16; 2180b57cec5SDimitry Andric break; 2190b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_LO: 2200b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_LO; 2210b57cec5SDimitry Andric break; 2220b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_HI: 2230b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_HI; 2240b57cec5SDimitry Andric break; 2250b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_HA: 2260b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_HA; 2270b57cec5SDimitry Andric break; 2280b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 2290b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16; 2300b57cec5SDimitry Andric break; 2310b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_LO: 2320b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16_LO; 2330b57cec5SDimitry Andric break; 2340b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HI: 2350b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16_HI; 2360b57cec5SDimitry Andric break; 2370b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HA: 2380b57cec5SDimitry Andric Type = ELF::R_PPC_TPREL16_HA; 2390b57cec5SDimitry Andric break; 2400b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: 2410b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGH; 2420b57cec5SDimitry Andric break; 2430b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: 2440b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHA; 2450b57cec5SDimitry Andric break; 2460b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: 2470b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHER; 2480b57cec5SDimitry Andric break; 2490b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: 2500b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHERA; 2510b57cec5SDimitry Andric break; 2520b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: 2530b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHEST; 2540b57cec5SDimitry Andric break; 2550b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: 2560b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_HIGHESTA; 2570b57cec5SDimitry Andric break; 2580b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 2590b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16; 2600b57cec5SDimitry Andric break; 2610b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 2620b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_LO; 2630b57cec5SDimitry Andric break; 2640b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HI: 2650b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HI; 2660b57cec5SDimitry Andric break; 2670b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HA: 2680b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HA; 2690b57cec5SDimitry Andric break; 2700b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: 2710b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGH; 2720b57cec5SDimitry Andric break; 2730b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: 2740b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHA; 2750b57cec5SDimitry Andric break; 2760b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: 2770b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHER; 2780b57cec5SDimitry Andric break; 2790b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: 2800b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHERA; 2810b57cec5SDimitry Andric break; 2820b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: 2830b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHEST; 2840b57cec5SDimitry Andric break; 2850b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: 2860b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_HIGHESTA; 2870b57cec5SDimitry Andric break; 2880b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: 2890b57cec5SDimitry Andric if (is64Bit()) 2900b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16; 2910b57cec5SDimitry Andric else 2920b57cec5SDimitry Andric Type = ELF::R_PPC_GOT_TLSGD16; 2930b57cec5SDimitry Andric break; 2940b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: 2950b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16_LO; 2960b57cec5SDimitry Andric break; 2970b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: 2980b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16_HI; 2990b57cec5SDimitry Andric break; 3000b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: 3010b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSGD16_HA; 3020b57cec5SDimitry Andric break; 3030b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: 3040b57cec5SDimitry Andric if (is64Bit()) 3050b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16; 3060b57cec5SDimitry Andric else 3070b57cec5SDimitry Andric Type = ELF::R_PPC_GOT_TLSLD16; 3080b57cec5SDimitry Andric break; 3090b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: 3100b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16_LO; 3110b57cec5SDimitry Andric break; 3120b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: 3130b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16_HI; 3140b57cec5SDimitry Andric break; 3150b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: 3160b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TLSLD16_HA; 3170b57cec5SDimitry Andric break; 3180b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 3190b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets 3200b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ 3210b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_DS; 3220b57cec5SDimitry Andric break; 3230b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 3240b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets 3250b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ 3260b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 3270b57cec5SDimitry Andric break; 3280b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: 3290b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_HI; 3300b57cec5SDimitry Andric break; 3310b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 3320b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets 3330b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ 3340b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_DS; 3350b57cec5SDimitry Andric break; 3360b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 3370b57cec5SDimitry Andric /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets 3380b57cec5SDimitry Andric are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ 3390b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 3400b57cec5SDimitry Andric break; 3410b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: 3420b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_HA; 3430b57cec5SDimitry Andric break; 3440b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: 3450b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_HI; 3460b57cec5SDimitry Andric break; 3470b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: 3480b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_HA; 3490b57cec5SDimitry Andric break; 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric break; 3520b57cec5SDimitry Andric case PPC::fixup_ppc_half16ds: 3533a9a9c0cSDimitry Andric case PPC::fixup_ppc_half16dq: 3540b57cec5SDimitry Andric switch (Modifier) { 3550b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 3560b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 3570b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_DS; 3580b57cec5SDimitry Andric break; 3590b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO: 3600b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR16_LO_DS; 3610b57cec5SDimitry Andric break; 3620b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT: 3630b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT16_DS; 3640b57cec5SDimitry Andric break; 3650b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_LO: 3660b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT16_LO_DS; 3670b57cec5SDimitry Andric break; 3680b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC: 3690b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_DS; 3700b57cec5SDimitry Andric break; 3710b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOC_LO: 3720b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC16_LO_DS; 3730b57cec5SDimitry Andric break; 3740b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 3750b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_DS; 3760b57cec5SDimitry Andric break; 3770b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_LO: 3780b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL16_LO_DS; 3790b57cec5SDimitry Andric break; 3800b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 3810b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_DS; 3820b57cec5SDimitry Andric break; 3830b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 3840b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL16_LO_DS; 3850b57cec5SDimitry Andric break; 3860b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 3870b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_DS; 3880b57cec5SDimitry Andric break; 3890b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 3900b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 3910b57cec5SDimitry Andric break; 3920b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 3930b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_DS; 3940b57cec5SDimitry Andric break; 3950b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 3960b57cec5SDimitry Andric Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 3970b57cec5SDimitry Andric break; 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric break; 4000b57cec5SDimitry Andric case PPC::fixup_ppc_nofixup: 4010b57cec5SDimitry Andric switch (Modifier) { 4020b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 4030b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLSGD: 4040b57cec5SDimitry Andric if (is64Bit()) 4050b57cec5SDimitry Andric Type = ELF::R_PPC64_TLSGD; 4060b57cec5SDimitry Andric else 4070b57cec5SDimitry Andric Type = ELF::R_PPC_TLSGD; 4080b57cec5SDimitry Andric break; 4090b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLSLD: 4100b57cec5SDimitry Andric if (is64Bit()) 4110b57cec5SDimitry Andric Type = ELF::R_PPC64_TLSLD; 4120b57cec5SDimitry Andric else 4130b57cec5SDimitry Andric Type = ELF::R_PPC_TLSLD; 4140b57cec5SDimitry Andric break; 4150b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLS: 4160b57cec5SDimitry Andric if (is64Bit()) 4170b57cec5SDimitry Andric Type = ELF::R_PPC64_TLS; 4180b57cec5SDimitry Andric else 4190b57cec5SDimitry Andric Type = ELF::R_PPC_TLS; 4200b57cec5SDimitry 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; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric break; 4380b57cec5SDimitry Andric case FK_Data_8: 4390b57cec5SDimitry Andric switch (Modifier) { 4400b57cec5SDimitry Andric default: llvm_unreachable("Unsupported Modifier"); 4410b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOCBASE: 4420b57cec5SDimitry Andric Type = ELF::R_PPC64_TOC; 4430b57cec5SDimitry Andric break; 4440b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 4450b57cec5SDimitry Andric Type = ELF::R_PPC64_ADDR64; 4460b57cec5SDimitry Andric break; 4470b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPMOD: 4480b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPMOD64; 4490b57cec5SDimitry Andric break; 4500b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 4510b57cec5SDimitry Andric Type = ELF::R_PPC64_TPREL64; 4520b57cec5SDimitry Andric break; 4530b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 4540b57cec5SDimitry Andric Type = ELF::R_PPC64_DTPREL64; 4550b57cec5SDimitry Andric break; 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric break; 4580b57cec5SDimitry Andric case FK_Data_4: 459*5f757f3fSDimitry Andric switch (Modifier) { 460*5f757f3fSDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 461*5f757f3fSDimitry Andric Type = ELF::R_PPC_DTPREL32; 462*5f757f3fSDimitry Andric break; 463*5f757f3fSDimitry Andric default: 4640b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR32; 465*5f757f3fSDimitry Andric } 4660b57cec5SDimitry Andric break; 4670b57cec5SDimitry Andric case FK_Data_2: 4680b57cec5SDimitry Andric Type = ELF::R_PPC_ADDR16; 4690b57cec5SDimitry Andric break; 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric return Type; 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric 475*5f757f3fSDimitry Andric bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCValue &, 476*5f757f3fSDimitry Andric const MCSymbol &Sym, 4770b57cec5SDimitry Andric unsigned Type) const { 4780b57cec5SDimitry Andric switch (Type) { 4790b57cec5SDimitry Andric default: 4800b57cec5SDimitry Andric return false; 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric case ELF::R_PPC_REL24: 4835ffd83dbSDimitry Andric case ELF::R_PPC64_REL24_NOTOC: 4840b57cec5SDimitry Andric // If the target symbol has a local entry point, we must keep the 4850b57cec5SDimitry Andric // target symbol to preserve that information for the linker. 4860b57cec5SDimitry Andric // The "other" values are stored in the last 6 bits of the second byte. 4870b57cec5SDimitry Andric // The traditional defines for STO values assume the full byte and thus 4880b57cec5SDimitry Andric // the shift to pack it. 4890b57cec5SDimitry Andric unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2; 4900b57cec5SDimitry Andric return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter> 4950b57cec5SDimitry Andric llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) { 4968bcb0991SDimitry Andric return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI); 4970b57cec5SDimitry Andric } 498