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