[PATCH] MC: Support COFF image-relative MCSymbolRefs
Nico Rieck
nico.rieck at gmail.com
Fri Apr 5 15:52:42 PDT 2013
Add support for the COFF relocation types IMAGE_REL_I386_DIR32NB and
IMAGE_REL_AMD64_ADDR32NB for 32- and 64-bit respectively. These are
similar to normal 4-byte relocations except that they do not include
the base address of the image.
Image-relative relocations are used for debug information (32-bit) and
SEH unwind tables (64-bit).
A new MCSymbolRef variant called 'VK_COFF_IMGREL32' is introduced to
specify such relocations. For AT&T assembly, this variant can be accessed
using the symbol suffix '@imgrel'.
http://llvm-reviews.chandlerc.com/D635
Files:
include/llvm/MC/MCExpr.h
include/llvm/MC/MCWinCOFFObjectWriter.h
lib/MC/MCExpr.cpp
lib/MC/WinCOFFObjectWriter.cpp
lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
test/MC/COFF/relocation-imgrel.s
Index: include/llvm/MC/MCExpr.h
===================================================================
--- include/llvm/MC/MCExpr.h
+++ include/llvm/MC/MCExpr.h
@@ -216,7 +216,9 @@
VK_Mips_GOT_HI16,
VK_Mips_GOT_LO16,
VK_Mips_CALL_HI16,
- VK_Mips_CALL_LO16
+ VK_Mips_CALL_LO16,
+
+ VK_COFF_IMGREL32 // symbol at imgrel (image-relative)
};
private:
Index: include/llvm/MC/MCWinCOFFObjectWriter.h
===================================================================
--- include/llvm/MC/MCWinCOFFObjectWriter.h
+++ include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -11,7 +11,9 @@
#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
namespace llvm {
+ class MCFixup;
class MCObjectWriter;
+ class MCValue;
class raw_ostream;
class MCWinCOFFObjectTargetWriter {
@@ -24,7 +26,9 @@
virtual ~MCWinCOFFObjectTargetWriter() {}
unsigned getMachine() const { return Machine; }
- virtual unsigned getRelocType(unsigned FixupKind) const = 0;
+ virtual unsigned getRelocType(const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsCrossSection) const = 0;
};
/// \brief Construct a new Win COFF writer instance.
Index: lib/MC/MCExpr.cpp
===================================================================
--- lib/MC/MCExpr.cpp
+++ lib/MC/MCExpr.cpp
@@ -250,6 +250,7 @@
case VK_Mips_GOT_LO16: return "GOT_LO16";
case VK_Mips_CALL_HI16: return "CALL_HI16";
case VK_Mips_CALL_LO16: return "CALL_LO16";
+ case VK_COFF_IMGREL32: return "IMGREL32";
}
llvm_unreachable("Invalid variant kind");
}
@@ -285,6 +286,8 @@
.Case("dtpoff", VK_DTPOFF)
.Case("TLVP", VK_TLVP)
.Case("tlvp", VK_TLVP)
+ .Case("IMGREL", VK_COFF_IMGREL32)
+ .Case("imgrel", VK_COFF_IMGREL32)
.Default(VK_Invalid);
}
Index: lib/MC/WinCOFFObjectWriter.cpp
===================================================================
--- lib/MC/WinCOFFObjectWriter.cpp
+++ lib/MC/WinCOFFObjectWriter.cpp
@@ -689,13 +689,8 @@
++Reloc.Symb->Relocations;
Reloc.Data.VirtualAddress += Fixup.getOffset();
-
- unsigned FixupKind = Fixup.getKind();
-
- if (CrossSection)
- FixupKind = FK_PCRel_4;
-
- Reloc.Data.Type = TargetObjectWriter->getRelocType(FixupKind);
+ Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup,
+ CrossSection);
// FIXME: Can anyone explain what this does other than adjust for the size
// of the offset?
Index: lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
===================================================================
--- lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
+++ lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
@@ -9,6 +9,8 @@
#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"
@@ -27,7 +29,9 @@
X86WinCOFFObjectWriter(bool Is64Bit_);
~X86WinCOFFObjectWriter();
- virtual unsigned getRelocType(unsigned FixupKind) const;
+ virtual unsigned getRelocType(const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsCrossSection) const LLVM_OVERRIDE;
};
}
@@ -38,14 +42,24 @@
X86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {}
-unsigned X86WinCOFFObjectWriter::getRelocType(unsigned FixupKind) const {
+unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsCrossSection) const {
+ unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind();
+
+ MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
+ MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
+
switch (FixupKind) {
case FK_PCRel_4:
case X86::reloc_riprel_4byte:
case X86::reloc_riprel_4byte_movq_load:
return Is64Bit ? COFF::IMAGE_REL_AMD64_REL32 : COFF::IMAGE_REL_I386_REL32;
case FK_Data_4:
case X86::reloc_signed_4byte:
+ if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
+ return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32NB :
+ COFF::IMAGE_REL_I386_DIR32NB;
return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32 : COFF::IMAGE_REL_I386_DIR32;
case FK_Data_8:
if (Is64Bit)
Index: test/MC/COFF/relocation-imgrel.s
===================================================================
--- /dev/null
+++ test/MC/COFF/relocation-imgrel.s
@@ -0,0 +1,29 @@
+// COFF Image-relative relocations
+//
+// Test that we produce image-relative relocations (IMAGE_REL_I386_DIR32NB
+// and IMAGE_REL_AMD64_ADDR32NB) when accessing foo at imgrel.
+
+// RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s | llvm-readobj -r | FileCheck --check-prefix=W32 %s
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s | llvm-readobj -r | FileCheck --check-prefix=W64 %s
+
+.data
+foo:
+ .long 1
+
+.text
+ mov foo at IMGREL(%ebx, %ecx, 4), %eax
+ mov foo at imgrel(%ebx, %ecx, 4), %eax
+
+// W32: Relocations [
+// W32-NEXT: Section (1) .text {
+// W32-NEXT: 0x3 IMAGE_REL_I386_DIR32NB foo
+// W32-NEXT: 0xA IMAGE_REL_I386_DIR32NB foo
+// W32-NEXT: }
+// W32-NEXT: ]
+
+// W64: Relocations [
+// W64-NEXT: Section (1) .text {
+// W64-NEXT: 0x4 IMAGE_REL_AMD64_ADDR32NB foo
+// W64-NEXT: 0xC IMAGE_REL_AMD64_ADDR32NB foo
+// W64-NEXT: }
+// W64-NEXT: ]
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D635.1.patch
Type: text/x-patch
Size: 5588 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130405/a39ad66a/attachment.bin>
More information about the llvm-commits
mailing list