1 //===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/X86FixupKinds.h"
11 #include "MCTargetDesc/X86MCTargetDesc.h"
12 #include "llvm/MC/MCExpr.h"
13 #include "llvm/MC/MCFixup.h"
14 #include "llvm/MC/MCValue.h"
15 #include "llvm/MC/MCWinCOFFObjectWriter.h"
16 #include "llvm/Support/COFF.h"
17 #include "llvm/Support/ErrorHandling.h"
23 class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
25 X86WinCOFFObjectWriter(bool Is64Bit);
26 ~X86WinCOFFObjectWriter() override = default;
28 unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
30 const MCAsmBackend &MAB) const override;
33 } // end anonymous namespace
35 X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit)
36 : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64
37 : COFF::IMAGE_FILE_MACHINE_I386) {}
39 unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
42 const MCAsmBackend &MAB) const {
43 unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind();
45 MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
46 MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
48 if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) {
51 case X86::reloc_riprel_4byte:
52 case X86::reloc_riprel_4byte_movq_load:
53 case X86::reloc_riprel_4byte_relax:
54 case X86::reloc_riprel_4byte_relax_rex:
55 return COFF::IMAGE_REL_AMD64_REL32;
57 case X86::reloc_signed_4byte:
58 case X86::reloc_signed_4byte_relax:
59 if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
60 return COFF::IMAGE_REL_AMD64_ADDR32NB;
61 if (Modifier == MCSymbolRefExpr::VK_SECREL)
62 return COFF::IMAGE_REL_AMD64_SECREL;
63 return COFF::IMAGE_REL_AMD64_ADDR32;
65 return COFF::IMAGE_REL_AMD64_ADDR64;
67 return COFF::IMAGE_REL_AMD64_SECTION;
69 return COFF::IMAGE_REL_AMD64_SECREL;
71 llvm_unreachable("unsupported relocation type");
73 } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) {
76 case X86::reloc_riprel_4byte:
77 case X86::reloc_riprel_4byte_movq_load:
78 return COFF::IMAGE_REL_I386_REL32;
80 case X86::reloc_signed_4byte:
81 case X86::reloc_signed_4byte_relax:
82 if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
83 return COFF::IMAGE_REL_I386_DIR32NB;
84 if (Modifier == MCSymbolRefExpr::VK_SECREL)
85 return COFF::IMAGE_REL_AMD64_SECREL;
86 return COFF::IMAGE_REL_I386_DIR32;
88 return COFF::IMAGE_REL_I386_SECTION;
90 return COFF::IMAGE_REL_I386_SECREL;
92 llvm_unreachable("unsupported relocation type");
95 llvm_unreachable("Unsupported COFF machine type.");
98 MCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_pwrite_stream &OS,
100 MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit);
101 return createWinCOFFObjectWriter(MOTW, OS);