X86WinCOFFObjectWriter.cpp revision 288943
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); 28288943Sdim ~X86WinCOFFObjectWriter() override; 29234285Sdim 30276479Sdim unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup, 31288943Sdim bool IsCrossSection, 32288943Sdim const MCAsmBackend &MAB) const override; 33234285Sdim }; 34234285Sdim} 35234285Sdim 36276479SdimX86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit) 37276479Sdim : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64 38276479Sdim : COFF::IMAGE_FILE_MACHINE_I386) {} 39234285Sdim 40234285SdimX86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {} 41234285Sdim 42251662Sdimunsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target, 43251662Sdim const MCFixup &Fixup, 44288943Sdim bool IsCrossSection, 45288943Sdim const MCAsmBackend &MAB) const { 46251662Sdim unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind(); 47251662Sdim 48251662Sdim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 49251662Sdim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 50251662Sdim 51276479Sdim if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) { 52276479Sdim switch (FixupKind) { 53276479Sdim case FK_PCRel_4: 54276479Sdim case X86::reloc_riprel_4byte: 55276479Sdim case X86::reloc_riprel_4byte_movq_load: 56276479Sdim return COFF::IMAGE_REL_AMD64_REL32; 57276479Sdim case FK_Data_4: 58276479Sdim case X86::reloc_signed_4byte: 59276479Sdim if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 60276479Sdim return COFF::IMAGE_REL_AMD64_ADDR32NB; 61276479Sdim return COFF::IMAGE_REL_AMD64_ADDR32; 62276479Sdim case FK_Data_8: 63234285Sdim return COFF::IMAGE_REL_AMD64_ADDR64; 64276479Sdim case FK_SecRel_2: 65276479Sdim return COFF::IMAGE_REL_AMD64_SECTION; 66276479Sdim case FK_SecRel_4: 67276479Sdim return COFF::IMAGE_REL_AMD64_SECREL; 68276479Sdim default: 69276479Sdim llvm_unreachable("unsupported relocation type"); 70276479Sdim } 71276479Sdim } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) { 72276479Sdim switch (FixupKind) { 73276479Sdim case FK_PCRel_4: 74276479Sdim case X86::reloc_riprel_4byte: 75276479Sdim case X86::reloc_riprel_4byte_movq_load: 76276479Sdim return COFF::IMAGE_REL_I386_REL32; 77276479Sdim case FK_Data_4: 78276479Sdim case X86::reloc_signed_4byte: 79276479Sdim if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 80276479Sdim return COFF::IMAGE_REL_I386_DIR32NB; 81276479Sdim return COFF::IMAGE_REL_I386_DIR32; 82276479Sdim case FK_SecRel_2: 83276479Sdim return COFF::IMAGE_REL_I386_SECTION; 84276479Sdim case FK_SecRel_4: 85276479Sdim return COFF::IMAGE_REL_I386_SECREL; 86276479Sdim default: 87276479Sdim llvm_unreachable("unsupported relocation type"); 88276479Sdim } 89276479Sdim } else 90276479Sdim llvm_unreachable("Unsupported COFF machine type."); 91234285Sdim} 92234285Sdim 93288943SdimMCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_pwrite_stream &OS, 94234285Sdim bool Is64Bit) { 95234285Sdim MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit); 96234285Sdim return createWinCOFFObjectWriter(MOTW, OS); 97234285Sdim} 98