LLVM API Documentation

X86WinCOFFObjectWriter.cpp
Go to the documentation of this file.
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 }