xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
15ffd83dbSDimitry Andric //===-- VEELFObjectWriter.cpp - VE ELF Writer -----------------------------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric 
95ffd83dbSDimitry Andric #include "VEFixupKinds.h"
105ffd83dbSDimitry Andric #include "VEMCExpr.h"
115ffd83dbSDimitry Andric #include "VEMCTargetDesc.h"
120eae32dcSDimitry Andric #include "llvm/MC/MCContext.h"
135ffd83dbSDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
145ffd83dbSDimitry Andric #include "llvm/MC/MCExpr.h"
155ffd83dbSDimitry Andric #include "llvm/MC/MCObjectWriter.h"
165ffd83dbSDimitry Andric #include "llvm/MC/MCValue.h"
175ffd83dbSDimitry Andric #include "llvm/Support/ErrorHandling.h"
185ffd83dbSDimitry Andric 
195ffd83dbSDimitry Andric using namespace llvm;
205ffd83dbSDimitry Andric 
215ffd83dbSDimitry Andric namespace {
225ffd83dbSDimitry Andric class VEELFObjectWriter : public MCELFObjectTargetWriter {
235ffd83dbSDimitry Andric public:
VEELFObjectWriter(uint8_t OSABI)245ffd83dbSDimitry Andric   VEELFObjectWriter(uint8_t OSABI)
255ffd83dbSDimitry Andric       : MCELFObjectTargetWriter(/* Is64Bit */ true, OSABI, ELF::EM_VE,
265ffd83dbSDimitry Andric                                 /* HasRelocationAddend */ true) {}
275ffd83dbSDimitry Andric 
2881ad6265SDimitry Andric   ~VEELFObjectWriter() override = default;
295ffd83dbSDimitry Andric 
305ffd83dbSDimitry Andric protected:
315ffd83dbSDimitry Andric   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
325ffd83dbSDimitry Andric                         const MCFixup &Fixup, bool IsPCRel) const override;
335ffd83dbSDimitry Andric 
34*5f757f3fSDimitry Andric   bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
355ffd83dbSDimitry Andric                                unsigned Type) const override;
365ffd83dbSDimitry Andric };
375ffd83dbSDimitry Andric } // namespace
385ffd83dbSDimitry Andric 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const395ffd83dbSDimitry Andric unsigned VEELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
405ffd83dbSDimitry Andric                                          const MCFixup &Fixup,
415ffd83dbSDimitry Andric                                          bool IsPCRel) const {
425ffd83dbSDimitry Andric   if (const VEMCExpr *SExpr = dyn_cast<VEMCExpr>(Fixup.getValue())) {
435ffd83dbSDimitry Andric     if (SExpr->getKind() == VEMCExpr::VK_VE_PC_LO32)
445ffd83dbSDimitry Andric       return ELF::R_VE_PC_LO32;
455ffd83dbSDimitry Andric   }
465ffd83dbSDimitry Andric 
475ffd83dbSDimitry Andric   if (IsPCRel) {
485ffd83dbSDimitry Andric     switch (Fixup.getTargetKind()) {
495ffd83dbSDimitry Andric     default:
500eae32dcSDimitry Andric       Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");
510eae32dcSDimitry Andric       return ELF::R_VE_NONE;
520eae32dcSDimitry Andric     case FK_Data_1:
535ffd83dbSDimitry Andric     case FK_PCRel_1:
540eae32dcSDimitry Andric       Ctx.reportError(Fixup.getLoc(),
550eae32dcSDimitry Andric                       "1-byte pc-relative data relocation is not supported");
560eae32dcSDimitry Andric       return ELF::R_VE_NONE;
570eae32dcSDimitry Andric     case FK_Data_2:
585ffd83dbSDimitry Andric     case FK_PCRel_2:
590eae32dcSDimitry Andric       Ctx.reportError(Fixup.getLoc(),
600eae32dcSDimitry Andric                       "2-byte pc-relative data relocation is not supported");
610eae32dcSDimitry Andric       return ELF::R_VE_NONE;
620eae32dcSDimitry Andric     case FK_Data_4:
635ffd83dbSDimitry Andric     case FK_PCRel_4:
640eae32dcSDimitry Andric       return ELF::R_VE_SREL32;
650eae32dcSDimitry Andric     case FK_Data_8:
665ffd83dbSDimitry Andric     case FK_PCRel_8:
670eae32dcSDimitry Andric       Ctx.reportError(Fixup.getLoc(),
680eae32dcSDimitry Andric                       "8-byte pc-relative data relocation is not supported");
690eae32dcSDimitry Andric       return ELF::R_VE_NONE;
700eae32dcSDimitry Andric     case VE::fixup_ve_reflong:
710eae32dcSDimitry Andric     case VE::fixup_ve_srel32:
720eae32dcSDimitry Andric       return ELF::R_VE_SREL32;
735ffd83dbSDimitry Andric     case VE::fixup_ve_pc_hi32:
745ffd83dbSDimitry Andric       return ELF::R_VE_PC_HI32;
755ffd83dbSDimitry Andric     case VE::fixup_ve_pc_lo32:
765ffd83dbSDimitry Andric       return ELF::R_VE_PC_LO32;
775ffd83dbSDimitry Andric     }
785ffd83dbSDimitry Andric   }
795ffd83dbSDimitry Andric 
805ffd83dbSDimitry Andric   switch (Fixup.getTargetKind()) {
815ffd83dbSDimitry Andric   default:
820eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
830eae32dcSDimitry Andric     return ELF::R_VE_NONE;
845ffd83dbSDimitry Andric   case FK_Data_1:
850eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(), "1-byte data relocation is not supported");
860eae32dcSDimitry Andric     return ELF::R_VE_NONE;
875ffd83dbSDimitry Andric   case FK_Data_2:
880eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(), "2-byte data relocation is not supported");
890eae32dcSDimitry Andric     return ELF::R_VE_NONE;
905ffd83dbSDimitry Andric   case FK_Data_4:
915ffd83dbSDimitry Andric     return ELF::R_VE_REFLONG;
925ffd83dbSDimitry Andric   case FK_Data_8:
935ffd83dbSDimitry Andric     return ELF::R_VE_REFQUAD;
945ffd83dbSDimitry Andric   case VE::fixup_ve_reflong:
955ffd83dbSDimitry Andric     return ELF::R_VE_REFLONG;
960eae32dcSDimitry Andric   case VE::fixup_ve_srel32:
970eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(),
980eae32dcSDimitry Andric                     "A non pc-relative srel32 relocation is not supported");
990eae32dcSDimitry Andric     return ELF::R_VE_NONE;
1005ffd83dbSDimitry Andric   case VE::fixup_ve_hi32:
1015ffd83dbSDimitry Andric     return ELF::R_VE_HI32;
1025ffd83dbSDimitry Andric   case VE::fixup_ve_lo32:
1035ffd83dbSDimitry Andric     return ELF::R_VE_LO32;
1045ffd83dbSDimitry Andric   case VE::fixup_ve_pc_hi32:
1050eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(),
1060eae32dcSDimitry Andric                     "A non pc-relative pc_hi32 relocation is not supported");
1070eae32dcSDimitry Andric     return ELF::R_VE_NONE;
1085ffd83dbSDimitry Andric   case VE::fixup_ve_pc_lo32:
1090eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(),
1100eae32dcSDimitry Andric                     "A non pc-relative pc_lo32 relocation is not supported");
1110eae32dcSDimitry Andric     return ELF::R_VE_NONE;
1125ffd83dbSDimitry Andric   case VE::fixup_ve_got_hi32:
1135ffd83dbSDimitry Andric     return ELF::R_VE_GOT_HI32;
1145ffd83dbSDimitry Andric   case VE::fixup_ve_got_lo32:
1155ffd83dbSDimitry Andric     return ELF::R_VE_GOT_LO32;
1165ffd83dbSDimitry Andric   case VE::fixup_ve_gotoff_hi32:
1175ffd83dbSDimitry Andric     return ELF::R_VE_GOTOFF_HI32;
1185ffd83dbSDimitry Andric   case VE::fixup_ve_gotoff_lo32:
1195ffd83dbSDimitry Andric     return ELF::R_VE_GOTOFF_LO32;
1205ffd83dbSDimitry Andric   case VE::fixup_ve_plt_hi32:
1215ffd83dbSDimitry Andric     return ELF::R_VE_PLT_HI32;
1225ffd83dbSDimitry Andric   case VE::fixup_ve_plt_lo32:
1235ffd83dbSDimitry Andric     return ELF::R_VE_PLT_LO32;
1245ffd83dbSDimitry Andric   case VE::fixup_ve_tls_gd_hi32:
1255ffd83dbSDimitry Andric     return ELF::R_VE_TLS_GD_HI32;
1265ffd83dbSDimitry Andric   case VE::fixup_ve_tls_gd_lo32:
1275ffd83dbSDimitry Andric     return ELF::R_VE_TLS_GD_LO32;
1285ffd83dbSDimitry Andric   case VE::fixup_ve_tpoff_hi32:
1295ffd83dbSDimitry Andric     return ELF::R_VE_TPOFF_HI32;
1305ffd83dbSDimitry Andric   case VE::fixup_ve_tpoff_lo32:
1315ffd83dbSDimitry Andric     return ELF::R_VE_TPOFF_LO32;
1325ffd83dbSDimitry Andric   }
1335ffd83dbSDimitry Andric 
1345ffd83dbSDimitry Andric   return ELF::R_VE_NONE;
1355ffd83dbSDimitry Andric }
1365ffd83dbSDimitry Andric 
needsRelocateWithSymbol(const MCValue &,const MCSymbol &,unsigned Type) const137*5f757f3fSDimitry Andric bool VEELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
138*5f757f3fSDimitry Andric                                                 const MCSymbol &,
1395ffd83dbSDimitry Andric                                                 unsigned Type) const {
1405ffd83dbSDimitry Andric   switch (Type) {
1415ffd83dbSDimitry Andric   default:
1425ffd83dbSDimitry Andric     return false;
1435ffd83dbSDimitry Andric 
1445ffd83dbSDimitry Andric   // All relocations that use a GOT need a symbol, not an offset, as
1455ffd83dbSDimitry Andric   // the offset of the symbol within the section is irrelevant to
1465ffd83dbSDimitry Andric   // where the GOT entry is. Don't need to list all the TLS entries,
1475ffd83dbSDimitry Andric   // as they're all marked as requiring a symbol anyways.
1485ffd83dbSDimitry Andric   case ELF::R_VE_GOT_HI32:
1495ffd83dbSDimitry Andric   case ELF::R_VE_GOT_LO32:
1505ffd83dbSDimitry Andric   case ELF::R_VE_GOTOFF_HI32:
1515ffd83dbSDimitry Andric   case ELF::R_VE_GOTOFF_LO32:
1525ffd83dbSDimitry Andric   case ELF::R_VE_TLS_GD_HI32:
1535ffd83dbSDimitry Andric   case ELF::R_VE_TLS_GD_LO32:
1545ffd83dbSDimitry Andric     return true;
1555ffd83dbSDimitry Andric   }
1565ffd83dbSDimitry Andric }
1575ffd83dbSDimitry Andric 
1585ffd83dbSDimitry Andric std::unique_ptr<MCObjectTargetWriter>
createVEELFObjectWriter(uint8_t OSABI)1595ffd83dbSDimitry Andric llvm::createVEELFObjectWriter(uint8_t OSABI) {
1605ffd83dbSDimitry Andric   return std::make_unique<VEELFObjectWriter>(OSABI);
1615ffd83dbSDimitry Andric }
162