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