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