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 20using namespace llvm; 21 22namespace { 23class ARMWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { 24public: 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 38unsigned 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 79bool ARMWinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const { 80 return static_cast<unsigned>(Fixup.getKind()) != ARM::fixup_t2_movt_hi16; 81} 82} 83 84namespace llvm { 85MCObjectWriter *createARMWinCOFFObjectWriter(raw_pwrite_stream &OS, 86 bool Is64Bit) { 87 MCWinCOFFObjectTargetWriter *MOTW = new ARMWinCOFFObjectWriter(Is64Bit); 88 return createWinCOFFObjectWriter(MOTW, OS); 89} 90} 91 92