1df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola//===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===// 2df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola// 3df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola// The LLVM Compiler Infrastructure 4df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola// 5df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola// This file is distributed under the University of Illinois Open Source 6df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola// License. See LICENSE.TXT for details. 7df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola// 8df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola//===----------------------------------------------------------------------===// 9df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 10df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola#include "MCTargetDesc/X86FixupKinds.h" 11df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola#include "MCTargetDesc/X86MCTargetDesc.h" 1218d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck#include "llvm/MC/MCExpr.h" 1318d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck#include "llvm/MC/MCValue.h" 14df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola#include "llvm/MC/MCWinCOFFObjectWriter.h" 15df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola#include "llvm/Support/COFF.h" 16df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola#include "llvm/Support/ErrorHandling.h" 17df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 18df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindolausing namespace llvm; 19df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 20df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindolanamespace llvm { 21df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola class MCObjectWriter; 22df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola} 23df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 24df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindolanamespace { 25df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { 26df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola public: 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines X86WinCOFFObjectWriter(bool Is64Bit); 282c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar ~X86WinCOFFObjectWriter() override; 29df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup, 31ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsCrossSection, 32ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const MCAsmBackend &MAB) const override; 33df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola }; 34df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola} 35df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesX86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit) 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64 38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : COFF::IMAGE_FILE_MACHINE_I386) {} 39df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 40df09270ae897e7fa64a7c162de163c32ee181a03Rafael EspindolaX86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {} 41df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 4218d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieckunsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target, 4318d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck const MCFixup &Fixup, 44ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsCrossSection, 45ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const MCAsmBackend &MAB) const { 4618d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind(); 4718d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck 4818d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 4918d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 5018d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck 51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) { 52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (FixupKind) { 53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_PCRel_4: 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case X86::reloc_riprel_4byte: 55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case X86::reloc_riprel_4byte_movq_load: 56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_AMD64_REL32; 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_Data_4: 58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case X86::reloc_signed_4byte: 59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_AMD64_ADDR32NB; 61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_AMD64_ADDR32; 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_Data_8: 63df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola return COFF::IMAGE_REL_AMD64_ADDR64; 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_SecRel_2: 65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_AMD64_SECTION; 66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_SecRel_4: 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_AMD64_SECREL; 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable("unsupported relocation type"); 70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) { 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (FixupKind) { 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_PCRel_4: 74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case X86::reloc_riprel_4byte: 75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case X86::reloc_riprel_4byte_movq_load: 76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_I386_REL32; 77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_Data_4: 78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case X86::reloc_signed_4byte: 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_I386_DIR32NB; 81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_I386_DIR32; 82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_SecRel_2: 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_I386_SECTION; 84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_SecRel_4: 85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return COFF::IMAGE_REL_I386_SECREL; 86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: 87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable("unsupported relocation type"); 88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else 90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable("Unsupported COFF machine type."); 91df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola} 92df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 932c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga NainarMCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_pwrite_stream &OS, 94df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola bool Is64Bit) { 95df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit); 96df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola return createWinCOFFObjectWriter(MOTW, OS); 97df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola} 98