This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch rfc] unwind sentinel id/pc


Hello,

Following on from my recent post to add an unwind_dummy_id() method, this code adds architecture specific methods to handle the edge case of unwinding the sentinel frame's PC/ID.

While I'm pretty sure that the methods are needed, I'm not 100% certain of their interfaces. The attached has:

unwind_sentinel_id(arch, regcache, unwind_cache)

I'm wondering if, instead it should use something like:

unwind_sentinel_id(arch, tpid, unwind_cache)

where a new method:

tpid_regcache (tpid)

could be used to obtain the tpid's register cache. I'm thinking this since, for the case of the i386, it may need the thread's state in addition to registers when determing the `pc'.

Anyway, I'm going to table this for a bit.
Andrew
2003-03-02  Andrew Cagney  <cagney at redhat dot com>

	* gdbarch.sh (UNWIND_SENTINEL_ID, UNWIND_SENTINEL_PC): New
	multi-arch methods with predicate.
	* gdbarch.h, gdbarch.c: Regenerate.
	* d10v-tdep.c (d10v_unwind_sentinel_id): New function.
	(d10v_unwind_sentinel_pc): New function.
	(d10v_gdbarch_init): Set unwind_sentinel_id and
	unwind_sentinel_pc.
	* sentinel-frame.c (struct frame_unwind_cache): Add field cache.
	(sentinel_frame_pc_unwind): Use gdbarch_unwind_sentinel_pc.
	(sentinel_frame_id_unwind): Use gdbarch_unwind_sentinel_id.

Index: d10v-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/d10v-tdep.c,v
retrieving revision 1.79
diff -u -r1.79 d10v-tdep.c
--- d10v-tdep.c	1 Mar 2003 17:59:12 -0000	1.79
+++ d10v-tdep.c	2 Mar 2003 20:11:11 -0000
@@ -920,6 +920,15 @@
   return retval;
 }
 
+static CORE_ADDR
+d10v_unwind_sentinel_pc (struct gdbarch *gdbarch, struct regcache *regcache,
+			 void **cache)
+{
+  ULONGEST tmp;
+  regcache_cooked_read_unsigned (regcache, PC_REGNUM, &tmp);
+  return d10v_make_iaddr (tmp);
+}
+
 static void
 d10v_write_pc (CORE_ADDR val, ptid_t ptid)
 {
@@ -949,6 +958,19 @@
   return (d10v_make_daddr (read_register (FP_REGNUM)));
 }
 
+static struct frame_id
+d10v_unwind_sentinel_id (struct gdbarch *gdbarch, struct regcache *regcache,
+			 void **cache)
+{
+  ULONGEST tmp;
+  struct frame_id id;
+  regcache_cooked_read_unsigned (regcache, FP_REGNUM, &tmp);
+  id.base = d10v_make_daddr (tmp);
+  regcache_cooked_read_unsigned (regcache, PC_REGNUM, &tmp);
+  id.pc = d10v_make_iaddr (tmp);
+  return id;
+}
+
 /* Function: push_return_address (pc)
    Set up the return address for the inferior function call.
    Needed for targets where we don't actually execute a JSR/BSR instruction */
@@ -1639,6 +1661,9 @@
   set_gdbarch_read_fp (gdbarch, d10v_read_fp);
   set_gdbarch_read_sp (gdbarch, d10v_read_sp);
   set_gdbarch_write_sp (gdbarch, d10v_write_sp);
+
+  set_gdbarch_unwind_sentinel_id (gdbarch, d10v_unwind_sentinel_id);
+  set_gdbarch_unwind_sentinel_pc (gdbarch, d10v_unwind_sentinel_pc);
 
   set_gdbarch_num_regs (gdbarch, d10v_num_regs);
   set_gdbarch_sp_regnum (gdbarch, 15);
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.198
diff -u -r1.198 gdbarch.sh
--- gdbarch.sh	2 Mar 2003 04:02:23 -0000	1.198
+++ gdbarch.sh	2 Mar 2003 20:11:38 -0000
@@ -431,6 +431,10 @@
 f:2:TARGET_READ_FP:CORE_ADDR:read_fp:void:::0:generic_target_read_fp::0
 f:2:TARGET_READ_SP:CORE_ADDR:read_sp:void:::0:generic_target_read_sp::0
 f:2:TARGET_WRITE_SP:void:write_sp:CORE_ADDR val:val::0:generic_target_write_sp::0
+# Unwind the sentinel frame's ID/PC returning the PC/ID of the inner
+# most frame.
+M::UNWIND_SENTINEL_ID:struct frame_id:unwind_sentinel_id:struct regcache *regcache, void **cache:regcache, cache::0:0
+M::UNWIND_SENTINEL_PC:CORE_ADDR:unwind_sentinel_pc:struct regcache *regcache, void **cache:regcache, cache::0:0
 # Function for getting target's idea of a frame pointer.  FIXME: GDB's
 # whole scheme for dealing with "frames" and "frame pointers" needs a
 # serious shakedown.
Index: sentinel-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/sentinel-frame.c,v
retrieving revision 1.2
diff -u -r1.2 sentinel-frame.c
--- sentinel-frame.c	27 Jan 2003 21:41:41 -0000	1.2
+++ sentinel-frame.c	2 Mar 2003 20:11:40 -0000
@@ -31,6 +31,7 @@
 struct frame_unwind_cache
 {
   struct regcache *regcache;
+  void *cache;
 };
 
 void *
@@ -72,26 +73,44 @@
 
 CORE_ADDR
 sentinel_frame_pc_unwind (struct frame_info *frame,
-			  void **cache)
+			  void **unwind_cache)
 {
-  /* FIXME: cagney/2003-01-08: This should be using a per-architecture
-     method that doesn't suffer from DECR_PC_AFTER_BREAK problems.
-     Such a method would take unwind_cache, regcache and stop reason
-     parameters.  */
-  return read_pc ();
+  struct frame_unwind_cache *cache = *unwind_cache;
+  if (gdbarch_unwind_sentinel_pc_p (current_gdbarch))
+    {
+      return gdbarch_unwind_sentinel_pc (current_gdbarch, cache->regcache,
+					 &cache->cache);
+    }
+  else
+    {
+      /* FIXME: cagney/2003-01-08: This should be using a
+	 per-architecture method that doesn't suffer from
+	 DECR_PC_AFTER_BREAK problems.  Such a method would take
+	 unwind_cache, regcache and stop reason parameters.  */
+      return read_pc ();
+    }
 }
 
 void
 sentinel_frame_id_unwind (struct frame_info *frame,
-			  void **cache,
+			  void **unwind_cache,
 			  struct frame_id *id)
 {
-  /* FIXME: cagney/2003-01-08: This should be using a per-architecture
-     method that doesn't suffer from DECR_PC_AFTER_BREAK problems.
-     Such a method would take unwind_cache, regcache and stop reason
-     parameters.  */
-  id->base = read_fp ();
-  id->pc = read_pc ();
+  struct frame_unwind_cache *cache = *unwind_cache;
+  if (gdbarch_unwind_sentinel_id_p (current_gdbarch))
+    {
+      (*id) = gdbarch_unwind_sentinel_id (current_gdbarch, cache->regcache,
+					  &cache->cache);
+    }
+  else
+    {
+      /* FIXME: cagney/2003-01-08: This should be using a
+	 per-architecture method that doesn't suffer from
+	 DECR_PC_AFTER_BREAK problems.  Such a method would take
+	 unwind_cache, regcache and stop reason parameters.  */
+      id->base = read_fp ();
+      id->pc = read_pc ();
+    }
 }
 
 static void

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]