1 //===-- VEELFObjectWriter.cpp - VE ELF Writer -----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "VEFixupKinds.h"
11 #include "VEMCTargetDesc.h"
12 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCELFObjectWriter.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCObjectWriter.h"
16 #include "llvm/MC/MCValue.h"
17 #include "llvm/Support/ErrorHandling.h"
22 class VEELFObjectWriter
: public MCELFObjectTargetWriter
{
24 VEELFObjectWriter(uint8_t OSABI
)
25 : MCELFObjectTargetWriter(/* Is64Bit */ true, OSABI
, ELF::EM_VE
,
26 /* HasRelocationAddend */ true) {}
28 ~VEELFObjectWriter() override
= default;
31 unsigned getRelocType(MCContext
&Ctx
, const MCValue
&Target
,
32 const MCFixup
&Fixup
, bool IsPCRel
) const override
;
34 bool needsRelocateWithSymbol(const MCValue
&Val
, const MCSymbol
&Sym
,
35 unsigned Type
) const override
;
39 unsigned VEELFObjectWriter::getRelocType(MCContext
&Ctx
, const MCValue
&Target
,
42 if (const VEMCExpr
*SExpr
= dyn_cast
<VEMCExpr
>(Fixup
.getValue())) {
43 if (SExpr
->getKind() == VEMCExpr::VK_VE_PC_LO32
)
44 return ELF::R_VE_PC_LO32
;
48 switch (Fixup
.getTargetKind()) {
50 Ctx
.reportError(Fixup
.getLoc(), "Unsupported pc-relative fixup kind");
51 return ELF::R_VE_NONE
;
54 Ctx
.reportError(Fixup
.getLoc(),
55 "1-byte pc-relative data relocation is not supported");
56 return ELF::R_VE_NONE
;
59 Ctx
.reportError(Fixup
.getLoc(),
60 "2-byte pc-relative data relocation is not supported");
61 return ELF::R_VE_NONE
;
64 return ELF::R_VE_SREL32
;
67 Ctx
.reportError(Fixup
.getLoc(),
68 "8-byte pc-relative data relocation is not supported");
69 return ELF::R_VE_NONE
;
70 case VE::fixup_ve_reflong
:
71 case VE::fixup_ve_srel32
:
72 return ELF::R_VE_SREL32
;
73 case VE::fixup_ve_pc_hi32
:
74 return ELF::R_VE_PC_HI32
;
75 case VE::fixup_ve_pc_lo32
:
76 return ELF::R_VE_PC_LO32
;
80 switch (Fixup
.getTargetKind()) {
82 Ctx
.reportError(Fixup
.getLoc(), "Unknown ELF relocation type");
83 return ELF::R_VE_NONE
;
85 Ctx
.reportError(Fixup
.getLoc(), "1-byte data relocation is not supported");
86 return ELF::R_VE_NONE
;
88 Ctx
.reportError(Fixup
.getLoc(), "2-byte data relocation is not supported");
89 return ELF::R_VE_NONE
;
91 return ELF::R_VE_REFLONG
;
93 return ELF::R_VE_REFQUAD
;
94 case VE::fixup_ve_reflong
:
95 return ELF::R_VE_REFLONG
;
96 case VE::fixup_ve_srel32
:
97 Ctx
.reportError(Fixup
.getLoc(),
98 "A non pc-relative srel32 relocation is not supported");
99 return ELF::R_VE_NONE
;
100 case VE::fixup_ve_hi32
:
101 return ELF::R_VE_HI32
;
102 case VE::fixup_ve_lo32
:
103 return ELF::R_VE_LO32
;
104 case VE::fixup_ve_pc_hi32
:
105 Ctx
.reportError(Fixup
.getLoc(),
106 "A non pc-relative pc_hi32 relocation is not supported");
107 return ELF::R_VE_NONE
;
108 case VE::fixup_ve_pc_lo32
:
109 Ctx
.reportError(Fixup
.getLoc(),
110 "A non pc-relative pc_lo32 relocation is not supported");
111 return ELF::R_VE_NONE
;
112 case VE::fixup_ve_got_hi32
:
113 return ELF::R_VE_GOT_HI32
;
114 case VE::fixup_ve_got_lo32
:
115 return ELF::R_VE_GOT_LO32
;
116 case VE::fixup_ve_gotoff_hi32
:
117 return ELF::R_VE_GOTOFF_HI32
;
118 case VE::fixup_ve_gotoff_lo32
:
119 return ELF::R_VE_GOTOFF_LO32
;
120 case VE::fixup_ve_plt_hi32
:
121 return ELF::R_VE_PLT_HI32
;
122 case VE::fixup_ve_plt_lo32
:
123 return ELF::R_VE_PLT_LO32
;
124 case VE::fixup_ve_tls_gd_hi32
:
125 return ELF::R_VE_TLS_GD_HI32
;
126 case VE::fixup_ve_tls_gd_lo32
:
127 return ELF::R_VE_TLS_GD_LO32
;
128 case VE::fixup_ve_tpoff_hi32
:
129 return ELF::R_VE_TPOFF_HI32
;
130 case VE::fixup_ve_tpoff_lo32
:
131 return ELF::R_VE_TPOFF_LO32
;
134 return ELF::R_VE_NONE
;
137 bool VEELFObjectWriter::needsRelocateWithSymbol(const MCValue
&,
139 unsigned Type
) const {
144 // All relocations that use a GOT need a symbol, not an offset, as
145 // the offset of the symbol within the section is irrelevant to
146 // where the GOT entry is. Don't need to list all the TLS entries,
147 // as they're all marked as requiring a symbol anyways.
148 case ELF::R_VE_GOT_HI32
:
149 case ELF::R_VE_GOT_LO32
:
150 case ELF::R_VE_GOTOFF_HI32
:
151 case ELF::R_VE_GOTOFF_LO32
:
152 case ELF::R_VE_TLS_GD_HI32
:
153 case ELF::R_VE_TLS_GD_LO32
:
158 std::unique_ptr
<MCObjectTargetWriter
>
159 llvm::createVEELFObjectWriter(uint8_t OSABI
) {
160 return std::make_unique
<VEELFObjectWriter
>(OSABI
);