1 //===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/X86FixupKinds.h"
10 #include "MCTargetDesc/X86MCTargetDesc.h"
11 #include "llvm/BinaryFormat/COFF.h"
12 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCFixup.h"
15 #include "llvm/MC/MCObjectWriter.h"
16 #include "llvm/MC/MCValue.h"
17 #include "llvm/MC/MCWinCOFFObjectWriter.h"
18 #include "llvm/Support/ErrorHandling.h"
24 class X86WinCOFFObjectWriter
: public MCWinCOFFObjectTargetWriter
{
26 X86WinCOFFObjectWriter(bool Is64Bit
);
27 ~X86WinCOFFObjectWriter() override
= default;
29 unsigned getRelocType(MCContext
&Ctx
, const MCValue
&Target
,
30 const MCFixup
&Fixup
, bool IsCrossSection
,
31 const MCAsmBackend
&MAB
) const override
;
34 } // end anonymous namespace
36 X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit
)
37 : MCWinCOFFObjectTargetWriter(Is64Bit
? COFF::IMAGE_FILE_MACHINE_AMD64
38 : COFF::IMAGE_FILE_MACHINE_I386
) {}
40 unsigned X86WinCOFFObjectWriter::getRelocType(MCContext
&Ctx
,
41 const MCValue
&Target
,
44 const MCAsmBackend
&MAB
) const {
45 unsigned FixupKind
= Fixup
.getKind();
47 if (FixupKind
!= FK_Data_4
&& FixupKind
!= llvm::X86::reloc_signed_4byte
) {
48 Ctx
.reportError(Fixup
.getLoc(), "Cannot represent this expression");
49 return COFF::IMAGE_REL_AMD64_ADDR32
;
51 FixupKind
= FK_PCRel_4
;
54 MCSymbolRefExpr::VariantKind Modifier
= Target
.isAbsolute() ?
55 MCSymbolRefExpr::VK_None
: Target
.getSymA()->getKind();
57 if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64
) {
60 case X86::reloc_riprel_4byte
:
61 case X86::reloc_riprel_4byte_movq_load
:
62 case X86::reloc_riprel_4byte_relax
:
63 case X86::reloc_riprel_4byte_relax_rex
:
64 case X86::reloc_branch_4byte_pcrel
:
65 return COFF::IMAGE_REL_AMD64_REL32
;
67 case X86::reloc_signed_4byte
:
68 case X86::reloc_signed_4byte_relax
:
69 if (Modifier
== MCSymbolRefExpr::VK_COFF_IMGREL32
)
70 return COFF::IMAGE_REL_AMD64_ADDR32NB
;
71 if (Modifier
== MCSymbolRefExpr::VK_SECREL
)
72 return COFF::IMAGE_REL_AMD64_SECREL
;
73 return COFF::IMAGE_REL_AMD64_ADDR32
;
75 return COFF::IMAGE_REL_AMD64_ADDR64
;
77 return COFF::IMAGE_REL_AMD64_SECTION
;
79 return COFF::IMAGE_REL_AMD64_SECREL
;
81 Ctx
.reportError(Fixup
.getLoc(), "unsupported relocation type");
82 return COFF::IMAGE_REL_AMD64_ADDR32
;
84 } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386
) {
87 case X86::reloc_riprel_4byte
:
88 case X86::reloc_riprel_4byte_movq_load
:
89 return COFF::IMAGE_REL_I386_REL32
;
91 case X86::reloc_signed_4byte
:
92 case X86::reloc_signed_4byte_relax
:
93 if (Modifier
== MCSymbolRefExpr::VK_COFF_IMGREL32
)
94 return COFF::IMAGE_REL_I386_DIR32NB
;
95 if (Modifier
== MCSymbolRefExpr::VK_SECREL
)
96 return COFF::IMAGE_REL_AMD64_SECREL
;
97 return COFF::IMAGE_REL_I386_DIR32
;
99 return COFF::IMAGE_REL_I386_SECTION
;
101 return COFF::IMAGE_REL_I386_SECREL
;
103 Ctx
.reportError(Fixup
.getLoc(), "unsupported relocation type");
104 return COFF::IMAGE_REL_I386_DIR32
;
107 llvm_unreachable("Unsupported COFF machine type.");
110 std::unique_ptr
<MCObjectTargetWriter
>
111 llvm::createX86WinCOFFObjectWriter(bool Is64Bit
) {
112 return std::make_unique
<X86WinCOFFObjectWriter
>(Is64Bit
);