LLVM API Documentation
00001 //===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "MCTargetDesc/X86FixupKinds.h" 00011 #include "MCTargetDesc/X86MCTargetDesc.h" 00012 #include "llvm/MC/MCExpr.h" 00013 #include "llvm/MC/MCValue.h" 00014 #include "llvm/MC/MCWinCOFFObjectWriter.h" 00015 #include "llvm/Support/COFF.h" 00016 #include "llvm/Support/ErrorHandling.h" 00017 00018 using namespace llvm; 00019 00020 namespace llvm { 00021 class MCObjectWriter; 00022 } 00023 00024 namespace { 00025 class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { 00026 public: 00027 X86WinCOFFObjectWriter(bool Is64Bit); 00028 virtual ~X86WinCOFFObjectWriter(); 00029 00030 unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup, 00031 bool IsCrossSection) const override; 00032 }; 00033 } 00034 00035 X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit) 00036 : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64 00037 : COFF::IMAGE_FILE_MACHINE_I386) {} 00038 00039 X86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {} 00040 00041 unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target, 00042 const MCFixup &Fixup, 00043 bool IsCrossSection) const { 00044 unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind(); 00045 00046 MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 00047 MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 00048 00049 if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) { 00050 switch (FixupKind) { 00051 case FK_PCRel_4: 00052 case X86::reloc_riprel_4byte: 00053 case X86::reloc_riprel_4byte_movq_load: 00054 return COFF::IMAGE_REL_AMD64_REL32; 00055 case FK_Data_4: 00056 case X86::reloc_signed_4byte: 00057 if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 00058 return COFF::IMAGE_REL_AMD64_ADDR32NB; 00059 return COFF::IMAGE_REL_AMD64_ADDR32; 00060 case FK_Data_8: 00061 return COFF::IMAGE_REL_AMD64_ADDR64; 00062 case FK_SecRel_2: 00063 return COFF::IMAGE_REL_AMD64_SECTION; 00064 case FK_SecRel_4: 00065 return COFF::IMAGE_REL_AMD64_SECREL; 00066 default: 00067 llvm_unreachable("unsupported relocation type"); 00068 } 00069 } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) { 00070 switch (FixupKind) { 00071 case FK_PCRel_4: 00072 case X86::reloc_riprel_4byte: 00073 case X86::reloc_riprel_4byte_movq_load: 00074 return COFF::IMAGE_REL_I386_REL32; 00075 case FK_Data_4: 00076 case X86::reloc_signed_4byte: 00077 if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 00078 return COFF::IMAGE_REL_I386_DIR32NB; 00079 return COFF::IMAGE_REL_I386_DIR32; 00080 case FK_SecRel_2: 00081 return COFF::IMAGE_REL_I386_SECTION; 00082 case FK_SecRel_4: 00083 return COFF::IMAGE_REL_I386_SECREL; 00084 default: 00085 llvm_unreachable("unsupported relocation type"); 00086 } 00087 } else 00088 llvm_unreachable("Unsupported COFF machine type."); 00089 } 00090 00091 MCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_ostream &OS, 00092 bool Is64Bit) { 00093 MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit); 00094 return createWinCOFFObjectWriter(MOTW, OS); 00095 }