1//===-- AArch64ELFObjectWriter.cpp - AArch64 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//
9// This file handles ELF-specific object emission, converting LLVM's internal
10// fixups into the appropriate relocations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MCTargetDesc/AArch64FixupKinds.h"
15#include "MCTargetDesc/AArch64MCAsmInfo.h"
16#include "MCTargetDesc/AArch64MCTargetDesc.h"
17#include "llvm/BinaryFormat/ELF.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCELFObjectWriter.h"
20#include "llvm/MC/MCFixup.h"
21#include "llvm/MC/MCObjectWriter.h"
22#include "llvm/MC/MCSymbolELF.h"
23#include "llvm/MC/MCValue.h"
24#include "llvm/Support/ErrorHandling.h"
25#include <cassert>
26#include <cstdint>
27
28using namespace llvm;
29
30namespace {
31
32class AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
33public:
34 AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32);
35
36 ~AArch64ELFObjectWriter() override = default;
37
38protected:
39 unsigned getRelocType(const MCFixup &, const MCValue &,
40 bool IsPCRel) const override;
41 bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;
42 bool isNonILP32reloc(const MCFixup &Fixup, AArch64::Specifier RefKind) const;
43
44 bool IsILP32;
45};
46
47} // end anonymous namespace
48
49AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
50 : MCELFObjectTargetWriter(/*Is64Bit*/ !IsILP32, OSABI, ELF::EM_AARCH64,
51 /*HasRelocationAddend*/ true),
52 IsILP32(IsILP32) {}
53
54#define R_CLS(rtype) \
55 IsILP32 ? ELF::R_AARCH64_P32_##rtype : ELF::R_AARCH64_##rtype
56
57// assumes IsILP32 is true
58bool AArch64ELFObjectWriter::isNonILP32reloc(const MCFixup &Fixup,
59 AArch64::Specifier RefKind) const {
60 if (Fixup.getTargetKind() != AArch64::fixup_aarch64_movw)
61 return false;
62 switch (RefKind) {
63 case AArch64::S_ABS_G3:
64 case AArch64::S_ABS_G2:
65 case AArch64::S_ABS_G2_S:
66 case AArch64::S_ABS_G2_NC:
67 case AArch64::S_ABS_G1_S:
68 case AArch64::S_ABS_G1_NC:
69 case AArch64::S_DTPREL_G2:
70 case AArch64::S_DTPREL_G1_NC:
71 case AArch64::S_TPREL_G2:
72 case AArch64::S_TPREL_G1_NC:
73 case AArch64::S_GOTTPREL_G1:
74 case AArch64::S_GOTTPREL_G0_NC:
75 reportError(L: Fixup.getLoc(),
76 Msg: "absolute MOV relocation is not supported in ILP32");
77 return true;
78 default:
79 return false;
80 }
81 return false;
82}
83
84unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup,
85 const MCValue &Target,
86 bool IsPCRel) const {
87 unsigned Kind = Fixup.getTargetKind();
88 AArch64::Specifier RefKind =
89 static_cast<AArch64::Specifier>(Target.getSpecifier());
90 AArch64::Specifier SymLoc = AArch64::getSymbolLoc(S: RefKind);
91 bool IsNC = AArch64::isNotChecked(S: RefKind);
92
93 switch (SymLoc) {
94 case AArch64::S_DTPREL:
95 case AArch64::S_GOTTPREL:
96 case AArch64::S_TPREL:
97 case AArch64::S_TLSDESC:
98 case AArch64::S_TLSDESC_AUTH:
99 if (auto *SA = Target.getAddSym())
100 cast<MCSymbolELF>(Val: SA)->setType(ELF::STT_TLS);
101 break;
102 default:
103 break;
104 }
105
106 // Extract the relocation type from the fixup kind, after applying STT_TLS as
107 // needed.
108 if (mc::isRelocation(FixupKind: Fixup.getKind()))
109 return Kind;
110
111 if (IsPCRel) {
112 switch (Kind) {
113 case FK_Data_1:
114 reportError(L: Fixup.getLoc(), Msg: "1-byte data relocations not supported");
115 return ELF::R_AARCH64_NONE;
116 case FK_Data_2:
117 return R_CLS(PREL16);
118 case FK_Data_4: {
119 return Target.getSpecifier() == AArch64::S_PLT ? R_CLS(PLT32)
120 : R_CLS(PREL32);
121 }
122 case FK_Data_8:
123 if (IsILP32) {
124 reportError(L: Fixup.getLoc(), Msg: "8 byte PC relative data "
125 "relocation is not supported in ILP32");
126 return ELF::R_AARCH64_NONE;
127 }
128 return ELF::R_AARCH64_PREL64;
129 case AArch64::fixup_aarch64_pcrel_adr_imm21:
130 if (SymLoc == AArch64::S_GOT_AUTH) {
131 if (IsILP32) {
132 reportError(L: Fixup.getLoc(),
133 Msg: "ADR AUTH relocation is not supported in ILP32");
134 return ELF::R_AARCH64_NONE;
135 }
136 return ELF::R_AARCH64_AUTH_GOT_ADR_PREL_LO21;
137 }
138 if (SymLoc != AArch64::S_ABS)
139 reportError(L: Fixup.getLoc(), Msg: "invalid symbol kind for ADR relocation");
140 return R_CLS(ADR_PREL_LO21);
141 case AArch64::fixup_aarch64_pcrel_adrp_imm21:
142 if (SymLoc == AArch64::S_ABS && !IsNC)
143 return R_CLS(ADR_PREL_PG_HI21);
144 if (SymLoc == AArch64::S_ABS && IsNC) {
145 if (IsILP32) {
146 reportError(L: Fixup.getLoc(),
147 Msg: "invalid fixup for 32-bit pcrel ADRP instruction "
148 "VK_ABS VK_NC");
149 return ELF::R_AARCH64_NONE;
150 }
151 return ELF::R_AARCH64_ADR_PREL_PG_HI21_NC;
152 }
153 if (SymLoc == AArch64::S_GOT && !IsNC)
154 return R_CLS(ADR_GOT_PAGE);
155 if (SymLoc == AArch64::S_GOT_AUTH && !IsNC) {
156 if (IsILP32) {
157 reportError(L: Fixup.getLoc(),
158 Msg: "ADRP AUTH relocation is not supported in ILP32");
159 return ELF::R_AARCH64_NONE;
160 }
161 return ELF::R_AARCH64_AUTH_ADR_GOT_PAGE;
162 }
163 if (SymLoc == AArch64::S_GOTTPREL && !IsNC)
164 return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
165 if (SymLoc == AArch64::S_TLSDESC && !IsNC)
166 return R_CLS(TLSDESC_ADR_PAGE21);
167 if (SymLoc == AArch64::S_TLSDESC_AUTH && !IsNC) {
168 if (IsILP32) {
169 reportError(L: Fixup.getLoc(),
170 Msg: "ADRP AUTH relocation is not supported in ILP32");
171 return ELF::R_AARCH64_NONE;
172 }
173 return ELF::R_AARCH64_AUTH_TLSDESC_ADR_PAGE21;
174 }
175 reportError(L: Fixup.getLoc(), Msg: "invalid symbol kind for ADRP relocation");
176 return ELF::R_AARCH64_NONE;
177 case AArch64::fixup_aarch64_pcrel_branch26:
178 return R_CLS(JUMP26);
179 case AArch64::fixup_aarch64_pcrel_call26:
180 return R_CLS(CALL26);
181 case AArch64::fixup_aarch64_ldr_pcrel_imm19:
182 if (SymLoc == AArch64::S_GOTTPREL)
183 return R_CLS(TLSIE_LD_GOTTPREL_PREL19);
184 if (SymLoc == AArch64::S_GOT)
185 return R_CLS(GOT_LD_PREL19);
186 if (SymLoc == AArch64::S_GOT_AUTH) {
187 if (IsILP32) {
188 reportError(L: Fixup.getLoc(),
189 Msg: "LDR AUTH relocation is not supported in ILP32");
190 return ELF::R_AARCH64_NONE;
191 }
192 return ELF::R_AARCH64_AUTH_GOT_LD_PREL19;
193 }
194 return R_CLS(LD_PREL_LO19);
195 case AArch64::fixup_aarch64_pcrel_branch14:
196 return R_CLS(TSTBR14);
197 case AArch64::fixup_aarch64_pcrel_branch16:
198 reportError(L: Fixup.getLoc(),
199 Msg: "relocation of PAC/AUT instructions is not supported");
200 return ELF::R_AARCH64_NONE;
201 case AArch64::fixup_aarch64_pcrel_branch9:
202 reportError(
203 L: Fixup.getLoc(),
204 Msg: "relocation of compare-and-branch instructions not supported");
205 return ELF::R_AARCH64_NONE;
206 case AArch64::fixup_aarch64_pcrel_branch19:
207 return R_CLS(CONDBR19);
208 default:
209 reportError(L: Fixup.getLoc(), Msg: "Unsupported pc-relative fixup kind");
210 return ELF::R_AARCH64_NONE;
211 }
212 } else {
213 if (IsILP32 && isNonILP32reloc(Fixup, RefKind))
214 return ELF::R_AARCH64_NONE;
215 switch (Fixup.getTargetKind()) {
216 case FK_Data_1:
217 reportError(L: Fixup.getLoc(), Msg: "1-byte data relocations not supported");
218 return ELF::R_AARCH64_NONE;
219 case FK_Data_2:
220 return R_CLS(ABS16);
221 case FK_Data_4:
222 return (!IsILP32 && Target.getSpecifier() == AArch64::S_GOTPCREL)
223 ? ELF::R_AARCH64_GOTPCREL32
224 : R_CLS(ABS32);
225 case FK_Data_8: {
226 if (IsILP32) {
227 reportError(
228 L: Fixup.getLoc(),
229 Msg: "8 byte absolute data relocation is not supported in ILP32");
230 return ELF::R_AARCH64_NONE;
231 }
232 if (RefKind == AArch64::S_AUTH || RefKind == AArch64::S_AUTHADDR)
233 return ELF::R_AARCH64_AUTH_ABS64;
234 return ELF::R_AARCH64_ABS64;
235 }
236 case AArch64::fixup_aarch64_add_imm12:
237 if (RefKind == AArch64::S_DTPREL_HI12)
238 return R_CLS(TLSLD_ADD_DTPREL_HI12);
239 if (RefKind == AArch64::S_TPREL_HI12)
240 return R_CLS(TLSLE_ADD_TPREL_HI12);
241 if (RefKind == AArch64::S_DTPREL_LO12_NC)
242 return R_CLS(TLSLD_ADD_DTPREL_LO12_NC);
243 if (RefKind == AArch64::S_DTPREL_LO12)
244 return R_CLS(TLSLD_ADD_DTPREL_LO12);
245 if (RefKind == AArch64::S_TPREL_LO12_NC)
246 return R_CLS(TLSLE_ADD_TPREL_LO12_NC);
247 if (RefKind == AArch64::S_TPREL_LO12)
248 return R_CLS(TLSLE_ADD_TPREL_LO12);
249 if (RefKind == AArch64::S_TLSDESC_LO12)
250 return R_CLS(TLSDESC_ADD_LO12);
251 if (RefKind == AArch64::S_TLSDESC_AUTH_LO12) {
252 if (IsILP32) {
253 reportError(L: Fixup.getLoc(),
254 Msg: "ADD AUTH relocation is not supported in ILP32");
255 return ELF::R_AARCH64_NONE;
256 }
257 return ELF::R_AARCH64_AUTH_TLSDESC_ADD_LO12;
258 }
259 if (RefKind == AArch64::S_GOT_AUTH_LO12 && IsNC) {
260 if (IsILP32) {
261 reportError(L: Fixup.getLoc(),
262 Msg: "ADD AUTH relocation is not supported in ILP32");
263 return ELF::R_AARCH64_NONE;
264 }
265 return ELF::R_AARCH64_AUTH_GOT_ADD_LO12_NC;
266 }
267 if (SymLoc == AArch64::S_ABS && IsNC)
268 return R_CLS(ADD_ABS_LO12_NC);
269
270 reportError(L: Fixup.getLoc(), Msg: "invalid fixup for add (uimm12) instruction");
271 return ELF::R_AARCH64_NONE;
272 case AArch64::fixup_aarch64_ldst_imm12_scale1:
273 if (SymLoc == AArch64::S_ABS && IsNC)
274 return R_CLS(LDST8_ABS_LO12_NC);
275 if (SymLoc == AArch64::S_DTPREL && !IsNC)
276 return R_CLS(TLSLD_LDST8_DTPREL_LO12);
277 if (SymLoc == AArch64::S_DTPREL && IsNC)
278 return R_CLS(TLSLD_LDST8_DTPREL_LO12_NC);
279 if (SymLoc == AArch64::S_TPREL && !IsNC)
280 return R_CLS(TLSLE_LDST8_TPREL_LO12);
281 if (SymLoc == AArch64::S_TPREL && IsNC)
282 return R_CLS(TLSLE_LDST8_TPREL_LO12_NC);
283
284 reportError(L: Fixup.getLoc(),
285 Msg: "invalid fixup for 8-bit load/store instruction");
286 return ELF::R_AARCH64_NONE;
287 case AArch64::fixup_aarch64_ldst_imm12_scale2:
288 if (SymLoc == AArch64::S_ABS && IsNC)
289 return R_CLS(LDST16_ABS_LO12_NC);
290 if (SymLoc == AArch64::S_DTPREL && !IsNC)
291 return R_CLS(TLSLD_LDST16_DTPREL_LO12);
292 if (SymLoc == AArch64::S_DTPREL && IsNC)
293 return R_CLS(TLSLD_LDST16_DTPREL_LO12_NC);
294 if (SymLoc == AArch64::S_TPREL && !IsNC)
295 return R_CLS(TLSLE_LDST16_TPREL_LO12);
296 if (SymLoc == AArch64::S_TPREL && IsNC)
297 return R_CLS(TLSLE_LDST16_TPREL_LO12_NC);
298
299 reportError(L: Fixup.getLoc(),
300 Msg: "invalid fixup for 16-bit load/store instruction");
301 return ELF::R_AARCH64_NONE;
302 case AArch64::fixup_aarch64_ldst_imm12_scale4:
303 if (SymLoc == AArch64::S_ABS && IsNC)
304 return R_CLS(LDST32_ABS_LO12_NC);
305 if (SymLoc == AArch64::S_DTPREL && !IsNC)
306 return R_CLS(TLSLD_LDST32_DTPREL_LO12);
307 if (SymLoc == AArch64::S_DTPREL && IsNC)
308 return R_CLS(TLSLD_LDST32_DTPREL_LO12_NC);
309 if (SymLoc == AArch64::S_TPREL && !IsNC)
310 return R_CLS(TLSLE_LDST32_TPREL_LO12);
311 if (SymLoc == AArch64::S_TPREL && IsNC)
312 return R_CLS(TLSLE_LDST32_TPREL_LO12_NC);
313 if (SymLoc == AArch64::S_GOT && IsNC) {
314 if (IsILP32)
315 return ELF::R_AARCH64_P32_LD32_GOT_LO12_NC;
316 reportError(L: Fixup.getLoc(), Msg: "4 byte unchecked GOT load/store "
317 "relocation is not supported in LP64");
318 return ELF::R_AARCH64_NONE;
319 }
320 if (SymLoc == AArch64::S_GOT && !IsNC) {
321 if (IsILP32) {
322 reportError(
323 L: Fixup.getLoc(),
324 Msg: "4 byte checked GOT load/store relocation is not supported");
325 }
326 return ELF::R_AARCH64_NONE;
327 }
328 if (SymLoc == AArch64::S_GOTTPREL && IsNC) {
329 if (IsILP32)
330 return ELF::R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC;
331 reportError(L: Fixup.getLoc(), Msg: "32-bit load/store "
332 "relocation is not supported in LP64");
333 return ELF::R_AARCH64_NONE;
334 }
335 if (SymLoc == AArch64::S_TLSDESC && !IsNC) {
336 if (IsILP32)
337 return ELF::R_AARCH64_P32_TLSDESC_LD32_LO12;
338 reportError(
339 L: Fixup.getLoc(),
340 Msg: "4 byte TLSDESC load/store relocation is not supported in LP64");
341 return ELF::R_AARCH64_NONE;
342 }
343
344 reportError(L: Fixup.getLoc(),
345 Msg: "invalid fixup for 32-bit load/store instruction "
346 "fixup_aarch64_ldst_imm12_scale4");
347 return ELF::R_AARCH64_NONE;
348 case AArch64::fixup_aarch64_ldst_imm12_scale8:
349 if (SymLoc == AArch64::S_ABS && IsNC)
350 return R_CLS(LDST64_ABS_LO12_NC);
351 if ((SymLoc == AArch64::S_GOT || SymLoc == AArch64::S_GOT_AUTH) && IsNC) {
352 AArch64::Specifier AddressLoc = AArch64::getAddressFrag(S: RefKind);
353 bool IsAuth = (SymLoc == AArch64::S_GOT_AUTH);
354 if (!IsILP32) {
355 if (AddressLoc == AArch64::S_LO15)
356 return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
357 return (IsAuth ? ELF::R_AARCH64_AUTH_LD64_GOT_LO12_NC
358 : ELF::R_AARCH64_LD64_GOT_LO12_NC);
359 }
360 reportError(L: Fixup.getLoc(),
361 Msg: "64-bit load/store relocation is not supported in ILP32");
362 return ELF::R_AARCH64_NONE;
363 }
364 if (SymLoc == AArch64::S_DTPREL && !IsNC)
365 return R_CLS(TLSLD_LDST64_DTPREL_LO12);
366 if (SymLoc == AArch64::S_DTPREL && IsNC)
367 return R_CLS(TLSLD_LDST64_DTPREL_LO12_NC);
368 if (SymLoc == AArch64::S_TPREL && !IsNC)
369 return R_CLS(TLSLE_LDST64_TPREL_LO12);
370 if (SymLoc == AArch64::S_TPREL && IsNC)
371 return R_CLS(TLSLE_LDST64_TPREL_LO12_NC);
372 if (SymLoc == AArch64::S_GOTTPREL && IsNC) {
373 if (!IsILP32)
374 return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
375 reportError(L: Fixup.getLoc(),
376 Msg: "64-bit load/store relocation is not supported in ILP32");
377 return ELF::R_AARCH64_NONE;
378 }
379 if (SymLoc == AArch64::S_TLSDESC) {
380 if (!IsILP32)
381 return ELF::R_AARCH64_TLSDESC_LD64_LO12;
382 reportError(L: Fixup.getLoc(),
383 Msg: "64-bit load/store relocation is not supported in ILP32");
384 return ELF::R_AARCH64_NONE;
385 }
386 if (SymLoc == AArch64::S_TLSDESC_AUTH) {
387 if (!IsILP32)
388 return ELF::R_AARCH64_AUTH_TLSDESC_LD64_LO12;
389 reportError(
390 L: Fixup.getLoc(),
391 Msg: "64-bit load/store AUTH relocation is not supported in ILP32");
392 return ELF::R_AARCH64_NONE;
393 }
394 reportError(L: Fixup.getLoc(),
395 Msg: "invalid fixup for 64-bit load/store instruction");
396 return ELF::R_AARCH64_NONE;
397 case AArch64::fixup_aarch64_ldst_imm12_scale16:
398 if (SymLoc == AArch64::S_ABS && IsNC)
399 return R_CLS(LDST128_ABS_LO12_NC);
400 if (SymLoc == AArch64::S_DTPREL && !IsNC)
401 return R_CLS(TLSLD_LDST128_DTPREL_LO12);
402 if (SymLoc == AArch64::S_DTPREL && IsNC)
403 return R_CLS(TLSLD_LDST128_DTPREL_LO12_NC);
404 if (SymLoc == AArch64::S_TPREL && !IsNC)
405 return R_CLS(TLSLE_LDST128_TPREL_LO12);
406 if (SymLoc == AArch64::S_TPREL && IsNC)
407 return R_CLS(TLSLE_LDST128_TPREL_LO12_NC);
408
409 reportError(L: Fixup.getLoc(),
410 Msg: "invalid fixup for 128-bit load/store instruction");
411 return ELF::R_AARCH64_NONE;
412 // ILP32 case not reached here, tested with isNonILP32reloc
413 case AArch64::fixup_aarch64_movw:
414 if (RefKind == AArch64::S_ABS_G3)
415 return ELF::R_AARCH64_MOVW_UABS_G3;
416 if (RefKind == AArch64::S_ABS_G2)
417 return ELF::R_AARCH64_MOVW_UABS_G2;
418 if (RefKind == AArch64::S_ABS_G2_S)
419 return ELF::R_AARCH64_MOVW_SABS_G2;
420 if (RefKind == AArch64::S_ABS_G2_NC)
421 return ELF::R_AARCH64_MOVW_UABS_G2_NC;
422 if (RefKind == AArch64::S_ABS_G1)
423 return R_CLS(MOVW_UABS_G1);
424 if (RefKind == AArch64::S_ABS_G1_S)
425 return ELF::R_AARCH64_MOVW_SABS_G1;
426 if (RefKind == AArch64::S_ABS_G1_NC)
427 return ELF::R_AARCH64_MOVW_UABS_G1_NC;
428 if (RefKind == AArch64::S_ABS_G0)
429 return R_CLS(MOVW_UABS_G0);
430 if (RefKind == AArch64::S_ABS_G0_S)
431 return R_CLS(MOVW_SABS_G0);
432 if (RefKind == AArch64::S_ABS_G0_NC)
433 return R_CLS(MOVW_UABS_G0_NC);
434 if (RefKind == AArch64::S_PREL_G3)
435 return ELF::R_AARCH64_MOVW_PREL_G3;
436 if (RefKind == AArch64::S_PREL_G2)
437 return ELF::R_AARCH64_MOVW_PREL_G2;
438 if (RefKind == AArch64::S_PREL_G2_NC)
439 return ELF::R_AARCH64_MOVW_PREL_G2_NC;
440 if (RefKind == AArch64::S_PREL_G1)
441 return R_CLS(MOVW_PREL_G1);
442 if (RefKind == AArch64::S_PREL_G1_NC)
443 return ELF::R_AARCH64_MOVW_PREL_G1_NC;
444 if (RefKind == AArch64::S_PREL_G0)
445 return R_CLS(MOVW_PREL_G0);
446 if (RefKind == AArch64::S_PREL_G0_NC)
447 return R_CLS(MOVW_PREL_G0_NC);
448 if (RefKind == AArch64::S_DTPREL_G2)
449 return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
450 if (RefKind == AArch64::S_DTPREL_G1)
451 return R_CLS(TLSLD_MOVW_DTPREL_G1);
452 if (RefKind == AArch64::S_DTPREL_G1_NC)
453 return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC;
454 if (RefKind == AArch64::S_DTPREL_G0)
455 return R_CLS(TLSLD_MOVW_DTPREL_G0);
456 if (RefKind == AArch64::S_DTPREL_G0_NC)
457 return R_CLS(TLSLD_MOVW_DTPREL_G0_NC);
458 if (RefKind == AArch64::S_TPREL_G2)
459 return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2;
460 if (RefKind == AArch64::S_TPREL_G1)
461 return R_CLS(TLSLE_MOVW_TPREL_G1);
462 if (RefKind == AArch64::S_TPREL_G1_NC)
463 return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC;
464 if (RefKind == AArch64::S_TPREL_G0)
465 return R_CLS(TLSLE_MOVW_TPREL_G0);
466 if (RefKind == AArch64::S_TPREL_G0_NC)
467 return R_CLS(TLSLE_MOVW_TPREL_G0_NC);
468 if (RefKind == AArch64::S_GOTTPREL_G1)
469 return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
470 if (RefKind == AArch64::S_GOTTPREL_G0_NC)
471 return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
472 reportError(L: Fixup.getLoc(), Msg: "invalid fixup for movz/movk instruction");
473 return ELF::R_AARCH64_NONE;
474 default:
475 reportError(L: Fixup.getLoc(), Msg: "Unknown ELF relocation type");
476 return ELF::R_AARCH64_NONE;
477 }
478 }
479
480 llvm_unreachable("Unimplemented fixup -> relocation");
481}
482
483bool AArch64ELFObjectWriter::needsRelocateWithSymbol(const MCValue &Val,
484 unsigned) const {
485 // For memory-tagged symbols, ensure that the relocation uses the symbol. For
486 // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special
487 // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that
488 // this global needs to be tagged. In addition, the linker needs to know
489 // whether to emit a special addend when relocating `end` symbols, and this
490 // can only be determined by the attributes of the symbol itself.
491 if (Val.getAddSym() && cast<MCSymbolELF>(Val: Val.getAddSym())->isMemtag())
492 return true;
493
494 if ((Val.getSpecifier() & AArch64::S_GOT) == AArch64::S_GOT)
495 return true;
496 return is_contained(Set: {AArch64::S_GOTPCREL, AArch64::S_PLT},
497 Element: Val.getSpecifier());
498}
499
500std::unique_ptr<MCObjectTargetWriter>
501llvm::createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32) {
502 return std::make_unique<AArch64ELFObjectWriter>(args&: OSABI, args&: IsILP32);
503}
504