xref: /llvm-project/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp (revision 3c661cf03a2b1f669710a93bf73b15c831171888)
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/AArch64MCExpr.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/MCValue.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include <cassert>
25 #include <cstdint>
26 
27 using namespace llvm;
28 
29 namespace {
30 
31 class AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
32 public:
33   AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32);
34 
35   ~AArch64ELFObjectWriter() override = default;
36 
37 protected:
38   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
39                         const MCFixup &Fixup, bool IsPCRel) const override;
40   bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
41                                unsigned Type) const override;
42   bool IsILP32;
43 };
44 
45 } // end anonymous namespace
46 
47 AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
48     : MCELFObjectTargetWriter(/*Is64Bit*/ !IsILP32, OSABI, ELF::EM_AARCH64,
49                               /*HasRelocationAddend*/ true),
50       IsILP32(IsILP32) {}
51 
52 #define R_CLS(rtype)                                                           \
53   IsILP32 ? ELF::R_AARCH64_P32_##rtype : ELF::R_AARCH64_##rtype
54 #define BAD_ILP32_MOV(lp64rtype)                                               \
55   "ILP32 absolute MOV relocation not "                                         \
56   "supported (LP64 eqv: " #lp64rtype ")"
57 
58 // assumes IsILP32 is true
59 static bool isNonILP32reloc(const MCFixup &Fixup,
60                             AArch64MCExpr::VariantKind RefKind,
61                             MCContext &Ctx) {
62   if (Fixup.getTargetKind() != AArch64::fixup_aarch64_movw)
63     return false;
64   switch (RefKind) {
65   case AArch64MCExpr::VK_ABS_G3:
66     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G3));
67     return true;
68   case AArch64MCExpr::VK_ABS_G2:
69     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2));
70     return true;
71   case AArch64MCExpr::VK_ABS_G2_S:
72     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G2));
73     return true;
74   case AArch64MCExpr::VK_ABS_G2_NC:
75     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2_NC));
76     return true;
77   case AArch64MCExpr::VK_ABS_G1_S:
78     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G1));
79     return true;
80   case AArch64MCExpr::VK_ABS_G1_NC:
81     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G1_NC));
82     return true;
83   case AArch64MCExpr::VK_DTPREL_G2:
84     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G2));
85     return true;
86   case AArch64MCExpr::VK_DTPREL_G1_NC:
87     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G1_NC));
88     return true;
89   case AArch64MCExpr::VK_TPREL_G2:
90     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G2));
91     return true;
92   case AArch64MCExpr::VK_TPREL_G1_NC:
93     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G1_NC));
94     return true;
95   case AArch64MCExpr::VK_GOTTPREL_G1:
96     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G1));
97     return true;
98   case AArch64MCExpr::VK_GOTTPREL_G0_NC:
99     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G0_NC));
100     return true;
101   default:
102     return false;
103   }
104   return false;
105 }
106 
107 unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
108                                               const MCValue &Target,
109                                               const MCFixup &Fixup,
110                                               bool IsPCRel) const {
111   unsigned Kind = Fixup.getTargetKind();
112   if (Kind >= FirstLiteralRelocationKind)
113     return Kind - FirstLiteralRelocationKind;
114   AArch64MCExpr::VariantKind RefKind =
115       static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
116   AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
117   bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
118 
119   assert((!Target.getSymA() ||
120           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
121           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
122           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
123          "Should only be expression-level modifiers here");
124 
125   assert((!Target.getSymB() ||
126           Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) &&
127          "Should only be expression-level modifiers here");
128 
129   if (IsPCRel) {
130     switch (Kind) {
131     case FK_Data_1:
132       Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
133       return ELF::R_AARCH64_NONE;
134     case FK_Data_2:
135       return R_CLS(PREL16);
136     case FK_Data_4: {
137       return Target.getAccessVariant() == MCSymbolRefExpr::VK_PLT
138                  ? R_CLS(PLT32)
139                  : R_CLS(PREL32);
140     }
141     case FK_Data_8:
142       if (IsILP32) {
143         Ctx.reportError(Fixup.getLoc(),
144                         "ILP32 8 byte PC relative data "
145                         "relocation not supported (LP64 eqv: PREL64)");
146         return ELF::R_AARCH64_NONE;
147       }
148       return ELF::R_AARCH64_PREL64;
149     case AArch64::fixup_aarch64_pcrel_adr_imm21:
150       if (SymLoc == AArch64MCExpr::VK_GOT_AUTH) {
151         if (IsILP32) {
152           Ctx.reportError(Fixup.getLoc(),
153                           "ILP32 ADR AUTH relocation not supported "
154                           "(LP64 eqv: AUTH_GOT_ADR_PREL_LO21)");
155           return ELF::R_AARCH64_NONE;
156         }
157         return ELF::R_AARCH64_AUTH_GOT_ADR_PREL_LO21;
158       }
159       if (SymLoc != AArch64MCExpr::VK_ABS)
160         Ctx.reportError(Fixup.getLoc(),
161                         "invalid symbol kind for ADR relocation");
162       return R_CLS(ADR_PREL_LO21);
163     case AArch64::fixup_aarch64_pcrel_adrp_imm21:
164       if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
165         return R_CLS(ADR_PREL_PG_HI21);
166       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) {
167         if (IsILP32) {
168           Ctx.reportError(Fixup.getLoc(),
169                           "invalid fixup for 32-bit pcrel ADRP instruction "
170                           "VK_ABS VK_NC");
171           return ELF::R_AARCH64_NONE;
172         }
173         return ELF::R_AARCH64_ADR_PREL_PG_HI21_NC;
174       }
175       if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
176         return R_CLS(ADR_GOT_PAGE);
177       if (SymLoc == AArch64MCExpr::VK_GOT_AUTH && !IsNC) {
178         if (IsILP32) {
179           Ctx.reportError(Fixup.getLoc(),
180                           "ILP32 ADRP AUTH relocation not supported "
181                           "(LP64 eqv: AUTH_ADR_GOT_PAGE)");
182           return ELF::R_AARCH64_NONE;
183         }
184         return ELF::R_AARCH64_AUTH_ADR_GOT_PAGE;
185       }
186       if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
187         return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
188       if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
189         return R_CLS(TLSDESC_ADR_PAGE21);
190       if (SymLoc == AArch64MCExpr::VK_TLSDESC_AUTH && !IsNC) {
191         if (IsILP32) {
192           Ctx.reportError(Fixup.getLoc(),
193                           "ILP32 ADRP AUTH relocation not supported "
194                           "(LP64 eqv: AUTH_TLSDESC_ADR_PAGE21)");
195           return ELF::R_AARCH64_NONE;
196         }
197         return ELF::R_AARCH64_AUTH_TLSDESC_ADR_PAGE21;
198       }
199       Ctx.reportError(Fixup.getLoc(),
200                       "invalid symbol kind for ADRP relocation");
201       return ELF::R_AARCH64_NONE;
202     case AArch64::fixup_aarch64_pcrel_branch26:
203       return R_CLS(JUMP26);
204     case AArch64::fixup_aarch64_pcrel_call26:
205       return R_CLS(CALL26);
206     case AArch64::fixup_aarch64_ldr_pcrel_imm19:
207       if (SymLoc == AArch64MCExpr::VK_GOTTPREL)
208         return R_CLS(TLSIE_LD_GOTTPREL_PREL19);
209       if (SymLoc == AArch64MCExpr::VK_GOT)
210         return R_CLS(GOT_LD_PREL19);
211       if (SymLoc == AArch64MCExpr::VK_GOT_AUTH) {
212         if (IsILP32) {
213           Ctx.reportError(Fixup.getLoc(),
214                           "ILP32 LDR AUTH relocation not supported "
215                           "(LP64 eqv: AUTH_GOT_LD_PREL19)");
216           return ELF::R_AARCH64_NONE;
217         }
218         return ELF::R_AARCH64_AUTH_GOT_LD_PREL19;
219       }
220       return R_CLS(LD_PREL_LO19);
221     case AArch64::fixup_aarch64_pcrel_branch14:
222       return R_CLS(TSTBR14);
223     case AArch64::fixup_aarch64_pcrel_branch16:
224       Ctx.reportError(Fixup.getLoc(),
225                       "relocation of PAC/AUT instructions is not supported");
226       return ELF::R_AARCH64_NONE;
227     case AArch64::fixup_aarch64_pcrel_branch9:
228       Ctx.reportError(
229           Fixup.getLoc(),
230           "relocation of compare-and-branch instructions not supported");
231       return ELF::R_AARCH64_NONE;
232     case AArch64::fixup_aarch64_pcrel_branch19:
233       return R_CLS(CONDBR19);
234     default:
235       Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");
236       return ELF::R_AARCH64_NONE;
237     }
238   } else {
239     if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx))
240       return ELF::R_AARCH64_NONE;
241     switch (Fixup.getTargetKind()) {
242     case FK_Data_1:
243       Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
244       return ELF::R_AARCH64_NONE;
245     case FK_Data_2:
246       return R_CLS(ABS16);
247     case FK_Data_4:
248       return (!IsILP32 &&
249               Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL)
250                  ? ELF::R_AARCH64_GOTPCREL32
251                  : R_CLS(ABS32);
252     case FK_Data_8: {
253       bool IsAuth = (RefKind == AArch64MCExpr::VK_AUTH ||
254                      RefKind == AArch64MCExpr::VK_AUTHADDR);
255       if (IsILP32) {
256         Ctx.reportError(Fixup.getLoc(),
257                         Twine("ILP32 8 byte absolute data "
258                               "relocation not supported (LP64 eqv: ") +
259                             (IsAuth ? "AUTH_ABS64" : "ABS64") + Twine(')'));
260         return ELF::R_AARCH64_NONE;
261       }
262       return (IsAuth ? ELF::R_AARCH64_AUTH_ABS64 : ELF::R_AARCH64_ABS64);
263     }
264     case AArch64::fixup_aarch64_add_imm12:
265       if (RefKind == AArch64MCExpr::VK_DTPREL_HI12)
266         return R_CLS(TLSLD_ADD_DTPREL_HI12);
267       if (RefKind == AArch64MCExpr::VK_TPREL_HI12)
268         return R_CLS(TLSLE_ADD_TPREL_HI12);
269       if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC)
270         return R_CLS(TLSLD_ADD_DTPREL_LO12_NC);
271       if (RefKind == AArch64MCExpr::VK_DTPREL_LO12)
272         return R_CLS(TLSLD_ADD_DTPREL_LO12);
273       if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC)
274         return R_CLS(TLSLE_ADD_TPREL_LO12_NC);
275       if (RefKind == AArch64MCExpr::VK_TPREL_LO12)
276         return R_CLS(TLSLE_ADD_TPREL_LO12);
277       if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
278         return R_CLS(TLSDESC_ADD_LO12);
279       if (RefKind == AArch64MCExpr::VK_TLSDESC_AUTH_LO12) {
280         if (IsILP32) {
281           Ctx.reportError(Fixup.getLoc(),
282                           "ILP32 ADD AUTH relocation not supported "
283                           "(LP64 eqv: AUTH_TLSDESC_ADD_LO12)");
284           return ELF::R_AARCH64_NONE;
285         }
286         return ELF::R_AARCH64_AUTH_TLSDESC_ADD_LO12;
287       }
288       if (RefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 && IsNC) {
289         if (IsILP32) {
290           Ctx.reportError(Fixup.getLoc(),
291                           "ILP32 ADD AUTH relocation not supported "
292                           "(LP64 eqv: AUTH_GOT_ADD_LO12_NC)");
293           return ELF::R_AARCH64_NONE;
294         }
295         return ELF::R_AARCH64_AUTH_GOT_ADD_LO12_NC;
296       }
297       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
298         return R_CLS(ADD_ABS_LO12_NC);
299 
300       Ctx.reportError(Fixup.getLoc(),
301                       "invalid fixup for add (uimm12) instruction");
302       return ELF::R_AARCH64_NONE;
303     case AArch64::fixup_aarch64_ldst_imm12_scale1:
304       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
305         return R_CLS(LDST8_ABS_LO12_NC);
306       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
307         return R_CLS(TLSLD_LDST8_DTPREL_LO12);
308       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
309         return R_CLS(TLSLD_LDST8_DTPREL_LO12_NC);
310       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
311         return R_CLS(TLSLE_LDST8_TPREL_LO12);
312       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
313         return R_CLS(TLSLE_LDST8_TPREL_LO12_NC);
314 
315       Ctx.reportError(Fixup.getLoc(),
316                       "invalid fixup for 8-bit load/store instruction");
317       return ELF::R_AARCH64_NONE;
318     case AArch64::fixup_aarch64_ldst_imm12_scale2:
319       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
320         return R_CLS(LDST16_ABS_LO12_NC);
321       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
322         return R_CLS(TLSLD_LDST16_DTPREL_LO12);
323       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
324         return R_CLS(TLSLD_LDST16_DTPREL_LO12_NC);
325       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
326         return R_CLS(TLSLE_LDST16_TPREL_LO12);
327       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
328         return R_CLS(TLSLE_LDST16_TPREL_LO12_NC);
329 
330       Ctx.reportError(Fixup.getLoc(),
331                       "invalid fixup for 16-bit load/store instruction");
332       return ELF::R_AARCH64_NONE;
333     case AArch64::fixup_aarch64_ldst_imm12_scale4:
334       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
335         return R_CLS(LDST32_ABS_LO12_NC);
336       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
337         return R_CLS(TLSLD_LDST32_DTPREL_LO12);
338       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
339         return R_CLS(TLSLD_LDST32_DTPREL_LO12_NC);
340       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
341         return R_CLS(TLSLE_LDST32_TPREL_LO12);
342       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
343         return R_CLS(TLSLE_LDST32_TPREL_LO12_NC);
344       if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
345         if (IsILP32)
346           return ELF::R_AARCH64_P32_LD32_GOT_LO12_NC;
347         Ctx.reportError(Fixup.getLoc(),
348                         "LP64 4 byte unchecked GOT load/store relocation "
349                         "not supported (ILP32 eqv: LD32_GOT_LO12_NC");
350         return ELF::R_AARCH64_NONE;
351       }
352       if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) {
353         if (IsILP32) {
354           Ctx.reportError(Fixup.getLoc(),
355                           "ILP32 4 byte checked GOT load/store relocation "
356                           "not supported (unchecked eqv: LD32_GOT_LO12_NC)");
357         } else {
358           Ctx.reportError(Fixup.getLoc(),
359                           "LP64 4 byte checked GOT load/store relocation "
360                           "not supported (unchecked/ILP32 eqv: "
361                           "LD32_GOT_LO12_NC)");
362         }
363         return ELF::R_AARCH64_NONE;
364       }
365       if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) {
366         if (IsILP32)
367           return ELF::R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC;
368         Ctx.reportError(Fixup.getLoc(), "LP64 32-bit load/store "
369                                         "relocation not supported (ILP32 eqv: "
370                                         "TLSIE_LD32_GOTTPREL_LO12_NC)");
371         return ELF::R_AARCH64_NONE;
372       }
373       if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) {
374         if (IsILP32)
375           return ELF::R_AARCH64_P32_TLSDESC_LD32_LO12;
376         Ctx.reportError(Fixup.getLoc(),
377                         "LP64 4 byte TLSDESC load/store relocation "
378                         "not supported (ILP32 eqv: TLSDESC_LD64_LO12)");
379         return ELF::R_AARCH64_NONE;
380       }
381 
382       Ctx.reportError(Fixup.getLoc(),
383                       "invalid fixup for 32-bit load/store instruction "
384                       "fixup_aarch64_ldst_imm12_scale4");
385       return ELF::R_AARCH64_NONE;
386     case AArch64::fixup_aarch64_ldst_imm12_scale8:
387       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
388         return R_CLS(LDST64_ABS_LO12_NC);
389       if ((SymLoc == AArch64MCExpr::VK_GOT ||
390            SymLoc == AArch64MCExpr::VK_GOT_AUTH) &&
391           IsNC) {
392         AArch64MCExpr::VariantKind AddressLoc =
393             AArch64MCExpr::getAddressFrag(RefKind);
394         bool IsAuth = (SymLoc == AArch64MCExpr::VK_GOT_AUTH);
395         if (!IsILP32) {
396           if (AddressLoc == AArch64MCExpr::VK_LO15)
397             return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
398           return (IsAuth ? ELF::R_AARCH64_AUTH_LD64_GOT_LO12_NC
399                          : ELF::R_AARCH64_LD64_GOT_LO12_NC);
400         }
401         Ctx.reportError(Fixup.getLoc(),
402                         Twine("ILP32 64-bit load/store "
403                               "relocation not supported (LP64 eqv: ") +
404                             (IsAuth ? "AUTH_GOT_LO12_NC" : "LD64_GOT_LO12_NC") +
405                             Twine(')'));
406         return ELF::R_AARCH64_NONE;
407       }
408       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
409         return R_CLS(TLSLD_LDST64_DTPREL_LO12);
410       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
411         return R_CLS(TLSLD_LDST64_DTPREL_LO12_NC);
412       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
413         return R_CLS(TLSLE_LDST64_TPREL_LO12);
414       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
415         return R_CLS(TLSLE_LDST64_TPREL_LO12_NC);
416       if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) {
417         if (!IsILP32)
418           return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
419         Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
420                                         "relocation not supported (LP64 eqv: "
421                                         "TLSIE_LD64_GOTTPREL_LO12_NC)");
422         return ELF::R_AARCH64_NONE;
423       }
424       if (SymLoc == AArch64MCExpr::VK_TLSDESC) {
425         if (!IsILP32)
426           return ELF::R_AARCH64_TLSDESC_LD64_LO12;
427         Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
428                                         "relocation not supported (LP64 eqv: "
429                                         "TLSDESC_LD64_LO12)");
430         return ELF::R_AARCH64_NONE;
431       }
432       if (SymLoc == AArch64MCExpr::VK_TLSDESC_AUTH) {
433         if (!IsILP32)
434           return ELF::R_AARCH64_AUTH_TLSDESC_LD64_LO12;
435         Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store AUTH "
436                                         "relocation not supported (LP64 eqv: "
437                                         "AUTH_TLSDESC_LD64_LO12)");
438         return ELF::R_AARCH64_NONE;
439       }
440       Ctx.reportError(Fixup.getLoc(),
441                       "invalid fixup for 64-bit load/store instruction");
442       return ELF::R_AARCH64_NONE;
443     case AArch64::fixup_aarch64_ldst_imm12_scale16:
444       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
445         return R_CLS(LDST128_ABS_LO12_NC);
446       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
447         return R_CLS(TLSLD_LDST128_DTPREL_LO12);
448       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
449         return R_CLS(TLSLD_LDST128_DTPREL_LO12_NC);
450       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
451         return R_CLS(TLSLE_LDST128_TPREL_LO12);
452       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
453         return R_CLS(TLSLE_LDST128_TPREL_LO12_NC);
454 
455       Ctx.reportError(Fixup.getLoc(),
456                       "invalid fixup for 128-bit load/store instruction");
457       return ELF::R_AARCH64_NONE;
458     // ILP32 case not reached here, tested with isNonILP32reloc
459     case AArch64::fixup_aarch64_movw:
460       if (RefKind == AArch64MCExpr::VK_ABS_G3)
461         return ELF::R_AARCH64_MOVW_UABS_G3;
462       if (RefKind == AArch64MCExpr::VK_ABS_G2)
463         return ELF::R_AARCH64_MOVW_UABS_G2;
464       if (RefKind == AArch64MCExpr::VK_ABS_G2_S)
465         return ELF::R_AARCH64_MOVW_SABS_G2;
466       if (RefKind == AArch64MCExpr::VK_ABS_G2_NC)
467         return ELF::R_AARCH64_MOVW_UABS_G2_NC;
468       if (RefKind == AArch64MCExpr::VK_ABS_G1)
469         return R_CLS(MOVW_UABS_G1);
470       if (RefKind == AArch64MCExpr::VK_ABS_G1_S)
471         return ELF::R_AARCH64_MOVW_SABS_G1;
472       if (RefKind == AArch64MCExpr::VK_ABS_G1_NC)
473         return ELF::R_AARCH64_MOVW_UABS_G1_NC;
474       if (RefKind == AArch64MCExpr::VK_ABS_G0)
475         return R_CLS(MOVW_UABS_G0);
476       if (RefKind == AArch64MCExpr::VK_ABS_G0_S)
477         return R_CLS(MOVW_SABS_G0);
478       if (RefKind == AArch64MCExpr::VK_ABS_G0_NC)
479         return R_CLS(MOVW_UABS_G0_NC);
480       if (RefKind == AArch64MCExpr::VK_PREL_G3)
481         return ELF::R_AARCH64_MOVW_PREL_G3;
482       if (RefKind == AArch64MCExpr::VK_PREL_G2)
483         return ELF::R_AARCH64_MOVW_PREL_G2;
484       if (RefKind == AArch64MCExpr::VK_PREL_G2_NC)
485         return ELF::R_AARCH64_MOVW_PREL_G2_NC;
486       if (RefKind == AArch64MCExpr::VK_PREL_G1)
487         return R_CLS(MOVW_PREL_G1);
488       if (RefKind == AArch64MCExpr::VK_PREL_G1_NC)
489         return ELF::R_AARCH64_MOVW_PREL_G1_NC;
490       if (RefKind == AArch64MCExpr::VK_PREL_G0)
491         return R_CLS(MOVW_PREL_G0);
492       if (RefKind == AArch64MCExpr::VK_PREL_G0_NC)
493         return R_CLS(MOVW_PREL_G0_NC);
494       if (RefKind == AArch64MCExpr::VK_DTPREL_G2)
495         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
496       if (RefKind == AArch64MCExpr::VK_DTPREL_G1)
497         return R_CLS(TLSLD_MOVW_DTPREL_G1);
498       if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC)
499         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC;
500       if (RefKind == AArch64MCExpr::VK_DTPREL_G0)
501         return R_CLS(TLSLD_MOVW_DTPREL_G0);
502       if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC)
503         return R_CLS(TLSLD_MOVW_DTPREL_G0_NC);
504       if (RefKind == AArch64MCExpr::VK_TPREL_G2)
505         return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2;
506       if (RefKind == AArch64MCExpr::VK_TPREL_G1)
507         return R_CLS(TLSLE_MOVW_TPREL_G1);
508       if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC)
509         return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC;
510       if (RefKind == AArch64MCExpr::VK_TPREL_G0)
511         return R_CLS(TLSLE_MOVW_TPREL_G0);
512       if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC)
513         return R_CLS(TLSLE_MOVW_TPREL_G0_NC);
514       if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1)
515         return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
516       if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC)
517         return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
518       Ctx.reportError(Fixup.getLoc(),
519                       "invalid fixup for movz/movk instruction");
520       return ELF::R_AARCH64_NONE;
521     default:
522       Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
523       return ELF::R_AARCH64_NONE;
524     }
525   }
526 
527   llvm_unreachable("Unimplemented fixup -> relocation");
528 }
529 
530 bool AArch64ELFObjectWriter::needsRelocateWithSymbol(const MCValue &Val,
531                                                      const MCSymbol &,
532                                                      unsigned) const {
533   return (Val.getRefKind() & AArch64MCExpr::VK_GOT) == AArch64MCExpr::VK_GOT;
534 }
535 
536 std::unique_ptr<MCObjectTargetWriter>
537 llvm::createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32) {
538   return std::make_unique<AArch64ELFObjectWriter>(OSABI, IsILP32);
539 }
540