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"
21#include <cstdint>
22
23using namespace llvm;
24
25namespace {
26
27 class ARMELFObjectWriter : public MCELFObjectTargetWriter {
28 enum { DefaultEABIVersion = 0x05000000U };
29
30 unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
31 bool IsPCRel, MCContext &Ctx) const;
32
33 public:
34 ARMELFObjectWriter(uint8_t OSABI);
35
36 ~ARMELFObjectWriter() override = default;
37
38 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
39 const MCFixup &Fixup, bool IsPCRel) const override;
40
41 bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
42 unsigned Type) const override;
43 };
44
45} // end anonymous namespace
46
47ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
48 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
49 ELF::EM_ARM,
50 /*HasRelocationAddend*/ false) {}
51
52bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
53 const MCSymbol &,
54 unsigned Type) const {
55 // FIXME: This is extremely conservative. This really needs to use an
56 // explicit list with a clear explanation for why each realocation needs to
57 // point to the symbol, not to the section.
58 switch (Type) {
59 default:
60 return true;
61
62 case ELF::R_ARM_PREL31:
63 case ELF::R_ARM_ABS32:
64 return false;
65 }
66}
67
68// Need to examine the Fixup when determining whether to
69// emit the relocation as an explicit symbol or as a section relative
70// offset
71unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
72 const MCFixup &Fixup,
73 bool IsPCRel) const {
74 return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
75}
76
77unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
78 const MCFixup &Fixup,
79 bool IsPCRel,
80 MCContext &Ctx) const {
81 unsigned Kind = Fixup.getTargetKind();
84 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
85 auto CheckFDPIC = [&](uint32_t Type) {
86 if (getOSABI() != ELF::ELFOSABI_ARM_FDPIC)
87 Ctx.reportError(Fixup.getLoc(),
88 "relocation " +
90 " only supported in FDPIC mode");
91 return Type;
92 };
93
94 if (IsPCRel) {
95 switch (Fixup.getTargetKind()) {
96 default:
97 Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
98 return ELF::R_ARM_NONE;
99 case FK_Data_4:
100 switch (Modifier) {
101 default:
102 Ctx.reportError(Fixup.getLoc(),
103 "invalid fixup for 4-byte pc-relative data relocation");
104 return ELF::R_ARM_NONE;
106 if (const MCSymbolRefExpr *SymRef = Target.getSymA()) {
107 // For GNU AS compatibility expressions such as
108 // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation.
109 if (SymRef->getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_")
110 return ELF::R_ARM_BASE_PREL;
111 }
112 return ELF::R_ARM_REL32;
113 }
115 return ELF::R_ARM_TLS_IE32;
117 return ELF::R_ARM_GOT_PREL;
119 return ELF::R_ARM_PREL31;
120 }
123 switch (Modifier) {
125 return ELF::R_ARM_CALL;
127 return ELF::R_ARM_TLS_CALL;
128 default:
129 return ELF::R_ARM_CALL;
130 }
134 return ELF::R_ARM_JUMP24;
136 return ELF::R_ARM_THM_JUMP19;
138 return ELF::R_ARM_THM_JUMP24;
140 return ELF::R_ARM_MOVT_PREL;
142 return ELF::R_ARM_MOVW_PREL_NC;
144 return ELF::R_ARM_THM_MOVT_PREL;
146 return ELF::R_ARM_THM_MOVW_PREL_NC;
148 return ELF::R_ARM_THM_ALU_ABS_G3;
150 return ELF::R_ARM_THM_ALU_ABS_G2_NC;
152 return ELF::R_ARM_THM_ALU_ABS_G1_NC;
154 return ELF::R_ARM_THM_ALU_ABS_G0_NC;
156 return ELF::R_ARM_THM_JUMP11;
158 return ELF::R_ARM_THM_JUMP8;
161 switch (Modifier) {
163 return ELF::R_ARM_THM_TLS_CALL;
164 default:
165 return ELF::R_ARM_THM_CALL;
166 }
168 return ELF::R_ARM_LDR_PC_G0;
170 return ELF::R_ARM_LDRS_PC_G0;
172 return ELF::R_ARM_THM_PC12;
174 return ELF::R_ARM_ALU_PC_G0;
176 return ELF::R_ARM_THM_PC8;
178 return ELF::R_ARM_THM_ALU_PREL_11_0;
180 return ELF::R_ARM_THM_BF16;
182 return ELF::R_ARM_THM_BF12;
184 return ELF::R_ARM_THM_BF18;
185 }
186 }
187 switch (Kind) {
188 default:
189 Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
190 return ELF::R_ARM_NONE;
191 case FK_Data_1:
192 switch (Modifier) {
193 default:
194 Ctx.reportError(Fixup.getLoc(),
195 "invalid fixup for 1-byte data relocation");
196 return ELF::R_ARM_NONE;
198 return ELF::R_ARM_ABS8;
199 }
200 case FK_Data_2:
201 switch (Modifier) {
202 default:
203 Ctx.reportError(Fixup.getLoc(),
204 "invalid fixup for 2-byte data relocation");
205 return ELF::R_ARM_NONE;
207 return ELF::R_ARM_ABS16;
208 }
209 case FK_Data_4:
210 switch (Modifier) {
211 default:
212 Ctx.reportError(Fixup.getLoc(),
213 "invalid fixup for 4-byte data relocation");
214 return ELF::R_ARM_NONE;
216 return ELF::R_ARM_NONE;
218 return ELF::R_ARM_GOT_BREL;
220 return ELF::R_ARM_TLS_GD32;
222 return ELF::R_ARM_TLS_LE32;
224 return ELF::R_ARM_TLS_IE32;
226 return ELF::R_ARM_ABS32;
228 return ELF::R_ARM_GOTOFF32;
230 return ELF::R_ARM_GOT_PREL;
232 return ELF::R_ARM_TARGET1;
234 return ELF::R_ARM_TARGET2;
236 return ELF::R_ARM_PREL31;
238 return ELF::R_ARM_SBREL32;
240 return ELF::R_ARM_TLS_LDO32;
242 return ELF::R_ARM_TLS_CALL;
244 return ELF::R_ARM_TLS_GOTDESC;
246 return ELF::R_ARM_TLS_LDM32;
248 return ELF::R_ARM_TLS_DESCSEQ;
250 return CheckFDPIC(ELF::R_ARM_FUNCDESC);
252 return CheckFDPIC(ELF::R_ARM_GOTFUNCDESC);
254 return CheckFDPIC(ELF::R_ARM_GOTOFFFUNCDESC);
256 return CheckFDPIC(ELF::R_ARM_TLS_GD32_FDPIC);
258 return CheckFDPIC(ELF::R_ARM_TLS_LDM32_FDPIC);
260 return CheckFDPIC(ELF::R_ARM_TLS_IE32_FDPIC);
261 }
264 return ELF::R_ARM_JUMP24;
266 switch (Modifier) {
267 default:
268 Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVT instruction");
269 return ELF::R_ARM_NONE;
271 return ELF::R_ARM_MOVT_ABS;
273 return ELF::R_ARM_MOVT_BREL;
274 }
276 switch (Modifier) {
277 default:
278 Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVW instruction");
279 return ELF::R_ARM_NONE;
281 return ELF::R_ARM_MOVW_ABS_NC;
283 return ELF::R_ARM_MOVW_BREL_NC;
284 }
286 switch (Modifier) {
287 default:
288 Ctx.reportError(Fixup.getLoc(),
289 "invalid fixup for Thumb MOVT instruction");
290 return ELF::R_ARM_NONE;
292 return ELF::R_ARM_THM_MOVT_ABS;
294 return ELF::R_ARM_THM_MOVT_BREL;
295 }
297 switch (Modifier) {
298 default:
299 Ctx.reportError(Fixup.getLoc(),
300 "invalid fixup for Thumb MOVW instruction");
301 return ELF::R_ARM_NONE;
303 return ELF::R_ARM_THM_MOVW_ABS_NC;
305 return ELF::R_ARM_THM_MOVW_BREL_NC;
306 }
307
309 return ELF::R_ARM_THM_ALU_ABS_G3;
311 return ELF::R_ARM_THM_ALU_ABS_G2_NC;
313 return ELF::R_ARM_THM_ALU_ABS_G1_NC;
315 return ELF::R_ARM_THM_ALU_ABS_G0_NC;
316 }
317}
318
319std::unique_ptr<MCObjectTargetWriter>
321 return std::make_unique<ARMELFObjectWriter>(OSABI);
322}
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:1072
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:192
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
@ ELFOSABI_ARM_FDPIC
Definition: ELF.h:368
@ EM_ARM
Definition: ELF.h:159
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition: ELF.cpp:24
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.