1*5ffd83dbSDimitry Andric //===-- VEELFObjectWriter.cpp - VE ELF Writer -----------------------------===// 2*5ffd83dbSDimitry Andric // 3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5ffd83dbSDimitry Andric // 7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 8*5ffd83dbSDimitry Andric 9*5ffd83dbSDimitry Andric #include "VEFixupKinds.h" 10*5ffd83dbSDimitry Andric #include "VEMCExpr.h" 11*5ffd83dbSDimitry Andric #include "VEMCTargetDesc.h" 12*5ffd83dbSDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 13*5ffd83dbSDimitry Andric #include "llvm/MC/MCExpr.h" 14*5ffd83dbSDimitry Andric #include "llvm/MC/MCObjectWriter.h" 15*5ffd83dbSDimitry Andric #include "llvm/MC/MCValue.h" 16*5ffd83dbSDimitry Andric #include "llvm/Support/ErrorHandling.h" 17*5ffd83dbSDimitry Andric 18*5ffd83dbSDimitry Andric using namespace llvm; 19*5ffd83dbSDimitry Andric 20*5ffd83dbSDimitry Andric namespace { 21*5ffd83dbSDimitry Andric class VEELFObjectWriter : public MCELFObjectTargetWriter { 22*5ffd83dbSDimitry Andric public: 23*5ffd83dbSDimitry Andric VEELFObjectWriter(uint8_t OSABI) 24*5ffd83dbSDimitry Andric : MCELFObjectTargetWriter(/* Is64Bit */ true, OSABI, ELF::EM_VE, 25*5ffd83dbSDimitry Andric /* HasRelocationAddend */ true) {} 26*5ffd83dbSDimitry Andric 27*5ffd83dbSDimitry Andric ~VEELFObjectWriter() override {} 28*5ffd83dbSDimitry Andric 29*5ffd83dbSDimitry Andric protected: 30*5ffd83dbSDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 31*5ffd83dbSDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override; 32*5ffd83dbSDimitry Andric 33*5ffd83dbSDimitry Andric bool needsRelocateWithSymbol(const MCSymbol &Sym, 34*5ffd83dbSDimitry Andric unsigned Type) const override; 35*5ffd83dbSDimitry Andric }; 36*5ffd83dbSDimitry Andric } // namespace 37*5ffd83dbSDimitry Andric 38*5ffd83dbSDimitry Andric unsigned VEELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, 39*5ffd83dbSDimitry Andric const MCFixup &Fixup, 40*5ffd83dbSDimitry Andric bool IsPCRel) const { 41*5ffd83dbSDimitry Andric if (const VEMCExpr *SExpr = dyn_cast<VEMCExpr>(Fixup.getValue())) { 42*5ffd83dbSDimitry Andric if (SExpr->getKind() == VEMCExpr::VK_VE_PC_LO32) 43*5ffd83dbSDimitry Andric return ELF::R_VE_PC_LO32; 44*5ffd83dbSDimitry Andric } 45*5ffd83dbSDimitry Andric 46*5ffd83dbSDimitry Andric if (IsPCRel) { 47*5ffd83dbSDimitry Andric switch (Fixup.getTargetKind()) { 48*5ffd83dbSDimitry Andric default: 49*5ffd83dbSDimitry Andric llvm_unreachable("Unimplemented fixup -> relocation"); 50*5ffd83dbSDimitry Andric case FK_PCRel_1: 51*5ffd83dbSDimitry Andric llvm_unreachable("Unimplemented fixup fk_data_1 -> relocation"); 52*5ffd83dbSDimitry Andric case FK_PCRel_2: 53*5ffd83dbSDimitry Andric llvm_unreachable("Unimplemented fixup fk_data_2 -> relocation"); 54*5ffd83dbSDimitry Andric // FIXME: relative kind? 55*5ffd83dbSDimitry Andric case FK_PCRel_4: 56*5ffd83dbSDimitry Andric return ELF::R_VE_REFLONG; 57*5ffd83dbSDimitry Andric case FK_PCRel_8: 58*5ffd83dbSDimitry Andric return ELF::R_VE_REFQUAD; 59*5ffd83dbSDimitry Andric case VE::fixup_ve_pc_hi32: 60*5ffd83dbSDimitry Andric return ELF::R_VE_PC_HI32; 61*5ffd83dbSDimitry Andric case VE::fixup_ve_pc_lo32: 62*5ffd83dbSDimitry Andric return ELF::R_VE_PC_LO32; 63*5ffd83dbSDimitry Andric } 64*5ffd83dbSDimitry Andric } 65*5ffd83dbSDimitry Andric 66*5ffd83dbSDimitry Andric switch (Fixup.getTargetKind()) { 67*5ffd83dbSDimitry Andric default: 68*5ffd83dbSDimitry Andric llvm_unreachable("Unimplemented fixup -> relocation"); 69*5ffd83dbSDimitry Andric case FK_Data_1: 70*5ffd83dbSDimitry Andric llvm_unreachable("Unimplemented fixup fk_data_1 -> relocation"); 71*5ffd83dbSDimitry Andric case FK_Data_2: 72*5ffd83dbSDimitry Andric llvm_unreachable("Unimplemented fixup fk_data_2 -> relocation"); 73*5ffd83dbSDimitry Andric case FK_Data_4: 74*5ffd83dbSDimitry Andric return ELF::R_VE_REFLONG; 75*5ffd83dbSDimitry Andric case FK_Data_8: 76*5ffd83dbSDimitry Andric return ELF::R_VE_REFQUAD; 77*5ffd83dbSDimitry Andric case VE::fixup_ve_reflong: 78*5ffd83dbSDimitry Andric return ELF::R_VE_REFLONG; 79*5ffd83dbSDimitry Andric case VE::fixup_ve_hi32: 80*5ffd83dbSDimitry Andric return ELF::R_VE_HI32; 81*5ffd83dbSDimitry Andric case VE::fixup_ve_lo32: 82*5ffd83dbSDimitry Andric return ELF::R_VE_LO32; 83*5ffd83dbSDimitry Andric case VE::fixup_ve_pc_hi32: 84*5ffd83dbSDimitry Andric llvm_unreachable("Unimplemented fixup pc_hi32 -> relocation"); 85*5ffd83dbSDimitry Andric case VE::fixup_ve_pc_lo32: 86*5ffd83dbSDimitry Andric llvm_unreachable("Unimplemented fixup pc_lo32 -> relocation"); 87*5ffd83dbSDimitry Andric case VE::fixup_ve_got_hi32: 88*5ffd83dbSDimitry Andric return ELF::R_VE_GOT_HI32; 89*5ffd83dbSDimitry Andric case VE::fixup_ve_got_lo32: 90*5ffd83dbSDimitry Andric return ELF::R_VE_GOT_LO32; 91*5ffd83dbSDimitry Andric case VE::fixup_ve_gotoff_hi32: 92*5ffd83dbSDimitry Andric return ELF::R_VE_GOTOFF_HI32; 93*5ffd83dbSDimitry Andric case VE::fixup_ve_gotoff_lo32: 94*5ffd83dbSDimitry Andric return ELF::R_VE_GOTOFF_LO32; 95*5ffd83dbSDimitry Andric case VE::fixup_ve_plt_hi32: 96*5ffd83dbSDimitry Andric return ELF::R_VE_PLT_HI32; 97*5ffd83dbSDimitry Andric case VE::fixup_ve_plt_lo32: 98*5ffd83dbSDimitry Andric return ELF::R_VE_PLT_LO32; 99*5ffd83dbSDimitry Andric case VE::fixup_ve_tls_gd_hi32: 100*5ffd83dbSDimitry Andric return ELF::R_VE_TLS_GD_HI32; 101*5ffd83dbSDimitry Andric case VE::fixup_ve_tls_gd_lo32: 102*5ffd83dbSDimitry Andric return ELF::R_VE_TLS_GD_LO32; 103*5ffd83dbSDimitry Andric case VE::fixup_ve_tpoff_hi32: 104*5ffd83dbSDimitry Andric return ELF::R_VE_TPOFF_HI32; 105*5ffd83dbSDimitry Andric case VE::fixup_ve_tpoff_lo32: 106*5ffd83dbSDimitry Andric return ELF::R_VE_TPOFF_LO32; 107*5ffd83dbSDimitry Andric } 108*5ffd83dbSDimitry Andric 109*5ffd83dbSDimitry Andric return ELF::R_VE_NONE; 110*5ffd83dbSDimitry Andric } 111*5ffd83dbSDimitry Andric 112*5ffd83dbSDimitry Andric bool VEELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, 113*5ffd83dbSDimitry Andric unsigned Type) const { 114*5ffd83dbSDimitry Andric switch (Type) { 115*5ffd83dbSDimitry Andric default: 116*5ffd83dbSDimitry Andric return false; 117*5ffd83dbSDimitry Andric 118*5ffd83dbSDimitry Andric // All relocations that use a GOT need a symbol, not an offset, as 119*5ffd83dbSDimitry Andric // the offset of the symbol within the section is irrelevant to 120*5ffd83dbSDimitry Andric // where the GOT entry is. Don't need to list all the TLS entries, 121*5ffd83dbSDimitry Andric // as they're all marked as requiring a symbol anyways. 122*5ffd83dbSDimitry Andric case ELF::R_VE_GOT_HI32: 123*5ffd83dbSDimitry Andric case ELF::R_VE_GOT_LO32: 124*5ffd83dbSDimitry Andric case ELF::R_VE_GOTOFF_HI32: 125*5ffd83dbSDimitry Andric case ELF::R_VE_GOTOFF_LO32: 126*5ffd83dbSDimitry Andric case ELF::R_VE_TLS_GD_HI32: 127*5ffd83dbSDimitry Andric case ELF::R_VE_TLS_GD_LO32: 128*5ffd83dbSDimitry Andric return true; 129*5ffd83dbSDimitry Andric } 130*5ffd83dbSDimitry Andric } 131*5ffd83dbSDimitry Andric 132*5ffd83dbSDimitry Andric std::unique_ptr<MCObjectTargetWriter> 133*5ffd83dbSDimitry Andric llvm::createVEELFObjectWriter(uint8_t OSABI) { 134*5ffd83dbSDimitry Andric return std::make_unique<VEELFObjectWriter>(OSABI); 135*5ffd83dbSDimitry Andric } 136