1dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===-- ARMWinCOFFObjectWriter.cpp - ARM Windows COFF Object Writer -- C++ -==//
2dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
3dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//                     The LLVM Compiler Infrastructure
4dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
5dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// This file is distributed under the University of Illinois Open Source
6dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// License. See LICENSE.TXT for details.
7dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
8dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===----------------------------------------------------------------------===//
9dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "MCTargetDesc/ARMFixupKinds.h"
11dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCFixup.h"
12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCValue.h"
13dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCWinCOFFObjectWriter.h"
14dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/COFF.h"
15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/Debug.h"
16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
17dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesusing namespace llvm;
18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesnamespace {
20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesclass ARMWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinespublic:
22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ARMWinCOFFObjectWriter(bool Is64Bit)
23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_ARMNT) {
24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(!Is64Bit && "AArch64 support not yet implemented");
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  virtual ~ARMWinCOFFObjectWriter() { }
27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                        bool IsCrossSection) const override;
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool recordRelocation(const MCFixup &) const override;
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned ARMWinCOFFObjectWriter::getRelocType(const MCValue &Target,
35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                              const MCFixup &Fixup,
36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                              bool IsCrossSection) const {
37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(getMachine() == COFF::IMAGE_FILE_MACHINE_ARMNT &&
38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "AArch64 support not yet implemented");
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCSymbolRefExpr::VariantKind Modifier =
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (static_cast<unsigned>(Fixup.getKind())) {
44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default: llvm_unreachable("unsupported relocation type");
45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_Data_4:
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Modifier) {
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case MCSymbolRefExpr::VK_COFF_IMGREL32:
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return COFF::IMAGE_REL_ARM_ADDR32NB;
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case MCSymbolRefExpr::VK_SECREL:
50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return COFF::IMAGE_REL_ARM_SECREL;
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return COFF::IMAGE_REL_ARM_ADDR32;
53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_SecRel_2:
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return COFF::IMAGE_REL_ARM_SECTION;
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_SecRel_4:
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return COFF::IMAGE_REL_ARM_SECREL;
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case ARM::fixup_t2_condbranch:
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return COFF::IMAGE_REL_ARM_BRANCH20T;
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case ARM::fixup_t2_uncondbranch:
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return COFF::IMAGE_REL_ARM_BRANCH24T;
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case ARM::fixup_arm_thumb_bl:
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case ARM::fixup_arm_thumb_blx:
64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return COFF::IMAGE_REL_ARM_BLX23T;
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case ARM::fixup_t2_movw_lo16:
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case ARM::fixup_t2_movt_hi16:
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return COFF::IMAGE_REL_ARM_MOV32T;
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool ARMWinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const {
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return static_cast<unsigned>(Fixup.getKind()) != ARM::fixup_t2_movt_hi16;
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesnamespace llvm {
77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMCObjectWriter *createARMWinCOFFObjectWriter(raw_ostream &OS, bool Is64Bit) {
78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCWinCOFFObjectTargetWriter *MOTW = new ARMWinCOFFObjectWriter(Is64Bit);
79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return createWinCOFFObjectWriter(MOTW, OS);
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
83