MC: Add partial x86-64 support to COFF.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111728 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Michael J. Spencer 2010-08-21 05:58:13 +00:00
parent 990bdd50d1
commit da0bfcdaf9
5 changed files with 58 additions and 23 deletions

View File

@ -162,7 +162,7 @@ public:
/// @}
};
MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS);
MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit);
} // End llvm namespace

View File

@ -50,7 +50,7 @@ namespace COFF {
enum MachineTypes {
IMAGE_FILE_MACHINE_I386 = 0x14C,
IMAGINE_FILE_MACHINE_AMD64 = 0x8664
IMAGE_FILE_MACHINE_AMD64 = 0x8664
};
struct symbol {

View File

@ -33,6 +33,8 @@
#include "llvm/System/TimeValue.h"
#include "../Target/X86/X86FixupKinds.h"
#include <cstdio>
using namespace llvm;
@ -132,7 +134,7 @@ public:
section_map SectionMap;
symbol_map SymbolMap;
WinCOFFObjectWriter(raw_ostream &OS);
WinCOFFObjectWriter(raw_ostream &OS, bool is64Bit);
~WinCOFFObjectWriter();
COFFSymbol *createSymbol(llvm::StringRef Name);
@ -271,11 +273,12 @@ size_t StringTable::insert(llvm::StringRef String) {
//------------------------------------------------------------------------------
// WinCOFFObjectWriter class implementation
WinCOFFObjectWriter::WinCOFFObjectWriter(raw_ostream &OS)
WinCOFFObjectWriter::WinCOFFObjectWriter(raw_ostream &OS, bool is64Bit)
: MCObjectWriter(OS, true) {
memset(&Header, 0, sizeof(Header));
// TODO: Move magic constant out to COFF.h
Header.Machine = 0x14C; // x86
is64Bit ? Header.Machine = COFF::IMAGE_FILE_MACHINE_AMD64
: Header.Machine = COFF::IMAGE_FILE_MACHINE_I386;
}
WinCOFFObjectWriter::~WinCOFFObjectWriter() {
@ -587,17 +590,40 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
Reloc.Data.VirtualAddress += Fixup.getOffset();
switch (Fixup.getKind()) {
case FirstTargetFixupKind: // reloc_pcrel_4byte
Reloc.Data.Type = COFF::IMAGE_REL_I386_REL32;
FixedValue += 4;
break;
case FK_Data_4:
Reloc.Data.Type = COFF::IMAGE_REL_I386_DIR32;
break;
default:
llvm_unreachable("unsupported relocation type");
}
COFF::RelocationTypeX86 Type;
if (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386) {
switch (Fixup.getKind()) {
case X86::reloc_pcrel_4byte:
Type = COFF::IMAGE_REL_I386_REL32;
FixedValue += 4;
break;
case FK_Data_4:
Type = COFF::IMAGE_REL_I386_DIR32;
break;
default:
llvm_unreachable("unsupported relocation type");
}
} else if (Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64) {
switch (Fixup.getKind()) {
case FK_Data_8:
Type = COFF::IMAGE_REL_AMD64_ADDR64;
break;
case X86::reloc_pcrel_4byte:
case X86::reloc_riprel_4byte:
Type = COFF::IMAGE_REL_AMD64_REL32;
FixedValue += 4;
break;
case FK_Data_4:
Type = COFF::IMAGE_REL_AMD64_ADDR32;
break;
default:
llvm_unreachable("unsupported relocation type");
}
} else
llvm_unreachable("unknown target architecture");
Reloc.Data.Type = Type;
coff_section->Relocations.push_back(Reloc);
}
@ -739,7 +765,7 @@ void WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm,
// WinCOFFObjectWriter factory function
namespace llvm {
MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS) {
return new WinCOFFObjectWriter(OS);
MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit) {
return new WinCOFFObjectWriter(OS, is64Bit);
}
}

View File

@ -223,14 +223,16 @@ public:
};
class WindowsX86AsmBackend : public X86AsmBackend {
bool Is64Bit;
public:
WindowsX86AsmBackend(const Target &T)
: X86AsmBackend(T) {
WindowsX86AsmBackend(const Target &T, bool is64Bit)
: X86AsmBackend(T)
, Is64Bit(is64Bit) {
HasScatteredSymbols = true;
}
MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
return createWinCOFFObjectWriter (OS);
return createWinCOFFObjectWriter(OS, Is64Bit);
}
bool isVirtualSection(const MCSection &Section) const {
@ -320,7 +322,7 @@ TargetAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
case Triple::MinGW32:
case Triple::Cygwin:
case Triple::Win32:
return new WindowsX86AsmBackend(T);
return new WindowsX86AsmBackend(T, false);
default:
return new ELFX86_32AsmBackend(T);
}
@ -331,6 +333,10 @@ TargetAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
switch (Triple(TT).getOS()) {
case Triple::Darwin:
return new DarwinX86_64AsmBackend(T);
case Triple::MinGW64:
case Triple::Cygwin:
case Triple::Win32:
return new WindowsX86AsmBackend(T, true);
default:
return new ELFX86_64AsmBackend(T);
}

View File

@ -103,6 +103,9 @@ getNonexecutableStackSection(MCContext &Ctx) const {
}
X86MCAsmInfoCOFF::X86MCAsmInfoCOFF(const Triple &Triple) {
if (Triple.getArch() == Triple::x86_64)
GlobalPrefix = "";
AsmTransCBE = x86_asm_table;
AssemblerDialect = AsmWriterFlavor;