diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 22eea7e022e..f1c1cb8a599 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -162,7 +162,7 @@ public: /// @} }; -MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS); +MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit); } // End llvm namespace diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h index a25cc78183b..bdcadf6e9f7 100644 --- a/include/llvm/Support/COFF.h +++ b/include/llvm/Support/COFF.h @@ -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 { diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index b7a669252c1..eab2ba97ab0 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -33,6 +33,8 @@ #include "llvm/System/TimeValue.h" +#include "../Target/X86/X86FixupKinds.h" + #include 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); } } diff --git a/lib/Target/X86/X86AsmBackend.cpp b/lib/Target/X86/X86AsmBackend.cpp index 6455a18a3fd..69dc967f9d8 100644 --- a/lib/Target/X86/X86AsmBackend.cpp +++ b/lib/Target/X86/X86AsmBackend.cpp @@ -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); } diff --git a/lib/Target/X86/X86MCAsmInfo.cpp b/lib/Target/X86/X86MCAsmInfo.cpp index 2b8720bac34..36badb403e8 100644 --- a/lib/Target/X86/X86MCAsmInfo.cpp +++ b/lib/Target/X86/X86MCAsmInfo.cpp @@ -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;