xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- AArch64ELFObjectWriter.cpp - AArch64 ELF Writer -------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file handles ELF-specific object emission, converting LLVM's internal
100b57cec5SDimitry Andric // fixups into the appropriate relocations.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "MCTargetDesc/AArch64FixupKinds.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/AArch64MCExpr.h"
160b57cec5SDimitry Andric #include "MCTargetDesc/AArch64MCTargetDesc.h"
170b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCValue.h"
230b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
240b57cec5SDimitry Andric #include <cassert>
250b57cec5SDimitry Andric #include <cstdint>
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric using namespace llvm;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric namespace {
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric class AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
320b57cec5SDimitry Andric public:
330b57cec5SDimitry Andric   AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32);
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric   ~AArch64ELFObjectWriter() override = default;
360b57cec5SDimitry Andric 
37bdd1243dSDimitry Andric   MCSectionELF *getMemtagRelocsSection(MCContext &Ctx) const override;
38bdd1243dSDimitry Andric 
390b57cec5SDimitry Andric protected:
400b57cec5SDimitry Andric   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
410b57cec5SDimitry Andric                         const MCFixup &Fixup, bool IsPCRel) const override;
425f757f3fSDimitry Andric   bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
435f757f3fSDimitry Andric                                unsigned Type) const override;
440b57cec5SDimitry Andric   bool IsILP32;
450b57cec5SDimitry Andric };
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric } // end anonymous namespace
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
50e8d8bef9SDimitry Andric     : MCELFObjectTargetWriter(/*Is64Bit*/ !IsILP32, OSABI, ELF::EM_AARCH64,
510b57cec5SDimitry Andric                               /*HasRelocationAddend*/ true),
520b57cec5SDimitry Andric       IsILP32(IsILP32) {}
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric #define R_CLS(rtype)                                                           \
550b57cec5SDimitry Andric   IsILP32 ? ELF::R_AARCH64_P32_##rtype : ELF::R_AARCH64_##rtype
560b57cec5SDimitry Andric #define BAD_ILP32_MOV(lp64rtype)                                               \
570b57cec5SDimitry Andric   "ILP32 absolute MOV relocation not "                                         \
580b57cec5SDimitry Andric   "supported (LP64 eqv: " #lp64rtype ")"
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric // assumes IsILP32 is true
610b57cec5SDimitry Andric static bool isNonILP32reloc(const MCFixup &Fixup,
620b57cec5SDimitry Andric                             AArch64MCExpr::VariantKind RefKind,
630b57cec5SDimitry Andric                             MCContext &Ctx) {
648bcb0991SDimitry Andric   if (Fixup.getTargetKind() != AArch64::fixup_aarch64_movw)
650b57cec5SDimitry Andric     return false;
660b57cec5SDimitry Andric   switch (RefKind) {
670b57cec5SDimitry Andric   case AArch64MCExpr::VK_ABS_G3:
680b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G3));
690b57cec5SDimitry Andric     return true;
700b57cec5SDimitry Andric   case AArch64MCExpr::VK_ABS_G2:
710b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2));
720b57cec5SDimitry Andric     return true;
730b57cec5SDimitry Andric   case AArch64MCExpr::VK_ABS_G2_S:
740b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G2));
750b57cec5SDimitry Andric     return true;
760b57cec5SDimitry Andric   case AArch64MCExpr::VK_ABS_G2_NC:
770b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2_NC));
780b57cec5SDimitry Andric     return true;
790b57cec5SDimitry Andric   case AArch64MCExpr::VK_ABS_G1_S:
800b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G1));
810b57cec5SDimitry Andric     return true;
820b57cec5SDimitry Andric   case AArch64MCExpr::VK_ABS_G1_NC:
830b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G1_NC));
840b57cec5SDimitry Andric     return true;
850b57cec5SDimitry Andric   case AArch64MCExpr::VK_DTPREL_G2:
860b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G2));
870b57cec5SDimitry Andric     return true;
880b57cec5SDimitry Andric   case AArch64MCExpr::VK_DTPREL_G1_NC:
890b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G1_NC));
900b57cec5SDimitry Andric     return true;
910b57cec5SDimitry Andric   case AArch64MCExpr::VK_TPREL_G2:
920b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G2));
930b57cec5SDimitry Andric     return true;
940b57cec5SDimitry Andric   case AArch64MCExpr::VK_TPREL_G1_NC:
950b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G1_NC));
960b57cec5SDimitry Andric     return true;
970b57cec5SDimitry Andric   case AArch64MCExpr::VK_GOTTPREL_G1:
980b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G1));
990b57cec5SDimitry Andric     return true;
1000b57cec5SDimitry Andric   case AArch64MCExpr::VK_GOTTPREL_G0_NC:
1010b57cec5SDimitry Andric     Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G0_NC));
1020b57cec5SDimitry Andric     return true;
1030b57cec5SDimitry Andric   default:
1040b57cec5SDimitry Andric     return false;
1050b57cec5SDimitry Andric   }
1060b57cec5SDimitry Andric   return false;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
1100b57cec5SDimitry Andric                                               const MCValue &Target,
1110b57cec5SDimitry Andric                                               const MCFixup &Fixup,
1120b57cec5SDimitry Andric                                               bool IsPCRel) const {
1135ffd83dbSDimitry Andric   unsigned Kind = Fixup.getTargetKind();
1145ffd83dbSDimitry Andric   if (Kind >= FirstLiteralRelocationKind)
1155ffd83dbSDimitry Andric     return Kind - FirstLiteralRelocationKind;
1160b57cec5SDimitry Andric   AArch64MCExpr::VariantKind RefKind =
1170b57cec5SDimitry Andric       static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
1180b57cec5SDimitry Andric   AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
1190b57cec5SDimitry Andric   bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   assert((!Target.getSymA() ||
1225ffd83dbSDimitry Andric           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
123297eecfbSDimitry Andric           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
124297eecfbSDimitry Andric           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
1250b57cec5SDimitry Andric          "Should only be expression-level modifiers here");
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   assert((!Target.getSymB() ||
1280b57cec5SDimitry Andric           Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) &&
1290b57cec5SDimitry Andric          "Should only be expression-level modifiers here");
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   if (IsPCRel) {
1325ffd83dbSDimitry Andric     switch (Kind) {
1330b57cec5SDimitry Andric     case FK_Data_1:
1340b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
1350b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
1360b57cec5SDimitry Andric     case FK_Data_2:
1370b57cec5SDimitry Andric       return R_CLS(PREL16);
1385ffd83dbSDimitry Andric     case FK_Data_4: {
1395ffd83dbSDimitry Andric       return Target.getAccessVariant() == MCSymbolRefExpr::VK_PLT
1405ffd83dbSDimitry Andric                  ? R_CLS(PLT32)
1415ffd83dbSDimitry Andric                  : R_CLS(PREL32);
1425ffd83dbSDimitry Andric     }
1430b57cec5SDimitry Andric     case FK_Data_8:
1440b57cec5SDimitry Andric       if (IsILP32) {
1450b57cec5SDimitry Andric         Ctx.reportError(Fixup.getLoc(),
1460b57cec5SDimitry Andric                         "ILP32 8 byte PC relative data "
1470b57cec5SDimitry Andric                         "relocation not supported (LP64 eqv: PREL64)");
1480b57cec5SDimitry Andric         return ELF::R_AARCH64_NONE;
149*0fca6ea1SDimitry Andric       }
1500b57cec5SDimitry Andric       return ELF::R_AARCH64_PREL64;
1510b57cec5SDimitry Andric     case AArch64::fixup_aarch64_pcrel_adr_imm21:
1520b57cec5SDimitry Andric       if (SymLoc != AArch64MCExpr::VK_ABS)
1530b57cec5SDimitry Andric         Ctx.reportError(Fixup.getLoc(),
1540b57cec5SDimitry Andric                         "invalid symbol kind for ADR relocation");
1550b57cec5SDimitry Andric       return R_CLS(ADR_PREL_LO21);
1560b57cec5SDimitry Andric     case AArch64::fixup_aarch64_pcrel_adrp_imm21:
1570b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
1580b57cec5SDimitry Andric         return R_CLS(ADR_PREL_PG_HI21);
1590b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) {
1600b57cec5SDimitry Andric         if (IsILP32) {
1610b57cec5SDimitry Andric           Ctx.reportError(Fixup.getLoc(),
1620b57cec5SDimitry Andric                           "invalid fixup for 32-bit pcrel ADRP instruction "
1630b57cec5SDimitry Andric                           "VK_ABS VK_NC");
1640b57cec5SDimitry Andric           return ELF::R_AARCH64_NONE;
1650b57cec5SDimitry Andric         }
166*0fca6ea1SDimitry Andric         return ELF::R_AARCH64_ADR_PREL_PG_HI21_NC;
1670b57cec5SDimitry Andric       }
1680b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
1690b57cec5SDimitry Andric         return R_CLS(ADR_GOT_PAGE);
1700b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
1710b57cec5SDimitry Andric         return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
1720b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
1730b57cec5SDimitry Andric         return R_CLS(TLSDESC_ADR_PAGE21);
1740b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(),
1750b57cec5SDimitry Andric                       "invalid symbol kind for ADRP relocation");
1760b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
1770b57cec5SDimitry Andric     case AArch64::fixup_aarch64_pcrel_branch26:
1780b57cec5SDimitry Andric       return R_CLS(JUMP26);
1790b57cec5SDimitry Andric     case AArch64::fixup_aarch64_pcrel_call26:
1800b57cec5SDimitry Andric       return R_CLS(CALL26);
1810b57cec5SDimitry Andric     case AArch64::fixup_aarch64_ldr_pcrel_imm19:
1820b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_GOTTPREL)
1830b57cec5SDimitry Andric         return R_CLS(TLSIE_LD_GOTTPREL_PREL19);
1840b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_GOT)
1850b57cec5SDimitry Andric         return R_CLS(GOT_LD_PREL19);
1860b57cec5SDimitry Andric       return R_CLS(LD_PREL_LO19);
1870b57cec5SDimitry Andric     case AArch64::fixup_aarch64_pcrel_branch14:
1880b57cec5SDimitry Andric       return R_CLS(TSTBR14);
189cb14a3feSDimitry Andric     case AArch64::fixup_aarch64_pcrel_branch16:
190cb14a3feSDimitry Andric       Ctx.reportError(Fixup.getLoc(),
191cb14a3feSDimitry Andric                       "relocation of PAC/AUT instructions is not supported");
192cb14a3feSDimitry Andric       return ELF::R_AARCH64_NONE;
1930b57cec5SDimitry Andric     case AArch64::fixup_aarch64_pcrel_branch19:
1940b57cec5SDimitry Andric       return R_CLS(CONDBR19);
1950b57cec5SDimitry Andric     default:
1960b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");
1970b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
1980b57cec5SDimitry Andric     }
1990b57cec5SDimitry Andric   } else {
2000b57cec5SDimitry Andric     if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx))
2010b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
2028bcb0991SDimitry Andric     switch (Fixup.getTargetKind()) {
2030b57cec5SDimitry Andric     case FK_Data_1:
2040b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
2050b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
2060b57cec5SDimitry Andric     case FK_Data_2:
2070b57cec5SDimitry Andric       return R_CLS(ABS16);
2080b57cec5SDimitry Andric     case FK_Data_4:
209297eecfbSDimitry Andric       return (!IsILP32 &&
210297eecfbSDimitry Andric               Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL)
211297eecfbSDimitry Andric                  ? ELF::R_AARCH64_GOTPCREL32
212297eecfbSDimitry Andric                  : R_CLS(ABS32);
213*0fca6ea1SDimitry Andric     case FK_Data_8: {
214*0fca6ea1SDimitry Andric       bool IsAuth = (RefKind == AArch64MCExpr::VK_AUTH ||
215*0fca6ea1SDimitry Andric                      RefKind == AArch64MCExpr::VK_AUTHADDR);
2160b57cec5SDimitry Andric       if (IsILP32) {
2170b57cec5SDimitry Andric         Ctx.reportError(Fixup.getLoc(),
218*0fca6ea1SDimitry Andric                         Twine("ILP32 8 byte absolute data "
219*0fca6ea1SDimitry Andric                               "relocation not supported (LP64 eqv: ") +
220*0fca6ea1SDimitry Andric                             (IsAuth ? "AUTH_ABS64" : "ABS64") + Twine(')'));
2210b57cec5SDimitry Andric         return ELF::R_AARCH64_NONE;
222*0fca6ea1SDimitry Andric       }
223*0fca6ea1SDimitry Andric       return (IsAuth ? ELF::R_AARCH64_AUTH_ABS64 : ELF::R_AARCH64_ABS64);
2245f757f3fSDimitry Andric     }
2250b57cec5SDimitry Andric     case AArch64::fixup_aarch64_add_imm12:
2260b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_DTPREL_HI12)
2270b57cec5SDimitry Andric         return R_CLS(TLSLD_ADD_DTPREL_HI12);
2280b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_TPREL_HI12)
2290b57cec5SDimitry Andric         return R_CLS(TLSLE_ADD_TPREL_HI12);
2300b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC)
2310b57cec5SDimitry Andric         return R_CLS(TLSLD_ADD_DTPREL_LO12_NC);
2320b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_DTPREL_LO12)
2330b57cec5SDimitry Andric         return R_CLS(TLSLD_ADD_DTPREL_LO12);
2340b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC)
2350b57cec5SDimitry Andric         return R_CLS(TLSLE_ADD_TPREL_LO12_NC);
2360b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_TPREL_LO12)
2370b57cec5SDimitry Andric         return R_CLS(TLSLE_ADD_TPREL_LO12);
2380b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
2390b57cec5SDimitry Andric         return R_CLS(TLSDESC_ADD_LO12);
2400b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
2410b57cec5SDimitry Andric         return R_CLS(ADD_ABS_LO12_NC);
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(),
2440b57cec5SDimitry Andric                       "invalid fixup for add (uimm12) instruction");
2450b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
2460b57cec5SDimitry Andric     case AArch64::fixup_aarch64_ldst_imm12_scale1:
2470b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
2480b57cec5SDimitry Andric         return R_CLS(LDST8_ABS_LO12_NC);
2490b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
2500b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST8_DTPREL_LO12);
2510b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
2520b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST8_DTPREL_LO12_NC);
2530b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
2540b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST8_TPREL_LO12);
2550b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
2560b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST8_TPREL_LO12_NC);
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(),
2590b57cec5SDimitry Andric                       "invalid fixup for 8-bit load/store instruction");
2600b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
2610b57cec5SDimitry Andric     case AArch64::fixup_aarch64_ldst_imm12_scale2:
2620b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
2630b57cec5SDimitry Andric         return R_CLS(LDST16_ABS_LO12_NC);
2640b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
2650b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST16_DTPREL_LO12);
2660b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
2670b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST16_DTPREL_LO12_NC);
2680b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
2690b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST16_TPREL_LO12);
2700b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
2710b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST16_TPREL_LO12_NC);
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(),
2740b57cec5SDimitry Andric                       "invalid fixup for 16-bit load/store instruction");
2750b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
2760b57cec5SDimitry Andric     case AArch64::fixup_aarch64_ldst_imm12_scale4:
2770b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
2780b57cec5SDimitry Andric         return R_CLS(LDST32_ABS_LO12_NC);
2790b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
2800b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST32_DTPREL_LO12);
2810b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
2820b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST32_DTPREL_LO12_NC);
2830b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
2840b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST32_TPREL_LO12);
2850b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
2860b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST32_TPREL_LO12_NC);
2870b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
288*0fca6ea1SDimitry Andric         if (IsILP32)
2890b57cec5SDimitry Andric           return ELF::R_AARCH64_P32_LD32_GOT_LO12_NC;
2900b57cec5SDimitry Andric         Ctx.reportError(Fixup.getLoc(),
2910b57cec5SDimitry Andric                         "LP64 4 byte unchecked GOT load/store relocation "
2920b57cec5SDimitry Andric                         "not supported (ILP32 eqv: LD32_GOT_LO12_NC");
2930b57cec5SDimitry Andric         return ELF::R_AARCH64_NONE;
2940b57cec5SDimitry Andric       }
2950b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) {
2960b57cec5SDimitry Andric         if (IsILP32) {
2970b57cec5SDimitry Andric           Ctx.reportError(Fixup.getLoc(),
2980b57cec5SDimitry Andric                           "ILP32 4 byte checked GOT load/store relocation "
2990b57cec5SDimitry Andric                           "not supported (unchecked eqv: LD32_GOT_LO12_NC)");
3000b57cec5SDimitry Andric         } else {
3010b57cec5SDimitry Andric           Ctx.reportError(Fixup.getLoc(),
3020b57cec5SDimitry Andric                           "LP64 4 byte checked GOT load/store relocation "
3030b57cec5SDimitry Andric                           "not supported (unchecked/ILP32 eqv: "
3040b57cec5SDimitry Andric                           "LD32_GOT_LO12_NC)");
3050b57cec5SDimitry Andric         }
3060b57cec5SDimitry Andric         return ELF::R_AARCH64_NONE;
3070b57cec5SDimitry Andric       }
3080b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) {
309*0fca6ea1SDimitry Andric         if (IsILP32)
3100b57cec5SDimitry Andric           return ELF::R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC;
311*0fca6ea1SDimitry Andric         Ctx.reportError(Fixup.getLoc(), "LP64 32-bit load/store "
3120b57cec5SDimitry Andric                                         "relocation not supported (ILP32 eqv: "
3130b57cec5SDimitry Andric                                         "TLSIE_LD32_GOTTPREL_LO12_NC)");
3140b57cec5SDimitry Andric         return ELF::R_AARCH64_NONE;
3150b57cec5SDimitry Andric       }
3160b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) {
317*0fca6ea1SDimitry Andric         if (IsILP32)
3180b57cec5SDimitry Andric           return ELF::R_AARCH64_P32_TLSDESC_LD32_LO12;
3190b57cec5SDimitry Andric         Ctx.reportError(Fixup.getLoc(),
3200b57cec5SDimitry Andric                         "LP64 4 byte TLSDESC load/store relocation "
3210b57cec5SDimitry Andric                         "not supported (ILP32 eqv: TLSDESC_LD64_LO12)");
3220b57cec5SDimitry Andric         return ELF::R_AARCH64_NONE;
3230b57cec5SDimitry Andric       }
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(),
3260b57cec5SDimitry Andric                       "invalid fixup for 32-bit load/store instruction "
3270b57cec5SDimitry Andric                       "fixup_aarch64_ldst_imm12_scale4");
3280b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
3290b57cec5SDimitry Andric     case AArch64::fixup_aarch64_ldst_imm12_scale8:
3300b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
3310b57cec5SDimitry Andric         return R_CLS(LDST64_ABS_LO12_NC);
3320b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
333e8d8bef9SDimitry Andric         AArch64MCExpr::VariantKind AddressLoc =
334e8d8bef9SDimitry Andric             AArch64MCExpr::getAddressFrag(RefKind);
3350b57cec5SDimitry Andric         if (!IsILP32) {
336e8d8bef9SDimitry Andric           if (AddressLoc == AArch64MCExpr::VK_LO15)
337e8d8bef9SDimitry Andric             return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
3380b57cec5SDimitry Andric           return ELF::R_AARCH64_LD64_GOT_LO12_NC;
339*0fca6ea1SDimitry Andric         }
3400b57cec5SDimitry Andric         Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
3410b57cec5SDimitry Andric                                         "relocation not supported (LP64 eqv: "
3420b57cec5SDimitry Andric                                         "LD64_GOT_LO12_NC)");
3430b57cec5SDimitry Andric         return ELF::R_AARCH64_NONE;
3440b57cec5SDimitry Andric       }
3450b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
3460b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST64_DTPREL_LO12);
3470b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
3480b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST64_DTPREL_LO12_NC);
3490b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
3500b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST64_TPREL_LO12);
3510b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
3520b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST64_TPREL_LO12_NC);
3530b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) {
354*0fca6ea1SDimitry Andric         if (!IsILP32)
3550b57cec5SDimitry Andric           return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
3560b57cec5SDimitry Andric         Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
3570b57cec5SDimitry Andric                                         "relocation not supported (LP64 eqv: "
3580b57cec5SDimitry Andric                                         "TLSIE_LD64_GOTTPREL_LO12_NC)");
3590b57cec5SDimitry Andric         return ELF::R_AARCH64_NONE;
3600b57cec5SDimitry Andric       }
3610b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TLSDESC) {
362*0fca6ea1SDimitry Andric         if (!IsILP32)
3630b57cec5SDimitry Andric           return ELF::R_AARCH64_TLSDESC_LD64_LO12;
3640b57cec5SDimitry Andric         Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
3650b57cec5SDimitry Andric                                         "relocation not supported (LP64 eqv: "
3660b57cec5SDimitry Andric                                         "TLSDESC_LD64_LO12)");
3670b57cec5SDimitry Andric         return ELF::R_AARCH64_NONE;
3680b57cec5SDimitry Andric       }
3690b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(),
3700b57cec5SDimitry Andric                       "invalid fixup for 64-bit load/store instruction");
3710b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
3720b57cec5SDimitry Andric     case AArch64::fixup_aarch64_ldst_imm12_scale16:
3730b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
3740b57cec5SDimitry Andric         return R_CLS(LDST128_ABS_LO12_NC);
3750b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
3760b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST128_DTPREL_LO12);
3770b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
3780b57cec5SDimitry Andric         return R_CLS(TLSLD_LDST128_DTPREL_LO12_NC);
3790b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
3800b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST128_TPREL_LO12);
3810b57cec5SDimitry Andric       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
3820b57cec5SDimitry Andric         return R_CLS(TLSLE_LDST128_TPREL_LO12_NC);
3830b57cec5SDimitry Andric 
3840b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(),
3850b57cec5SDimitry Andric                       "invalid fixup for 128-bit load/store instruction");
3860b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
3870b57cec5SDimitry Andric     // ILP32 case not reached here, tested with isNonILP32reloc
3880b57cec5SDimitry Andric     case AArch64::fixup_aarch64_movw:
3890b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G3)
3900b57cec5SDimitry Andric         return ELF::R_AARCH64_MOVW_UABS_G3;
3910b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G2)
3920b57cec5SDimitry Andric         return ELF::R_AARCH64_MOVW_UABS_G2;
3930b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G2_S)
3940b57cec5SDimitry Andric         return ELF::R_AARCH64_MOVW_SABS_G2;
3950b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G2_NC)
3960b57cec5SDimitry Andric         return ELF::R_AARCH64_MOVW_UABS_G2_NC;
3970b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G1)
3980b57cec5SDimitry Andric         return R_CLS(MOVW_UABS_G1);
3990b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G1_S)
4000b57cec5SDimitry Andric         return ELF::R_AARCH64_MOVW_SABS_G1;
4010b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G1_NC)
4020b57cec5SDimitry Andric         return ELF::R_AARCH64_MOVW_UABS_G1_NC;
4030b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G0)
4040b57cec5SDimitry Andric         return R_CLS(MOVW_UABS_G0);
4050b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G0_S)
4060b57cec5SDimitry Andric         return R_CLS(MOVW_SABS_G0);
4070b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_ABS_G0_NC)
4080b57cec5SDimitry Andric         return R_CLS(MOVW_UABS_G0_NC);
4098bcb0991SDimitry Andric       if (RefKind == AArch64MCExpr::VK_PREL_G3)
4108bcb0991SDimitry Andric         return ELF::R_AARCH64_MOVW_PREL_G3;
4118bcb0991SDimitry Andric       if (RefKind == AArch64MCExpr::VK_PREL_G2)
4128bcb0991SDimitry Andric         return ELF::R_AARCH64_MOVW_PREL_G2;
4138bcb0991SDimitry Andric       if (RefKind == AArch64MCExpr::VK_PREL_G2_NC)
4148bcb0991SDimitry Andric         return ELF::R_AARCH64_MOVW_PREL_G2_NC;
4158bcb0991SDimitry Andric       if (RefKind == AArch64MCExpr::VK_PREL_G1)
4168bcb0991SDimitry Andric         return R_CLS(MOVW_PREL_G1);
4178bcb0991SDimitry Andric       if (RefKind == AArch64MCExpr::VK_PREL_G1_NC)
4188bcb0991SDimitry Andric         return ELF::R_AARCH64_MOVW_PREL_G1_NC;
4198bcb0991SDimitry Andric       if (RefKind == AArch64MCExpr::VK_PREL_G0)
4208bcb0991SDimitry Andric         return R_CLS(MOVW_PREL_G0);
4218bcb0991SDimitry Andric       if (RefKind == AArch64MCExpr::VK_PREL_G0_NC)
4228bcb0991SDimitry Andric         return R_CLS(MOVW_PREL_G0_NC);
4230b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_DTPREL_G2)
4240b57cec5SDimitry Andric         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
4250b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_DTPREL_G1)
4260b57cec5SDimitry Andric         return R_CLS(TLSLD_MOVW_DTPREL_G1);
4270b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC)
4280b57cec5SDimitry Andric         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC;
4290b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_DTPREL_G0)
4300b57cec5SDimitry Andric         return R_CLS(TLSLD_MOVW_DTPREL_G0);
4310b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC)
4320b57cec5SDimitry Andric         return R_CLS(TLSLD_MOVW_DTPREL_G0_NC);
4330b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_TPREL_G2)
4340b57cec5SDimitry Andric         return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2;
4350b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_TPREL_G1)
4360b57cec5SDimitry Andric         return R_CLS(TLSLE_MOVW_TPREL_G1);
4370b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC)
4380b57cec5SDimitry Andric         return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC;
4390b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_TPREL_G0)
4400b57cec5SDimitry Andric         return R_CLS(TLSLE_MOVW_TPREL_G0);
4410b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC)
4420b57cec5SDimitry Andric         return R_CLS(TLSLE_MOVW_TPREL_G0_NC);
4430b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1)
4440b57cec5SDimitry Andric         return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
4450b57cec5SDimitry Andric       if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC)
4460b57cec5SDimitry Andric         return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
4470b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(),
4480b57cec5SDimitry Andric                       "invalid fixup for movz/movk instruction");
4490b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
4500b57cec5SDimitry Andric     default:
4510b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
4520b57cec5SDimitry Andric       return ELF::R_AARCH64_NONE;
4530b57cec5SDimitry Andric     }
4540b57cec5SDimitry Andric   }
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric   llvm_unreachable("Unimplemented fixup -> relocation");
4570b57cec5SDimitry Andric }
4580b57cec5SDimitry Andric 
4595f757f3fSDimitry Andric bool AArch64ELFObjectWriter::needsRelocateWithSymbol(const MCValue &Val,
4605f757f3fSDimitry Andric                                                      const MCSymbol &,
4615f757f3fSDimitry Andric                                                      unsigned) const {
4625f757f3fSDimitry Andric   return (Val.getRefKind() & AArch64MCExpr::VK_GOT) == AArch64MCExpr::VK_GOT;
4635f757f3fSDimitry Andric }
4645f757f3fSDimitry Andric 
465bdd1243dSDimitry Andric MCSectionELF *
466bdd1243dSDimitry Andric AArch64ELFObjectWriter::getMemtagRelocsSection(MCContext &Ctx) const {
467bdd1243dSDimitry Andric   return Ctx.getELFSection(".memtag.globals.static",
468bdd1243dSDimitry Andric                            ELF::SHT_AARCH64_MEMTAG_GLOBALS_STATIC, 0);
469bdd1243dSDimitry Andric }
470bdd1243dSDimitry Andric 
4710b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
4720b57cec5SDimitry Andric llvm::createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32) {
4738bcb0991SDimitry Andric   return std::make_unique<AArch64ELFObjectWriter>(OSABI, IsILP32);
4740b57cec5SDimitry Andric }
475