xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp (revision 0eae32dcef82f6f06de6419a0d623d7def0cc8f6)
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"
12*0eae32dcSDimitry 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:
245ffd83dbSDimitry Andric   VEELFObjectWriter(uint8_t OSABI)
255ffd83dbSDimitry Andric       : MCELFObjectTargetWriter(/* Is64Bit */ true, OSABI, ELF::EM_VE,
265ffd83dbSDimitry Andric                                 /* HasRelocationAddend */ true) {}
275ffd83dbSDimitry Andric 
285ffd83dbSDimitry Andric   ~VEELFObjectWriter() override {}
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 
345ffd83dbSDimitry Andric   bool needsRelocateWithSymbol(const MCSymbol &Sym,
355ffd83dbSDimitry Andric                                unsigned Type) const override;
365ffd83dbSDimitry Andric };
375ffd83dbSDimitry Andric } // namespace
385ffd83dbSDimitry Andric 
395ffd83dbSDimitry 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:
50*0eae32dcSDimitry Andric       Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");
51*0eae32dcSDimitry Andric       return ELF::R_VE_NONE;
52*0eae32dcSDimitry Andric     case FK_Data_1:
535ffd83dbSDimitry Andric     case FK_PCRel_1:
54*0eae32dcSDimitry Andric       Ctx.reportError(Fixup.getLoc(),
55*0eae32dcSDimitry Andric                       "1-byte pc-relative data relocation is not supported");
56*0eae32dcSDimitry Andric       return ELF::R_VE_NONE;
57*0eae32dcSDimitry Andric     case FK_Data_2:
585ffd83dbSDimitry Andric     case FK_PCRel_2:
59*0eae32dcSDimitry Andric       Ctx.reportError(Fixup.getLoc(),
60*0eae32dcSDimitry Andric                       "2-byte pc-relative data relocation is not supported");
61*0eae32dcSDimitry Andric       return ELF::R_VE_NONE;
62*0eae32dcSDimitry Andric     case FK_Data_4:
635ffd83dbSDimitry Andric     case FK_PCRel_4:
64*0eae32dcSDimitry Andric       return ELF::R_VE_SREL32;
65*0eae32dcSDimitry Andric     case FK_Data_8:
665ffd83dbSDimitry Andric     case FK_PCRel_8:
67*0eae32dcSDimitry Andric       Ctx.reportError(Fixup.getLoc(),
68*0eae32dcSDimitry Andric                       "8-byte pc-relative data relocation is not supported");
69*0eae32dcSDimitry Andric       return ELF::R_VE_NONE;
70*0eae32dcSDimitry Andric     case VE::fixup_ve_reflong:
71*0eae32dcSDimitry Andric     case VE::fixup_ve_srel32:
72*0eae32dcSDimitry 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:
82*0eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
83*0eae32dcSDimitry Andric     return ELF::R_VE_NONE;
845ffd83dbSDimitry Andric   case FK_Data_1:
85*0eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(), "1-byte data relocation is not supported");
86*0eae32dcSDimitry Andric     return ELF::R_VE_NONE;
875ffd83dbSDimitry Andric   case FK_Data_2:
88*0eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(), "2-byte data relocation is not supported");
89*0eae32dcSDimitry 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;
96*0eae32dcSDimitry Andric   case VE::fixup_ve_srel32:
97*0eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(),
98*0eae32dcSDimitry Andric                     "A non pc-relative srel32 relocation is not supported");
99*0eae32dcSDimitry 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:
105*0eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(),
106*0eae32dcSDimitry Andric                     "A non pc-relative pc_hi32 relocation is not supported");
107*0eae32dcSDimitry Andric     return ELF::R_VE_NONE;
1085ffd83dbSDimitry Andric   case VE::fixup_ve_pc_lo32:
109*0eae32dcSDimitry Andric     Ctx.reportError(Fixup.getLoc(),
110*0eae32dcSDimitry Andric                     "A non pc-relative pc_lo32 relocation is not supported");
111*0eae32dcSDimitry 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 
1375ffd83dbSDimitry Andric bool VEELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
1385ffd83dbSDimitry Andric                                                 unsigned Type) const {
1395ffd83dbSDimitry Andric   switch (Type) {
1405ffd83dbSDimitry Andric   default:
1415ffd83dbSDimitry Andric     return false;
1425ffd83dbSDimitry Andric 
1435ffd83dbSDimitry Andric   // All relocations that use a GOT need a symbol, not an offset, as
1445ffd83dbSDimitry Andric   // the offset of the symbol within the section is irrelevant to
1455ffd83dbSDimitry Andric   // where the GOT entry is. Don't need to list all the TLS entries,
1465ffd83dbSDimitry Andric   // as they're all marked as requiring a symbol anyways.
1475ffd83dbSDimitry Andric   case ELF::R_VE_GOT_HI32:
1485ffd83dbSDimitry Andric   case ELF::R_VE_GOT_LO32:
1495ffd83dbSDimitry Andric   case ELF::R_VE_GOTOFF_HI32:
1505ffd83dbSDimitry Andric   case ELF::R_VE_GOTOFF_LO32:
1515ffd83dbSDimitry Andric   case ELF::R_VE_TLS_GD_HI32:
1525ffd83dbSDimitry Andric   case ELF::R_VE_TLS_GD_LO32:
1535ffd83dbSDimitry Andric     return true;
1545ffd83dbSDimitry Andric   }
1555ffd83dbSDimitry Andric }
1565ffd83dbSDimitry Andric 
1575ffd83dbSDimitry Andric std::unique_ptr<MCObjectTargetWriter>
1585ffd83dbSDimitry Andric llvm::createVEELFObjectWriter(uint8_t OSABI) {
1595ffd83dbSDimitry Andric   return std::make_unique<VEELFObjectWriter>(OSABI);
1605ffd83dbSDimitry Andric }
161