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