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