1 //===-- ARMWinCOFFObjectWriter.cpp - ARM Windows COFF Object Writer -- C++ -==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/ARMFixupKinds.h" 10 #include "llvm/ADT/Twine.h" 11 #include "llvm/BinaryFormat/COFF.h" 12 #include "llvm/MC/MCAsmBackend.h" 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/MC/MCFixup.h" 15 #include "llvm/MC/MCFixupKindInfo.h" 16 #include "llvm/MC/MCObjectWriter.h" 17 #include "llvm/MC/MCValue.h" 18 #include "llvm/MC/MCWinCOFFObjectWriter.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/Support/raw_ostream.h" 21 #include <cassert> 22 23 using namespace llvm; 24 25 namespace { 26 27 class ARMWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { 28 public: 29 ARMWinCOFFObjectWriter() 30 : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_ARMNT) { 31 } 32 33 ~ARMWinCOFFObjectWriter() override = default; 34 35 unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 36 const MCFixup &Fixup, bool IsCrossSection, 37 const MCAsmBackend &MAB) const override; 38 39 bool recordRelocation(const MCFixup &) const override; 40 }; 41 42 } // end anonymous namespace 43 44 unsigned ARMWinCOFFObjectWriter::getRelocType(MCContext &Ctx, 45 const MCValue &Target, 46 const MCFixup &Fixup, 47 bool IsCrossSection, 48 const MCAsmBackend &MAB) const { 49 MCSymbolRefExpr::VariantKind Modifier = 50 Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 51 52 switch (static_cast<unsigned>(Fixup.getKind())) { 53 default: { 54 const MCFixupKindInfo &Info = MAB.getFixupKindInfo(Fixup.getKind()); 55 report_fatal_error(Twine("unsupported relocation type: ") + Info.Name); 56 } 57 case FK_Data_4: 58 switch (Modifier) { 59 case MCSymbolRefExpr::VK_COFF_IMGREL32: 60 return COFF::IMAGE_REL_ARM_ADDR32NB; 61 case MCSymbolRefExpr::VK_SECREL: 62 return COFF::IMAGE_REL_ARM_SECREL; 63 default: 64 return COFF::IMAGE_REL_ARM_ADDR32; 65 } 66 case FK_SecRel_2: 67 return COFF::IMAGE_REL_ARM_SECTION; 68 case FK_SecRel_4: 69 return COFF::IMAGE_REL_ARM_SECREL; 70 case ARM::fixup_t2_condbranch: 71 return COFF::IMAGE_REL_ARM_BRANCH20T; 72 case ARM::fixup_t2_uncondbranch: 73 case ARM::fixup_arm_thumb_bl: 74 return COFF::IMAGE_REL_ARM_BRANCH24T; 75 case ARM::fixup_arm_thumb_blx: 76 return COFF::IMAGE_REL_ARM_BLX23T; 77 case ARM::fixup_t2_movw_lo16: 78 case ARM::fixup_t2_movt_hi16: 79 return COFF::IMAGE_REL_ARM_MOV32T; 80 } 81 } 82 83 bool ARMWinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const { 84 return static_cast<unsigned>(Fixup.getKind()) != ARM::fixup_t2_movt_hi16; 85 } 86 87 namespace llvm { 88 89 std::unique_ptr<MCObjectTargetWriter> 90 createARMWinCOFFObjectWriter() { 91 return std::make_unique<ARMWinCOFFObjectWriter>(); 92 } 93 94 } // end namespace llvm 95