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