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