summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2017-06-23 04:07:44 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2017-06-23 04:07:44 +0000
commit58173b97209bfc907dd0b47ecfc5ab7c1fe1f036 (patch)
treec05199260e332ee7793659d617a2766a84f06d04
parent4ab0f4910a2b494b89f3ea11516fb04d3f3a49c8 (diff)
downloadbcm5719-llvm-58173b97209bfc907dd0b47ecfc5ab7c1fe1f036.tar.gz
bcm5719-llvm-58173b97209bfc907dd0b47ecfc5ab7c1fe1f036.zip
COFF: Produce an error on invalid pcrel relocs.
X86_64 COFF only has support for 32 bit pcrel relocations. Produce an error on all others. Note that gnu as has extended the relocation values to support this. It is not clear if we should support the gnu extension. llvm-svn: 306082
-rw-r--r--llvm/include/llvm/MC/MCWinCOFFObjectWriter.h4
-rw-r--r--llvm/lib/MC/WinCOFFObjectWriter.cpp4
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp7
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp17
-rw-r--r--llvm/test/MC/COFF/cross-section-relative-err.s12
-rw-r--r--llvm/test/MC/COFF/cross-section-relative.s31
6 files changed, 39 insertions, 36 deletions
diff --git a/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h b/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
index 57bed213aad..6e14cefaa0a 100644
--- a/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -30,8 +30,8 @@ class raw_pwrite_stream;
virtual ~MCWinCOFFObjectTargetWriter() = default;
unsigned getMachine() const { return Machine; }
- virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsCrossSection,
+ virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsCrossSection,
const MCAsmBackend &MAB) const = 0;
virtual bool recordRelocation(const MCFixup &) const { return true; }
};
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index 8d8c5ff9b60..fc523495039 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -781,8 +781,8 @@ void WinCOFFObjectWriter::recordRelocation(
++Reloc.Symb->Relocations;
Reloc.Data.VirtualAddress += Fixup.getOffset();
- Reloc.Data.Type =
- TargetObjectWriter->getRelocType(Target, Fixup, SymB, Asm.getBackend());
+ Reloc.Data.Type = TargetObjectWriter->getRelocType(
+ Asm.getContext(), Target, Fixup, SymB, Asm.getBackend());
// FIXME: Can anyone explain what this does other than adjust for the size
// of the offset?
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp
index 00505a103e0..f74fb2e20b5 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp
@@ -33,8 +33,8 @@ public:
~ARMWinCOFFObjectWriter() override = default;
- unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsCrossSection,
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsCrossSection,
const MCAsmBackend &MAB) const override;
bool recordRelocation(const MCFixup &) const override;
@@ -42,7 +42,8 @@ public:
} // end anonymous namespace
-unsigned ARMWinCOFFObjectWriter::getRelocType(const MCValue &Target,
+unsigned ARMWinCOFFObjectWriter::getRelocType(MCContext &Ctx,
+ const MCValue &Target,
const MCFixup &Fixup,
bool IsCrossSection,
const MCAsmBackend &MAB) const {
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
index 105580c913a..5892f1de33e 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
@@ -10,6 +10,7 @@
#include "MCTargetDesc/X86FixupKinds.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCValue.h"
@@ -25,8 +26,8 @@ public:
X86WinCOFFObjectWriter(bool Is64Bit);
~X86WinCOFFObjectWriter() override = default;
- unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsCrossSection,
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsCrossSection,
const MCAsmBackend &MAB) const override;
};
@@ -36,11 +37,19 @@ X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit)
: MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64
: COFF::IMAGE_FILE_MACHINE_I386) {}
-unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
+unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,
+ const MCValue &Target,
const MCFixup &Fixup,
bool IsCrossSection,
const MCAsmBackend &MAB) const {
- unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind();
+ unsigned FixupKind = Fixup.getKind();
+ if (IsCrossSection) {
+ if (FixupKind != FK_Data_4) {
+ Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");
+ return COFF::IMAGE_REL_AMD64_ADDR32;
+ }
+ FixupKind = FK_PCRel_4;
+ }
MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
diff --git a/llvm/test/MC/COFF/cross-section-relative-err.s b/llvm/test/MC/COFF/cross-section-relative-err.s
new file mode 100644
index 00000000000..e237f60e9a3
--- /dev/null
+++ b/llvm/test/MC/COFF/cross-section-relative-err.s
@@ -0,0 +1,12 @@
+// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s
+
+
+// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: Cannot represent this expression
+ .byte foo - .
+
+// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: Cannot represent this expression
+ .short foo - .
+
+// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: Cannot represent this expression
+ .quad foo - .
+
diff --git a/llvm/test/MC/COFF/cross-section-relative.s b/llvm/test/MC/COFF/cross-section-relative.s
index 8d96c8f8df4..6f172922e9b 100644
--- a/llvm/test/MC/COFF/cross-section-relative.s
+++ b/llvm/test/MC/COFF/cross-section-relative.s
@@ -27,17 +27,14 @@ g4:
.globl t1 # @t1
.align 8
t1:
- .quad (g3-t1)+4
.globl t2 # @t2
.align 8
t2:
- .quad g3-t2
.globl t3 # @t3
.align 8
t3:
- .quad (g3-t3)-4
.globl t4 # @t4
.align 4
@@ -78,10 +75,9 @@ t6:
// READOBJ-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000)
// READOBJ-NEXT: ]
// READOBJ-NEXT: SectionData (
-// READOBJ-NEXT: 0000: 08000000 00000000 04000000 00000000 |
-// READOBJ-NEXT: 0010: 00000000 00000000 04000000 00000000 |
-// READOBJ-NEXT: 0020: 01020000 00000000 00010000 00000000 |
-// READOBJ-NEXT: 0030: 04000000 00000000 04000000 |
+// READOBJ-NEXT: 0000: 04000000 00000000 00000000 00000000 |
+// READOBJ-NEXT: 0010: 01020000 00000000 00010000 00000000 |
+// READOBJ-NEXT: 0020: 04000000 00000000 04000000 |
// READOBJ-NEXT: )
// READOBJ-NEXT: }
// READOBJ-NEXT: ]
@@ -93,32 +89,17 @@ t6:
// READOBJ-NEXT: Symbol: g3
// READOBJ-NEXT: }
// READOBJ-NEXT: Relocation {
-// READOBJ-NEXT: Offset: 0x8
-// READOBJ-NEXT: Type: IMAGE_REL_AMD64_REL32 (4)
-// READOBJ-NEXT: Symbol: g3
-// READOBJ-NEXT: }
-// READOBJ-NEXT: Relocation {
-// READOBJ-NEXT: Offset: 0x10
-// READOBJ-NEXT: Type: IMAGE_REL_AMD64_REL32 (4)
-// READOBJ-NEXT: Symbol: g3
-// READOBJ-NEXT: }
-// READOBJ-NEXT: Relocation {
-// READOBJ-NEXT: Offset: 0x18
-// READOBJ-NEXT: Type: IMAGE_REL_AMD64_REL32 (4)
-// READOBJ-NEXT: Symbol: g3
-// READOBJ-NEXT: }
-// READOBJ-NEXT: Relocation {
-// READOBJ-NEXT: Offset: 0x1C
+// READOBJ-NEXT: Offset: 0x4
// READOBJ-NEXT: Type: IMAGE_REL_AMD64_ADDR32NB (3)
// READOBJ-NEXT: Symbol: g3
// READOBJ-NEXT: }
// READOBJ-NEXT: Relocation {
-// READOBJ-NEXT: Offset: 0x30
+// READOBJ-NEXT: Offset: 0x20
// READOBJ-NEXT: Type: IMAGE_REL_AMD64_REL32 (4)
// READOBJ-NEXT: Symbol: g3
// READOBJ-NEXT: }
// READOBJ-NEXT: Relocation {
-// READOBJ-NEXT: Offset: 0x38
+// READOBJ-NEXT: Offset: 0x28
// READOBJ-NEXT: Type: IMAGE_REL_AMD64_REL32 (4)
// READOBJ-NEXT: Symbol: foobar
// READOBJ-NEXT: }
OpenPOWER on IntegriCloud