X86WinCOFFObjectWriter.cpp revision 276479
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 public: 27276479Sdim X86WinCOFFObjectWriter(bool Is64Bit); 28261991Sdim virtual ~X86WinCOFFObjectWriter(); 29234285Sdim 30276479Sdim unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup, 31276479Sdim bool IsCrossSection) const override; 32234285Sdim }; 33234285Sdim} 34234285Sdim 35276479SdimX86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit) 36276479Sdim : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64 37276479Sdim : COFF::IMAGE_FILE_MACHINE_I386) {} 38234285Sdim 39234285SdimX86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {} 40234285Sdim 41251662Sdimunsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target, 42251662Sdim const MCFixup &Fixup, 43251662Sdim bool IsCrossSection) const { 44251662Sdim unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind(); 45251662Sdim 46251662Sdim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 47251662Sdim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 48251662Sdim 49276479Sdim if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) { 50276479Sdim switch (FixupKind) { 51276479Sdim case FK_PCRel_4: 52276479Sdim case X86::reloc_riprel_4byte: 53276479Sdim case X86::reloc_riprel_4byte_movq_load: 54276479Sdim return COFF::IMAGE_REL_AMD64_REL32; 55276479Sdim case FK_Data_4: 56276479Sdim case X86::reloc_signed_4byte: 57276479Sdim if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 58276479Sdim return COFF::IMAGE_REL_AMD64_ADDR32NB; 59276479Sdim return COFF::IMAGE_REL_AMD64_ADDR32; 60276479Sdim case FK_Data_8: 61234285Sdim return COFF::IMAGE_REL_AMD64_ADDR64; 62276479Sdim case FK_SecRel_2: 63276479Sdim return COFF::IMAGE_REL_AMD64_SECTION; 64276479Sdim case FK_SecRel_4: 65276479Sdim return COFF::IMAGE_REL_AMD64_SECREL; 66276479Sdim default: 67276479Sdim llvm_unreachable("unsupported relocation type"); 68276479Sdim } 69276479Sdim } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) { 70276479Sdim switch (FixupKind) { 71276479Sdim case FK_PCRel_4: 72276479Sdim case X86::reloc_riprel_4byte: 73276479Sdim case X86::reloc_riprel_4byte_movq_load: 74276479Sdim return COFF::IMAGE_REL_I386_REL32; 75276479Sdim case FK_Data_4: 76276479Sdim case X86::reloc_signed_4byte: 77276479Sdim if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 78276479Sdim return COFF::IMAGE_REL_I386_DIR32NB; 79276479Sdim return COFF::IMAGE_REL_I386_DIR32; 80276479Sdim case FK_SecRel_2: 81276479Sdim return COFF::IMAGE_REL_I386_SECTION; 82276479Sdim case FK_SecRel_4: 83276479Sdim return COFF::IMAGE_REL_I386_SECREL; 84276479Sdim default: 85276479Sdim llvm_unreachable("unsupported relocation type"); 86276479Sdim } 87276479Sdim } else 88276479Sdim llvm_unreachable("Unsupported COFF machine type."); 89234285Sdim} 90234285Sdim 91234285SdimMCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_ostream &OS, 92234285Sdim bool Is64Bit) { 93234285Sdim MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit); 94234285Sdim return createWinCOFFObjectWriter(MOTW, OS); 95234285Sdim} 96