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