LLVM 20.0.0git
ARMELFObjectWriter.cpp
Go to the documentation of this file.
1//===-- ARMELFObjectWriter.cpp - ARM 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
12#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCExpr.h"
15#include "llvm/MC/MCFixup.h"
18#include "llvm/MC/MCValue.h"
19#include "llvm/Object/ELF.h"
22#include <cstdint>
23
24using namespace llvm;
25
26namespace {
27
28 class ARMELFObjectWriter : public MCELFObjectTargetWriter {
29 enum { DefaultEABIVersion = 0x05000000U };
30
31 unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
32 bool IsPCRel, MCContext &Ctx) const;
33
34 public:
35 ARMELFObjectWriter(uint8_t OSABI);
36
37 ~ARMELFObjectWriter() override = default;
38
39 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
40 const MCFixup &Fixup, bool IsPCRel) const override;
41
42 bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
43 unsigned Type) const override;
44 };
45
46} // end anonymous namespace
47
48ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
49 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
50 ELF::EM_ARM,
51 /*HasRelocationAddend*/ false) {}
52
53bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
54 const MCSymbol &,
55 unsigned Type) const {
56 // FIXME: This is extremely conservative. This really needs to use an
57 // explicit list with a clear explanation for why each realocation needs to
58 // point to the symbol, not to the section.
59 switch (Type) {
60 default:
61 return true;
62
63 case ELF::R_ARM_PREL31:
64 case ELF::R_ARM_ABS32:
65 return false;
66 }
67}
68
69// Need to examine the Fixup when determining whether to
70// emit the relocation as an explicit symbol or as a section relative
71// offset
72unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
73 const MCFixup &Fixup,
74 bool IsPCRel) const {
75 return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
76}
77
78unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
79 const MCFixup &Fixup,
80 bool IsPCRel,
81 MCContext &Ctx) const {
82 unsigned Kind = Fixup.getTargetKind();
85 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
86 auto CheckFDPIC = [&](uint32_t Type) {
87 if (getOSABI() != ELF::ELFOSABI_ARM_FDPIC)
88 Ctx.reportError(Fixup.getLoc(),
89 "relocation " +
91 " only supported in FDPIC mode");
92 return Type;
93 };
94
95 if (IsPCRel) {
96 switch (Fixup.getTargetKind()) {
97 default:
98 Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
99 return ELF::R_ARM_NONE;
100 case FK_Data_4:
101 switch (Modifier) {
102 default:
103 Ctx.reportError(Fixup.getLoc(),
104 "invalid fixup for 4-byte pc-relative data relocation");
105 return ELF::R_ARM_NONE;
107 if (const MCSymbolRefExpr *SymRef = Target.getSymA()) {
108 // For GNU AS compatibility expressions such as
109 // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation.
110 if (SymRef->getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_")
111 return ELF::R_ARM_BASE_PREL;
112 }
113 return ELF::R_ARM_REL32;
114 }
116 return ELF::R_ARM_TLS_IE32;
118 return ELF::R_ARM_GOT_PREL;
120 return ELF::R_ARM_PREL31;
121 }
124 switch (Modifier) {
126 return ELF::R_ARM_CALL;
128 return ELF::R_ARM_TLS_CALL;
129 default:
130 return ELF::R_ARM_CALL;
131 }
135 return ELF::R_ARM_JUMP24;
137 return ELF::R_ARM_THM_JUMP19;
139 return ELF::R_ARM_THM_JUMP24;
141 return ELF::R_ARM_MOVT_PREL;
143 return ELF::R_ARM_MOVW_PREL_NC;
145 return ELF::R_ARM_THM_MOVT_PREL;
147 return ELF::R_ARM_THM_MOVW_PREL_NC;
149 return ELF::R_ARM_THM_ALU_ABS_G3;
151 return ELF::R_ARM_THM_ALU_ABS_G2_NC;
153 return ELF::R_ARM_THM_ALU_ABS_G1_NC;
155 return ELF::R_ARM_THM_ALU_ABS_G0_NC;
157 return ELF::R_ARM_THM_JUMP11;
159 return ELF::R_ARM_THM_JUMP8;
162 switch (Modifier) {
164 return ELF::R_ARM_THM_TLS_CALL;
165 default:
166 return ELF::R_ARM_THM_CALL;
167 }
169 return ELF::R_ARM_LDR_PC_G0;
171 return ELF::R_ARM_LDRS_PC_G0;
173 return ELF::R_ARM_THM_PC12;
175 return ELF::R_ARM_ALU_PC_G0;
177 return ELF::R_ARM_THM_PC8;
179 return ELF::R_ARM_THM_ALU_PREL_11_0;
181 return ELF::R_ARM_THM_BF16;
183 return ELF::R_ARM_THM_BF12;
185 return ELF::R_ARM_THM_BF18;
186 }
187 }
188 switch (Kind) {
189 default:
190 Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
191 return ELF::R_ARM_NONE;
192 case FK_Data_1:
193 switch (Modifier) {
194 default:
195 Ctx.reportError(Fixup.getLoc(),
196 "invalid fixup for 1-byte data relocation");
197 return ELF::R_ARM_NONE;
199 return ELF::R_ARM_ABS8;
200 }
201 case FK_Data_2:
202 switch (Modifier) {
203 default:
204 Ctx.reportError(Fixup.getLoc(),
205 "invalid fixup for 2-byte data relocation");
206 return ELF::R_ARM_NONE;
208 return ELF::R_ARM_ABS16;
209 }
210 case FK_Data_4:
211 switch (Modifier) {
212 default:
213 Ctx.reportError(Fixup.getLoc(),
214 "invalid fixup for 4-byte data relocation");
215 return ELF::R_ARM_NONE;
217 return ELF::R_ARM_NONE;
219 return ELF::R_ARM_GOT_BREL;
221 return ELF::R_ARM_TLS_GD32;
223 return ELF::R_ARM_TLS_LE32;
225 return ELF::R_ARM_TLS_IE32;
227 return ELF::R_ARM_ABS32;
229 return ELF::R_ARM_GOTOFF32;
231 return ELF::R_ARM_GOT_PREL;
233 return ELF::R_ARM_TARGET1;
235 return ELF::R_ARM_TARGET2;
237 return ELF::R_ARM_PREL31;
239 return ELF::R_ARM_SBREL32;
241 return ELF::R_ARM_TLS_LDO32;
243 return ELF::R_ARM_TLS_CALL;
245 return ELF::R_ARM_TLS_GOTDESC;
247 return ELF::R_ARM_TLS_LDM32;
249 return ELF::R_ARM_TLS_DESCSEQ;
251 return CheckFDPIC(ELF::R_ARM_FUNCDESC);
253 return CheckFDPIC(ELF::R_ARM_GOTFUNCDESC);
255 return CheckFDPIC(ELF::R_ARM_GOTOFFFUNCDESC);
257 return CheckFDPIC(ELF::R_ARM_TLS_GD32_FDPIC);
259 return CheckFDPIC(ELF::R_ARM_TLS_LDM32_FDPIC);
261 return CheckFDPIC(ELF::R_ARM_TLS_IE32_FDPIC);
262 }
265 return ELF::R_ARM_JUMP24;
267 switch (Modifier) {
268 default:
269 Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVT instruction");
270 return ELF::R_ARM_NONE;
272 return ELF::R_ARM_MOVT_ABS;
274 return ELF::R_ARM_MOVT_BREL;
275 }
277 switch (Modifier) {
278 default:
279 Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVW instruction");
280 return ELF::R_ARM_NONE;
282 return ELF::R_ARM_MOVW_ABS_NC;
284 return ELF::R_ARM_MOVW_BREL_NC;
285 }
287 switch (Modifier) {
288 default:
289 Ctx.reportError(Fixup.getLoc(),
290 "invalid fixup for Thumb MOVT instruction");
291 return ELF::R_ARM_NONE;
293 return ELF::R_ARM_THM_MOVT_ABS;
295 return ELF::R_ARM_THM_MOVT_BREL;
296 }
298 switch (Modifier) {
299 default:
300 Ctx.reportError(Fixup.getLoc(),
301 "invalid fixup for Thumb MOVW instruction");
302 return ELF::R_ARM_NONE;
304 return ELF::R_ARM_THM_MOVW_ABS_NC;
306 return ELF::R_ARM_THM_MOVW_BREL_NC;
307 }
308
310 return ELF::R_ARM_THM_ALU_ABS_G3;
312 return ELF::R_ARM_THM_ALU_ABS_G2_NC;
314 return ELF::R_ARM_THM_ALU_ABS_G1_NC;
316 return ELF::R_ARM_THM_ALU_ABS_G0_NC;
317 }
318}
319
320std::unique_ptr<MCObjectTargetWriter>
322 return std::make_unique<ARMELFObjectWriter>(OSABI);
323}
Symbol * Sym
Definition: ELF_riscv.cpp:479
PowerPC TLS Dynamic Call Fixup
Context object for machine code objects.
Definition: MCContext.h:83
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1068
virtual bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const
virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const =0
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:188
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
This represents an "assembler immediate".
Definition: MCValue.h:36
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
@ fixup_arm_thumb_br
Definition: ARMFixupKinds.h:60
@ fixup_thumb_adr_pcrel_10
Definition: ARMFixupKinds.h:43
@ fixup_arm_thumb_upper_8_15
@ fixup_arm_adr_pcrel_12
Definition: ARMFixupKinds.h:45
@ fixup_arm_uncondbranch
Definition: ARMFixupKinds.h:51
@ fixup_arm_movw_lo16
Definition: ARMFixupKinds.h:98
@ fixup_t2_movt_hi16
Definition: ARMFixupKinds.h:99
@ fixup_t2_ldst_pcrel_12
Definition: ARMFixupKinds.h:21
@ fixup_arm_thumb_lower_0_7
@ fixup_arm_movt_hi16
Definition: ARMFixupKinds.h:97
@ fixup_arm_thumb_blx
Definition: ARMFixupKinds.h:84
@ fixup_t2_uncondbranch
Definition: ARMFixupKinds.h:57
@ fixup_arm_uncondbl
Definition: ARMFixupKinds.h:72
@ fixup_arm_pcrel_10_unscaled
Definition: ARMFixupKinds.h:25
@ fixup_arm_thumb_bcc
Definition: ARMFixupKinds.h:93
@ fixup_arm_thumb_upper_0_7
@ fixup_t2_adr_pcrel_12
Definition: ARMFixupKinds.h:47
@ fixup_t2_condbranch
Definition: ARMFixupKinds.h:54
@ fixup_arm_condbl
Definition: ARMFixupKinds.h:75
@ fixup_arm_ldst_pcrel_12
Definition: ARMFixupKinds.h:18
@ fixup_arm_thumb_lower_8_15
@ fixup_arm_thumb_bl
Definition: ARMFixupKinds.h:81
@ fixup_t2_movw_lo16
@ fixup_arm_condbranch
Definition: ARMFixupKinds.h:49
@ EM_ARM
Definition: ELF.h:157
@ ELFOSABI_ARM_FDPIC
Definition: ELF.h:366
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition: ELF.cpp:23
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:23
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:25
@ FK_Data_2
A two-byte fixup.
Definition: MCFixup.h:24
std::unique_ptr< MCObjectTargetWriter > createARMELFObjectWriter(uint8_t OSABI)
Construct an ELF Mach-O object writer.