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