Blame SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-3of7.patch

7b26da
  Message-ID: <548343C8.1020109@gmail.com>
7b26da
  Date: Sun, 07 Dec 2014 01:58:32 +0800
7b26da
  From: Wei-cheng Wang <cole945 at gmail dot com>
7b26da
  To: uweigand at de dot ibm dot com, gdb-patches at sourceware dot org
7b26da
  Subject: Re: [PATCH 1/3 v2] Process record support for PowerPC
7b26da
7b26da
  2014-12-06  Wei-cheng Wang  <cole945@gmail.com>
7b26da
7b26da
	      * rs6000-tdep.c (rs6000_in_function_epilogue_p): Rename to
7b26da
	      rs6000_in_function_epilogue_frame_p and add an argument
7b26da
	      for frame_info.
7b26da
	      (rs6000_epilogue_frame_cache, rs6000_epilogue_frame_this_id,
7b26da
	      rs6000_epilogue_frame_prev_register, rs6000_epilogue_frame_sniffer):
7b26da
	      New functions.
7b26da
	      (rs6000_epilogue_frame_unwind): New.
7b26da
	      (rs6000_gdbarch_init): Append epilogue unwinder.
7b26da
7b26da
7b26da
commit 2608dbf8a3ee666ac0a7d5d7c45611d489edcda5
7b26da
Author: Wei-cheng Wang <cole945@gmail.com>
7b26da
Date:   Sat Jan 17 14:29:16 2015 +0800
7b26da
7b26da
    Epilogue unwinder for PowerPC.
7b26da
7b26da
Index: gdb-7.6.1/gdb/rs6000-tdep.c
7b26da
===================================================================
7b26da
--- gdb-7.6.1.orig/gdb/rs6000-tdep.c
7b26da
+++ gdb-7.6.1/gdb/rs6000-tdep.c
7b26da
@@ -873,14 +873,14 @@ insn_changes_sp_or_jumps (unsigned long
7b26da
            limit for the size of an epilogue.  */
7b26da
 
7b26da
 static int
7b26da
-rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
7b26da
+rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
7b26da
+				     struct gdbarch *gdbarch, CORE_ADDR pc)
7b26da
 {
7b26da
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
7b26da
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
7b26da
   bfd_byte insn_buf[PPC_INSN_SIZE];
7b26da
   CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end;
7b26da
   unsigned long insn;
7b26da
-  struct frame_info *curfrm;
7b26da
 
7b26da
   /* Find the search limits based on function boundaries and hard limit.  */
7b26da
 
7b26da
@@ -893,8 +893,6 @@ rs6000_in_function_epilogue_p (struct gd
7b26da
   epilogue_end = pc + PPC_MAX_EPILOGUE_INSTRUCTIONS * PPC_INSN_SIZE;
7b26da
   if (epilogue_end > func_end) epilogue_end = func_end;
7b26da
 
7b26da
-  curfrm = get_current_frame ();
7b26da
-
7b26da
   /* Scan forward until next 'blr'.  */
7b26da
 
7b26da
   for (scan_pc = pc; scan_pc < epilogue_end; scan_pc += PPC_INSN_SIZE)
7b26da
@@ -935,6 +933,15 @@ rs6000_in_function_epilogue_p (struct gd
7b26da
   return 0;
7b26da
 }
7b26da
 
7b26da
+/* Implementation of gdbarch_in_function_epilogue_p.  */
7b26da
+
7b26da
+static int
7b26da
+rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
7b26da
+{
7b26da
+  return rs6000_in_function_epilogue_frame_p (get_current_frame (),
7b26da
+					      gdbarch, pc);
7b26da
+}
7b26da
+
7b26da
 /* Get the ith function argument for the current function.  */
7b26da
 static CORE_ADDR
7b26da
 rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, 
7b26da
@@ -3388,6 +3395,89 @@ static const struct frame_unwind rs6000_
7b26da
   NULL,
7b26da
   default_frame_sniffer
7b26da
 };
7b26da
+
7b26da
+static struct rs6000_frame_cache *
7b26da
+rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
7b26da
+{
7b26da
+  volatile struct gdb_exception ex;
7b26da
+  struct rs6000_frame_cache *cache;
7b26da
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
7b26da
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
7b26da
+  CORE_ADDR sp;
7b26da
+
7b26da
+  if (*this_cache)
7b26da
+    return *this_cache;
7b26da
+
7b26da
+  cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
7b26da
+  (*this_cache) = cache;
7b26da
+  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
7b26da
+
7b26da
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
7b26da
+    {
7b26da
+      /* At this point the stack looks as if we just entered the
7b26da
+	 function, and the return address is stored in LR.  */
7b26da
+      CORE_ADDR sp, lr;
7b26da
+
7b26da
+      sp = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
7b26da
+      lr = get_frame_register_unsigned (this_frame, tdep->ppc_lr_regnum);
7b26da
+
7b26da
+      cache->base = sp;
7b26da
+      cache->initial_sp = sp;
7b26da
+
7b26da
+      trad_frame_set_value (cache->saved_regs,
7b26da
+			    gdbarch_pc_regnum (gdbarch), lr);
7b26da
+    }
7b26da
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
7b26da
+    throw_exception (ex);
7b26da
+
7b26da
+  return cache;
7b26da
+}
7b26da
+
7b26da
+static void
7b26da
+rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
7b26da
+			       void **this_cache, struct frame_id *this_id)
7b26da
+{
7b26da
+  CORE_ADDR pc;
7b26da
+  struct rs6000_frame_cache *info =
7b26da
+    rs6000_epilogue_frame_cache (this_frame, this_cache);
7b26da
+
7b26da
+  pc = get_frame_func (this_frame);
7b26da
+  if (info->base == 0)
7b26da
+    (*this_id) = frame_id_build_unavailable_stack (pc);
7b26da
+  else
7b26da
+    (*this_id) = frame_id_build (info->base, pc);
7b26da
+}
7b26da
+
7b26da
+static struct value *
7b26da
+rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
7b26da
+				     void **this_cache, int regnum)
7b26da
+{
7b26da
+  struct rs6000_frame_cache *info =
7b26da
+    rs6000_epilogue_frame_cache (this_frame, this_cache);
7b26da
+  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
7b26da
+}
7b26da
+
7b26da
+static int
7b26da
+rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
7b26da
+			       struct frame_info *this_frame,
7b26da
+			       void **this_prologue_cache)
7b26da
+{
7b26da
+  if (frame_relative_level (this_frame) == 0)
7b26da
+    return rs6000_in_function_epilogue_frame_p (this_frame,
7b26da
+						get_frame_arch (this_frame),
7b26da
+						get_frame_pc (this_frame));
7b26da
+  else
7b26da
+    return 0;
7b26da
+}
7b26da
+
7b26da
+static const struct frame_unwind rs6000_epilogue_frame_unwind =
7b26da
+{
7b26da
+  NORMAL_FRAME,
7b26da
+  default_frame_unwind_stop_reason,
7b26da
+  rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
7b26da
+  NULL,
7b26da
+  rs6000_epilogue_frame_sniffer
7b26da
+};
7b26da
 
7b26da
 
7b26da
 static CORE_ADDR
7b26da
@@ -4207,6 +4297,7 @@ rs6000_gdbarch_init (struct gdbarch_info
7b26da
     case GDB_OSABI_NETBSD_ELF:
7b26da
     case GDB_OSABI_UNKNOWN:
7b26da
       set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
7b26da
+      frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
7b26da
       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
7b26da
       set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
7b26da
       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
7b26da
@@ -4215,6 +4306,7 @@ rs6000_gdbarch_init (struct gdbarch_info
7b26da
       set_gdbarch_believe_pcc_promotion (gdbarch, 1);
7b26da
 
7b26da
       set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
7b26da
+      frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
7b26da
       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
7b26da
       set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
7b26da
       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);