Honour PRIVATE keyword
[deliverable/binutils-gdb.git] / gdb / frame.c
index bedbae45003cd08fbb60d8b2ec95dba3019ef74c..a032c47e92b1437dc33550c2128d5ea648e4dd4d 100644 (file)
@@ -1,7 +1,7 @@
 /* Cache and manage frames for GDB, the GNU debugger.
 
    Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000,
-   2001, 2002, 2003 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -86,10 +86,6 @@ struct frame_info
      initialized by DEPRECATED_INIT_EXTRA_FRAME_INFO */
   struct frame_extra_info *extra_info;
 
-  /* If dwarf2 unwind frame informations is used, this structure holds
-     all related unwind data.  */
-  struct context *context;
-
   /* The frame's low-level unwinder and corresponding cache.  The
      low-level unwinder is responsible for unwinding register values
      for the previous frame.  The low-level unwind methods are
@@ -238,7 +234,6 @@ get_frame_id (struct frame_info *fi)
             directly.  Unfortunately, legacy code, called by
             legacy_get_prev_frame, explicitly set the frames type
             using the method deprecated_set_frame_type().  */
-         gdb_assert (fi->unwind->type != UNKNOWN_FRAME);
          fi->type = fi->unwind->type;
        }
       /* Find THIS frame's ID.  */
@@ -514,9 +509,10 @@ frame_register_unwind (struct frame_info *frame, int regnum,
 
   if (frame_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         "{ frame_register_unwind (frame=%d,regnum=\"%s\",...) ",
-                         frame->level, frame_map_regnum_to_name (frame, regnum));
+      fprintf_unfiltered (gdb_stdlog, "\
+{ frame_register_unwind (frame=%d,regnum=%d(%s),...) ",
+                         frame->level, regnum,
+                         frame_map_regnum_to_name (frame, regnum));
     }
 
   /* Require all but BUFFERP to be valid.  A NULL BUFFERP indicates
@@ -542,7 +538,6 @@ frame_register_unwind (struct frame_info *frame, int regnum,
         directly.  Unfortunately, legacy code, called by
         legacy_get_prev_frame, explicitly set the frames type using
         the method deprecated_set_frame_type().  */
-      gdb_assert (frame->unwind->type != UNKNOWN_FRAME);
       frame->type = frame->unwind->type;
     }
 
@@ -667,15 +662,6 @@ get_frame_register_unsigned (struct frame_info *frame, int regnum)
   return frame_unwind_register_unsigned (frame->next, regnum);
 }
 
-void
-frame_unwind_signed_register (struct frame_info *frame, int regnum,
-                             LONGEST *val)
-{
-  char buf[MAX_REGISTER_SIZE];
-  frame_unwind_register (frame, regnum, buf);
-  (*val) = extract_signed_integer (buf, DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum));
-}
-
 void
 frame_unwind_unsigned_register (struct frame_info *frame, int regnum,
                                ULONGEST *val)
@@ -930,7 +916,13 @@ select_frame (struct frame_info *fi)
      source language of this frame, and switch to it if desired.  */
   if (fi)
     {
-      s = find_pc_symtab (get_frame_pc (fi));
+      /* We retrieve the frame's symtab by using the frame PC.  However
+         we cannot use the frame pc as is, because it usually points to
+         the instruction following the "call", which is sometimes the
+         first instruction of another function.  So we rely on
+         get_frame_address_in_block() which provides us with a PC which
+         is guaranteed to be inside the frame's code block.  */
+      s = find_pc_symtab (get_frame_address_in_block (fi));
       if (s
          && s->language != current_language->la_language
          && s->language != language_unknown
@@ -1036,9 +1028,12 @@ legacy_saved_regs_this_id (struct frame_info *next_frame,
                           void **this_prologue_cache,
                           struct frame_id *id)
 {
-  /* legacy_get_prev_frame() always sets ->this_id.p, hence this is
-     never needed.  */
-  internal_error (__FILE__, __LINE__, "legacy_saved_regs_this_id() called");
+  /* A developer is trying to bring up a new architecture, help them
+     by providing a default unwinder that refuses to unwind anything
+     (the ID is always NULL).  In the case of legacy code,
+     legacy_get_prev_frame() will have previously set ->this_id.p, so
+     this code won't be called.  */
+  (*id) = null_frame_id;
 }
        
 const struct frame_unwind legacy_saved_regs_unwinder = {
@@ -1232,12 +1227,6 @@ get_next_frame (struct frame_info *this_frame)
     return NULL;
 }
 
-struct frame_info *
-deprecated_get_next_frame_hack (struct frame_info *this_frame)
-{
-  return this_frame->next;
-}
-
 /* Flush the entire frame cache.  */
 
 void
@@ -1291,7 +1280,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
   prev = FRAME_OBSTACK_ZALLOC (struct frame_info);
   prev->level = this_frame->level + 1;
 
-  /* Do not completly wire it in to the frame chain.  Some (bad) code
+  /* Do not completely wire it in to the frame chain.  Some (bad) code
      in INIT_FRAME_EXTRA_INFO tries to look along frame->prev to pull
      some fancy tricks (of course such code is, by definition,
      recursive).
@@ -1460,7 +1449,8 @@ legacy_get_prev_frame (struct frame_info *this_frame)
        the frame chain, not just the inner most frame!  The generic,
        per-architecture, frame code should handle this and the below
        should simply be removed.  */
-    fromleaf = FRAMELESS_FUNCTION_INVOCATION (this_frame);
+    fromleaf = (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P ()
+               && DEPRECATED_FRAMELESS_FUNCTION_INVOCATION (this_frame));
   else
     fromleaf = 0;
 
@@ -1733,7 +1723,12 @@ legacy_get_prev_frame (struct frame_info *this_frame)
 
 /* Return a structure containing various interesting information
    about the frame that called THIS_FRAME.  Returns NULL
-   if there is no such frame.  */
+   if there is no such frame.
+
+   This function tests some target-independent conditions that should
+   terminate the frame chain, such as unwinding past main().  It
+   should not contain any target-dependent tests, such as checking
+   whether the program-counter is zero.  */
 
 struct frame_info *
 get_prev_frame (struct frame_info *this_frame)
@@ -1840,7 +1835,7 @@ get_prev_frame (struct frame_info *this_frame)
       && backtrace_beyond_entry_func
 #endif
       && this_frame->type != DUMMY_FRAME && this_frame->level >= 0
-      && inside_entry_func (get_frame_pc (this_frame)))
+      && inside_entry_func (this_frame))
     {
       if (frame_debug)
        {
@@ -1950,37 +1945,6 @@ get_prev_frame (struct frame_info *this_frame)
   prev_frame = FRAME_OBSTACK_ZALLOC (struct frame_info);
   prev_frame->level = this_frame->level + 1;
 
-  /* Try to unwind the PC.  If that doesn't work, assume we've reached
-     the oldest frame and simply return.  Is there a better sentinal
-     value?  The unwound PC value is then used to initialize the new
-     previous frame's type.
-
-     Note that the pc-unwind is intentionally performed before the
-     frame chain.  This is ok since, for old targets, both
-     frame_pc_unwind (nee, FRAME_SAVED_PC) and
-     DEPRECATED_FRAME_CHAIN()) assume THIS_FRAME's data structures
-     have already been initialized (using
-     DEPRECATED_INIT_EXTRA_FRAME_INFO) and hence the call order
-     doesn't matter.
-
-     By unwinding the PC first, it becomes possible to, in the case of
-     a dummy frame, avoid also unwinding the frame ID.  This is
-     because (well ignoring the PPC) a dummy frame can be located
-     using THIS_FRAME's frame ID.  */
-
-  if (frame_pc_unwind (this_frame) == 0)
-    {
-      /* The allocated PREV_FRAME will be reclaimed when the frame
-        obstack is next purged.  */
-      if (frame_debug)
-       {
-         fprintf_unfiltered (gdb_stdlog, "-> ");
-         fprint_frame (gdb_stdlog, NULL);
-         fprintf_unfiltered (gdb_stdlog, " // unwound PC zero }\n");
-       }
-      return NULL;
-    }
-
   /* Don't yet compute ->unwind (and hence ->type).  It is computed
      on-demand in get_frame_type, frame_register_unwind, and
      get_frame_id.  */
@@ -2166,7 +2130,6 @@ get_frame_type (struct frame_info *frame)
         directly.  Unfortunately, legacy code, called by
         legacy_get_prev_frame, explicitly set the frames type using
         the method deprecated_set_frame_type().  */
-      gdb_assert (frame->unwind->type != UNKNOWN_FRAME);
       frame->type = frame->unwind->type;
     }
   if (frame->type == UNKNOWN_FRAME)
@@ -2227,61 +2190,13 @@ deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base)
   frame->this_id.value.stack_addr = base;
 }
 
-void
-deprecated_set_frame_saved_regs_hack (struct frame_info *frame,
-                                     CORE_ADDR *saved_regs)
-{
-  frame->saved_regs = saved_regs;
-}
-
-void
-deprecated_set_frame_extra_info_hack (struct frame_info *frame,
-                                     struct frame_extra_info *extra_info)
-{
-  frame->extra_info = extra_info;
-}
-
-void
-deprecated_set_frame_next_hack (struct frame_info *fi,
-                               struct frame_info *next)
-{
-  fi->next = next;
-}
-
-void
-deprecated_set_frame_prev_hack (struct frame_info *fi,
-                               struct frame_info *prev)
-{
-  fi->prev = prev;
-}
-
-struct context *
-deprecated_get_frame_context (struct frame_info *fi)
-{
-  return fi->context;
-}
-
-void
-deprecated_set_frame_context (struct frame_info *fi,
-                             struct context *context)
-{
-  fi->context = context;
-}
-
 struct frame_info *
-deprecated_frame_xmalloc (void)
+deprecated_frame_xmalloc_with_cleanup (long sizeof_saved_regs,
+                                      long sizeof_extra_info)
 {
   struct frame_info *frame = XMALLOC (struct frame_info);
   memset (frame, 0, sizeof (*frame));
   frame->this_id.p = 1;
-  return frame;
-}
-
-struct frame_info *
-deprecated_frame_xmalloc_with_cleanup (long sizeof_saved_regs,
-                                      long sizeof_extra_info)
-{
-  struct frame_info *frame = deprecated_frame_xmalloc ();
   make_cleanup (xfree, frame);
   if (sizeof_saved_regs > 0)
     {
@@ -2361,11 +2276,28 @@ frame_sp_unwind (struct frame_info *next_frame)
 int
 legacy_frame_p (struct gdbarch *current_gdbarch)
 {
-  return (DEPRECATED_INIT_FRAME_PC_P ()
-         || DEPRECATED_INIT_FRAME_PC_FIRST_P ()
-         || DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()
-         || DEPRECATED_FRAME_CHAIN_P ()
-         || !gdbarch_unwind_dummy_id_p (current_gdbarch));
+  if (DEPRECATED_INIT_FRAME_PC_P ()
+      || DEPRECATED_INIT_FRAME_PC_FIRST_P ()
+      || DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()
+      || DEPRECATED_FRAME_CHAIN_P ())
+    /* No question, it's a legacy frame.  */
+    return 1;
+  if (gdbarch_unwind_dummy_id_p (current_gdbarch))
+    /* No question, it's not a legacy frame (provided none of the
+       deprecated methods checked above are present that is).  */
+    return 0;
+  if (DEPRECATED_TARGET_READ_FP_P ()
+      || DEPRECATED_FP_REGNUM >= 0)
+    /* Assume it's legacy.  If you're trying to convert a legacy frame
+       target to the new mechanism, get rid of these.  legacy
+       get_prev_frame requires these when unwind_frame_id isn't
+       available.  */
+    return 1;
+  /* Default to assuming that it's brand new code, and hence not
+     legacy.  Force it down the non-legacy path so that the new code
+     uses the new frame mechanism from day one.  Dummy frame's won't
+     work very well but we can live with that.  */
+  return 0;
 }
 
 extern initialize_file_ftype _initialize_frame; /* -Wmissing-prototypes */
This page took 0.028061 seconds and 4 git commands to generate.