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