xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
ARMELFObjectWriter(uint8_t OSABI)500b57cec5SDimitry Andric ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
510b57cec5SDimitry Andric   : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
520b57cec5SDimitry Andric                             ELF::EM_ARM,
530b57cec5SDimitry Andric                             /*HasRelocationAddend*/ false) {}
540b57cec5SDimitry Andric 
needsRelocateWithSymbol(const MCValue &,const MCSymbol &,unsigned Type) const555f757f3fSDimitry 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
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const740b57cec5SDimitry 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 
GetRelocTypeInner(const MCValue & Target,const MCFixup & Fixup,bool IsPCRel,MCContext & Ctx) const800b57cec5SDimitry 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 
addTargetSectionFlags(MCContext & Ctx,MCSectionELF & Sec)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>
createARMELFObjectWriter(uint8_t OSABI)3420b57cec5SDimitry Andric llvm::createARMELFObjectWriter(uint8_t OSABI) {
3438bcb0991SDimitry Andric   return std::make_unique<ARMELFObjectWriter>(OSABI);
3440b57cec5SDimitry Andric }
345