summaryrefslogtreecommitdiff
path: root/lib/MC/WinCOFFObjectWriter.cpp
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2010-08-21 05:58:13 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2010-08-21 05:58:13 +0000
commitda0bfcdaf95d95a66e306ef6d45f638939272d34 (patch)
treed33c41991aa469843f559f531320f0dc2458f4e3 /lib/MC/WinCOFFObjectWriter.cpp
parent990bdd50d17f8a05c14392cc402a7e098fd2505f (diff)
downloadllvm-da0bfcdaf95d95a66e306ef6d45f638939272d34.tar.gz
llvm-da0bfcdaf95d95a66e306ef6d45f638939272d34.tar.bz2
llvm-da0bfcdaf95d95a66e306ef6d45f638939272d34.tar.xz
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
Diffstat (limited to 'lib/MC/WinCOFFObjectWriter.cpp')
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp60
1 files changed, 43 insertions, 17 deletions
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index b7a669252c..eab2ba97ab 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 <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);
}
}