13b0846e8STim Northover //===-- AArch64ELFObjectWriter.cpp - AArch64 ELF Writer -------------------===//
23b0846e8STim Northover //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63b0846e8STim Northover //
73b0846e8STim Northover //===----------------------------------------------------------------------===//
83b0846e8STim Northover //
93b0846e8STim Northover // This file handles ELF-specific object emission, converting LLVM's internal
103b0846e8STim Northover // fixups into the appropriate relocations.
113b0846e8STim Northover //
123b0846e8STim Northover //===----------------------------------------------------------------------===//
133b0846e8STim Northover
143b0846e8STim Northover #include "MCTargetDesc/AArch64FixupKinds.h"
153b0846e8STim Northover #include "MCTargetDesc/AArch64MCExpr.h"
163b0846e8STim Northover #include "MCTargetDesc/AArch64MCTargetDesc.h"
17264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h"
18aa77b1e0SOliver Stannard #include "llvm/MC/MCContext.h"
193b0846e8STim Northover #include "llvm/MC/MCELFObjectWriter.h"
20049b0175SEugene Zelenko #include "llvm/MC/MCFixup.h"
2160fbc7ccSLang Hames #include "llvm/MC/MCObjectWriter.h"
223b0846e8STim Northover #include "llvm/MC/MCValue.h"
233b0846e8STim Northover #include "llvm/Support/ErrorHandling.h"
24049b0175SEugene Zelenko #include <cassert>
25049b0175SEugene Zelenko #include <cstdint>
263b0846e8STim Northover
273b0846e8STim Northover using namespace llvm;
283b0846e8STim Northover
293b0846e8STim Northover namespace {
30049b0175SEugene Zelenko
313b0846e8STim Northover class AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
323b0846e8STim Northover public:
33dcd7d6c3SPeter Collingbourne AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32);
343b0846e8STim Northover
35049b0175SEugene Zelenko ~AArch64ELFObjectWriter() override = default;
363b0846e8STim Northover
373b0846e8STim Northover protected:
388340f94dSRafael Espindola unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
398340f94dSRafael Espindola const MCFixup &Fixup, bool IsPCRel) const override;
40504bf334SJoel Jones bool IsILP32;
413b0846e8STim Northover };
42049b0175SEugene Zelenko
43049b0175SEugene Zelenko } // end anonymous namespace
443b0846e8STim Northover
AArch64ELFObjectWriter(uint8_t OSABI,bool IsILP32)45dcd7d6c3SPeter Collingbourne AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
4621bfd068SAmanieu d'Antras : MCELFObjectTargetWriter(/*Is64Bit*/ !IsILP32, OSABI, ELF::EM_AARCH64,
47504bf334SJoel Jones /*HasRelocationAddend*/ true),
48504bf334SJoel Jones IsILP32(IsILP32) {}
493b0846e8STim Northover
50504bf334SJoel Jones #define R_CLS(rtype) \
51504bf334SJoel Jones IsILP32 ? ELF::R_AARCH64_P32_##rtype : ELF::R_AARCH64_##rtype
52650c96e0SRafael Espindola #define BAD_ILP32_MOV(lp64rtype) \
53650c96e0SRafael Espindola "ILP32 absolute MOV relocation not " \
54504bf334SJoel Jones "supported (LP64 eqv: " #lp64rtype ")"
55504bf334SJoel Jones
56504bf334SJoel Jones // assumes IsILP32 is true
isNonILP32reloc(const MCFixup & Fixup,AArch64MCExpr::VariantKind RefKind,MCContext & Ctx)57ffd3715dSBenjamin Kramer static bool isNonILP32reloc(const MCFixup &Fixup,
58ffd3715dSBenjamin Kramer AArch64MCExpr::VariantKind RefKind,
59ffd3715dSBenjamin Kramer MCContext &Ctx) {
6090b6bb75SSam Clegg if (Fixup.getTargetKind() != AArch64::fixup_aarch64_movw)
61504bf334SJoel Jones return false;
62504bf334SJoel Jones switch (RefKind) {
63504bf334SJoel Jones case AArch64MCExpr::VK_ABS_G3:
64504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G3));
65504bf334SJoel Jones return true;
66504bf334SJoel Jones case AArch64MCExpr::VK_ABS_G2:
67504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2));
68504bf334SJoel Jones return true;
69504bf334SJoel Jones case AArch64MCExpr::VK_ABS_G2_S:
70504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G2));
7165134057SJoel Jones return true;
72504bf334SJoel Jones case AArch64MCExpr::VK_ABS_G2_NC:
73504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2_NC));
7465134057SJoel Jones return true;
75504bf334SJoel Jones case AArch64MCExpr::VK_ABS_G1_S:
76504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G1));
7765134057SJoel Jones return true;
78504bf334SJoel Jones case AArch64MCExpr::VK_ABS_G1_NC:
79504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G1_NC));
8065134057SJoel Jones return true;
81504bf334SJoel Jones case AArch64MCExpr::VK_DTPREL_G2:
82504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G2));
8365134057SJoel Jones return true;
84504bf334SJoel Jones case AArch64MCExpr::VK_DTPREL_G1_NC:
85504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G1_NC));
8665134057SJoel Jones return true;
87504bf334SJoel Jones case AArch64MCExpr::VK_TPREL_G2:
88504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G2));
8965134057SJoel Jones return true;
90504bf334SJoel Jones case AArch64MCExpr::VK_TPREL_G1_NC:
91504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G1_NC));
9265134057SJoel Jones return true;
93504bf334SJoel Jones case AArch64MCExpr::VK_GOTTPREL_G1:
94504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G1));
9565134057SJoel Jones return true;
96504bf334SJoel Jones case AArch64MCExpr::VK_GOTTPREL_G0_NC:
97504bf334SJoel Jones Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G0_NC));
9865134057SJoel Jones return true;
99650c96e0SRafael Espindola default:
100650c96e0SRafael Espindola return false;
101504bf334SJoel Jones }
102504bf334SJoel Jones return false;
103504bf334SJoel Jones }
104504bf334SJoel Jones
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const1058340f94dSRafael Espindola unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
1068340f94dSRafael Espindola const MCValue &Target,
1073b0846e8STim Northover const MCFixup &Fixup,
1083b0846e8STim Northover bool IsPCRel) const {
10934d77516SFangrui Song unsigned Kind = Fixup.getTargetKind();
11034d77516SFangrui Song if (Kind >= FirstLiteralRelocationKind)
11134d77516SFangrui Song return Kind - FirstLiteralRelocationKind;
1123b0846e8STim Northover AArch64MCExpr::VariantKind RefKind =
1133b0846e8STim Northover static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
1143b0846e8STim Northover AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
1153b0846e8STim Northover bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
1163b0846e8STim Northover
1173b0846e8STim Northover assert((!Target.getSymA() ||
1186adc664bSLeonard Chan Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
1196adc664bSLeonard Chan Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) &&
1203b0846e8STim Northover "Should only be expression-level modifiers here");
1213b0846e8STim Northover
1223b0846e8STim Northover assert((!Target.getSymB() ||
1233b0846e8STim Northover Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) &&
1243b0846e8STim Northover "Should only be expression-level modifiers here");
1253b0846e8STim Northover
1263b0846e8STim Northover if (IsPCRel) {
12734d77516SFangrui Song switch (Kind) {
128aa77b1e0SOliver Stannard case FK_Data_1:
129aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
130aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
1313b0846e8STim Northover case FK_Data_2:
132504bf334SJoel Jones return R_CLS(PREL16);
1336adc664bSLeonard Chan case FK_Data_4: {
1346adc664bSLeonard Chan return Target.getAccessVariant() == MCSymbolRefExpr::VK_PLT
1356adc664bSLeonard Chan ? R_CLS(PLT32)
1366adc664bSLeonard Chan : R_CLS(PREL32);
1376adc664bSLeonard Chan }
1383b0846e8STim Northover case FK_Data_8:
139504bf334SJoel Jones if (IsILP32) {
140650c96e0SRafael Espindola Ctx.reportError(Fixup.getLoc(),
141650c96e0SRafael Espindola "ILP32 8 byte PC relative data "
142504bf334SJoel Jones "relocation not supported (LP64 eqv: PREL64)");
143504bf334SJoel Jones return ELF::R_AARCH64_NONE;
144504bf334SJoel Jones } else
1453b0846e8STim Northover return ELF::R_AARCH64_PREL64;
1463b0846e8STim Northover case AArch64::fixup_aarch64_pcrel_adr_imm21:
1479dd1d451SDavid Green if (SymLoc != AArch64MCExpr::VK_ABS)
1489dd1d451SDavid Green Ctx.reportError(Fixup.getLoc(),
1499dd1d451SDavid Green "invalid symbol kind for ADR relocation");
150504bf334SJoel Jones return R_CLS(ADR_PREL_LO21);
1513b0846e8STim Northover case AArch64::fixup_aarch64_pcrel_adrp_imm21:
1523b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
153504bf334SJoel Jones return R_CLS(ADR_PREL_PG_HI21);
15465134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) {
15565134057SJoel Jones if (IsILP32) {
15665134057SJoel Jones Ctx.reportError(Fixup.getLoc(),
15765134057SJoel Jones "invalid fixup for 32-bit pcrel ADRP instruction "
15865134057SJoel Jones "VK_ABS VK_NC");
15965134057SJoel Jones return ELF::R_AARCH64_NONE;
16065134057SJoel Jones } else {
16165134057SJoel Jones return ELF::R_AARCH64_ADR_PREL_PG_HI21_NC;
16265134057SJoel Jones }
16365134057SJoel Jones }
1643b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
165504bf334SJoel Jones return R_CLS(ADR_GOT_PAGE);
1663b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
167504bf334SJoel Jones return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
1683b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
169504bf334SJoel Jones return R_CLS(TLSDESC_ADR_PAGE21);
170aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(),
171aa77b1e0SOliver Stannard "invalid symbol kind for ADRP relocation");
172aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
1733b0846e8STim Northover case AArch64::fixup_aarch64_pcrel_branch26:
174504bf334SJoel Jones return R_CLS(JUMP26);
1753b0846e8STim Northover case AArch64::fixup_aarch64_pcrel_call26:
176504bf334SJoel Jones return R_CLS(CALL26);
1773b0846e8STim Northover case AArch64::fixup_aarch64_ldr_pcrel_imm19:
1783b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_GOTTPREL)
179504bf334SJoel Jones return R_CLS(TLSIE_LD_GOTTPREL_PREL19);
180ea60446cSDavid Green if (SymLoc == AArch64MCExpr::VK_GOT)
181ea60446cSDavid Green return R_CLS(GOT_LD_PREL19);
182504bf334SJoel Jones return R_CLS(LD_PREL_LO19);
1833b0846e8STim Northover case AArch64::fixup_aarch64_pcrel_branch14:
184504bf334SJoel Jones return R_CLS(TSTBR14);
1853b0846e8STim Northover case AArch64::fixup_aarch64_pcrel_branch19:
186504bf334SJoel Jones return R_CLS(CONDBR19);
1873b0846e8STim Northover default:
188aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");
189aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
1903b0846e8STim Northover }
1913b0846e8STim Northover } else {
192504bf334SJoel Jones if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx))
193504bf334SJoel Jones return ELF::R_AARCH64_NONE;
19490b6bb75SSam Clegg switch (Fixup.getTargetKind()) {
195aa77b1e0SOliver Stannard case FK_Data_1:
196aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
197aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
1983b0846e8STim Northover case FK_Data_2:
199504bf334SJoel Jones return R_CLS(ABS16);
2003b0846e8STim Northover case FK_Data_4:
201504bf334SJoel Jones return R_CLS(ABS32);
2023b0846e8STim Northover case FK_Data_8:
203504bf334SJoel Jones if (IsILP32) {
204650c96e0SRafael Espindola Ctx.reportError(Fixup.getLoc(),
205650c96e0SRafael Espindola "ILP32 8 byte absolute data "
20665134057SJoel Jones "relocation not supported (LP64 eqv: ABS64)");
207504bf334SJoel Jones return ELF::R_AARCH64_NONE;
208504bf334SJoel Jones } else
2093b0846e8STim Northover return ELF::R_AARCH64_ABS64;
2103b0846e8STim Northover case AArch64::fixup_aarch64_add_imm12:
2113b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_DTPREL_HI12)
212504bf334SJoel Jones return R_CLS(TLSLD_ADD_DTPREL_HI12);
2133b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_TPREL_HI12)
214504bf334SJoel Jones return R_CLS(TLSLE_ADD_TPREL_HI12);
2153b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC)
216504bf334SJoel Jones return R_CLS(TLSLD_ADD_DTPREL_LO12_NC);
2173b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_DTPREL_LO12)
218504bf334SJoel Jones return R_CLS(TLSLD_ADD_DTPREL_LO12);
2193b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC)
220504bf334SJoel Jones return R_CLS(TLSLE_ADD_TPREL_LO12_NC);
2213b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_TPREL_LO12)
222504bf334SJoel Jones return R_CLS(TLSLE_ADD_TPREL_LO12);
2233b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
22465134057SJoel Jones return R_CLS(TLSDESC_ADD_LO12);
2253b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
226504bf334SJoel Jones return R_CLS(ADD_ABS_LO12_NC);
2273b0846e8STim Northover
228aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(),
229aa77b1e0SOliver Stannard "invalid fixup for add (uimm12) instruction");
230aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
2313b0846e8STim Northover case AArch64::fixup_aarch64_ldst_imm12_scale1:
2323b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
233504bf334SJoel Jones return R_CLS(LDST8_ABS_LO12_NC);
2343b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
235504bf334SJoel Jones return R_CLS(TLSLD_LDST8_DTPREL_LO12);
2363b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
237504bf334SJoel Jones return R_CLS(TLSLD_LDST8_DTPREL_LO12_NC);
2383b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
239504bf334SJoel Jones return R_CLS(TLSLE_LDST8_TPREL_LO12);
2403b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
241504bf334SJoel Jones return R_CLS(TLSLE_LDST8_TPREL_LO12_NC);
2423b0846e8STim Northover
243aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(),
244aa77b1e0SOliver Stannard "invalid fixup for 8-bit load/store instruction");
245aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
2463b0846e8STim Northover case AArch64::fixup_aarch64_ldst_imm12_scale2:
2473b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
248504bf334SJoel Jones return R_CLS(LDST16_ABS_LO12_NC);
2493b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
250504bf334SJoel Jones return R_CLS(TLSLD_LDST16_DTPREL_LO12);
2513b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
252504bf334SJoel Jones return R_CLS(TLSLD_LDST16_DTPREL_LO12_NC);
2533b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
254504bf334SJoel Jones return R_CLS(TLSLE_LDST16_TPREL_LO12);
2553b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
256504bf334SJoel Jones return R_CLS(TLSLE_LDST16_TPREL_LO12_NC);
2573b0846e8STim Northover
258aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(),
259aa77b1e0SOliver Stannard "invalid fixup for 16-bit load/store instruction");
260aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
2613b0846e8STim Northover case AArch64::fixup_aarch64_ldst_imm12_scale4:
2623b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
263504bf334SJoel Jones return R_CLS(LDST32_ABS_LO12_NC);
2643b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
265504bf334SJoel Jones return R_CLS(TLSLD_LDST32_DTPREL_LO12);
2663b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
267504bf334SJoel Jones return R_CLS(TLSLD_LDST32_DTPREL_LO12_NC);
2683b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
269504bf334SJoel Jones return R_CLS(TLSLE_LDST32_TPREL_LO12);
2703b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
271504bf334SJoel Jones return R_CLS(TLSLE_LDST32_TPREL_LO12_NC);
27265134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
27365134057SJoel Jones if (IsILP32) {
27465134057SJoel Jones return ELF::R_AARCH64_P32_LD32_GOT_LO12_NC;
27565134057SJoel Jones } else {
27665134057SJoel Jones Ctx.reportError(Fixup.getLoc(),
27765134057SJoel Jones "LP64 4 byte unchecked GOT load/store relocation "
27865134057SJoel Jones "not supported (ILP32 eqv: LD32_GOT_LO12_NC");
27965134057SJoel Jones return ELF::R_AARCH64_NONE;
28065134057SJoel Jones }
28165134057SJoel Jones }
28265134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) {
28365134057SJoel Jones if (IsILP32) {
28465134057SJoel Jones Ctx.reportError(Fixup.getLoc(),
28565134057SJoel Jones "ILP32 4 byte checked GOT load/store relocation "
28665134057SJoel Jones "not supported (unchecked eqv: LD32_GOT_LO12_NC)");
28765134057SJoel Jones } else {
28865134057SJoel Jones Ctx.reportError(Fixup.getLoc(),
28965134057SJoel Jones "LP64 4 byte checked GOT load/store relocation "
29065134057SJoel Jones "not supported (unchecked/ILP32 eqv: "
29165134057SJoel Jones "LD32_GOT_LO12_NC)");
29265134057SJoel Jones }
29365134057SJoel Jones return ELF::R_AARCH64_NONE;
29465134057SJoel Jones }
29565134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) {
29665134057SJoel Jones if (IsILP32) {
29765134057SJoel Jones return ELF::R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC;
29865134057SJoel Jones } else {
299650c96e0SRafael Espindola Ctx.reportError(Fixup.getLoc(),
300650c96e0SRafael Espindola "LP64 32-bit load/store "
30165134057SJoel Jones "relocation not supported (ILP32 eqv: "
30265134057SJoel Jones "TLSIE_LD32_GOTTPREL_LO12_NC)");
30365134057SJoel Jones return ELF::R_AARCH64_NONE;
30465134057SJoel Jones }
30565134057SJoel Jones }
30665134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) {
30765134057SJoel Jones if (IsILP32) {
30865134057SJoel Jones return ELF::R_AARCH64_P32_TLSDESC_LD32_LO12;
30965134057SJoel Jones } else {
31065134057SJoel Jones Ctx.reportError(Fixup.getLoc(),
31165134057SJoel Jones "LP64 4 byte TLSDESC load/store relocation "
31265134057SJoel Jones "not supported (ILP32 eqv: TLSDESC_LD64_LO12)");
31365134057SJoel Jones return ELF::R_AARCH64_NONE;
31465134057SJoel Jones }
31565134057SJoel Jones }
3163b0846e8STim Northover
317aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(),
31865134057SJoel Jones "invalid fixup for 32-bit load/store instruction "
31965134057SJoel Jones "fixup_aarch64_ldst_imm12_scale4");
320aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
3213b0846e8STim Northover case AArch64::fixup_aarch64_ldst_imm12_scale8:
3223b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
323504bf334SJoel Jones return R_CLS(LDST64_ABS_LO12_NC);
32465134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
325*ff41ae8bSAdhemerval Zanella AArch64MCExpr::VariantKind AddressLoc =
326*ff41ae8bSAdhemerval Zanella AArch64MCExpr::getAddressFrag(RefKind);
32765134057SJoel Jones if (!IsILP32) {
328*ff41ae8bSAdhemerval Zanella if (AddressLoc == AArch64MCExpr::VK_LO15)
329*ff41ae8bSAdhemerval Zanella return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
33065134057SJoel Jones return ELF::R_AARCH64_LD64_GOT_LO12_NC;
33165134057SJoel Jones } else {
33265134057SJoel Jones Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
33365134057SJoel Jones "relocation not supported (LP64 eqv: "
33465134057SJoel Jones "LD64_GOT_LO12_NC)");
33565134057SJoel Jones return ELF::R_AARCH64_NONE;
33665134057SJoel Jones }
33765134057SJoel Jones }
3383b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
339504bf334SJoel Jones return R_CLS(TLSLD_LDST64_DTPREL_LO12);
3403b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
341504bf334SJoel Jones return R_CLS(TLSLD_LDST64_DTPREL_LO12_NC);
3423b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
343504bf334SJoel Jones return R_CLS(TLSLE_LDST64_TPREL_LO12);
3443b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
345504bf334SJoel Jones return R_CLS(TLSLE_LDST64_TPREL_LO12_NC);
34665134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) {
34765134057SJoel Jones if (!IsILP32) {
34865134057SJoel Jones return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
34965134057SJoel Jones } else {
35065134057SJoel Jones Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
35165134057SJoel Jones "relocation not supported (LP64 eqv: "
35265134057SJoel Jones "TLSIE_LD64_GOTTPREL_LO12_NC)");
35365134057SJoel Jones return ELF::R_AARCH64_NONE;
35465134057SJoel Jones }
35565134057SJoel Jones }
35665134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_TLSDESC) {
35765134057SJoel Jones if (!IsILP32) {
35865134057SJoel Jones return ELF::R_AARCH64_TLSDESC_LD64_LO12;
35965134057SJoel Jones } else {
36065134057SJoel Jones Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
36165134057SJoel Jones "relocation not supported (LP64 eqv: "
36265134057SJoel Jones "TLSDESC_LD64_LO12)");
36365134057SJoel Jones return ELF::R_AARCH64_NONE;
36465134057SJoel Jones }
36565134057SJoel Jones }
366aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(),
367aa77b1e0SOliver Stannard "invalid fixup for 64-bit load/store instruction");
368aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
3693b0846e8STim Northover case AArch64::fixup_aarch64_ldst_imm12_scale16:
3703b0846e8STim Northover if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
371504bf334SJoel Jones return R_CLS(LDST128_ABS_LO12_NC);
37265134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
37365134057SJoel Jones return R_CLS(TLSLD_LDST128_DTPREL_LO12);
37465134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
37565134057SJoel Jones return R_CLS(TLSLD_LDST128_DTPREL_LO12_NC);
37665134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
37765134057SJoel Jones return R_CLS(TLSLE_LDST128_TPREL_LO12);
37865134057SJoel Jones if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
37965134057SJoel Jones return R_CLS(TLSLE_LDST128_TPREL_LO12_NC);
3803b0846e8STim Northover
381aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(),
382aa77b1e0SOliver Stannard "invalid fixup for 128-bit load/store instruction");
383aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
384504bf334SJoel Jones // ILP32 case not reached here, tested with isNonILP32reloc
3853b0846e8STim Northover case AArch64::fixup_aarch64_movw:
3863b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G3)
3873b0846e8STim Northover return ELF::R_AARCH64_MOVW_UABS_G3;
3883b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G2)
3893b0846e8STim Northover return ELF::R_AARCH64_MOVW_UABS_G2;
3903b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G2_S)
3913b0846e8STim Northover return ELF::R_AARCH64_MOVW_SABS_G2;
3923b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G2_NC)
3933b0846e8STim Northover return ELF::R_AARCH64_MOVW_UABS_G2_NC;
3943b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G1)
395504bf334SJoel Jones return R_CLS(MOVW_UABS_G1);
3963b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G1_S)
3973b0846e8STim Northover return ELF::R_AARCH64_MOVW_SABS_G1;
3983b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G1_NC)
3993b0846e8STim Northover return ELF::R_AARCH64_MOVW_UABS_G1_NC;
4003b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G0)
401504bf334SJoel Jones return R_CLS(MOVW_UABS_G0);
4023b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G0_S)
403504bf334SJoel Jones return R_CLS(MOVW_SABS_G0);
4043b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_ABS_G0_NC)
405504bf334SJoel Jones return R_CLS(MOVW_UABS_G0_NC);
406aa6a7df6SPeter Collingbourne if (RefKind == AArch64MCExpr::VK_PREL_G3)
407aa6a7df6SPeter Collingbourne return ELF::R_AARCH64_MOVW_PREL_G3;
408aa6a7df6SPeter Collingbourne if (RefKind == AArch64MCExpr::VK_PREL_G2)
409aa6a7df6SPeter Collingbourne return ELF::R_AARCH64_MOVW_PREL_G2;
410aa6a7df6SPeter Collingbourne if (RefKind == AArch64MCExpr::VK_PREL_G2_NC)
411aa6a7df6SPeter Collingbourne return ELF::R_AARCH64_MOVW_PREL_G2_NC;
412aa6a7df6SPeter Collingbourne if (RefKind == AArch64MCExpr::VK_PREL_G1)
413aa6a7df6SPeter Collingbourne return R_CLS(MOVW_PREL_G1);
414aa6a7df6SPeter Collingbourne if (RefKind == AArch64MCExpr::VK_PREL_G1_NC)
415aa6a7df6SPeter Collingbourne return ELF::R_AARCH64_MOVW_PREL_G1_NC;
416aa6a7df6SPeter Collingbourne if (RefKind == AArch64MCExpr::VK_PREL_G0)
417aa6a7df6SPeter Collingbourne return R_CLS(MOVW_PREL_G0);
418aa6a7df6SPeter Collingbourne if (RefKind == AArch64MCExpr::VK_PREL_G0_NC)
419aa6a7df6SPeter Collingbourne return R_CLS(MOVW_PREL_G0_NC);
4203b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_DTPREL_G2)
4213b0846e8STim Northover return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
4223b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_DTPREL_G1)
423504bf334SJoel Jones return R_CLS(TLSLD_MOVW_DTPREL_G1);
4243b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC)
4253b0846e8STim Northover return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC;
4263b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_DTPREL_G0)
427504bf334SJoel Jones return R_CLS(TLSLD_MOVW_DTPREL_G0);
4283b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC)
429504bf334SJoel Jones return R_CLS(TLSLD_MOVW_DTPREL_G0_NC);
4303b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_TPREL_G2)
4313b0846e8STim Northover return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2;
4323b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_TPREL_G1)
433504bf334SJoel Jones return R_CLS(TLSLE_MOVW_TPREL_G1);
4343b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC)
4353b0846e8STim Northover return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC;
4363b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_TPREL_G0)
437504bf334SJoel Jones return R_CLS(TLSLE_MOVW_TPREL_G0);
4383b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC)
439504bf334SJoel Jones return R_CLS(TLSLE_MOVW_TPREL_G0_NC);
4403b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1)
4413b0846e8STim Northover return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
4423b0846e8STim Northover if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC)
4433b0846e8STim Northover return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
444aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(),
445aa77b1e0SOliver Stannard "invalid fixup for movz/movk instruction");
446aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
4473b0846e8STim Northover default:
448aa77b1e0SOliver Stannard Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
449aa77b1e0SOliver Stannard return ELF::R_AARCH64_NONE;
4503b0846e8STim Northover }
4513b0846e8STim Northover }
4523b0846e8STim Northover
4533b0846e8STim Northover llvm_unreachable("Unimplemented fixup -> relocation");
4543b0846e8STim Northover }
4553b0846e8STim Northover
456dcd7d6c3SPeter Collingbourne std::unique_ptr<MCObjectTargetWriter>
createAArch64ELFObjectWriter(uint8_t OSABI,bool IsILP32)457dcd7d6c3SPeter Collingbourne llvm::createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32) {
4580eaee545SJonas Devlieghere return std::make_unique<AArch64ELFObjectWriter>(OSABI, IsILP32);
4593b0846e8STim Northover }
460