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_srel32: 71 return ELF::R_VE_SREL32; 72 case VE::fixup_ve_pc_hi32: 73 return ELF::R_VE_PC_HI32; 74 case VE::fixup_ve_pc_lo32: 75 return ELF::R_VE_PC_LO32; 76 } 77 } 78 79 switch (Fixup.getTargetKind()) { 80 default: 81 Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type"); 82 return ELF::R_VE_NONE; 83 case FK_Data_1: 84 Ctx.reportError(Fixup.getLoc(), "1-byte data relocation is not supported"); 85 return ELF::R_VE_NONE; 86 case FK_Data_2: 87 Ctx.reportError(Fixup.getLoc(), "2-byte data relocation is not supported"); 88 return ELF::R_VE_NONE; 89 case FK_Data_4: 90 return ELF::R_VE_REFLONG; 91 case FK_Data_8: 92 return ELF::R_VE_REFQUAD; 93 case VE::fixup_ve_reflong: 94 return ELF::R_VE_REFLONG; 95 case VE::fixup_ve_srel32: 96 Ctx.reportError(Fixup.getLoc(), 97 "A non pc-relative srel32 relocation is not supported"); 98 return ELF::R_VE_NONE; 99 case VE::fixup_ve_hi32: 100 return ELF::R_VE_HI32; 101 case VE::fixup_ve_lo32: 102 return ELF::R_VE_LO32; 103 case VE::fixup_ve_pc_hi32: 104 Ctx.reportError(Fixup.getLoc(), 105 "A non pc-relative pc_hi32 relocation is not supported"); 106 return ELF::R_VE_NONE; 107 case VE::fixup_ve_pc_lo32: 108 Ctx.reportError(Fixup.getLoc(), 109 "A non pc-relative pc_lo32 relocation is not supported"); 110 return ELF::R_VE_NONE; 111 case VE::fixup_ve_got_hi32: 112 return ELF::R_VE_GOT_HI32; 113 case VE::fixup_ve_got_lo32: 114 return ELF::R_VE_GOT_LO32; 115 case VE::fixup_ve_gotoff_hi32: 116 return ELF::R_VE_GOTOFF_HI32; 117 case VE::fixup_ve_gotoff_lo32: 118 return ELF::R_VE_GOTOFF_LO32; 119 case VE::fixup_ve_plt_hi32: 120 return ELF::R_VE_PLT_HI32; 121 case VE::fixup_ve_plt_lo32: 122 return ELF::R_VE_PLT_LO32; 123 case VE::fixup_ve_tls_gd_hi32: 124 return ELF::R_VE_TLS_GD_HI32; 125 case VE::fixup_ve_tls_gd_lo32: 126 return ELF::R_VE_TLS_GD_LO32; 127 case VE::fixup_ve_tpoff_hi32: 128 return ELF::R_VE_TPOFF_HI32; 129 case VE::fixup_ve_tpoff_lo32: 130 return ELF::R_VE_TPOFF_LO32; 131 } 132 133 return ELF::R_VE_NONE; 134 } 135 136 bool VEELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, 137 unsigned Type) const { 138 switch (Type) { 139 default: 140 return false; 141 142 // All relocations that use a GOT need a symbol, not an offset, as 143 // the offset of the symbol within the section is irrelevant to 144 // where the GOT entry is. Don't need to list all the TLS entries, 145 // as they're all marked as requiring a symbol anyways. 146 case ELF::R_VE_GOT_HI32: 147 case ELF::R_VE_GOT_LO32: 148 case ELF::R_VE_GOTOFF_HI32: 149 case ELF::R_VE_GOTOFF_LO32: 150 case ELF::R_VE_TLS_GD_HI32: 151 case ELF::R_VE_TLS_GD_LO32: 152 return true; 153 } 154 } 155 156 std::unique_ptr<MCObjectTargetWriter> 157 llvm::createVEELFObjectWriter(uint8_t OSABI) { 158 return std::make_unique<VEELFObjectWriter>(OSABI); 159 } 160