blob: 40af822953c47264e6c47348659f2a3e017cee5e [file] [log] [blame]
Rafael Espindola908d2ed2011-12-24 02:14:02 +00001//===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===//
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/X86FixupKinds.h"
11#include "MCTargetDesc/X86MCTargetDesc.h"
Nico Rieck1da45292013-04-10 23:28:17 +000012#include "llvm/MC/MCExpr.h"
13#include "llvm/MC/MCValue.h"
Rafael Espindola908d2ed2011-12-24 02:14:02 +000014#include "llvm/MC/MCWinCOFFObjectWriter.h"
15#include "llvm/Support/COFF.h"
16#include "llvm/Support/ErrorHandling.h"
17
18using namespace llvm;
19
20namespace llvm {
21 class MCObjectWriter;
22}
23
24namespace {
25 class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
Rafael Espindola908d2ed2011-12-24 02:14:02 +000026 public:
David Majnemerc9d26252014-04-08 02:15:13 +000027 X86WinCOFFObjectWriter(bool Is64Bit);
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +000028 virtual ~X86WinCOFFObjectWriter();
Rafael Espindola908d2ed2011-12-24 02:14:02 +000029
Craig Topper24e685f2014-03-10 05:29:18 +000030 unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
31 bool IsCrossSection) const override;
Rafael Espindola908d2ed2011-12-24 02:14:02 +000032 };
33}
34
David Majnemerc9d26252014-04-08 02:15:13 +000035X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit)
36 : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64
37 : COFF::IMAGE_FILE_MACHINE_I386) {}
Rafael Espindola908d2ed2011-12-24 02:14:02 +000038
39X86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {}
40
Nico Rieck1da45292013-04-10 23:28:17 +000041unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
42 const MCFixup &Fixup,
43 bool IsCrossSection) const {
44 unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind();
45
46 MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
47 MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
48
David Majnemerc9d26252014-04-08 02:15:13 +000049 if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) {
50 switch (FixupKind) {
51 case FK_PCRel_4:
52 case X86::reloc_riprel_4byte:
53 case X86::reloc_riprel_4byte_movq_load:
54 return COFF::IMAGE_REL_AMD64_REL32;
55 case FK_Data_4:
56 case X86::reloc_signed_4byte:
57 if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
58 return COFF::IMAGE_REL_AMD64_ADDR32NB;
59 return COFF::IMAGE_REL_AMD64_ADDR32;
60 case FK_Data_8:
Rafael Espindola908d2ed2011-12-24 02:14:02 +000061 return COFF::IMAGE_REL_AMD64_ADDR64;
David Majnemerc9d26252014-04-08 02:15:13 +000062 case FK_SecRel_2:
63 return COFF::IMAGE_REL_AMD64_SECTION;
64 case FK_SecRel_4:
65 return COFF::IMAGE_REL_AMD64_SECREL;
66 default:
67 llvm_unreachable("unsupported relocation type");
68 }
69 } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) {
70 switch (FixupKind) {
71 case FK_PCRel_4:
72 case X86::reloc_riprel_4byte:
73 case X86::reloc_riprel_4byte_movq_load:
74 return COFF::IMAGE_REL_I386_REL32;
75 case FK_Data_4:
76 case X86::reloc_signed_4byte:
77 if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
78 return COFF::IMAGE_REL_I386_DIR32NB;
79 return COFF::IMAGE_REL_I386_DIR32;
80 case FK_SecRel_2:
81 return COFF::IMAGE_REL_I386_SECTION;
82 case FK_SecRel_4:
83 return COFF::IMAGE_REL_I386_SECREL;
84 default:
85 llvm_unreachable("unsupported relocation type");
86 }
87 } else
88 llvm_unreachable("Unsupported COFF machine type.");
Rafael Espindola908d2ed2011-12-24 02:14:02 +000089}
90
91MCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_ostream &OS,
92 bool Is64Bit) {
93 MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit);
94 return createWinCOFFObjectWriter(MOTW, OS);
95}