15ffd83dbSDimitry Andric //===-- VEELFObjectWriter.cpp - VE ELF Writer -----------------------------===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric 95ffd83dbSDimitry Andric #include "VEFixupKinds.h" 105ffd83dbSDimitry Andric #include "VEMCExpr.h" 115ffd83dbSDimitry Andric #include "VEMCTargetDesc.h" 12*0eae32dcSDimitry Andric #include "llvm/MC/MCContext.h" 135ffd83dbSDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 145ffd83dbSDimitry Andric #include "llvm/MC/MCExpr.h" 155ffd83dbSDimitry Andric #include "llvm/MC/MCObjectWriter.h" 165ffd83dbSDimitry Andric #include "llvm/MC/MCValue.h" 175ffd83dbSDimitry Andric #include "llvm/Support/ErrorHandling.h" 185ffd83dbSDimitry Andric 195ffd83dbSDimitry Andric using namespace llvm; 205ffd83dbSDimitry Andric 215ffd83dbSDimitry Andric namespace { 225ffd83dbSDimitry Andric class VEELFObjectWriter : public MCELFObjectTargetWriter { 235ffd83dbSDimitry Andric public: 245ffd83dbSDimitry Andric VEELFObjectWriter(uint8_t OSABI) 255ffd83dbSDimitry Andric : MCELFObjectTargetWriter(/* Is64Bit */ true, OSABI, ELF::EM_VE, 265ffd83dbSDimitry Andric /* HasRelocationAddend */ true) {} 275ffd83dbSDimitry Andric 285ffd83dbSDimitry Andric ~VEELFObjectWriter() override {} 295ffd83dbSDimitry Andric 305ffd83dbSDimitry Andric protected: 315ffd83dbSDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 325ffd83dbSDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override; 335ffd83dbSDimitry Andric 345ffd83dbSDimitry Andric bool needsRelocateWithSymbol(const MCSymbol &Sym, 355ffd83dbSDimitry Andric unsigned Type) const override; 365ffd83dbSDimitry Andric }; 375ffd83dbSDimitry Andric } // namespace 385ffd83dbSDimitry Andric 395ffd83dbSDimitry Andric unsigned VEELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, 405ffd83dbSDimitry Andric const MCFixup &Fixup, 415ffd83dbSDimitry Andric bool IsPCRel) const { 425ffd83dbSDimitry Andric if (const VEMCExpr *SExpr = dyn_cast<VEMCExpr>(Fixup.getValue())) { 435ffd83dbSDimitry Andric if (SExpr->getKind() == VEMCExpr::VK_VE_PC_LO32) 445ffd83dbSDimitry Andric return ELF::R_VE_PC_LO32; 455ffd83dbSDimitry Andric } 465ffd83dbSDimitry Andric 475ffd83dbSDimitry Andric if (IsPCRel) { 485ffd83dbSDimitry Andric switch (Fixup.getTargetKind()) { 495ffd83dbSDimitry Andric default: 50*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind"); 51*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 52*0eae32dcSDimitry Andric case FK_Data_1: 535ffd83dbSDimitry Andric case FK_PCRel_1: 54*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), 55*0eae32dcSDimitry Andric "1-byte pc-relative data relocation is not supported"); 56*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 57*0eae32dcSDimitry Andric case FK_Data_2: 585ffd83dbSDimitry Andric case FK_PCRel_2: 59*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), 60*0eae32dcSDimitry Andric "2-byte pc-relative data relocation is not supported"); 61*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 62*0eae32dcSDimitry Andric case FK_Data_4: 635ffd83dbSDimitry Andric case FK_PCRel_4: 64*0eae32dcSDimitry Andric return ELF::R_VE_SREL32; 65*0eae32dcSDimitry Andric case FK_Data_8: 665ffd83dbSDimitry Andric case FK_PCRel_8: 67*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), 68*0eae32dcSDimitry Andric "8-byte pc-relative data relocation is not supported"); 69*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 70*0eae32dcSDimitry Andric case VE::fixup_ve_reflong: 71*0eae32dcSDimitry Andric case VE::fixup_ve_srel32: 72*0eae32dcSDimitry Andric return ELF::R_VE_SREL32; 735ffd83dbSDimitry Andric case VE::fixup_ve_pc_hi32: 745ffd83dbSDimitry Andric return ELF::R_VE_PC_HI32; 755ffd83dbSDimitry Andric case VE::fixup_ve_pc_lo32: 765ffd83dbSDimitry Andric return ELF::R_VE_PC_LO32; 775ffd83dbSDimitry Andric } 785ffd83dbSDimitry Andric } 795ffd83dbSDimitry Andric 805ffd83dbSDimitry Andric switch (Fixup.getTargetKind()) { 815ffd83dbSDimitry Andric default: 82*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type"); 83*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 845ffd83dbSDimitry Andric case FK_Data_1: 85*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), "1-byte data relocation is not supported"); 86*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 875ffd83dbSDimitry Andric case FK_Data_2: 88*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), "2-byte data relocation is not supported"); 89*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 905ffd83dbSDimitry Andric case FK_Data_4: 915ffd83dbSDimitry Andric return ELF::R_VE_REFLONG; 925ffd83dbSDimitry Andric case FK_Data_8: 935ffd83dbSDimitry Andric return ELF::R_VE_REFQUAD; 945ffd83dbSDimitry Andric case VE::fixup_ve_reflong: 955ffd83dbSDimitry Andric return ELF::R_VE_REFLONG; 96*0eae32dcSDimitry Andric case VE::fixup_ve_srel32: 97*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), 98*0eae32dcSDimitry Andric "A non pc-relative srel32 relocation is not supported"); 99*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 1005ffd83dbSDimitry Andric case VE::fixup_ve_hi32: 1015ffd83dbSDimitry Andric return ELF::R_VE_HI32; 1025ffd83dbSDimitry Andric case VE::fixup_ve_lo32: 1035ffd83dbSDimitry Andric return ELF::R_VE_LO32; 1045ffd83dbSDimitry Andric case VE::fixup_ve_pc_hi32: 105*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), 106*0eae32dcSDimitry Andric "A non pc-relative pc_hi32 relocation is not supported"); 107*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 1085ffd83dbSDimitry Andric case VE::fixup_ve_pc_lo32: 109*0eae32dcSDimitry Andric Ctx.reportError(Fixup.getLoc(), 110*0eae32dcSDimitry Andric "A non pc-relative pc_lo32 relocation is not supported"); 111*0eae32dcSDimitry Andric return ELF::R_VE_NONE; 1125ffd83dbSDimitry Andric case VE::fixup_ve_got_hi32: 1135ffd83dbSDimitry Andric return ELF::R_VE_GOT_HI32; 1145ffd83dbSDimitry Andric case VE::fixup_ve_got_lo32: 1155ffd83dbSDimitry Andric return ELF::R_VE_GOT_LO32; 1165ffd83dbSDimitry Andric case VE::fixup_ve_gotoff_hi32: 1175ffd83dbSDimitry Andric return ELF::R_VE_GOTOFF_HI32; 1185ffd83dbSDimitry Andric case VE::fixup_ve_gotoff_lo32: 1195ffd83dbSDimitry Andric return ELF::R_VE_GOTOFF_LO32; 1205ffd83dbSDimitry Andric case VE::fixup_ve_plt_hi32: 1215ffd83dbSDimitry Andric return ELF::R_VE_PLT_HI32; 1225ffd83dbSDimitry Andric case VE::fixup_ve_plt_lo32: 1235ffd83dbSDimitry Andric return ELF::R_VE_PLT_LO32; 1245ffd83dbSDimitry Andric case VE::fixup_ve_tls_gd_hi32: 1255ffd83dbSDimitry Andric return ELF::R_VE_TLS_GD_HI32; 1265ffd83dbSDimitry Andric case VE::fixup_ve_tls_gd_lo32: 1275ffd83dbSDimitry Andric return ELF::R_VE_TLS_GD_LO32; 1285ffd83dbSDimitry Andric case VE::fixup_ve_tpoff_hi32: 1295ffd83dbSDimitry Andric return ELF::R_VE_TPOFF_HI32; 1305ffd83dbSDimitry Andric case VE::fixup_ve_tpoff_lo32: 1315ffd83dbSDimitry Andric return ELF::R_VE_TPOFF_LO32; 1325ffd83dbSDimitry Andric } 1335ffd83dbSDimitry Andric 1345ffd83dbSDimitry Andric return ELF::R_VE_NONE; 1355ffd83dbSDimitry Andric } 1365ffd83dbSDimitry Andric 1375ffd83dbSDimitry Andric bool VEELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, 1385ffd83dbSDimitry Andric unsigned Type) const { 1395ffd83dbSDimitry Andric switch (Type) { 1405ffd83dbSDimitry Andric default: 1415ffd83dbSDimitry Andric return false; 1425ffd83dbSDimitry Andric 1435ffd83dbSDimitry Andric // All relocations that use a GOT need a symbol, not an offset, as 1445ffd83dbSDimitry Andric // the offset of the symbol within the section is irrelevant to 1455ffd83dbSDimitry Andric // where the GOT entry is. Don't need to list all the TLS entries, 1465ffd83dbSDimitry Andric // as they're all marked as requiring a symbol anyways. 1475ffd83dbSDimitry Andric case ELF::R_VE_GOT_HI32: 1485ffd83dbSDimitry Andric case ELF::R_VE_GOT_LO32: 1495ffd83dbSDimitry Andric case ELF::R_VE_GOTOFF_HI32: 1505ffd83dbSDimitry Andric case ELF::R_VE_GOTOFF_LO32: 1515ffd83dbSDimitry Andric case ELF::R_VE_TLS_GD_HI32: 1525ffd83dbSDimitry Andric case ELF::R_VE_TLS_GD_LO32: 1535ffd83dbSDimitry Andric return true; 1545ffd83dbSDimitry Andric } 1555ffd83dbSDimitry Andric } 1565ffd83dbSDimitry Andric 1575ffd83dbSDimitry Andric std::unique_ptr<MCObjectTargetWriter> 1585ffd83dbSDimitry Andric llvm::createVEELFObjectWriter(uint8_t OSABI) { 1595ffd83dbSDimitry Andric return std::make_unique<VEELFObjectWriter>(OSABI); 1605ffd83dbSDimitry Andric } 161