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/MC/MCAsmBackend.h" 13 #include "llvm/MC/MCFixup.h" 14 #include "llvm/MC/MCFixupKindInfo.h" 15 #include "llvm/MC/MCValue.h" 16 #include "llvm/MC/MCWinCOFFObjectWriter.h" 17 #include "llvm/Support/COFF.h" 18 #include "llvm/Support/Debug.h" 19 20 using namespace llvm; 21 22 namespace { 23 class ARMWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { 24 public: 25 ARMWinCOFFObjectWriter(bool Is64Bit) 26 : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_ARMNT) { 27 assert(!Is64Bit && "AArch64 support not yet implemented"); 28 } 29 ~ARMWinCOFFObjectWriter() override {} 30 31 unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup, 32 bool IsCrossSection, 33 const MCAsmBackend &MAB) const override; 34 35 bool recordRelocation(const MCFixup &) const override; 36 }; 37 38 unsigned ARMWinCOFFObjectWriter::getRelocType(const MCValue &Target, 39 const MCFixup &Fixup, 40 bool IsCrossSection, 41 const MCAsmBackend &MAB) const { 42 assert(getMachine() == COFF::IMAGE_FILE_MACHINE_ARMNT && 43 "AArch64 support not yet implemented"); 44 45 MCSymbolRefExpr::VariantKind Modifier = 46 Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 47 48 switch (static_cast<unsigned>(Fixup.getKind())) { 49 default: { 50 const MCFixupKindInfo &Info = MAB.getFixupKindInfo(Fixup.getKind()); 51 report_fatal_error(Twine("unsupported relocation type: ") + Info.Name); 52 } 53 case FK_Data_4: 54 switch (Modifier) { 55 case MCSymbolRefExpr::VK_COFF_IMGREL32: 56 return COFF::IMAGE_REL_ARM_ADDR32NB; 57 case MCSymbolRefExpr::VK_SECREL: 58 return COFF::IMAGE_REL_ARM_SECREL; 59 default: 60 return COFF::IMAGE_REL_ARM_ADDR32; 61 } 62 case FK_SecRel_2: 63 return COFF::IMAGE_REL_ARM_SECTION; 64 case FK_SecRel_4: 65 return COFF::IMAGE_REL_ARM_SECREL; 66 case ARM::fixup_t2_condbranch: 67 return COFF::IMAGE_REL_ARM_BRANCH20T; 68 case ARM::fixup_t2_uncondbranch: 69 return COFF::IMAGE_REL_ARM_BRANCH24T; 70 case ARM::fixup_arm_thumb_bl: 71 case ARM::fixup_arm_thumb_blx: 72 return COFF::IMAGE_REL_ARM_BLX23T; 73 case ARM::fixup_t2_movw_lo16: 74 case ARM::fixup_t2_movt_hi16: 75 return COFF::IMAGE_REL_ARM_MOV32T; 76 } 77 } 78 79 bool ARMWinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const { 80 return static_cast<unsigned>(Fixup.getKind()) != ARM::fixup_t2_movt_hi16; 81 } 82 } 83 84 namespace llvm { 85 MCObjectWriter *createARMWinCOFFObjectWriter(raw_pwrite_stream &OS, 86 bool Is64Bit) { 87 MCWinCOFFObjectTargetWriter *MOTW = new ARMWinCOFFObjectWriter(Is64Bit); 88 return createWinCOFFObjectWriter(MOTW, OS); 89 } 90 } 91 92