MC: Add partial x86-64 support to COFF.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Sat, 21 Aug 2010 05:58:13 +0000 (05:58 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Sat, 21 Aug 2010 05:58:13 +0000 (05:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111728 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCObjectWriter.h
include/llvm/Support/COFF.h
lib/MC/WinCOFFObjectWriter.cpp
lib/Target/X86/X86AsmBackend.cpp
lib/Target/X86/X86MCAsmInfo.cpp

index 22eea7e022e3f801c4fbd1fdb1a175a320b9472e..f1c1cb8a5991715d5adfe0ff24e0d8e62694d395 100644 (file)
@@ -162,7 +162,7 @@ public:
   /// @}
 };
 
-MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS);
+MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit);
 
 } // End llvm namespace
 
index a25cc78183b5c0b28123c305035a76dc495547de..bdcadf6e9f77eeb8bc7f30684583c3a0623f0144 100644 (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 {
index b7a669252c1e34c09abe492889407dba17639a6a..eab2ba97ab0f47113b6b59e48dfa65dd98241d9c 100644 (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);
   }
 }
index 6455a18a3fdf52a68ab26216085be54816b3b10e..69dc967f9d88c6a3cbbb59cb94273bf1fb1627ef 100644 (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);
   }
index 2b8720bac34385c6d621930bfe25cbc87490f566..36badb403e8155b25eda70929693c56a4fd3a124 100644 (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;