diff options
Diffstat (limited to 'contrib/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp b/contrib/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp new file mode 100644 index 0000000..bd1bc99 --- /dev/null +++ b/contrib/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp @@ -0,0 +1,97 @@ +//===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/X86FixupKinds.h" +#include "MCTargetDesc/X86MCTargetDesc.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCWinCOFFObjectWriter.h" +#include "llvm/Support/COFF.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +namespace llvm { + class MCObjectWriter; +} + +namespace { + class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { + public: + X86WinCOFFObjectWriter(bool Is64Bit); + ~X86WinCOFFObjectWriter() override; + + unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup, + bool IsCrossSection, + const MCAsmBackend &MAB) const override; + }; +} + +X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit) + : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64 + : COFF::IMAGE_FILE_MACHINE_I386) {} + +X86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {} + +unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target, + const MCFixup &Fixup, + bool IsCrossSection, + const MCAsmBackend &MAB) const { + unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind(); + + MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? + MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); + + if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) { + switch (FixupKind) { + case FK_PCRel_4: + case X86::reloc_riprel_4byte: + case X86::reloc_riprel_4byte_movq_load: + return COFF::IMAGE_REL_AMD64_REL32; + case FK_Data_4: + case X86::reloc_signed_4byte: + if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) + return COFF::IMAGE_REL_AMD64_ADDR32NB; + return COFF::IMAGE_REL_AMD64_ADDR32; + case FK_Data_8: + return COFF::IMAGE_REL_AMD64_ADDR64; + case FK_SecRel_2: + return COFF::IMAGE_REL_AMD64_SECTION; + case FK_SecRel_4: + return COFF::IMAGE_REL_AMD64_SECREL; + default: + llvm_unreachable("unsupported relocation type"); + } + } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) { + switch (FixupKind) { + case FK_PCRel_4: + case X86::reloc_riprel_4byte: + case X86::reloc_riprel_4byte_movq_load: + return COFF::IMAGE_REL_I386_REL32; + case FK_Data_4: + case X86::reloc_signed_4byte: + if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) + return COFF::IMAGE_REL_I386_DIR32NB; + return COFF::IMAGE_REL_I386_DIR32; + case FK_SecRel_2: + return COFF::IMAGE_REL_I386_SECTION; + case FK_SecRel_4: + return COFF::IMAGE_REL_I386_SECREL; + default: + llvm_unreachable("unsupported relocation type"); + } + } else + llvm_unreachable("Unsupported COFF machine type."); +} + +MCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_pwrite_stream &OS, + bool Is64Bit) { + MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit); + return createWinCOFFObjectWriter(MOTW, OS); +} |