10b57cec5SDimitry Andric //===-- ARMELFObjectWriter.cpp - ARM 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 #include "MCTargetDesc/ARMFixupKinds.h" 100b57cec5SDimitry Andric #include "MCTargetDesc/ARMMCTargetDesc.h" 110b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 120b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 130b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 140b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 19*0fca6ea1SDimitry Andric #include "llvm/Object/ELF.h" 200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 210b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 220b57cec5SDimitry Andric #include <cstdint> 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric using namespace llvm; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric class ARMELFObjectWriter : public MCELFObjectTargetWriter { 290b57cec5SDimitry Andric enum { DefaultEABIVersion = 0x05000000U }; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup, 320b57cec5SDimitry Andric bool IsPCRel, MCContext &Ctx) const; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric public: 350b57cec5SDimitry Andric ARMELFObjectWriter(uint8_t OSABI); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric ~ARMELFObjectWriter() override = default; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 400b57cec5SDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override; 410b57cec5SDimitry Andric 425f757f3fSDimitry Andric bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, 430b57cec5SDimitry Andric unsigned Type) const override; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override; 460b57cec5SDimitry Andric }; 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric } // end anonymous namespace 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI) 510b57cec5SDimitry Andric : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, 520b57cec5SDimitry Andric ELF::EM_ARM, 530b57cec5SDimitry Andric /*HasRelocationAddend*/ false) {} 540b57cec5SDimitry Andric 555f757f3fSDimitry Andric bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCValue &, 565f757f3fSDimitry Andric const MCSymbol &, 570b57cec5SDimitry Andric unsigned Type) const { 585ffd83dbSDimitry Andric // FIXME: This is extremely conservative. This really needs to use an 595ffd83dbSDimitry Andric // explicit list with a clear explanation for why each realocation needs to 600b57cec5SDimitry Andric // point to the symbol, not to the section. 610b57cec5SDimitry Andric switch (Type) { 620b57cec5SDimitry Andric default: 630b57cec5SDimitry Andric return true; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric case ELF::R_ARM_PREL31: 660b57cec5SDimitry Andric case ELF::R_ARM_ABS32: 670b57cec5SDimitry Andric return false; 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric // Need to examine the Fixup when determining whether to 720b57cec5SDimitry Andric // emit the relocation as an explicit symbol or as a section relative 730b57cec5SDimitry Andric // offset 740b57cec5SDimitry Andric unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, 750b57cec5SDimitry Andric const MCFixup &Fixup, 760b57cec5SDimitry Andric bool IsPCRel) const { 770b57cec5SDimitry Andric return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx); 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, 810b57cec5SDimitry Andric const MCFixup &Fixup, 820b57cec5SDimitry Andric bool IsPCRel, 830b57cec5SDimitry Andric MCContext &Ctx) const { 845ffd83dbSDimitry Andric unsigned Kind = Fixup.getTargetKind(); 855ffd83dbSDimitry Andric if (Kind >= FirstLiteralRelocationKind) 865ffd83dbSDimitry Andric return Kind - FirstLiteralRelocationKind; 870b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); 88*0fca6ea1SDimitry Andric auto CheckFDPIC = [&](uint32_t Type) { 89*0fca6ea1SDimitry Andric if (getOSABI() != ELF::ELFOSABI_ARM_FDPIC) 90*0fca6ea1SDimitry Andric Ctx.reportError(Fixup.getLoc(), 91*0fca6ea1SDimitry Andric "relocation " + 92*0fca6ea1SDimitry Andric object::getELFRelocationTypeName(ELF::EM_ARM, Type) + 93*0fca6ea1SDimitry Andric " only supported in FDPIC mode"); 94*0fca6ea1SDimitry Andric return Type; 95*0fca6ea1SDimitry Andric }; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric if (IsPCRel) { 988bcb0991SDimitry Andric switch (Fixup.getTargetKind()) { 990b57cec5SDimitry Andric default: 10006c3fb27SDimitry Andric Ctx.reportError(Fixup.getLoc(), "unsupported relocation type"); 1010b57cec5SDimitry Andric return ELF::R_ARM_NONE; 1020b57cec5SDimitry Andric case FK_Data_4: 1030b57cec5SDimitry Andric switch (Modifier) { 1040b57cec5SDimitry Andric default: 1055ffd83dbSDimitry Andric Ctx.reportError(Fixup.getLoc(), 1065ffd83dbSDimitry Andric "invalid fixup for 4-byte pc-relative data relocation"); 1075ffd83dbSDimitry Andric return ELF::R_ARM_NONE; 1085ffd83dbSDimitry Andric case MCSymbolRefExpr::VK_None: { 1095ffd83dbSDimitry Andric if (const MCSymbolRefExpr *SymRef = Target.getSymA()) { 1105ffd83dbSDimitry Andric // For GNU AS compatibility expressions such as 1115ffd83dbSDimitry Andric // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation. 1125ffd83dbSDimitry Andric if (SymRef->getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_") 1135ffd83dbSDimitry Andric return ELF::R_ARM_BASE_PREL; 1145ffd83dbSDimitry Andric } 1150b57cec5SDimitry Andric return ELF::R_ARM_REL32; 1165ffd83dbSDimitry Andric } 1170b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTTPOFF: 1180b57cec5SDimitry Andric return ELF::R_ARM_TLS_IE32; 1190b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_GOT_PREL: 1200b57cec5SDimitry Andric return ELF::R_ARM_GOT_PREL; 1210b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_PREL31: 1220b57cec5SDimitry Andric return ELF::R_ARM_PREL31; 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric case ARM::fixup_arm_blx: 1250b57cec5SDimitry Andric case ARM::fixup_arm_uncondbl: 1260b57cec5SDimitry Andric switch (Modifier) { 1270b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PLT: 1280b57cec5SDimitry Andric return ELF::R_ARM_CALL; 1290b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSCALL: 1300b57cec5SDimitry Andric return ELF::R_ARM_TLS_CALL; 1310b57cec5SDimitry Andric default: 1320b57cec5SDimitry Andric return ELF::R_ARM_CALL; 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric case ARM::fixup_arm_condbl: 1350b57cec5SDimitry Andric case ARM::fixup_arm_condbranch: 1360b57cec5SDimitry Andric case ARM::fixup_arm_uncondbranch: 1370b57cec5SDimitry Andric return ELF::R_ARM_JUMP24; 1380b57cec5SDimitry Andric case ARM::fixup_t2_condbranch: 1390b57cec5SDimitry Andric return ELF::R_ARM_THM_JUMP19; 1400b57cec5SDimitry Andric case ARM::fixup_t2_uncondbranch: 1410b57cec5SDimitry Andric return ELF::R_ARM_THM_JUMP24; 1420b57cec5SDimitry Andric case ARM::fixup_arm_movt_hi16: 1430b57cec5SDimitry Andric return ELF::R_ARM_MOVT_PREL; 1440b57cec5SDimitry Andric case ARM::fixup_arm_movw_lo16: 1450b57cec5SDimitry Andric return ELF::R_ARM_MOVW_PREL_NC; 1460b57cec5SDimitry Andric case ARM::fixup_t2_movt_hi16: 1470b57cec5SDimitry Andric return ELF::R_ARM_THM_MOVT_PREL; 1480b57cec5SDimitry Andric case ARM::fixup_t2_movw_lo16: 1490b57cec5SDimitry Andric return ELF::R_ARM_THM_MOVW_PREL_NC; 15006c3fb27SDimitry Andric case ARM::fixup_arm_thumb_upper_8_15: 15106c3fb27SDimitry Andric return ELF::R_ARM_THM_ALU_ABS_G3; 15206c3fb27SDimitry Andric case ARM::fixup_arm_thumb_upper_0_7: 15306c3fb27SDimitry Andric return ELF::R_ARM_THM_ALU_ABS_G2_NC; 15406c3fb27SDimitry Andric case ARM::fixup_arm_thumb_lower_8_15: 15506c3fb27SDimitry Andric return ELF::R_ARM_THM_ALU_ABS_G1_NC; 15606c3fb27SDimitry Andric case ARM::fixup_arm_thumb_lower_0_7: 15706c3fb27SDimitry Andric return ELF::R_ARM_THM_ALU_ABS_G0_NC; 1580b57cec5SDimitry Andric case ARM::fixup_arm_thumb_br: 1590b57cec5SDimitry Andric return ELF::R_ARM_THM_JUMP11; 1600b57cec5SDimitry Andric case ARM::fixup_arm_thumb_bcc: 1610b57cec5SDimitry Andric return ELF::R_ARM_THM_JUMP8; 1620b57cec5SDimitry Andric case ARM::fixup_arm_thumb_bl: 1630b57cec5SDimitry Andric case ARM::fixup_arm_thumb_blx: 1640b57cec5SDimitry Andric switch (Modifier) { 1650b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSCALL: 1660b57cec5SDimitry Andric return ELF::R_ARM_THM_TLS_CALL; 1670b57cec5SDimitry Andric default: 1680b57cec5SDimitry Andric return ELF::R_ARM_THM_CALL; 1690b57cec5SDimitry Andric } 1705f757f3fSDimitry Andric case ARM::fixup_arm_ldst_pcrel_12: 1715f757f3fSDimitry Andric return ELF::R_ARM_LDR_PC_G0; 1725f757f3fSDimitry Andric case ARM::fixup_arm_pcrel_10_unscaled: 1735f757f3fSDimitry Andric return ELF::R_ARM_LDRS_PC_G0; 1745f757f3fSDimitry Andric case ARM::fixup_t2_ldst_pcrel_12: 1755f757f3fSDimitry Andric return ELF::R_ARM_THM_PC12; 1765f757f3fSDimitry Andric case ARM::fixup_arm_adr_pcrel_12: 1775f757f3fSDimitry Andric return ELF::R_ARM_ALU_PC_G0; 1785f757f3fSDimitry Andric case ARM::fixup_thumb_adr_pcrel_10: 1795f757f3fSDimitry Andric return ELF::R_ARM_THM_PC8; 1805f757f3fSDimitry Andric case ARM::fixup_t2_adr_pcrel_12: 1815f757f3fSDimitry Andric return ELF::R_ARM_THM_ALU_PREL_11_0; 1820b57cec5SDimitry Andric case ARM::fixup_bf_target: 1830b57cec5SDimitry Andric return ELF::R_ARM_THM_BF16; 1840b57cec5SDimitry Andric case ARM::fixup_bfc_target: 1850b57cec5SDimitry Andric return ELF::R_ARM_THM_BF12; 1860b57cec5SDimitry Andric case ARM::fixup_bfl_target: 1870b57cec5SDimitry Andric return ELF::R_ARM_THM_BF18; 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric } 1905ffd83dbSDimitry Andric switch (Kind) { 1910b57cec5SDimitry Andric default: 19206c3fb27SDimitry Andric Ctx.reportError(Fixup.getLoc(), "unsupported relocation type"); 1930b57cec5SDimitry Andric return ELF::R_ARM_NONE; 1940b57cec5SDimitry Andric case FK_Data_1: 1950b57cec5SDimitry Andric switch (Modifier) { 1960b57cec5SDimitry Andric default: 1975ffd83dbSDimitry Andric Ctx.reportError(Fixup.getLoc(), 1985ffd83dbSDimitry Andric "invalid fixup for 1-byte data relocation"); 1995ffd83dbSDimitry Andric return ELF::R_ARM_NONE; 2000b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 2010b57cec5SDimitry Andric return ELF::R_ARM_ABS8; 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric case FK_Data_2: 2040b57cec5SDimitry Andric switch (Modifier) { 2050b57cec5SDimitry Andric default: 2065ffd83dbSDimitry Andric Ctx.reportError(Fixup.getLoc(), 2075ffd83dbSDimitry Andric "invalid fixup for 2-byte data relocation"); 2085ffd83dbSDimitry Andric return ELF::R_ARM_NONE; 2090b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 2100b57cec5SDimitry Andric return ELF::R_ARM_ABS16; 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric case FK_Data_4: 2130b57cec5SDimitry Andric switch (Modifier) { 2140b57cec5SDimitry Andric default: 2155ffd83dbSDimitry Andric Ctx.reportError(Fixup.getLoc(), 2165ffd83dbSDimitry Andric "invalid fixup for 4-byte data relocation"); 2175ffd83dbSDimitry Andric return ELF::R_ARM_NONE; 2180b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_NONE: 2190b57cec5SDimitry Andric return ELF::R_ARM_NONE; 2200b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT: 2210b57cec5SDimitry Andric return ELF::R_ARM_GOT_BREL; 2220b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSGD: 2230b57cec5SDimitry Andric return ELF::R_ARM_TLS_GD32; 2240b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPOFF: 2250b57cec5SDimitry Andric return ELF::R_ARM_TLS_LE32; 2260b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTTPOFF: 2270b57cec5SDimitry Andric return ELF::R_ARM_TLS_IE32; 2280b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 2290b57cec5SDimitry Andric return ELF::R_ARM_ABS32; 2300b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTOFF: 2310b57cec5SDimitry Andric return ELF::R_ARM_GOTOFF32; 2320b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_GOT_PREL: 2330b57cec5SDimitry Andric return ELF::R_ARM_GOT_PREL; 2340b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_TARGET1: 2350b57cec5SDimitry Andric return ELF::R_ARM_TARGET1; 2360b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_TARGET2: 2370b57cec5SDimitry Andric return ELF::R_ARM_TARGET2; 2380b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_PREL31: 2390b57cec5SDimitry Andric return ELF::R_ARM_PREL31; 2400b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_SBREL: 2410b57cec5SDimitry Andric return ELF::R_ARM_SBREL32; 2420b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_TLSLDO: 2430b57cec5SDimitry Andric return ELF::R_ARM_TLS_LDO32; 2440b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSCALL: 2450b57cec5SDimitry Andric return ELF::R_ARM_TLS_CALL; 2460b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSDESC: 2470b57cec5SDimitry Andric return ELF::R_ARM_TLS_GOTDESC; 2480b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSLDM: 2490b57cec5SDimitry Andric return ELF::R_ARM_TLS_LDM32; 2500b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ: 2510b57cec5SDimitry Andric return ELF::R_ARM_TLS_DESCSEQ; 252*0fca6ea1SDimitry Andric case MCSymbolRefExpr::VK_FUNCDESC: 253*0fca6ea1SDimitry Andric return CheckFDPIC(ELF::R_ARM_FUNCDESC); 254*0fca6ea1SDimitry Andric case MCSymbolRefExpr::VK_GOTFUNCDESC: 255*0fca6ea1SDimitry Andric return CheckFDPIC(ELF::R_ARM_GOTFUNCDESC); 256*0fca6ea1SDimitry Andric case MCSymbolRefExpr::VK_GOTOFFFUNCDESC: 257*0fca6ea1SDimitry Andric return CheckFDPIC(ELF::R_ARM_GOTOFFFUNCDESC); 258*0fca6ea1SDimitry Andric case MCSymbolRefExpr::VK_TLSGD_FDPIC: 259*0fca6ea1SDimitry Andric return CheckFDPIC(ELF::R_ARM_TLS_GD32_FDPIC); 260*0fca6ea1SDimitry Andric case MCSymbolRefExpr::VK_TLSLDM_FDPIC: 261*0fca6ea1SDimitry Andric return CheckFDPIC(ELF::R_ARM_TLS_LDM32_FDPIC); 262*0fca6ea1SDimitry Andric case MCSymbolRefExpr::VK_GOTTPOFF_FDPIC: 263*0fca6ea1SDimitry Andric return CheckFDPIC(ELF::R_ARM_TLS_IE32_FDPIC); 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric case ARM::fixup_arm_condbranch: 2660b57cec5SDimitry Andric case ARM::fixup_arm_uncondbranch: 2670b57cec5SDimitry Andric return ELF::R_ARM_JUMP24; 2680b57cec5SDimitry Andric case ARM::fixup_arm_movt_hi16: 2690b57cec5SDimitry Andric switch (Modifier) { 2700b57cec5SDimitry Andric default: 2715ffd83dbSDimitry Andric Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVT instruction"); 2725ffd83dbSDimitry Andric return ELF::R_ARM_NONE; 2730b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 2740b57cec5SDimitry Andric return ELF::R_ARM_MOVT_ABS; 2750b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_SBREL: 2760b57cec5SDimitry Andric return ELF::R_ARM_MOVT_BREL; 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric case ARM::fixup_arm_movw_lo16: 2790b57cec5SDimitry Andric switch (Modifier) { 2800b57cec5SDimitry Andric default: 2815ffd83dbSDimitry Andric Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVW instruction"); 2825ffd83dbSDimitry Andric return ELF::R_ARM_NONE; 2830b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 2840b57cec5SDimitry Andric return ELF::R_ARM_MOVW_ABS_NC; 2850b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_SBREL: 2860b57cec5SDimitry Andric return ELF::R_ARM_MOVW_BREL_NC; 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric case ARM::fixup_t2_movt_hi16: 2890b57cec5SDimitry Andric switch (Modifier) { 2900b57cec5SDimitry Andric default: 2915ffd83dbSDimitry Andric Ctx.reportError(Fixup.getLoc(), 2925ffd83dbSDimitry Andric "invalid fixup for Thumb MOVT instruction"); 2935ffd83dbSDimitry Andric return ELF::R_ARM_NONE; 2940b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 2950b57cec5SDimitry Andric return ELF::R_ARM_THM_MOVT_ABS; 2960b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_SBREL: 2970b57cec5SDimitry Andric return ELF::R_ARM_THM_MOVT_BREL; 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric case ARM::fixup_t2_movw_lo16: 3000b57cec5SDimitry Andric switch (Modifier) { 3010b57cec5SDimitry Andric default: 3025ffd83dbSDimitry Andric Ctx.reportError(Fixup.getLoc(), 3035ffd83dbSDimitry Andric "invalid fixup for Thumb MOVW instruction"); 3045ffd83dbSDimitry Andric return ELF::R_ARM_NONE; 3050b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None: 3060b57cec5SDimitry Andric return ELF::R_ARM_THM_MOVW_ABS_NC; 3070b57cec5SDimitry Andric case MCSymbolRefExpr::VK_ARM_SBREL: 3080b57cec5SDimitry Andric return ELF::R_ARM_THM_MOVW_BREL_NC; 3090b57cec5SDimitry Andric } 31006c3fb27SDimitry Andric 31106c3fb27SDimitry Andric case ARM::fixup_arm_thumb_upper_8_15: 31206c3fb27SDimitry Andric return ELF::R_ARM_THM_ALU_ABS_G3; 31306c3fb27SDimitry Andric case ARM::fixup_arm_thumb_upper_0_7: 31406c3fb27SDimitry Andric return ELF::R_ARM_THM_ALU_ABS_G2_NC; 31506c3fb27SDimitry Andric case ARM::fixup_arm_thumb_lower_8_15: 31606c3fb27SDimitry Andric return ELF::R_ARM_THM_ALU_ABS_G1_NC; 31706c3fb27SDimitry Andric case ARM::fixup_arm_thumb_lower_0_7: 31806c3fb27SDimitry Andric return ELF::R_ARM_THM_ALU_ABS_G0_NC; 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx, 3230b57cec5SDimitry Andric MCSectionELF &Sec) { 3240b57cec5SDimitry Andric // The mix of execute-only and non-execute-only at link time is 3250b57cec5SDimitry Andric // non-execute-only. To avoid the empty implicitly created .text 3260b57cec5SDimitry Andric // section from making the whole .text section non-execute-only, we 3270b57cec5SDimitry Andric // mark it execute-only if it is empty and there is at least one 3280b57cec5SDimitry Andric // execute-only section in the object. 3290b57cec5SDimitry Andric MCSectionELF *TextSection = 3300b57cec5SDimitry Andric static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection()); 331*0fca6ea1SDimitry Andric bool IsExecOnly = Sec.getFlags() & ELF::SHF_ARM_PURECODE; 332*0fca6ea1SDimitry Andric if (IsExecOnly && !TextSection->hasInstructions()) { 333*0fca6ea1SDimitry Andric for (auto &F : *TextSection) 334480093f4SDimitry Andric if (auto *DF = dyn_cast<MCDataFragment>(&F)) 335480093f4SDimitry Andric if (!DF->getContents().empty()) 336480093f4SDimitry Andric return; 3370b57cec5SDimitry Andric TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE); 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter> 3420b57cec5SDimitry Andric llvm::createARMELFObjectWriter(uint8_t OSABI) { 3438bcb0991SDimitry Andric return std::make_unique<ARMELFObjectWriter>(OSABI); 3440b57cec5SDimitry Andric } 345