[VE] Change error handling of data references
authorKazushi (Jam) Marukawa <marukawa@nec.com>
Sun, 5 Dec 2021 17:25:44 +0000 (02:25 +0900)
committerKazushi (Jam) Marukawa <marukawa@nec.com>
Wed, 8 Dec 2021 12:06:57 +0000 (21:06 +0900)
Change to use Ctx.reportError() instead of llvm_unreachable for
better error handling.  Also correct evaluateAsRelocatableImpl().

Reviewed By: simoll

Differential Revision: https://reviews.llvm.org/D115251

llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp
llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp
llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp
llvm/test/MC/VE/data-reloc-error.s [new file with mode: 0644]
llvm/test/MC/VE/data-reloc.s [new file with mode: 0644]

index c1d18dc..3b0a469 100644 (file)
@@ -9,6 +9,7 @@
 #include "VEFixupKinds.h"
 #include "VEMCExpr.h"
 #include "VEMCTargetDesc.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCObjectWriter.h"
@@ -46,16 +47,26 @@ unsigned VEELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
   if (IsPCRel) {
     switch (Fixup.getTargetKind()) {
     default:
-      llvm_unreachable("Unimplemented fixup -> relocation");
+      Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");
+      return ELF::R_VE_NONE;
+    case FK_Data_1:
     case FK_PCRel_1:
-      llvm_unreachable("Unimplemented fixup fk_data_1 -> relocation");
+      Ctx.reportError(Fixup.getLoc(),
+                      "1-byte pc-relative data relocation is not supported");
+      return ELF::R_VE_NONE;
+    case FK_Data_2:
     case FK_PCRel_2:
-      llvm_unreachable("Unimplemented fixup fk_data_2 -> relocation");
-    // FIXME: relative kind?
+      Ctx.reportError(Fixup.getLoc(),
+                      "2-byte pc-relative data relocation is not supported");
+      return ELF::R_VE_NONE;
+    case FK_Data_4:
     case FK_PCRel_4:
-      return ELF::R_VE_REFLONG;
+      return ELF::R_VE_SREL32;
+    case FK_Data_8:
     case FK_PCRel_8:
-      return ELF::R_VE_REFQUAD;
+      Ctx.reportError(Fixup.getLoc(),
+                      "8-byte pc-relative data relocation is not supported");
+      return ELF::R_VE_NONE;
     case VE::fixup_ve_srel32:
       return ELF::R_VE_SREL32;
     case VE::fixup_ve_pc_hi32:
@@ -67,11 +78,14 @@ unsigned VEELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
 
   switch (Fixup.getTargetKind()) {
   default:
-    llvm_unreachable("Unimplemented fixup -> relocation");
+    Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
+    return ELF::R_VE_NONE;
   case FK_Data_1:
-    llvm_unreachable("Unimplemented fixup fk_data_1 -> relocation");
+    Ctx.reportError(Fixup.getLoc(), "1-byte data relocation is not supported");
+    return ELF::R_VE_NONE;
   case FK_Data_2:
-    llvm_unreachable("Unimplemented fixup fk_data_2 -> relocation");
+    Ctx.reportError(Fixup.getLoc(), "2-byte data relocation is not supported");
+    return ELF::R_VE_NONE;
   case FK_Data_4:
     return ELF::R_VE_REFLONG;
   case FK_Data_8:
@@ -79,15 +93,21 @@ unsigned VEELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
   case VE::fixup_ve_reflong:
     return ELF::R_VE_REFLONG;
   case VE::fixup_ve_srel32:
-    llvm_unreachable("Unimplemented fixup pc_hi32 -> relocation");
+    Ctx.reportError(Fixup.getLoc(),
+                    "A non pc-relative srel32 relocation is not supported");
+    return ELF::R_VE_NONE;
   case VE::fixup_ve_hi32:
     return ELF::R_VE_HI32;
   case VE::fixup_ve_lo32:
     return ELF::R_VE_LO32;
   case VE::fixup_ve_pc_hi32:
-    llvm_unreachable("Unimplemented fixup pc_hi32 -> relocation");
+    Ctx.reportError(Fixup.getLoc(),
+                    "A non pc-relative pc_hi32 relocation is not supported");
+    return ELF::R_VE_NONE;
   case VE::fixup_ve_pc_lo32:
-    llvm_unreachable("Unimplemented fixup pc_lo32 -> relocation");
+    Ctx.reportError(Fixup.getLoc(),
+                    "A non pc-relative pc_lo32 relocation is not supported");
+    return ELF::R_VE_NONE;
   case VE::fixup_ve_got_hi32:
     return ELF::R_VE_GOT_HI32;
   case VE::fixup_ve_got_lo32:
index 878a3f6..65bb0cf 100644 (file)
@@ -102,11 +102,11 @@ unsigned VEMCCodeEmitter::getMachineOpValue(const MCInst &MI,
                                             const MCSubtargetInfo &STI) const {
   if (MO.isReg())
     return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
-
   if (MO.isImm())
-    return MO.getImm();
+    return static_cast<unsigned>(MO.getImm());
 
   assert(MO.isExpr());
+
   const MCExpr *Expr = MO.getExpr();
   if (const VEMCExpr *SExpr = dyn_cast<VEMCExpr>(Expr)) {
     MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
index a3ce3b3..4d45918 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "VEMCExpr.h"
+#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCObjectStreamer.h"
 #include "llvm/MC/MCSymbolELF.h"
-#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/MCValue.h"
 
 using namespace llvm;
 
@@ -174,7 +175,13 @@ VE::Fixups VEMCExpr::getFixupKind(VEMCExpr::VariantKind Kind) {
 bool VEMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
                                          const MCAsmLayout *Layout,
                                          const MCFixup *Fixup) const {
-  return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
+  if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup))
+    return false;
+
+  Res =
+      MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
+
+  return true;
 }
 
 static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
diff --git a/llvm/test/MC/VE/data-reloc-error.s b/llvm/test/MC/VE/data-reloc-error.s
new file mode 100644 (file)
index 0000000..e312ac4
--- /dev/null
@@ -0,0 +1,26 @@
+# RUN: not llvm-mc -filetype=obj -triple=ve %s -o /dev/null 2>&1 | \
+# RUN:     FileCheck %s
+# RUN: not llvm-mc -filetype=obj -triple=ve -position-independent %s \
+# RUN:     -o /dev/null 2>&1 | FileCheck %s
+
+.data
+a:
+## An undefined reference of _GLOBAL_OFFSET_TABLE_ causes .got[0] to be
+## allocated to store _DYNAMIC.
+.byte _GLOBAL_OFFSET_TABLE_
+.byte _GLOBAL_OFFSET_TABLE_ - .
+.2byte _GLOBAL_OFFSET_TABLE_
+.2byte _GLOBAL_OFFSET_TABLE_ - .
+.8byte _GLOBAL_OFFSET_TABLE_ - .
+
+# CHECK:      data-reloc-error.s:10:7: error: 1-byte data relocation is not supported
+# CHECK-NEXT: .byte _GLOBAL_OFFSET_TABLE_
+# CHECK:      data-reloc-error.s:11:7: error: 1-byte pc-relative data relocation is not supported
+# CHECK-NEXT: .byte _GLOBAL_OFFSET_TABLE_ - .
+# CHECK:      data-reloc-error.s:12:8: error: 2-byte data relocation is not supported
+# CHECK-NEXT: .2byte _GLOBAL_OFFSET_TABLE_
+# CHECK:      data-reloc-error.s:13:8: error: 2-byte pc-relative data relocation is not supported
+# CHECK-NEXT: .2byte _GLOBAL_OFFSET_TABLE_ - .
+# CHECK:      data-reloc-error.s:14:8: error: 8-byte pc-relative data relocation is not supported
+# CHECK-NEXT: .8byte _GLOBAL_OFFSET_TABLE_ - .
+
diff --git a/llvm/test/MC/VE/data-reloc.s b/llvm/test/MC/VE/data-reloc.s
new file mode 100644 (file)
index 0000000..e64a436
--- /dev/null
@@ -0,0 +1,16 @@
+# RUN: llvm-mc -triple=ve -filetype=obj %s -o - | \
+# RUN:     llvm-objdump -r - | FileCheck %s
+# RUN: llvm-mc -triple=ve -filetype=obj -position-independent %s -o - | \
+# RUN:     llvm-objdump -r - | FileCheck %s
+
+.data
+a:
+## An undefined reference of _GLOBAL_OFFSET_TABLE_ causes .got[0] to be
+## allocated to store _DYNAMIC.
+.4byte _GLOBAL_OFFSET_TABLE_ - 8
+.4byte _GLOBAL_OFFSET_TABLE_ - . - 8
+.8byte _GLOBAL_OFFSET_TABLE_ - 8
+
+# CHECK: 0000000000000000 R_VE_REFLONG _GLOBAL_OFFSET_TABLE_-0x8
+# CHECK: 0000000000000004 R_VE_SREL32 _GLOBAL_OFFSET_TABLE_-0x8
+# CHECK: 0000000000000008 R_VE_REFQUAD _GLOBAL_OFFSET_TABLE_-0x8