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_pc_hi32: 60 return ELF::R_VE_PC_HI32; 61 case VE::fixup_ve_pc_lo32: 62 return ELF::R_VE_PC_LO32; 63 } 64 } 65 66 switch (Fixup.getTargetKind()) { 67 default: 68 llvm_unreachable("Unimplemented fixup -> relocation"); 69 case FK_Data_1: 70 llvm_unreachable("Unimplemented fixup fk_data_1 -> relocation"); 71 case FK_Data_2: 72 llvm_unreachable("Unimplemented fixup fk_data_2 -> relocation"); 73 case FK_Data_4: 74 return ELF::R_VE_REFLONG; 75 case FK_Data_8: 76 return ELF::R_VE_REFQUAD; 77 case VE::fixup_ve_reflong: 78 return ELF::R_VE_REFLONG; 79 case VE::fixup_ve_hi32: 80 return ELF::R_VE_HI32; 81 case VE::fixup_ve_lo32: 82 return ELF::R_VE_LO32; 83 case VE::fixup_ve_pc_hi32: 84 llvm_unreachable("Unimplemented fixup pc_hi32 -> relocation"); 85 case VE::fixup_ve_pc_lo32: 86 llvm_unreachable("Unimplemented fixup pc_lo32 -> relocation"); 87 case VE::fixup_ve_got_hi32: 88 return ELF::R_VE_GOT_HI32; 89 case VE::fixup_ve_got_lo32: 90 return ELF::R_VE_GOT_LO32; 91 case VE::fixup_ve_gotoff_hi32: 92 return ELF::R_VE_GOTOFF_HI32; 93 case VE::fixup_ve_gotoff_lo32: 94 return ELF::R_VE_GOTOFF_LO32; 95 case VE::fixup_ve_plt_hi32: 96 return ELF::R_VE_PLT_HI32; 97 case VE::fixup_ve_plt_lo32: 98 return ELF::R_VE_PLT_LO32; 99 case VE::fixup_ve_tls_gd_hi32: 100 return ELF::R_VE_TLS_GD_HI32; 101 case VE::fixup_ve_tls_gd_lo32: 102 return ELF::R_VE_TLS_GD_LO32; 103 case VE::fixup_ve_tpoff_hi32: 104 return ELF::R_VE_TPOFF_HI32; 105 case VE::fixup_ve_tpoff_lo32: 106 return ELF::R_VE_TPOFF_LO32; 107 } 108 109 return ELF::R_VE_NONE; 110 } 111 112 bool VEELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, 113 unsigned Type) const { 114 switch (Type) { 115 default: 116 return false; 117 118 // All relocations that use a GOT need a symbol, not an offset, as 119 // the offset of the symbol within the section is irrelevant to 120 // where the GOT entry is. Don't need to list all the TLS entries, 121 // as they're all marked as requiring a symbol anyways. 122 case ELF::R_VE_GOT_HI32: 123 case ELF::R_VE_GOT_LO32: 124 case ELF::R_VE_GOTOFF_HI32: 125 case ELF::R_VE_GOTOFF_LO32: 126 case ELF::R_VE_TLS_GD_HI32: 127 case ELF::R_VE_TLS_GD_LO32: 128 return true; 129 } 130 } 131 132 std::unique_ptr<MCObjectTargetWriter> 133 llvm::createVEELFObjectWriter(uint8_t OSABI) { 134 return std::make_unique<VEELFObjectWriter>(OSABI); 135 } 136