1 //===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/X86FixupKinds.h" 11 #include "MCTargetDesc/X86MCTargetDesc.h" 12 #include "llvm/MC/MCExpr.h" 13 #include "llvm/MC/MCValue.h" 14 #include "llvm/MC/MCWinCOFFObjectWriter.h" 15 #include "llvm/Support/COFF.h" 16 #include "llvm/Support/ErrorHandling.h" 17 18 using namespace llvm; 19 20 namespace llvm { 21 class MCObjectWriter; 22 } 23 24 namespace { 25 class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { 26 const bool Is64Bit; 27 28 public: 29 X86WinCOFFObjectWriter(bool Is64Bit_); 30 virtual ~X86WinCOFFObjectWriter(); 31 32 virtual unsigned getRelocType(const MCValue &Target, 33 const MCFixup &Fixup, 34 bool IsCrossSection) const LLVM_OVERRIDE; 35 }; 36 } 37 38 X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit_) 39 : MCWinCOFFObjectTargetWriter(Is64Bit_ ? COFF::IMAGE_FILE_MACHINE_AMD64 : 40 COFF::IMAGE_FILE_MACHINE_I386), 41 Is64Bit(Is64Bit_) {} 42 43 X86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {} 44 45 unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target, 46 const MCFixup &Fixup, 47 bool IsCrossSection) const { 48 unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind(); 49 50 MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 51 MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 52 53 switch (FixupKind) { 54 case FK_PCRel_4: 55 case X86::reloc_riprel_4byte: 56 case X86::reloc_riprel_4byte_movq_load: 57 return Is64Bit ? COFF::IMAGE_REL_AMD64_REL32 : COFF::IMAGE_REL_I386_REL32; 58 case FK_Data_4: 59 case X86::reloc_signed_4byte: 60 if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 61 return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32NB : 62 COFF::IMAGE_REL_I386_DIR32NB; 63 return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32 : COFF::IMAGE_REL_I386_DIR32; 64 case FK_Data_8: 65 if (Is64Bit) 66 return COFF::IMAGE_REL_AMD64_ADDR64; 67 llvm_unreachable("unsupported relocation type"); 68 case FK_SecRel_4: 69 return Is64Bit ? COFF::IMAGE_REL_AMD64_SECREL : COFF::IMAGE_REL_I386_SECREL; 70 default: 71 llvm_unreachable("unsupported relocation type"); 72 } 73 } 74 75 MCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_ostream &OS, 76 bool Is64Bit) { 77 MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit); 78 return createWinCOFFObjectWriter(MOTW, OS); 79 } 80