Blame SOURCES/gdb-aarch64-nextoverthrow.patch

7a6771
http://sourceware.org/ml/gdb-patches/2016-10/msg00287.html
7a6771
Subject: Re: aarch64 regression: gdb.cp/nextoverthrow.exp [Re: [PATCH master+7.12] [AArch64] Match instruction "STP with base register" in prologue]
7a6771
7a6771
Jan Kratochvil <jan.kratochvil@redhat.com> writes:
7a6771
7a6771
>> Could you open a ticket in bugzilla for this error?  I am testing a patch.
7a6771
>
7a6771
> https://sourceware.org/bugzilla/show_bug.cgi?id=20682
7a6771
7a6771
Thanks, here is the patch...
7a6771
7a6771
-- 
7a6771
Yao (齐尧)
7a6771
7a6771
>From 5794d10bcda63da8fc47d0a76c29669af83ed48b Mon Sep 17 00:00:00 2001
7a6771
From: Yao Qi <yao.qi@linaro.org>
7a6771
Date: Tue, 11 Oct 2016 12:12:46 +0100
7a6771
Subject: [PATCH] [AArch64] Track FP registers in prologue analyzer
7a6771
7a6771
We don't track FP registers in aarch64 prologue analyzer, so this causes
7a6771
an internal error when FP registers are saved by "stp" instruction in
7a6771
prologue (stp	d8, d9, [sp,#128]),
7a6771
7a6771
 tbreak _Unwind_RaiseException^M
7a6771
 aarch64-tdep.c:335: internal-error: CORE_ADDR aarch64_analyze_prologue(gdbarch*, CORE_ADDR, CORE_ADDR, aarch64_prologue_cache*): Assertion `inst.operands[0].type == AARCH64_OPND_Rt' failed.^M
7a6771
 A problem internal to GDB has been detected,
7a6771
7a6771
This patch teaches GDB to track FP registers (D registers) in prologue
7a6771
analyzer.
7a6771
7a6771
gdb:
7a6771
7a6771
2016-10-12  Yao Qi  <yao.qi@linaro.org>
7a6771
7a6771
	PR tdep/20682
7a6771
	* aarch64-tdep.c: Replace 32 with AARCH64_D_REGISTER_COUNT.
7a6771
	(aarch64_analyze_prologue): Extend array 'regs' for D registers.
7a6771
	Assert that operand 0 and 1 can be X or D registers.  Update
7a6771
	register number for D registers.  Update registers in frame
7a6771
	cache.
7a6771
	* aarch64-tdep.h (AARCH64_D_REGISTER_COUNT): New macro.
7a6771
7a6771
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
7a6771
index 16dd365..be72785 100644
7a6771
--- a/gdb/aarch64-tdep.c
7a6771
+++ b/gdb/aarch64-tdep.c
7a6771
@@ -68,7 +68,7 @@
7a6771
 
7a6771
 /* Pseudo register base numbers.  */
7a6771
 #define AARCH64_Q0_REGNUM 0
7a6771
-#define AARCH64_D0_REGNUM (AARCH64_Q0_REGNUM + 32)
7a6771
+#define AARCH64_D0_REGNUM (AARCH64_Q0_REGNUM + AARCH64_D_REGISTER_COUNT)
7a6771
 #define AARCH64_S0_REGNUM (AARCH64_D0_REGNUM + 32)
7a6771
 #define AARCH64_H0_REGNUM (AARCH64_S0_REGNUM + 32)
7a6771
 #define AARCH64_B0_REGNUM (AARCH64_H0_REGNUM + 32)
7a6771
@@ -206,11 +206,12 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
7a6771
 {
7a6771
   enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
7a6771
   int i;
7a6771
-  pv_t regs[AARCH64_X_REGISTER_COUNT];
7a6771
+  /* Track X registers and D registers in prologue.  */
7a6771
+  pv_t regs[AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT];
7a6771
   struct pv_area *stack;
7a6771
   struct cleanup *back_to;
7a6771
 
7a6771
-  for (i = 0; i < AARCH64_X_REGISTER_COUNT; i++)
7a6771
+  for (i = 0; i < AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT; i++)
7a6771
     regs[i] = pv_register (i, 0);
7a6771
   stack = make_pv_area (AARCH64_SP_REGNUM, gdbarch_addr_bit (gdbarch));
7a6771
   back_to = make_cleanup_free_pv_area (stack);
7a6771
@@ -328,13 +329,15 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
7a6771
 	       && strcmp ("stp", inst.opcode->name) == 0)
7a6771
 	{
7a6771
 	  /* STP with addressing mode Pre-indexed and Base register.  */
7a6771
-	  unsigned rt1 = inst.operands[0].reg.regno;
7a6771
-	  unsigned rt2 = inst.operands[1].reg.regno;
7a6771
+	  unsigned rt1;
7a6771
+	  unsigned rt2;
7a6771
 	  unsigned rn = inst.operands[2].addr.base_regno;
7a6771
 	  int32_t imm = inst.operands[2].addr.offset.imm;
7a6771
 
7a6771
-	  gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt);
7a6771
-	  gdb_assert (inst.operands[1].type == AARCH64_OPND_Rt2);
7a6771
+	  gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt
7a6771
+		      || inst.operands[0].type == AARCH64_OPND_Ft);
7a6771
+	  gdb_assert (inst.operands[1].type == AARCH64_OPND_Rt2
7a6771
+		      || inst.operands[1].type == AARCH64_OPND_Ft2);
7a6771
 	  gdb_assert (inst.operands[2].type == AARCH64_OPND_ADDR_SIMM7);
7a6771
 	  gdb_assert (!inst.operands[2].addr.offset.is_reg);
7a6771
 
7a6771
@@ -349,6 +352,17 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
7a6771
 					 pv_add_constant (regs[rn], imm + 8)))
7a6771
 	    break;
7a6771
 
7a6771
+	  rt1 = inst.operands[0].reg.regno;
7a6771
+	  rt2 = inst.operands[1].reg.regno;
7a6771
+	  if (inst.operands[0].type == AARCH64_OPND_Ft)
7a6771
+	    {
7a6771
+	      /* Only bottom 64-bit of each V register (D register) need
7a6771
+		 to be preserved.  */
7a6771
+	      gdb_assert (inst.operands[0].qualifier == AARCH64_OPND_QLF_S_D);
7a6771
+	      rt1 += AARCH64_X_REGISTER_COUNT;
7a6771
+	      rt2 += AARCH64_X_REGISTER_COUNT;
7a6771
+	    }
7a6771
+
7a6771
 	  pv_area_store (stack, pv_add_constant (regs[rn], imm), 8,
7a6771
 			 regs[rt1]);
7a6771
 	  pv_area_store (stack, pv_add_constant (regs[rn], imm + 8), 8,
7a6771
@@ -408,6 +422,16 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
7a6771
 	cache->saved_regs[i].addr = offset;
7a6771
     }
7a6771
 
7a6771
+  for (i = 0; i < AARCH64_D_REGISTER_COUNT; i++)
7a6771
+    {
7a6771
+      int regnum = gdbarch_num_regs (gdbarch);
7a6771
+      CORE_ADDR offset;
7a6771
+
7a6771
+      if (pv_area_find_reg (stack, gdbarch, i + AARCH64_X_REGISTER_COUNT,
7a6771
+			    &offset))
7a6771
+	cache->saved_regs[i + regnum + AARCH64_D0_REGNUM].addr = offset;
7a6771
+    }
7a6771
+
7a6771
   do_cleanups (back_to);
7a6771
   return start;
7a6771
 }
7a6771
diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h
7a6771
index a95b613..6252820 100644
7a6771
--- a/gdb/aarch64-tdep.h
7a6771
+++ b/gdb/aarch64-tdep.h
7a6771
@@ -68,6 +68,8 @@ enum aarch64_regnum
7a6771
 
7a6771
 /* Total number of general (X) registers.  */
7a6771
 #define AARCH64_X_REGISTER_COUNT 32
7a6771
+/* Total number of D registers.  */
7a6771
+#define AARCH64_D_REGISTER_COUNT 32
7a6771
 
7a6771
 /* The maximum number of modified instructions generated for one
7a6771
    single-stepped instruction.  */