]> granicus.if.org Git - llvm/commitdiff
COFF: Produce an error on invalid pcrel relocs.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 23 Jun 2017 04:07:44 +0000 (04:07 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 23 Jun 2017 04:07:44 +0000 (04:07 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306082 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCWinCOFFObjectWriter.h
lib/MC/WinCOFFObjectWriter.cpp
lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp
lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
test/MC/COFF/cross-section-relative-err.s [new file with mode: 0644]
test/MC/COFF/cross-section-relative.s

index 57bed213aad47102c66cd9fbffcb53d0e0fe6526..6e14cefaa0abcc4639f330f7e81a8d72039333b8 100644 (file)
@@ -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; }
   };
index 8d8c5ff9b60308ed828b5d815cf456848b80b318..fc5234950391bf21c85a89f9b9530fe81e8e020d 100644 (file)
@@ -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?
index 00505a103e00ff9c851dee3da7c38dee17731d1c..f74fb2e20b5a304ff44d2342028041bcc47f9992 100644 (file)
@@ -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 {
index 105580c913a16c7d04868aa307bc5f62a80c475f..5892f1de33eece1312b916b5a694d63483d1695d 100644 (file)
@@ -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/test/MC/COFF/cross-section-relative-err.s b/test/MC/COFF/cross-section-relative-err.s
new file mode 100644 (file)
index 0000000..e237f60
--- /dev/null
@@ -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 - .
+
index 8d96c8f8df4fa417de30d232bce09c59fe75665b..6f172922e9b8ed9d86b89cf67503a459a337cd49 100644 (file)
@@ -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:    }