1234285Sdim//===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===// 2234285Sdim// 3234285Sdim// The LLVM Compiler Infrastructure 4234285Sdim// 5234285Sdim// This file is distributed under the University of Illinois Open Source 6234285Sdim// License. See LICENSE.TXT for details. 7234285Sdim// 8234285Sdim//===----------------------------------------------------------------------===// 9234285Sdim 10234285Sdim#include "MCTargetDesc/X86FixupKinds.h" 11234285Sdim#include "MCTargetDesc/X86MCTargetDesc.h" 12251662Sdim#include "llvm/MC/MCExpr.h" 13251662Sdim#include "llvm/MC/MCValue.h" 14234285Sdim#include "llvm/MC/MCWinCOFFObjectWriter.h" 15234285Sdim#include "llvm/Support/COFF.h" 16234285Sdim#include "llvm/Support/ErrorHandling.h" 17234285Sdim 18234285Sdimusing namespace llvm; 19234285Sdim 20234285Sdimnamespace llvm { 21234285Sdim class MCObjectWriter; 22234285Sdim} 23234285Sdim 24234285Sdimnamespace { 25234285Sdim class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { 26234285Sdim const bool Is64Bit; 27234285Sdim 28234285Sdim public: 29234285Sdim X86WinCOFFObjectWriter(bool Is64Bit_); 30263508Sdim virtual ~X86WinCOFFObjectWriter(); 31234285Sdim 32251662Sdim virtual unsigned getRelocType(const MCValue &Target, 33251662Sdim const MCFixup &Fixup, 34251662Sdim bool IsCrossSection) const LLVM_OVERRIDE; 35234285Sdim }; 36234285Sdim} 37234285Sdim 38234285SdimX86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit_) 39234285Sdim : MCWinCOFFObjectTargetWriter(Is64Bit_ ? COFF::IMAGE_FILE_MACHINE_AMD64 : 40234285Sdim COFF::IMAGE_FILE_MACHINE_I386), 41234285Sdim Is64Bit(Is64Bit_) {} 42234285Sdim 43234285SdimX86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {} 44234285Sdim 45251662Sdimunsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target, 46251662Sdim const MCFixup &Fixup, 47251662Sdim bool IsCrossSection) const { 48251662Sdim unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind(); 49251662Sdim 50251662Sdim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 51251662Sdim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 52251662Sdim 53234285Sdim switch (FixupKind) { 54234285Sdim case FK_PCRel_4: 55234285Sdim case X86::reloc_riprel_4byte: 56234285Sdim case X86::reloc_riprel_4byte_movq_load: 57234285Sdim return Is64Bit ? COFF::IMAGE_REL_AMD64_REL32 : COFF::IMAGE_REL_I386_REL32; 58234285Sdim case FK_Data_4: 59234285Sdim case X86::reloc_signed_4byte: 60251662Sdim if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 61251662Sdim return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32NB : 62251662Sdim COFF::IMAGE_REL_I386_DIR32NB; 63234285Sdim return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32 : COFF::IMAGE_REL_I386_DIR32; 64234285Sdim case FK_Data_8: 65234285Sdim if (Is64Bit) 66234285Sdim return COFF::IMAGE_REL_AMD64_ADDR64; 67234285Sdim llvm_unreachable("unsupported relocation type"); 68234285Sdim case FK_SecRel_4: 69234285Sdim return Is64Bit ? COFF::IMAGE_REL_AMD64_SECREL : COFF::IMAGE_REL_I386_SECREL; 70234285Sdim default: 71234285Sdim llvm_unreachable("unsupported relocation type"); 72234285Sdim } 73234285Sdim} 74234285Sdim 75234285SdimMCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_ostream &OS, 76234285Sdim bool Is64Bit) { 77234285Sdim MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit); 78234285Sdim return createWinCOFFObjectWriter(MOTW, OS); 79234285Sdim} 80