ARM: fail less catastrophically on invalid Windows input
authorSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 22 Jan 2015 04:03:32 +0000 (04:03 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 22 Jan 2015 04:03:32 +0000 (04:03 +0000)
Windows supports a restricted set of relocations (compared to ARM ELF).  In some
cases, we may end up generating an unsupported relocation.  This can occur with
bad input to the assembler in particular (the frontend should never generate
code that cannot be compiled).  Generate an error rather than just aborting.

The change in the API is driven by the desire to provide a slightly more helpful
message for debugging purposes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226779 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/ARM/Windows/invalid-relocation.s [new file with mode: 0644]

index dad7bb597039ba31039eeea1d84ab57518b9b9ea..956e43642c35f4e3d2cb569c0444b8d74c392f64 100644 (file)
 #define LLVM_MC_MCWINCOFFOBJECTWRITER_H
 
 namespace llvm {
-  class MCFixup;
-  class MCObjectWriter;
-  class MCValue;
-  class raw_ostream;
+class MCAsmBackend;
+class MCFixup;
+class MCObjectWriter;
+class MCValue;
+class raw_ostream;
 
   class MCWinCOFFObjectTargetWriter {
     virtual void anchor();
@@ -27,9 +28,9 @@ namespace llvm {
     virtual ~MCWinCOFFObjectTargetWriter() {}
 
     unsigned getMachine() const { return Machine; }
-    virtual unsigned getRelocType(const MCValue &Target,
-                                  const MCFixup &Fixup,
-                                  bool IsCrossSection) const = 0;
+    virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
+                                  bool IsCrossSection,
+                                  const MCAsmBackend &MAB) const = 0;
     virtual bool recordRelocation(const MCFixup &) const { return true; }
   };
 
index d8729bdbc4bbd017779b190328ca840628d2f5a2..bd750af5de46ffa14f9baf5f6a4df47b1b6d088b 100644 (file)
@@ -737,8 +737,9 @@ void WinCOFFObjectWriter::RecordRelocation(
   ++Reloc.Symb->Relocations;
 
   Reloc.Data.VirtualAddress += Fixup.getOffset();
-  Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup,
-                                                     CrossSection);
+  Reloc.Data.Type =
+      TargetObjectWriter->getRelocType(Target, Fixup, CrossSection,
+                                       Asm.getBackend());
 
   // FIXME: Can anyone explain what this does other than adjust for the size
   // of the offset?
index d31f1f41c697f99c492bf3bfb8fd2dc12a6a648e..2ee0e511b53f2a3fcf3423aa6b23dfb6fd102c5a 100644 (file)
@@ -8,9 +8,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "MCTargetDesc/ARMFixupKinds.h"
+#include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFixupKindInfo.h"
 #include "llvm/MC/MCValue.h"
 #include "llvm/MC/MCWinCOFFObjectWriter.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/COFF.h"
 #include "llvm/Support/Debug.h"
 
@@ -26,14 +29,16 @@ public:
   virtual ~ARMWinCOFFObjectWriter() { }
 
   unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
-                        bool IsCrossSection) const override;
+                        bool IsCrossSection,
+                        const MCAsmBackend &MAB) const override;
 
   bool recordRelocation(const MCFixup &) const override;
 };
 
 unsigned ARMWinCOFFObjectWriter::getRelocType(const MCValue &Target,
                                               const MCFixup &Fixup,
-                                              bool IsCrossSection) const {
+                                              bool IsCrossSection,
+                                              const MCAsmBackend &MAB) const {
   assert(getMachine() == COFF::IMAGE_FILE_MACHINE_ARMNT &&
          "AArch64 support not yet implemented");
 
@@ -41,7 +46,10 @@ unsigned ARMWinCOFFObjectWriter::getRelocType(const MCValue &Target,
     Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
 
   switch (static_cast<unsigned>(Fixup.getKind())) {
-  default: llvm_unreachable("unsupported relocation type");
+  default: {
+    const MCFixupKindInfo &Info = MAB.getFixupKindInfo(Fixup.getKind());
+    report_fatal_error(Twine("unsupported relocation type: ") + Info.Name);
+  }
   case FK_Data_4:
     switch (Modifier) {
     case MCSymbolRefExpr::VK_COFF_IMGREL32:
index 40af822953c47264e6c47348659f2a3e017cee5e..e1df5c2d3c77d098dd9c8363801bdd67797e4912 100644 (file)
@@ -28,7 +28,8 @@ namespace {
     virtual ~X86WinCOFFObjectWriter();
 
     unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
-                          bool IsCrossSection) const override;
+                          bool IsCrossSection,
+                          const MCAsmBackend &MAB) const override;
   };
 }
 
@@ -40,7 +41,8 @@ X86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {}
 
 unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
                                               const MCFixup &Fixup,
-                                              bool IsCrossSection) const {
+                                              bool IsCrossSection,
+                                              const MCAsmBackend &MAB) const {
   unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind();
 
   MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
diff --git a/test/MC/ARM/Windows/invalid-relocation.s b/test/MC/ARM/Windows/invalid-relocation.s
new file mode 100644 (file)
index 0000000..4f4c598
--- /dev/null
@@ -0,0 +1,14 @@
+# RUN: not llvm-mc -triple thumbv7-windows -filetype obj -o /dev/null 2>&1 %s \
+# RUN:     | FileCheck %s
+
+       .def invalid_relocation
+               .type 32
+               .scl 2
+       .endef
+       .global invalid_relocation
+       .thumb_func
+invalid_relocation:
+       adr r0, invalid_relocation+1
+
+# CHECK: LLVM ERROR: unsupported relocation type: fixup_t2_adr_pcrel_12
+