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] More generic unwinders


Hello,

This patch (based on my tramp branch) extends frame-unwind so that it is easier to parameterize an unwinder with both static (unwind_data) and dynamic (this_prologue_cache) information. It does this by adding a "static" method (i.e., callable before an instance of the unwinder has been created) to the frame_unwind object.

I've now managed to trim things back to the point where no existing code is affected. With this in place it becomes possible to implement the tramp frame.

I previously posted a draft version of this patch here:
http://sources.redhat.com/ml/gdb-patches/2004-03/msg00353.html

Baring comments, I'll look to commit in a few days,
Andrew
2004-03-17  Andrew Cagney  <cagney@redhat.com>

	* frame-unwind.h: Update copyright.
	(struct frame_data): Add opaque declaration.
	(frame_sniffer_ftype): Declare.
	(struct frame_unwind): Add "unwind_data" and "sniffer".
	(frame_unwind_register_unwinder): Declare.
	(frame_unwind_find_by_frame): Add parameter "this_cache".
	* frame-unwind.c (struct frame_unwind_table_entry): Add field
	"unwinder".
	(frame_unwind_register_unwinder): New function.
	(frame_unwind_find_by_frame): Handle an unwind sniffer.
	* frame.c (get_frame_id, create_new_frame, legacy_get_prev_frame)
	(legacy_get_prev_frame, legacy_get_prev_frame)
	(get_frame_type): Pass the prologue_cache to
	frame_unwind_find_by_frame.

Index: frame-unwind.c
===================================================================
RCS file: /cvs/src/src/gdb/frame-unwind.c,v
retrieving revision 1.10
diff -u -r1.10 frame-unwind.c
--- frame-unwind.c	15 Mar 2004 23:08:28 -0000	1.10
+++ frame-unwind.c	18 Mar 2004 22:29:48 -0000
@@ -31,6 +31,7 @@
 struct frame_unwind_table_entry
 {
   frame_unwind_sniffer_ftype *sniffer;
+  const struct frame_unwind *unwinder;
   struct frame_unwind_table_entry *next;
 };
 
@@ -61,8 +62,19 @@
   table->tail = &((*table->tail)->next);
 }
 
+void
+frame_unwind_register_unwinder (struct gdbarch *gdbarch,
+				const struct frame_unwind *unwinder)
+{
+  struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
+  (*table->tail) = GDBARCH_OBSTACK_ZALLOC (gdbarch,
+					   struct frame_unwind_table_entry);
+  (*table->tail)->unwinder = unwinder;
+  table->tail = &((*table->tail)->next);
+}
+
 const struct frame_unwind *
-frame_unwind_find_by_frame (struct frame_info *next_frame)
+frame_unwind_find_by_frame (struct frame_info *next_frame, void **this_cache)
 {
   int i;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
@@ -76,10 +88,19 @@
     return legacy_saved_regs_unwind;
   for (entry = table->head; entry != NULL; entry = entry->next)
     {
-      const struct frame_unwind *desc;
-      desc = entry->sniffer (next_frame);
-      if (desc != NULL)
-	return desc;
+      if (entry->sniffer != NULL)
+	{
+	  const struct frame_unwind *desc = NULL;
+	  desc = entry->sniffer (next_frame);
+	  if (desc != NULL)
+	    return desc;
+	}
+      if (entry->unwinder != NULL)
+	{
+	  if (entry->unwinder->sniffer (entry->unwinder, next_frame,
+					this_cache))
+	    return entry->unwinder;
+	}
     }
   return legacy_saved_regs_unwind;
 }
Index: frame-unwind.h
===================================================================
RCS file: /cvs/src/src/gdb/frame-unwind.h,v
retrieving revision 1.9
diff -u -r1.9 frame-unwind.h
--- frame-unwind.h	16 Jul 2003 22:29:13 -0000	1.9
+++ frame-unwind.h	18 Mar 2004 22:29:48 -0000
@@ -1,6 +1,6 @@
 /* Definitions for a frame unwinder, for GDB, the GNU debugger.
 
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -22,6 +22,7 @@
 #if !defined (FRAME_UNWIND_H)
 #define FRAME_UNWIND_H 1
 
+struct frame_data;
 struct frame_info;
 struct frame_id;
 struct frame_unwind;
@@ -42,6 +43,14 @@
    as where this frame's prologue stores the previous frame's
    registers.  */
 
+/* Given the NEXT frame, take a wiff of THIS frame's registers (namely
+   the PC and attributes) and if SELF is the applicable unwinder,
+   return non-zero.  Possibly also initialize THIS_PROLOGUE_CACHE.  */
+
+typedef int (frame_sniffer_ftype) (const struct frame_unwind *self,
+				   struct frame_info *next_frame,
+				   void **this_prologue_cache);
+
 /* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
    use the NEXT frame, and its register unwind method, to determine
    the frame ID of THIS frame.
@@ -118,8 +127,16 @@
      here?  */
   frame_this_id_ftype *this_id;
   frame_prev_register_ftype *prev_register;
+  const struct frame_data *unwind_data;
+  frame_sniffer_ftype *sniffer;
 };
 
+/* Register a frame unwinder, _appending_ it to the end of the search
+   list.  */
+extern void frame_unwind_register_unwinder (struct gdbarch *gdbarch,
+					    const struct frame_unwind *unwinder);
+
+
 /* Given the NEXT frame, take a wiff of THIS frame's registers (namely
    the PC and attributes) and if it is the applicable unwinder return
    the unwind methods, or NULL if it is not.  */
@@ -134,8 +151,9 @@
 					 frame_unwind_sniffer_ftype *sniffer);
 
 /* Iterate through the next frame's sniffers until one returns with an
-   unwinder implementation.  */
+   unwinder implementation.  Possibly initialize THIS_CACHE.  */
 
-extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame);
+extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame,
+							      void **this_cache);
 
 #endif
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.163
diff -u -r1.163 frame.c
--- frame.c	17 Mar 2004 23:43:36 -0000	1.163
+++ frame.c	18 Mar 2004 22:29:48 -0000
@@ -228,7 +228,8 @@
       /* Find the unwinder.  */
       if (fi->unwind == NULL)
 	{
-	  fi->unwind = frame_unwind_find_by_frame (fi->next);
+	  fi->unwind = frame_unwind_find_by_frame (fi->next,
+						   &fi->prologue_cache);
 	  /* FIXME: cagney/2003-04-02: Rather than storing the frame's
 	     type in the frame, the unwinder's type should be returned
 	     directly.  Unfortunately, legacy code, called by
@@ -532,7 +533,8 @@
   /* Find the unwinder.  */
   if (frame->unwind == NULL)
     {
-      frame->unwind = frame_unwind_find_by_frame (frame->next);
+      frame->unwind = frame_unwind_find_by_frame (frame->next,
+						  &frame->prologue_cache);
       /* FIXME: cagney/2003-04-02: Rather than storing the frame's
 	 type in the frame, the unwinder's type should be returned
 	 directly.  Unfortunately, legacy code, called by
@@ -1191,7 +1193,7 @@
 
   /* Select/initialize both the unwind function and the frame's type
      based on the PC.  */
-  fi->unwind = frame_unwind_find_by_frame (fi->next);
+  fi->unwind = frame_unwind_find_by_frame (fi->next, &fi->prologue_cache);
   if (fi->unwind->type != UNKNOWN_FRAME)
     fi->type = fi->unwind->type;
   else
@@ -1344,7 +1346,8 @@
 
       /* Set the unwind functions based on that identified PC.  Ditto
          for the "type" but strongly prefer the unwinder's frame type.  */
-      prev->unwind = frame_unwind_find_by_frame (prev->next);
+      prev->unwind = frame_unwind_find_by_frame (prev->next,
+						 &prev->prologue_cache);
       if (prev->unwind->type == UNKNOWN_FRAME)
 	prev->type = frame_type_from_pc (get_frame_pc (prev));
       else
@@ -1493,7 +1496,8 @@
              to the new frame code.  Implement FRAME_CHAIN the way the
              new frame will.  */
 	  /* Find PREV frame's unwinder.  */
-	  prev->unwind = frame_unwind_find_by_frame (this_frame);
+	  prev->unwind = frame_unwind_find_by_frame (this_frame,
+						     &prev->prologue_cache);
 	  /* FIXME: cagney/2003-04-02: Rather than storing the frame's
 	     type in the frame, the unwinder's type should be returned
 	     directly.  Unfortunately, legacy code, called by
@@ -1654,7 +1658,8 @@
      If there isn't a FRAME_CHAIN, the code above will have already
      done this.  */
   if (prev->unwind == NULL)
-    prev->unwind = frame_unwind_find_by_frame (prev->next);
+    prev->unwind = frame_unwind_find_by_frame (prev->next,
+					       &prev->prologue_cache);
 
   /* If the unwinder provides a frame type, use it.  Otherwize
      continue on to that heuristic mess.  */
@@ -2124,7 +2129,8 @@
     {
       /* Initialize the frame's unwinder because it is that which
          provides the frame's type.  */
-      frame->unwind = frame_unwind_find_by_frame (frame->next);
+      frame->unwind = frame_unwind_find_by_frame (frame->next, 
+						  &frame->prologue_cache);
       /* FIXME: cagney/2003-04-02: Rather than storing the frame's
 	 type in the frame, the unwinder's type should be returned
 	 directly.  Unfortunately, legacy code, called by

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