blob: 291056e35266257f72ccca00c8ffb19496674aa5 [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"
Zachary Turner264b5d92017-06-07 03:48:56 +000012#include "llvm/BinaryFormat/COFF.h"
Rafael Espindola58173b92017-06-23 04:07:44 +000013#include "llvm/MC/MCContext.h"
Nico Rieck1da45292013-04-10 23:28:17 +000014#include "llvm/MC/MCExpr.h"
Eugene Zelenkofbd13c52017-02-02 22:55:55 +000015#include "llvm/MC/MCFixup.h"
Lang Hames60fbc7c2017-10-10 16:28:07 +000016#include "llvm/MC/MCObjectWriter.h"
Nico Rieck1da45292013-04-10 23:28:17 +000017#include "llvm/MC/MCValue.h"
Rafael Espindola908d2ed2011-12-24 02:14:02 +000018#include "llvm/MC/MCWinCOFFObjectWriter.h"
Rafael Espindola908d2ed2011-12-24 02:14:02 +000019#include "llvm/Support/ErrorHandling.h"
20
21using namespace llvm;
22
Rafael Espindola908d2ed2011-12-24 02:14:02 +000023namespace {
Rafael Espindola908d2ed2011-12-24 02:14:02 +000024
Eugene Zelenkofbd13c52017-02-02 22:55:55 +000025class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
26public:
27 X86WinCOFFObjectWriter(bool Is64Bit);
28 ~X86WinCOFFObjectWriter() override = default;
29
Rafael Espindola58173b92017-06-23 04:07:44 +000030 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
31 const MCFixup &Fixup, bool IsCrossSection,
Eugene Zelenkofbd13c52017-02-02 22:55:55 +000032 const MCAsmBackend &MAB) const override;
33};
34
35} // end anonymous namespace
Rafael Espindola908d2ed2011-12-24 02:14:02 +000036
David Majnemerc9d26252014-04-08 02:15:13 +000037X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit)
38 : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64
39 : COFF::IMAGE_FILE_MACHINE_I386) {}
Rafael Espindola908d2ed2011-12-24 02:14:02 +000040
Rafael Espindola58173b92017-06-23 04:07:44 +000041unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,
42 const MCValue &Target,
Nico Rieck1da45292013-04-10 23:28:17 +000043 const MCFixup &Fixup,
Saleem Abdulrasool10ed0ba2015-01-22 04:03:32 +000044 bool IsCrossSection,
45 const MCAsmBackend &MAB) const {
Rafael Espindola58173b92017-06-23 04:07:44 +000046 unsigned FixupKind = Fixup.getKind();
47 if (IsCrossSection) {
Rafael Espindola96367a32017-06-28 17:56:07 +000048 if (FixupKind != FK_Data_4 && FixupKind != llvm::X86::reloc_signed_4byte) {
Rafael Espindola58173b92017-06-23 04:07:44 +000049 Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");
50 return COFF::IMAGE_REL_AMD64_ADDR32;
51 }
52 FixupKind = FK_PCRel_4;
53 }
Nico Rieck1da45292013-04-10 23:28:17 +000054
55 MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
56 MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
57
David Majnemerc9d26252014-04-08 02:15:13 +000058 if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) {
59 switch (FixupKind) {
60 case FK_PCRel_4:
61 case X86::reloc_riprel_4byte:
62 case X86::reloc_riprel_4byte_movq_load:
Rafael Espindola4f1062a2016-05-30 20:18:53 +000063 case X86::reloc_riprel_4byte_relax:
64 case X86::reloc_riprel_4byte_relax_rex:
George Rimarda4f43a42018-02-20 10:17:57 +000065 case X86::reloc_branch_4byte_pcrel:
David Majnemerc9d26252014-04-08 02:15:13 +000066 return COFF::IMAGE_REL_AMD64_REL32;
67 case FK_Data_4:
68 case X86::reloc_signed_4byte:
Rafael Espindolab34cba92016-07-07 14:00:07 +000069 case X86::reloc_signed_4byte_relax:
David Majnemerc9d26252014-04-08 02:15:13 +000070 if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
71 return COFF::IMAGE_REL_AMD64_ADDR32NB;
David Majnemerce108422016-01-19 23:05:27 +000072 if (Modifier == MCSymbolRefExpr::VK_SECREL)
73 return COFF::IMAGE_REL_AMD64_SECREL;
David Majnemerc9d26252014-04-08 02:15:13 +000074 return COFF::IMAGE_REL_AMD64_ADDR32;
75 case FK_Data_8:
Rafael Espindola908d2ed2011-12-24 02:14:02 +000076 return COFF::IMAGE_REL_AMD64_ADDR64;
David Majnemerc9d26252014-04-08 02:15:13 +000077 case FK_SecRel_2:
78 return COFF::IMAGE_REL_AMD64_SECTION;
79 case FK_SecRel_4:
80 return COFF::IMAGE_REL_AMD64_SECREL;
81 default:
82 llvm_unreachable("unsupported relocation type");
83 }
84 } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) {
85 switch (FixupKind) {
86 case FK_PCRel_4:
87 case X86::reloc_riprel_4byte:
88 case X86::reloc_riprel_4byte_movq_load:
89 return COFF::IMAGE_REL_I386_REL32;
90 case FK_Data_4:
91 case X86::reloc_signed_4byte:
Rafael Espindolaa29971f2016-07-06 21:19:11 +000092 case X86::reloc_signed_4byte_relax:
David Majnemerc9d26252014-04-08 02:15:13 +000093 if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
94 return COFF::IMAGE_REL_I386_DIR32NB;
David Majnemerce108422016-01-19 23:05:27 +000095 if (Modifier == MCSymbolRefExpr::VK_SECREL)
96 return COFF::IMAGE_REL_AMD64_SECREL;
David Majnemerc9d26252014-04-08 02:15:13 +000097 return COFF::IMAGE_REL_I386_DIR32;
98 case FK_SecRel_2:
99 return COFF::IMAGE_REL_I386_SECTION;
100 case FK_SecRel_4:
101 return COFF::IMAGE_REL_I386_SECREL;
102 default:
103 llvm_unreachable("unsupported relocation type");
104 }
105 } else
106 llvm_unreachable("Unsupported COFF machine type.");
Rafael Espindola908d2ed2011-12-24 02:14:02 +0000107}
108
Lang Hames60fbc7c2017-10-10 16:28:07 +0000109std::unique_ptr<MCObjectWriter>
110llvm::createX86WinCOFFObjectWriter(raw_pwrite_stream &OS, bool Is64Bit) {
Lang Hames77dff392017-10-10 00:50:29 +0000111 auto MOTW = llvm::make_unique<X86WinCOFFObjectWriter>(Is64Bit);
112 return createWinCOFFObjectWriter(std::move(MOTW), OS);
Rafael Espindola908d2ed2011-12-24 02:14:02 +0000113}