LLVM 22.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
13#include "llvm/MC/MCAssembler.h"
14#include "llvm/MC/MCContext.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCFixup.h"
19#include "llvm/MC/MCValue.h"
20#include "llvm/Object/ELF.h"
22#include <cstdint>
23
24using namespace llvm;
25
26namespace {
27
28class ARMELFObjectWriter : public MCELFObjectTargetWriter {
29 enum { DefaultEABIVersion = 0x05000000U };
30
31public:
32 ARMELFObjectWriter(uint8_t OSABI);
33
34 ~ARMELFObjectWriter() override = default;
35
36 unsigned getRelocType(const MCFixup &, const MCValue &,
37 bool IsPCRel) const override;
38
39 bool needsRelocateWithSymbol(const MCValue &Val,
40 unsigned Type) const override;
41};
42
43} // end anonymous namespace
44
45ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
46 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
47 ELF::EM_ARM,
48 /*HasRelocationAddend*/ false) {}
49
50bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCValue &V,
51 unsigned Type) const {
52 // If the symbol is a thumb function the final relocation must set the lowest
53 // bit. With a symbol that is done by just having the symbol have that bit
54 // set, so we would lose the bit if we relocated with the section.
55 // We could use the section but add the bit to the relocation value.
56 if (Asm->isThumbFunc(V.getAddSym()))
57 return true;
58
59 // FIXME: This is extremely conservative. This really needs to use an
60 // explicit list with a clear explanation for why each realocation needs to
61 // point to the symbol, not to the section.
62 switch (Type) {
63 default:
64 return true;
65
66 case ELF::R_ARM_PREL31:
67 case ELF::R_ARM_ABS32:
68 return false;
69 }
70}
71
72// Need to examine the Fixup when determining whether to
73// emit the relocation as an explicit symbol or as a section relative
74// offset
75unsigned ARMELFObjectWriter::getRelocType(const MCFixup &Fixup,
76 const MCValue &Target,
77 bool IsPCRel) const {
78 auto Kind = Fixup.getKind();
79 uint8_t Specifier = Target.getSpecifier();
80 auto CheckFDPIC = [&](uint32_t Type) {
81 if (getOSABI() != ELF::ELFOSABI_ARM_FDPIC)
82 reportError(Fixup.getLoc(),
83 "relocation " +
85 " only supported in FDPIC mode");
86 return Type;
87 };
88
89 switch (Specifier) {
90 case ARM::S_GOTTPOFF:
92 case ARM::S_TLSCALL:
93 case ARM::S_TLSDESC:
94 case ARM::S_TLSGD:
96 case ARM::S_TLSLDM:
98 case ARM::S_TLSLDO:
99 case ARM::S_TPOFF:
100 if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))
101 static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);
102 break;
103 default:
104 break;
105 }
106
107 if (IsPCRel) {
108 switch (Fixup.getKind()) {
109 default:
110 reportError(Fixup.getLoc(), "unsupported relocation type");
111 return ELF::R_ARM_NONE;
112 case FK_Data_4:
113 switch (Specifier) {
114 default:
115 reportError(Fixup.getLoc(),
116 "invalid fixup for 4-byte pc-relative data relocation");
117 return ELF::R_ARM_NONE;
118 case ARM::S_None: {
119 if (const auto *SA = Target.getAddSym()) {
120 // For GNU AS compatibility expressions such as
121 // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation.
122 if (SA->getName() == "_GLOBAL_OFFSET_TABLE_")
123 return ELF::R_ARM_BASE_PREL;
124 }
125 return ELF::R_ARM_REL32;
126 }
127 case ARM::S_GOTTPOFF:
128 return ELF::R_ARM_TLS_IE32;
129 case ARM::S_GOT_PREL:
130 return ELF::R_ARM_GOT_PREL;
131 case ARM::S_PREL31:
132 return ELF::R_ARM_PREL31;
133 }
136 switch (Specifier) {
137 case ARM::S_PLT:
138 return ELF::R_ARM_CALL;
139 case ARM::S_TLSCALL:
140 return ELF::R_ARM_TLS_CALL;
141 default:
142 return ELF::R_ARM_CALL;
143 }
147 return ELF::R_ARM_JUMP24;
149 return ELF::R_ARM_THM_JUMP19;
151 return ELF::R_ARM_THM_JUMP24;
153 return ELF::R_ARM_MOVT_PREL;
155 return ELF::R_ARM_MOVW_PREL_NC;
157 return ELF::R_ARM_THM_MOVT_PREL;
159 return ELF::R_ARM_THM_MOVW_PREL_NC;
161 return ELF::R_ARM_THM_ALU_ABS_G3;
163 return ELF::R_ARM_THM_ALU_ABS_G2_NC;
165 return ELF::R_ARM_THM_ALU_ABS_G1_NC;
167 return ELF::R_ARM_THM_ALU_ABS_G0_NC;
169 return ELF::R_ARM_THM_JUMP11;
171 return ELF::R_ARM_THM_JUMP8;
174 switch (Specifier) {
175 case ARM::S_TLSCALL:
176 return ELF::R_ARM_THM_TLS_CALL;
177 default:
178 return ELF::R_ARM_THM_CALL;
179 }
181 return ELF::R_ARM_LDR_PC_G0;
183 return ELF::R_ARM_LDRS_PC_G0;
185 return ELF::R_ARM_THM_PC12;
187 return ELF::R_ARM_ALU_PC_G0;
189 return ELF::R_ARM_THM_PC8;
191 return ELF::R_ARM_THM_ALU_PREL_11_0;
193 return ELF::R_ARM_THM_BF16;
195 return ELF::R_ARM_THM_BF12;
197 return ELF::R_ARM_THM_BF18;
198 }
199 }
200 switch (Kind) {
201 default:
202 reportError(Fixup.getLoc(), "unsupported relocation type");
203 return ELF::R_ARM_NONE;
204 case FK_Data_1:
205 switch (Specifier) {
206 default:
207 reportError(Fixup.getLoc(), "invalid fixup for 1-byte data relocation");
208 return ELF::R_ARM_NONE;
209 case ARM::S_None:
210 return ELF::R_ARM_ABS8;
211 }
212 case FK_Data_2:
213 switch (Specifier) {
214 default:
215 reportError(Fixup.getLoc(), "invalid fixup for 2-byte data relocation");
216 return ELF::R_ARM_NONE;
217 case ARM::S_None:
218 return ELF::R_ARM_ABS16;
219 }
220 case FK_Data_4:
221 switch (Specifier) {
222 default:
223 reportError(Fixup.getLoc(), "invalid fixup for 4-byte data relocation");
224 return ELF::R_ARM_NONE;
225 case ARM::S_ARM_NONE:
226 return ELF::R_ARM_NONE;
227 case ARM::S_GOT:
228 return ELF::R_ARM_GOT_BREL;
229 case ARM::S_TLSGD:
230 return ELF::R_ARM_TLS_GD32;
231 case ARM::S_TPOFF:
232 return ELF::R_ARM_TLS_LE32;
233 case ARM::S_GOTTPOFF:
234 return ELF::R_ARM_TLS_IE32;
235 case ARM::S_None:
236 return ELF::R_ARM_ABS32;
237 case ARM::S_GOTOFF:
238 return ELF::R_ARM_GOTOFF32;
239 case ARM::S_GOT_PREL:
240 return ELF::R_ARM_GOT_PREL;
241 case ARM::S_TARGET1:
242 return ELF::R_ARM_TARGET1;
243 case ARM::S_TARGET2:
244 return ELF::R_ARM_TARGET2;
245 case ARM::S_PREL31:
246 return ELF::R_ARM_PREL31;
247 case ARM::S_SBREL:
248 return ELF::R_ARM_SBREL32;
249 case ARM::S_TLSLDO:
250 return ELF::R_ARM_TLS_LDO32;
251 case ARM::S_TLSCALL:
252 return ELF::R_ARM_TLS_CALL;
253 case ARM::S_TLSDESC:
254 return ELF::R_ARM_TLS_GOTDESC;
255 case ARM::S_TLSLDM:
256 return ELF::R_ARM_TLS_LDM32;
258 return ELF::R_ARM_TLS_DESCSEQ;
259 case ARM::S_FUNCDESC:
260 return CheckFDPIC(ELF::R_ARM_FUNCDESC);
262 return CheckFDPIC(ELF::R_ARM_GOTFUNCDESC);
264 return CheckFDPIC(ELF::R_ARM_GOTOFFFUNCDESC);
266 return CheckFDPIC(ELF::R_ARM_TLS_GD32_FDPIC);
268 return CheckFDPIC(ELF::R_ARM_TLS_LDM32_FDPIC);
270 return CheckFDPIC(ELF::R_ARM_TLS_IE32_FDPIC);
271 }
274 return ELF::R_ARM_JUMP24;
276 switch (Specifier) {
277 default:
278 reportError(Fixup.getLoc(), "invalid fixup for ARM MOVT instruction");
279 return ELF::R_ARM_NONE;
280 case ARM::S_None:
281 return ELF::R_ARM_MOVT_ABS;
282 case ARM::S_SBREL:
283 return ELF::R_ARM_MOVT_BREL;
284 }
286 switch (Specifier) {
287 default:
288 reportError(Fixup.getLoc(), "invalid fixup for ARM MOVW instruction");
289 return ELF::R_ARM_NONE;
290 case ARM::S_None:
291 return ELF::R_ARM_MOVW_ABS_NC;
292 case ARM::S_SBREL:
293 return ELF::R_ARM_MOVW_BREL_NC;
294 }
296 switch (Specifier) {
297 default:
298 reportError(Fixup.getLoc(), "invalid fixup for Thumb MOVT instruction");
299 return ELF::R_ARM_NONE;
300 case ARM::S_None:
301 return ELF::R_ARM_THM_MOVT_ABS;
302 case ARM::S_SBREL:
303 return ELF::R_ARM_THM_MOVT_BREL;
304 }
306 switch (Specifier) {
307 default:
308 reportError(Fixup.getLoc(), "invalid fixup for Thumb MOVW instruction");
309 return ELF::R_ARM_NONE;
310 case ARM::S_None:
311 return ELF::R_ARM_THM_MOVW_ABS_NC;
312 case ARM::S_SBREL:
313 return ELF::R_ARM_THM_MOVW_BREL_NC;
314 }
315
317 return ELF::R_ARM_THM_ALU_ABS_G3;
319 return ELF::R_ARM_THM_ALU_ABS_G2_NC;
321 return ELF::R_ARM_THM_ALU_ABS_G1_NC;
323 return ELF::R_ARM_THM_ALU_ABS_G0_NC;
324 }
325}
326
327std::unique_ptr<MCObjectTargetWriter>
329 return std::make_unique<ARMELFObjectWriter>(OSABI);
330}
static Error reportError(StringRef Message)
PowerPC TLS Dynamic Call Fixup
virtual unsigned getRelocType(const MCFixup &Fixup, const MCValue &Target, bool IsPCRel) const =0
virtual bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:61
void setType(unsigned Type) const
Definition: MCSymbolELF.cpp:92
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
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
@ S_GOTOFFFUNCDESC
Definition: ARMMCAsmInfo.h:116
@ S_GOTTPOFF_FDPIC
Definition: ARMMCAsmInfo.h:118
@ 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:371
@ EM_ARM
Definition: ELF.h:161
@ STT_TLS
Definition: ELF.h:1414
LLVM_ABI StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition: ELF.cpp:25
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:34
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:36
@ FK_Data_2
A two-byte fixup.
Definition: MCFixup.h:35
std::unique_ptr< MCObjectTargetWriter > createARMELFObjectWriter(uint8_t OSABI)
Construct an ELF Mach-O object writer.