LLVM 18.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"
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 void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override;
45 };
46
47} // end anonymous namespace
48
49ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
50 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
51 ELF::EM_ARM,
52 /*HasRelocationAddend*/ false) {}
53
54bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
55 const MCSymbol &,
56 unsigned Type) const {
57 // FIXME: This is extremely conservative. This really needs to use an
58 // explicit list with a clear explanation for why each realocation needs to
59 // point to the symbol, not to the section.
60 switch (Type) {
61 default:
62 return true;
63
64 case ELF::R_ARM_PREL31:
65 case ELF::R_ARM_ABS32:
66 return false;
67 }
68}
69
70// Need to examine the Fixup when determining whether to
71// emit the relocation as an explicit symbol or as a section relative
72// offset
73unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
74 const MCFixup &Fixup,
75 bool IsPCRel) const {
76 return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
77}
78
79unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
80 const MCFixup &Fixup,
81 bool IsPCRel,
82 MCContext &Ctx) const {
83 unsigned Kind = Fixup.getTargetKind();
86 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
87
88 if (IsPCRel) {
89 switch (Fixup.getTargetKind()) {
90 default:
91 Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
92 return ELF::R_ARM_NONE;
93 case FK_Data_4:
94 switch (Modifier) {
95 default:
96 Ctx.reportError(Fixup.getLoc(),
97 "invalid fixup for 4-byte pc-relative data relocation");
98 return ELF::R_ARM_NONE;
100 if (const MCSymbolRefExpr *SymRef = Target.getSymA()) {
101 // For GNU AS compatibility expressions such as
102 // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation.
103 if (SymRef->getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_")
104 return ELF::R_ARM_BASE_PREL;
105 }
106 return ELF::R_ARM_REL32;
107 }
109 return ELF::R_ARM_TLS_IE32;
111 return ELF::R_ARM_GOT_PREL;
113 return ELF::R_ARM_PREL31;
114 }
117 switch (Modifier) {
119 return ELF::R_ARM_CALL;
121 return ELF::R_ARM_TLS_CALL;
122 default:
123 return ELF::R_ARM_CALL;
124 }
128 return ELF::R_ARM_JUMP24;
130 return ELF::R_ARM_THM_JUMP19;
132 return ELF::R_ARM_THM_JUMP24;
134 return ELF::R_ARM_MOVT_PREL;
136 return ELF::R_ARM_MOVW_PREL_NC;
138 return ELF::R_ARM_THM_MOVT_PREL;
140 return ELF::R_ARM_THM_MOVW_PREL_NC;
142 return ELF::R_ARM_THM_ALU_ABS_G3;
144 return ELF::R_ARM_THM_ALU_ABS_G2_NC;
146 return ELF::R_ARM_THM_ALU_ABS_G1_NC;
148 return ELF::R_ARM_THM_ALU_ABS_G0_NC;
150 return ELF::R_ARM_THM_JUMP11;
152 return ELF::R_ARM_THM_JUMP8;
155 switch (Modifier) {
157 return ELF::R_ARM_THM_TLS_CALL;
158 default:
159 return ELF::R_ARM_THM_CALL;
160 }
162 return ELF::R_ARM_LDR_PC_G0;
164 return ELF::R_ARM_LDRS_PC_G0;
166 return ELF::R_ARM_THM_PC12;
168 return ELF::R_ARM_ALU_PC_G0;
170 return ELF::R_ARM_THM_PC8;
172 return ELF::R_ARM_THM_ALU_PREL_11_0;
174 return ELF::R_ARM_THM_BF16;
176 return ELF::R_ARM_THM_BF12;
178 return ELF::R_ARM_THM_BF18;
179 }
180 }
181 switch (Kind) {
182 default:
183 Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
184 return ELF::R_ARM_NONE;
185 case FK_Data_1:
186 switch (Modifier) {
187 default:
188 Ctx.reportError(Fixup.getLoc(),
189 "invalid fixup for 1-byte data relocation");
190 return ELF::R_ARM_NONE;
192 return ELF::R_ARM_ABS8;
193 }
194 case FK_Data_2:
195 switch (Modifier) {
196 default:
197 Ctx.reportError(Fixup.getLoc(),
198 "invalid fixup for 2-byte data relocation");
199 return ELF::R_ARM_NONE;
201 return ELF::R_ARM_ABS16;
202 }
203 case FK_Data_4:
204 switch (Modifier) {
205 default:
206 Ctx.reportError(Fixup.getLoc(),
207 "invalid fixup for 4-byte data relocation");
208 return ELF::R_ARM_NONE;
210 return ELF::R_ARM_NONE;
212 return ELF::R_ARM_GOT_BREL;
214 return ELF::R_ARM_TLS_GD32;
216 return ELF::R_ARM_TLS_LE32;
218 return ELF::R_ARM_TLS_IE32;
220 return ELF::R_ARM_ABS32;
222 return ELF::R_ARM_GOTOFF32;
224 return ELF::R_ARM_GOT_PREL;
226 return ELF::R_ARM_TARGET1;
228 return ELF::R_ARM_TARGET2;
230 return ELF::R_ARM_PREL31;
232 return ELF::R_ARM_SBREL32;
234 return ELF::R_ARM_TLS_LDO32;
236 return ELF::R_ARM_TLS_CALL;
238 return ELF::R_ARM_TLS_GOTDESC;
240 return ELF::R_ARM_TLS_LDM32;
242 return ELF::R_ARM_TLS_DESCSEQ;
243 }
246 return ELF::R_ARM_JUMP24;
248 switch (Modifier) {
249 default:
250 Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVT instruction");
251 return ELF::R_ARM_NONE;
253 return ELF::R_ARM_MOVT_ABS;
255 return ELF::R_ARM_MOVT_BREL;
256 }
258 switch (Modifier) {
259 default:
260 Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVW instruction");
261 return ELF::R_ARM_NONE;
263 return ELF::R_ARM_MOVW_ABS_NC;
265 return ELF::R_ARM_MOVW_BREL_NC;
266 }
268 switch (Modifier) {
269 default:
270 Ctx.reportError(Fixup.getLoc(),
271 "invalid fixup for Thumb MOVT instruction");
272 return ELF::R_ARM_NONE;
274 return ELF::R_ARM_THM_MOVT_ABS;
276 return ELF::R_ARM_THM_MOVT_BREL;
277 }
279 switch (Modifier) {
280 default:
281 Ctx.reportError(Fixup.getLoc(),
282 "invalid fixup for Thumb MOVW instruction");
283 return ELF::R_ARM_NONE;
285 return ELF::R_ARM_THM_MOVW_ABS_NC;
287 return ELF::R_ARM_THM_MOVW_BREL_NC;
288 }
289
291 return ELF::R_ARM_THM_ALU_ABS_G3;
293 return ELF::R_ARM_THM_ALU_ABS_G2_NC;
295 return ELF::R_ARM_THM_ALU_ABS_G1_NC;
297 return ELF::R_ARM_THM_ALU_ABS_G0_NC;
298 }
299}
300
301void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
302 MCSectionELF &Sec) {
303 // The mix of execute-only and non-execute-only at link time is
304 // non-execute-only. To avoid the empty implicitly created .text
305 // section from making the whole .text section non-execute-only, we
306 // mark it execute-only if it is empty and there is at least one
307 // execute-only section in the object.
308 MCSectionELF *TextSection =
309 static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
310 if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions()) {
311 for (auto &F : TextSection->getFragmentList())
312 if (auto *DF = dyn_cast<MCDataFragment>(&F))
313 if (!DF->getContents().empty())
314 return;
315 TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
316 }
317}
318
319std::unique_ptr<MCObjectTargetWriter>
321 return std::make_unique<ARMELFObjectWriter>(OSABI);
322}
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
Symbol * Sym
Definition: ELF_riscv.cpp:477
#define F(x, y, z)
Definition: MD5.cpp:55
PowerPC TLS Dynamic Call Fixup
Context object for machine code objects.
Definition: MCContext.h:76
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:450
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1058
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
virtual void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec)
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
MCSection * getTextSection() const
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:26
unsigned getFlags() const
Definition: MCSectionELF.h:73
void setFlags(unsigned F)
Definition: MCSectionELF.h:75
MCSection::FragmentListType & getFragmentList()
Definition: MCSection.h:172
bool hasInstructions() const
Definition: MCSection.h:166
SectionKind getKind() const
Definition: MCSection.h:125
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:40
This represents an "assembler immediate".
Definition: MCValue.h:36
bool isExecuteOnly() const
Definition: SectionKind.h:129
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:156
@ SHF_ARM_PURECODE
Definition: ELF.h:1188
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.