LLVM API Documentation

ARMWinCOFFObjectWriter.cpp
Go to the documentation of this file.
00001 //===-- ARMWinCOFFObjectWriter.cpp - ARM Windows COFF Object Writer -- C++ -==//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "MCTargetDesc/ARMFixupKinds.h"
00011 #include "llvm/MC/MCFixup.h"
00012 #include "llvm/MC/MCValue.h"
00013 #include "llvm/MC/MCWinCOFFObjectWriter.h"
00014 #include "llvm/Support/COFF.h"
00015 #include "llvm/Support/Debug.h"
00016 
00017 using namespace llvm;
00018 
00019 namespace {
00020 class ARMWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
00021 public:
00022   ARMWinCOFFObjectWriter(bool Is64Bit)
00023     : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_ARMNT) {
00024     assert(!Is64Bit && "AArch64 support not yet implemented");
00025   }
00026   virtual ~ARMWinCOFFObjectWriter() { }
00027 
00028   unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
00029                         bool IsCrossSection) const override;
00030 
00031   bool recordRelocation(const MCFixup &) const override;
00032 };
00033 
00034 unsigned ARMWinCOFFObjectWriter::getRelocType(const MCValue &Target,
00035                                               const MCFixup &Fixup,
00036                                               bool IsCrossSection) const {
00037   assert(getMachine() == COFF::IMAGE_FILE_MACHINE_ARMNT &&
00038          "AArch64 support not yet implemented");
00039 
00040   MCSymbolRefExpr::VariantKind Modifier =
00041     Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
00042 
00043   switch (static_cast<unsigned>(Fixup.getKind())) {
00044   default: llvm_unreachable("unsupported relocation type");
00045   case FK_Data_4:
00046     switch (Modifier) {
00047     case MCSymbolRefExpr::VK_COFF_IMGREL32:
00048       return COFF::IMAGE_REL_ARM_ADDR32NB;
00049     case MCSymbolRefExpr::VK_SECREL:
00050       return COFF::IMAGE_REL_ARM_SECREL;
00051     default:
00052       return COFF::IMAGE_REL_ARM_ADDR32;
00053     }
00054   case FK_SecRel_2:
00055     return COFF::IMAGE_REL_ARM_SECTION;
00056   case FK_SecRel_4:
00057     return COFF::IMAGE_REL_ARM_SECREL;
00058   case ARM::fixup_t2_condbranch:
00059     return COFF::IMAGE_REL_ARM_BRANCH20T;
00060   case ARM::fixup_t2_uncondbranch:
00061     return COFF::IMAGE_REL_ARM_BRANCH24T;
00062   case ARM::fixup_arm_thumb_bl:
00063   case ARM::fixup_arm_thumb_blx:
00064     return COFF::IMAGE_REL_ARM_BLX23T;
00065   case ARM::fixup_t2_movw_lo16:
00066   case ARM::fixup_t2_movt_hi16:
00067     return COFF::IMAGE_REL_ARM_MOV32T;
00068   }
00069 }
00070 
00071 bool ARMWinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const {
00072   return static_cast<unsigned>(Fixup.getKind()) != ARM::fixup_t2_movt_hi16;
00073 }
00074 }
00075 
00076 namespace llvm {
00077 MCObjectWriter *createARMWinCOFFObjectWriter(raw_ostream &OS, bool Is64Bit) {
00078   MCWinCOFFObjectTargetWriter *MOTW = new ARMWinCOFFObjectWriter(Is64Bit);
00079   return createWinCOFFObjectWriter(MOTW, OS);
00080 }
00081 }
00082