mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 13:11:39 +01:00
47bffde92c
Windows supports a restricted set of relocations (compared to ARM ELF). In some cases, we may end up generating an unsupported relocation. This can occur with bad input to the assembler in particular (the frontend should never generate code that cannot be compiled). Generate an error rather than just aborting. The change in the API is driven by the desire to provide a slightly more helpful message for debugging purposes. llvm-svn: 226779
98 lines
3.3 KiB
C++
98 lines
3.3 KiB
C++
//===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "MCTargetDesc/X86FixupKinds.h"
|
|
#include "MCTargetDesc/X86MCTargetDesc.h"
|
|
#include "llvm/MC/MCExpr.h"
|
|
#include "llvm/MC/MCValue.h"
|
|
#include "llvm/MC/MCWinCOFFObjectWriter.h"
|
|
#include "llvm/Support/COFF.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace llvm {
|
|
class MCObjectWriter;
|
|
}
|
|
|
|
namespace {
|
|
class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
|
|
public:
|
|
X86WinCOFFObjectWriter(bool Is64Bit);
|
|
virtual ~X86WinCOFFObjectWriter();
|
|
|
|
unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
|
|
bool IsCrossSection,
|
|
const MCAsmBackend &MAB) const override;
|
|
};
|
|
}
|
|
|
|
X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit)
|
|
: MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64
|
|
: COFF::IMAGE_FILE_MACHINE_I386) {}
|
|
|
|
X86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {}
|
|
|
|
unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
|
|
const MCFixup &Fixup,
|
|
bool IsCrossSection,
|
|
const MCAsmBackend &MAB) const {
|
|
unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind();
|
|
|
|
MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
|
|
MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
|
|
|
|
if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) {
|
|
switch (FixupKind) {
|
|
case FK_PCRel_4:
|
|
case X86::reloc_riprel_4byte:
|
|
case X86::reloc_riprel_4byte_movq_load:
|
|
return COFF::IMAGE_REL_AMD64_REL32;
|
|
case FK_Data_4:
|
|
case X86::reloc_signed_4byte:
|
|
if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
|
|
return COFF::IMAGE_REL_AMD64_ADDR32NB;
|
|
return COFF::IMAGE_REL_AMD64_ADDR32;
|
|
case FK_Data_8:
|
|
return COFF::IMAGE_REL_AMD64_ADDR64;
|
|
case FK_SecRel_2:
|
|
return COFF::IMAGE_REL_AMD64_SECTION;
|
|
case FK_SecRel_4:
|
|
return COFF::IMAGE_REL_AMD64_SECREL;
|
|
default:
|
|
llvm_unreachable("unsupported relocation type");
|
|
}
|
|
} else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) {
|
|
switch (FixupKind) {
|
|
case FK_PCRel_4:
|
|
case X86::reloc_riprel_4byte:
|
|
case X86::reloc_riprel_4byte_movq_load:
|
|
return COFF::IMAGE_REL_I386_REL32;
|
|
case FK_Data_4:
|
|
case X86::reloc_signed_4byte:
|
|
if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
|
|
return COFF::IMAGE_REL_I386_DIR32NB;
|
|
return COFF::IMAGE_REL_I386_DIR32;
|
|
case FK_SecRel_2:
|
|
return COFF::IMAGE_REL_I386_SECTION;
|
|
case FK_SecRel_4:
|
|
return COFF::IMAGE_REL_I386_SECREL;
|
|
default:
|
|
llvm_unreachable("unsupported relocation type");
|
|
}
|
|
} else
|
|
llvm_unreachable("Unsupported COFF machine type.");
|
|
}
|
|
|
|
MCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_ostream &OS,
|
|
bool Is64Bit) {
|
|
MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit);
|
|
return createWinCOFFObjectWriter(MOTW, OS);
|
|
}
|