2003-04-04 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Sat, 5 Apr 2003 03:56:00 +0000 (03:56 +0000)
committerAndrew Cagney <cagney@redhat.com>
Sat, 5 Apr 2003 03:56:00 +0000 (03:56 +0000)
* frame.c (get_prev_frame): Do not call frame_type_from_pc.  Set
the frame's type from the unwinder.
(get_frame_type): Map UNKNOWN_FRAME onto NORMAL_FRAME.
(create_new_frame, legacy_get_prev_frame): When the unwinder's
type isn't UNKNOWN_FRAME, initalize "type" from the unwinder.
(get_frame_base_address): Use get_frame_type.
(get_frame_locals_address, get_frame_args_address): Ditto.
(legacy_saved_regs_unwinder): Set the type to UNKNOWN_TYPE.
* frame.h (enum frame_type): Add UNKNOWN_FRAME.
(struct frame_info): Add comment explaining why the frame contains
a "type" field.
* dummy-frame.c (dummy_frame_unwind): Set the type to DUMMY_FRAME.
* d10v-tdep.c (d10v_frame_unwind): Set the type to NORMAL_FRAME.
* sentinel-frame.c (sentinel_frame_unwinder): Set the type to
NORMAL_FRAME.
* frame-unwind.h: Include "frame.h".
(struct frame_unwind): Add "type" field.
* Makefile.in (frame_unwind_h): Add $(frame_h).

gdb/ChangeLog
gdb/Makefile.in
gdb/d10v-tdep.c
gdb/dummy-frame.c
gdb/frame-unwind.h
gdb/frame.c
gdb/frame.h
gdb/sentinel-frame.c

index 1c43f50c6afad63a9dca8cca2ca02166f21415fd..3c041cf1ffbb243f6ce8f58ad57da0a5d85f130d 100644 (file)
@@ -1,3 +1,24 @@
+2003-04-04  Andrew Cagney  <cagney@redhat.com>
+
+       * frame.c (get_prev_frame): Do not call frame_type_from_pc.  Set
+       the frame's type from the unwinder.
+       (get_frame_type): Map UNKNOWN_FRAME onto NORMAL_FRAME.
+       (create_new_frame, legacy_get_prev_frame): When the unwinder's
+       type isn't UNKNOWN_FRAME, initalize "type" from the unwinder.
+       (get_frame_base_address): Use get_frame_type.
+       (get_frame_locals_address, get_frame_args_address): Ditto.
+       (legacy_saved_regs_unwinder): Set the type to UNKNOWN_TYPE.
+       * frame.h (enum frame_type): Add UNKNOWN_FRAME.
+       (struct frame_info): Add comment explaining why the frame contains
+       a "type" field.
+       * dummy-frame.c (dummy_frame_unwind): Set the type to DUMMY_FRAME.
+       * d10v-tdep.c (d10v_frame_unwind): Set the type to NORMAL_FRAME.
+       * sentinel-frame.c (sentinel_frame_unwinder): Set the type to
+       NORMAL_FRAME.
+       * frame-unwind.h: Include "frame.h".
+       (struct frame_unwind): Add "type" field.
+       * Makefile.in (frame_unwind_h): Add $(frame_h).
+       
 2003-04-04  Andrew Cagney  <cagney@redhat.com>
 
        * x86-64-tdep.c (x86_64_unwind_dummy_id): Use frame_id_build.
index c5ba5d84218cbbffe0cec0c882d4de2a2afe9fe2..a825d7a2a0f2fe6c5f367e9cf6110f8119f41fde 100644 (file)
@@ -641,7 +641,7 @@ event_top_h = event-top.h
 expression_h = expression.h $(symtab_h) $(doublest_h)
 f_lang_h = f-lang.h
 frame_h = frame.h
-frame_unwind_h = frame-unwind.h
+frame_unwind_h = frame-unwind.h $(frame_h)
 frame_base_h = frame-base.h
 gdb_events_h = gdb-events.h
 gdb_stabs_h = gdb-stabs.h
index 8a57cf2b699e9927db65e124bfd08941f29214e5..6c234cce1e81e8a10c9fad226f3b5cc7a5ae6609 100644 (file)
@@ -1553,6 +1553,7 @@ d10v_frame_prev_register (struct frame_info *next_frame,
 }
 
 static const struct frame_unwind d10v_frame_unwind = {
+  NORMAL_FRAME,
   d10v_frame_this_id,
   d10v_frame_prev_register
 };
index 4181735f2daa95d40e26664b5bbf28d2e55d3d7e..991ee280832afa2cae943955e8fe4bf7b9851812 100644 (file)
@@ -402,6 +402,7 @@ dummy_frame_this_id (struct frame_info *next_frame,
 
 static struct frame_unwind dummy_frame_unwind =
 {
+  DUMMY_FRAME,
   dummy_frame_this_id,
   dummy_frame_prev_register
 };
index 099f9dee420db305741f09f83b1255264a9ce70a..ad1efdf353b3d548f44d4e8e44d1de3d95fc2f2c 100644 (file)
@@ -28,6 +28,8 @@ struct frame_unwind;
 struct gdbarch;
 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.  */
 
@@ -128,7 +130,9 @@ typedef void (frame_prev_register_ftype) (struct frame_info *next_frame,
 
 struct frame_unwind
 {
-  /* Should the frame's type go here? */
+  /* The frame's type.  Should this instead be a collection of
+     predicates that test the frame for various attributes?  */
+  enum frame_type type;
   /* Should an attribute indicating the frame's address-in-block go
      here?  */
   frame_this_id_ftype *this_id;
index e27eac36de34097ad801f55e77dd0dd0614fe232..924900568989c9c9ef1b43957db49e5c29cafb7a 100644 (file)
@@ -819,6 +819,8 @@ legacy_saved_regs_this_id (struct frame_info *next_frame,
 }
        
 const struct frame_unwind legacy_saved_regs_unwinder = {
+  /* Not really.  It gets overridden by legacy_get_prev_frame.  */
+  UNKNOWN_FRAME,
   legacy_saved_regs_this_id,
   legacy_saved_regs_prev_register
 };
@@ -960,16 +962,21 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
   fi = frame_obstack_zalloc (sizeof (struct frame_info));
 
   fi->next = create_sentinel_frame (current_regcache);
-  fi->type = frame_type_from_pc (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, fi->pc);
+  if (fi->unwind->type != UNKNOWN_FRAME)
+    fi->type = fi->unwind->type;
+  else
+    fi->type = frame_type_from_pc (pc);
+
   deprecated_update_frame_base_hack (fi, addr);
   deprecated_update_frame_pc_hack (fi, pc);
 
   if (DEPRECATED_INIT_EXTRA_FRAME_INFO_P ())
     DEPRECATED_INIT_EXTRA_FRAME_INFO (0, fi);
 
-  /* Select/initialize an unwind function.  */
-  fi->unwind = frame_unwind_find_by_pc (current_gdbarch, get_frame_pc (fi));
-
   return fi;
 }
 
@@ -1047,7 +1054,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
      Unfortunatly those same work-arounds rely on the type defaulting
      to NORMAL_FRAME.  Ulgh!  The new frame code does not have this
      problem.  */
-  prev->type = NORMAL_FRAME;
+  prev->type = UNKNOWN_FRAME;
 
   /* A legacy frame's ID is always computed here.  Mark it as valid.  */
   prev->id_p = 1;
@@ -1083,11 +1090,14 @@ legacy_get_prev_frame (struct frame_info *this_frame)
                                "Outermost frame - unwound PC zero\n");
          return NULL;
        }
-      prev->type = frame_type_from_pc (get_frame_pc (prev));
 
-      /* Set the unwind functions based on that identified PC.  */
-      prev->unwind = frame_unwind_find_by_pc (current_gdbarch,
-                                             get_frame_pc (prev));
+      /* 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, prev->pc);
+      if (prev->unwind->type == UNKNOWN_FRAME)
+       prev->type = frame_type_from_pc (prev->pc);
+      else
+       prev->type = prev->unwind->type;
 
       /* Find the prev's frame's ID.  */
       if (prev->type == DUMMY_FRAME
@@ -1336,6 +1346,14 @@ legacy_get_prev_frame (struct frame_info *this_frame)
   prev->unwind = frame_unwind_find_by_pc (current_gdbarch,
                                          get_frame_pc (prev));
 
+  /* If the unwinder provides a frame type, use it.  Otherwize
+     continue on to that heuristic mess.  */
+  if (prev->unwind->type != UNKNOWN_FRAME)
+    {
+      prev->type = prev->unwind->type;
+      return prev;
+    }
+
   /* NOTE: cagney/2002-11-18: The code segments, found in
      create_new_frame and get_prev_frame(), that initializes the
      frames type is subtly different.  The latter only updates ->type
@@ -1574,12 +1592,22 @@ get_prev_frame (struct frame_info *this_frame)
                            "Outermost frame - unwound PC zero\n");
       return NULL;
     }
-  prev_frame->type = frame_type_from_pc (prev_frame->pc);
 
   /* Set the unwind functions based on that identified PC.  */
   prev_frame->unwind = frame_unwind_find_by_pc (current_gdbarch,
                                                prev_frame->pc);
 
+  /* 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 legacy_get_prev_frame,
+     explicitly set the frames type using the method
+     deprecated_set_frame_type().  */
+  gdb_assert (prev_frame->unwind->type != UNKNOWN_FRAME);
+  prev_frame->type = prev_frame->unwind->type;
+
+  /* Can the frame's type and unwinder be computed on demand?  That
+     would make a frame's creation really really lite!  */
+
   /* The prev's frame's ID is computed by demand in get_frame_id().  */
 
   /* The unwound frame ID is validate at the start of this function,
@@ -1649,7 +1677,7 @@ get_frame_base (struct frame_info *fi)
 CORE_ADDR
 get_frame_base_address (struct frame_info *fi)
 {
-  if (fi->type != NORMAL_FRAME)
+  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));
@@ -1664,7 +1692,7 @@ CORE_ADDR
 get_frame_locals_address (struct frame_info *fi)
 {
   void **cache;
-  if (fi->type != NORMAL_FRAME)
+  if (get_frame_type (fi) != NORMAL_FRAME)
     return 0;
   /* If there isn't a frame address method, find it.  */
   if (fi->base == NULL)
@@ -1682,7 +1710,7 @@ CORE_ADDR
 get_frame_args_address (struct frame_info *fi)
 {
   void **cache;
-  if (fi->type != NORMAL_FRAME)
+  if (get_frame_type (fi) != NORMAL_FRAME)
     return 0;
   /* If there isn't a frame address method, find it.  */
   if (fi->base == NULL)
@@ -1716,7 +1744,10 @@ get_frame_type (struct frame_info *frame)
   if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES
       && deprecated_frame_in_dummy (frame))
     return DUMMY_FRAME;
-  return frame->type;
+  if (frame->type == UNKNOWN_FRAME)
+    return NORMAL_FRAME;
+  else
+    return frame->type;
 }
 
 void
index 231aaadbd0faff29d6c5c2d8e962f0b4de07312e..9870fc2b9a0780a63df07dbecf3101572e9fddc4 100644 (file)
@@ -225,6 +225,11 @@ extern int frame_relative_level (struct frame_info *fi);
 
 enum frame_type
 {
+  /* The frame's type hasn't yet been defined.  This is a catch-all
+     for legacy code that uses really strange technicques, such as
+     deprecated_set_frame_type, to set the frame's type.  New code
+     should not use this value.  */
+  UNKNOWN_FRAME,
   /* A true stack frame, created by the target program during normal
      execution.  */
   NORMAL_FRAME,
@@ -367,6 +372,10 @@ struct frame_info
     int level;
 
     /* The frame's type.  */
+    /* FIXME: cagney/2003-04-02: Should instead be returning
+       ->unwind->type.  Unfortunatly, legacy code is still explicitly
+       setting the type using the method deprecated_set_frame_type.
+       Eliminate that method and this field can be eliminated.  */
     enum frame_type type;
 
     /* For each register, address of where it was saved on entry to
index e4060d2776741732083608f32b715019fa34d74f..dab164784135c429a14ddfd77c12fb383fce1783 100644 (file)
@@ -83,6 +83,8 @@ sentinel_frame_this_id (struct frame_info *next_frame,
 
 const struct frame_unwind sentinel_frame_unwinder =
 {
+  /* Should the sentinel frame be given a special type?  */
+  NORMAL_FRAME,
   sentinel_frame_this_id,
   sentinel_frame_prev_register
 };