2003-07-15 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Tue, 15 Jul 2003 17:35:00 +0000 (17:35 +0000)
committerAndrew Cagney <cagney@redhat.com>
Tue, 15 Jul 2003 17:35:00 +0000 (17:35 +0000)
* frame.c (get_frame_id): Use frame_unwind_find_by_frame.
(frame_register_unwind, create_new_frame): Ditto.
(legacy_get_prev_frame, get_frame_type): Ditto.
(get_frame_base_address): Use frame_base_find_by_frame.
(get_frame_locals_address): Use frame_base_find_by_frame.
(get_frame_args_address): Use frame_base_find_by_frame.
* frame-base.h (frame_base_sniffer_ftype): Declare.
(frame_base_append_sniffer): Declare.
(frame_base_find_by_frame): Replace frame_base_find_by_pc.
* frame-base.c (append_predicate): Add a "sniffer" parameter.
(frame_base_append_sniffer): New function.
(frame_base_append_predicate): Add a NULL sniffer.
(frame_base_find_by_frame): Replace "frame_base_find_by_pc".
(struct frame_base_table): Add "sniffer".
(frame_base_free): Free the "sniffer" table.
* frame-unwind.h (frame_unwind_sniffer_ftype): Define.
(frame_unwind_append_sniffer): Declare.
(frame_unwind_find_by_frame): Replace frame_unwind_find_by_pc.
* frame-unwind.c (frame_unwind_free): Free the "sniffer" table.
(struct frame_unwind_table): Add "sniffer", delete "middle".
(append_predicate): Add "sniffer" parameter, append the sniffer.
(frame_unwind_init): Update append_predicate call.
(frame_unwind_append_sniffer): New function.
(frame_unwind_append_predicate): Update append_predicate call.
(frame_unwind_find_by_frame): Replace frame_unwind_find_by_pc.

gdb/ChangeLog
gdb/frame-base.c
gdb/frame-base.h
gdb/frame-unwind.c
gdb/frame-unwind.h
gdb/frame.c

index 89730536a863a2f2d695103ea62799cbfa2f10b4..074cf454f618d4c94d5fb129da2ba518af8411f5 100644 (file)
@@ -1,3 +1,31 @@
+2003-07-15  Andrew Cagney  <cagney@redhat.com>
+
+       * frame.c (get_frame_id): Use frame_unwind_find_by_frame.
+       (frame_register_unwind, create_new_frame): Ditto.
+       (legacy_get_prev_frame, get_frame_type): Ditto.
+       (get_frame_base_address): Use frame_base_find_by_frame.
+       (get_frame_locals_address): Use frame_base_find_by_frame.
+       (get_frame_args_address): Use frame_base_find_by_frame.
+       * frame-base.h (frame_base_sniffer_ftype): Declare.
+       (frame_base_append_sniffer): Declare.
+       (frame_base_find_by_frame): Replace frame_base_find_by_pc.
+       * frame-base.c (append_predicate): Add a "sniffer" parameter.
+       (frame_base_append_sniffer): New function.
+       (frame_base_append_predicate): Add a NULL sniffer.
+       (frame_base_find_by_frame): Replace "frame_base_find_by_pc".
+       (struct frame_base_table): Add "sniffer".
+       (frame_base_free): Free the "sniffer" table.
+       * frame-unwind.h (frame_unwind_sniffer_ftype): Define.
+       (frame_unwind_append_sniffer): Declare.
+       (frame_unwind_find_by_frame): Replace frame_unwind_find_by_pc.
+       * frame-unwind.c (frame_unwind_free): Free the "sniffer" table.
+       (struct frame_unwind_table): Add "sniffer", delete "middle".
+       (append_predicate): Add "sniffer" parameter, append the sniffer.
+       (frame_unwind_init): Update append_predicate call.
+       (frame_unwind_append_sniffer): New function.
+       (frame_unwind_append_predicate): Update append_predicate call.
+       (frame_unwind_find_by_frame): Replace frame_unwind_find_by_pc.
+
 2003-07-15  Andrew Cagney  <cagney@redhat.com>
 
        * frame.c (get_prev_frame): Move disabled inside_entry_func to
index 0865a0ce6c9460d1a78e333afa46894a71aaec27..86d955b30699cc8e37230198409c520b8896a4bc 100644 (file)
@@ -71,6 +71,7 @@ static struct gdbarch_data *frame_base_data;
 struct frame_base_table
 {
   frame_base_p_ftype **p;
+  frame_base_sniffer_ftype **sniffer;
   const struct frame_base *default_base;
   int nr;
 };
@@ -89,6 +90,7 @@ frame_base_free (struct gdbarch *gdbarch, void *data)
   struct frame_base_table *table =
     gdbarch_data (gdbarch, frame_base_data);
   xfree (table->p);
+  xfree (table->sniffer);
   xfree (table);
 }
 
@@ -108,11 +110,16 @@ frame_base_table (struct gdbarch *gdbarch)
 
 /* Append a predicate to the end of the table.  */
 static void
-append_predicate (struct frame_base_table *table, frame_base_p_ftype *p)
+append_predicate (struct frame_base_table *table, frame_base_p_ftype *p,
+                 frame_base_sniffer_ftype *sniffer)
 {
   table->p = xrealloc (table->p, ((table->nr + 1)
                                  * sizeof (frame_base_p_ftype *)));
+  table->sniffer = xrealloc (table->sniffer,
+                            ((table->nr + 1)
+                             * sizeof (frame_base_sniffer_ftype *)));
   table->p[table->nr] = p;
+  table->sniffer[table->nr] = sniffer;
   table->nr++;
 }
 
@@ -121,7 +128,15 @@ frame_base_append_predicate (struct gdbarch *gdbarch,
                             frame_base_p_ftype *p)
 {
   struct frame_base_table *table = frame_base_table (gdbarch);
-  append_predicate (table, p);
+  append_predicate (table, p, NULL);
+}
+
+void
+frame_base_append_sniffer (struct gdbarch *gdbarch,
+                          frame_base_sniffer_ftype *sniffer)
+{
+  struct frame_base_table *table = frame_base_table (gdbarch);
+  append_predicate (table, NULL, sniffer);
 }
 
 void
@@ -133,13 +148,18 @@ frame_base_set_default (struct gdbarch *gdbarch,
 }
 
 const struct frame_base *
-frame_base_find_by_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
+frame_base_find_by_frame (struct frame_info *next_frame)
 {
-  int i;
+  struct gdbarch *gdbarch = get_frame_arch (next_frame);
   struct frame_base_table *table = frame_base_table (gdbarch);
+  int i;
   for (i = 0; i < table->nr; i++)
     {
-      const struct frame_base *desc = table->p[i] (pc);
+      const struct frame_base *desc = NULL;
+      if (table->p[i] != NULL)
+       desc = table->p[i] (frame_pc_unwind (next_frame));
+      else if (table->sniffer[i] != NULL)
+       desc = table->sniffer[i] (next_frame);
       if (desc != NULL)
        return desc;
     }
index 5e0d5db2e25635712641dba06c040af803eb7d41..7433c54f8905d3ed786fa061ca78e8cc570009c1 100644 (file)
@@ -29,30 +29,12 @@ struct frame_base;
 struct gdbarch;
 struct regcache;
 
-/* Return the frame base methods for the function that contains PC, or
-   NULL if it can't handle this frame.  */
+/* For compatibility.  */
 
 typedef const struct frame_base *(frame_base_p_ftype) (CORE_ADDR pc);
-
-/* Add a frame base handler to the list.  The predicates are polled in
-   the order that they are appended.  */
-
 extern void frame_base_append_predicate (struct gdbarch *gdbarch,
                                         frame_base_p_ftype *p);
 
-/* Set the default frame base.  If all else fails, this one is
-   returned.  If this isn't set, the default is to use legacy code
-   that uses things like the frame ID's base (ulgh!).  */
-
-extern void frame_base_set_default (struct gdbarch *gdbarch,
-                                   const struct frame_base *def);
-
-/* Iterate through the list of frame base handlers until one returns
-   an implementation.  */
-
-extern const struct frame_base *frame_base_find_by_pc (struct gdbarch *gdbarch,
-                                                      CORE_ADDR pc);
-
 /* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
    and that this is a `normal frame'; use the NEXT frame, and its
    register unwind method, to determine the address of THIS frame's
@@ -91,4 +73,27 @@ struct frame_base
   frame_this_args_ftype *this_args;
 };
 
+/* Given the NEXT frame, return the frame base methods for THIS frame,
+   or NULL if it can't handle THIS frame.  */
+
+typedef const struct frame_base *(frame_base_sniffer_ftype) (struct frame_info *next_frame);
+
+/* Append a frame base sniffer to the list.  The sniffers are polled
+   in the order that they are appended.  */
+
+extern void frame_base_append_sniffer (struct gdbarch *gdbarch,
+                                      frame_base_sniffer_ftype *sniffer);
+
+/* Set the default frame base.  If all else fails, this one is
+   returned.  If this isn't set, the default is to use legacy code
+   that uses things like the frame ID's base (ulgh!).  */
+
+extern void frame_base_set_default (struct gdbarch *gdbarch,
+                                   const struct frame_base *def);
+
+/* Iterate through the list of frame base handlers until one returns
+   an implementation.  */
+
+extern const struct frame_base *frame_base_find_by_frame (struct frame_info *next_frame);
+
 #endif
index 921d30b31d5dad23bb4e0af68de51be14756c122..ed43cb3bf51c11cd671129cc3d53ba44d1b05ed4 100644 (file)
@@ -30,17 +30,21 @@ static struct gdbarch_data *frame_unwind_data;
 struct frame_unwind_table
 {
   frame_unwind_p_ftype **p;
-  int middle;
+  frame_unwind_sniffer_ftype **sniffer;
   int nr;
 };
 
 /* Append a predicate to the end of the table.  */
 static void
-append_predicate (struct frame_unwind_table *table, frame_unwind_p_ftype *p)
+append_predicate (struct frame_unwind_table *table, frame_unwind_p_ftype *p,
+                 frame_unwind_sniffer_ftype *sniffer)
 {
   table->p = xrealloc (table->p, ((table->nr + 1)
                                  * sizeof (frame_unwind_p_ftype *)));
+  table->sniffer = xrealloc (table->sniffer, ((table->nr + 1)
+                                             * sizeof (frame_unwind_sniffer_ftype *)));
   table->p[table->nr] = p;
+  table->sniffer[table->nr] = sniffer;
   table->nr++;
 }
 
@@ -48,7 +52,7 @@ static void *
 frame_unwind_init (struct gdbarch *gdbarch)
 {
   struct frame_unwind_table *table = XCALLOC (1, struct frame_unwind_table);
-  append_predicate (table, dummy_frame_p);
+  append_predicate (table, dummy_frame_p, NULL);
   return table;
 }
 
@@ -58,6 +62,7 @@ frame_unwind_free (struct gdbarch *gdbarch, void *data)
   struct frame_unwind_table *table =
     gdbarch_data (gdbarch, frame_unwind_data);
   xfree (table->p);
+  xfree (table->sniffer);
   xfree (table);
 }
 
@@ -74,15 +79,31 @@ frame_unwind_append_predicate (struct gdbarch *gdbarch,
       table = frame_unwind_init (gdbarch);
       set_gdbarch_data (gdbarch, frame_unwind_data, table);
     }
-  append_predicate (table, p);
+  append_predicate (table, p, NULL);
 }
 
-const struct frame_unwind *
-frame_unwind_find_by_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
+void
+frame_unwind_append_sniffer (struct gdbarch *gdbarch,
+                            frame_unwind_sniffer_ftype *sniffer)
 {
-  int i;
   struct frame_unwind_table *table =
     gdbarch_data (gdbarch, frame_unwind_data);
+  if (table == NULL)
+    {
+      /* ULGH, called during architecture initialization.  Patch
+         things up.  */
+      table = frame_unwind_init (gdbarch);
+      set_gdbarch_data (gdbarch, frame_unwind_data, table);
+    }
+  append_predicate (table, NULL, sniffer);
+}
+
+const struct frame_unwind *
+frame_unwind_find_by_frame (struct frame_info *next_frame)
+{
+  int i;
+  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
   if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
     /* Seriously old code.  Don't even try to use this new mechanism.
        (Note: The variable USE_GENERIC_DUMMY_FRAMES is deprecated, not
@@ -91,7 +112,13 @@ frame_unwind_find_by_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
     return legacy_saved_regs_unwind;
   for (i = 0; i < table->nr; i++)
     {
-      const struct frame_unwind *desc = table->p[i] (pc);
+      const struct frame_unwind *desc;
+      if (table->p[i] != NULL)
+       desc = table->p[i] (frame_pc_unwind (next_frame));
+      else if (table->sniffer[i] != NULL)
+       desc = table->sniffer[i] (next_frame);
+      else
+       internal_error (__FILE__, __LINE__, "Missing sniffer?");
       if (desc != NULL)
        return desc;
     }
index ad1efdf353b3d548f44d4e8e44d1de3d95fc2f2c..80ce4b6dd0d8e55cdccbeceb8d1cadb88ad9a115 100644 (file)
@@ -30,25 +30,12 @@ struct regcache;
 
 #include "frame.h"             /* For enum frame_type.  */
 
-/* Return the frame unwind methods for the function that contains PC,
-   or NULL if this this unwinder can't handle this frame.  */
-
+/* For compatibility with the old frame code.  See end of header for
+   new methods.  */
 typedef const struct frame_unwind *(frame_unwind_p_ftype) (CORE_ADDR pc);
-
-/* Add a frame unwinder to the list.  The predicates are polled in the
-   order that they are appended.  The initial list contains the dummy
-   frame's predicate.  */
-
 extern void frame_unwind_append_predicate (struct gdbarch *gdbarch,
                                           frame_unwind_p_ftype *p);
 
-/* Iterate through the list of frame unwinders until one returns an
-   implementation.  */
-
-extern const struct frame_unwind *frame_unwind_find_by_pc (struct gdbarch
-                                                          *gdbarch,
-                                                          CORE_ADDR pc);
-
 /* The following unwind functions assume a chain of frames forming the
    sequence: (outer) prev <-> this <-> next (inner).  All the
    functions are called with called with the next frame's `struct
@@ -139,4 +126,22 @@ struct frame_unwind
   frame_prev_register_ftype *prev_register;
 };
 
+/* 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.  */
+
+typedef const struct frame_unwind *(frame_unwind_sniffer_ftype) (struct frame_info *next_frame);
+
+/* Add a frame sniffer to the list.  The predicates are polled in the
+   order that they are appended.  The initial list contains the dummy
+   frame sniffer.  */
+
+extern void frame_unwind_append_sniffer (struct gdbarch *gdbarch,
+                                        frame_unwind_sniffer_ftype *sniffer);
+
+/* Iterate through the next frame's sniffers until one returns with an
+   unwinder implementation.  */
+
+extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame);
+
 #endif
index 73895e24631afcfa382da51285cf33989fc468e5..9b95e9caec19f9295de55ab16281de6cf1cfc574 100644 (file)
@@ -229,8 +229,7 @@ get_frame_id (struct frame_info *fi)
       /* Find the unwinder.  */
       if (fi->unwind == NULL)
        {
-         fi->unwind = frame_unwind_find_by_pc (current_gdbarch,
-                                               get_frame_pc (fi));
+         fi->unwind = frame_unwind_find_by_frame (fi->next);
          /* FIXME: cagney/2003-04-02: Rather than storing the frame's
             type in the frame, the unwinder's type should be returned
             directly.  Unfortunatly, legacy code, called by
@@ -517,8 +516,7 @@ frame_register_unwind (struct frame_info *frame, int regnum,
   /* Find the unwinder.  */
   if (frame->unwind == NULL)
     {
-      frame->unwind = frame_unwind_find_by_pc (current_gdbarch,
-                                              get_frame_pc (frame));
+      frame->unwind = frame_unwind_find_by_frame (frame->next);
       /* FIXME: cagney/2003-04-02: Rather than storing the frame's
         type in the frame, the unwinder's type should be returned
         directly.  Unfortunatly, legacy code, called by
@@ -1206,7 +1204,7 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
 
   /* Select/initialize both the unwind function and the frame's type
      based on the PC.  */
-  fi->unwind = frame_unwind_find_by_pc (current_gdbarch, pc);
+  fi->unwind = frame_unwind_find_by_frame (fi->next);
   if (fi->unwind->type != UNKNOWN_FRAME)
     fi->type = fi->unwind->type;
   else
@@ -1365,8 +1363,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
 
       /* 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_pc (current_gdbarch,
-                                             get_frame_pc (prev));
+      prev->unwind = frame_unwind_find_by_frame (prev->next);
       if (prev->unwind->type == UNKNOWN_FRAME)
        prev->type = frame_type_from_pc (get_frame_pc (prev));
       else
@@ -1514,8 +1511,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
              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_pc (current_gdbarch,
-                                                 frame_pc_unwind (this_frame));
+         prev->unwind = frame_unwind_find_by_frame (this_frame->next);
          /* FIXME: cagney/2003-04-02: Rather than storing the frame's
             type in the frame, the unwinder's type should be returned
             directly.  Unfortunatly, legacy code, called by
@@ -1676,8 +1672,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
      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_pc (current_gdbarch,
-                                           get_frame_pc (prev));
+    prev->unwind = frame_unwind_find_by_frame (prev->next);
 
   /* If the unwinder provides a frame type, use it.  Otherwize
      continue on to that heuristic mess.  */
@@ -2090,7 +2085,7 @@ get_frame_base_address (struct frame_info *fi)
   if (get_frame_type (fi) != NORMAL_FRAME)
     return 0;
   if (fi->base == NULL)
-    fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi));
+    fi->base = frame_base_find_by_frame (fi->next);
   /* Sneaky: If the low-level unwind and high-level base code share a
      common unwinder, let them share the prologue cache.  */
   if (fi->base->unwind == fi->unwind)
@@ -2106,7 +2101,7 @@ get_frame_locals_address (struct frame_info *fi)
     return 0;
   /* If there isn't a frame address method, find it.  */
   if (fi->base == NULL)
-    fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi));
+    fi->base = frame_base_find_by_frame (fi->next);
   /* Sneaky: If the low-level unwind and high-level base code share a
      common unwinder, let them share the prologue cache.  */
   if (fi->base->unwind == fi->unwind)
@@ -2124,7 +2119,7 @@ get_frame_args_address (struct frame_info *fi)
     return 0;
   /* If there isn't a frame address method, find it.  */
   if (fi->base == NULL)
-    fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi));
+    fi->base = frame_base_find_by_frame (fi->next);
   /* Sneaky: If the low-level unwind and high-level base code share a
      common unwinder, let them share the prologue cache.  */
   if (fi->base->unwind == fi->unwind)
@@ -2163,8 +2158,7 @@ get_frame_type (struct frame_info *frame)
     {
       /* Initialize the frame's unwinder because it is that which
          provides the frame's type.  */
-      frame->unwind = frame_unwind_find_by_pc (current_gdbarch,
-                                              get_frame_pc (frame));
+      frame->unwind = frame_unwind_find_by_frame (frame->next);
       /* FIXME: cagney/2003-04-02: Rather than storing the frame's
         type in the frame, the unwinder's type should be returned
         directly.  Unfortunatly, legacy code, called by