]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2003-03-13 Andrew Cagney <cagney@redhat.com> offbyone-20030313-branch
authorAndrew Cagney <cagney@redhat.com>
Thu, 13 Mar 2003 21:43:34 +0000 (21:43 +0000)
committerAndrew Cagney <cagney@redhat.com>
Thu, 13 Mar 2003 21:43:34 +0000 (21:43 +0000)
* frame.c (legacy_saved_regs_this_id): Handle a sentinel frame.
(get_prev_frame): Simplify.  Frame ID logic moved to
dummy_frame_this_id and legacy_saved_regs_this_id.

gdb/ChangeLog
gdb/frame.c

index c634d4cbde9e0f5bb4eef59eaf05bb81808f1008..5565723af9ec991eb137030e45b23e3d206a26d3 100644 (file)
@@ -1,5 +1,9 @@
 2003-03-13  Andrew Cagney  <cagney@redhat.com>
 
+       * frame.c (legacy_saved_regs_this_id): Handle a sentinel frame.
+       (get_prev_frame): Simplify.  Frame ID logic moved to
+       dummy_frame_this_id and legacy_saved_regs_this_id.
+
        * d10v-tdep.c (d10v_frame_this_id): Replace d10v_frame_id_unwind.
        (d10v_frame_unwind): Update.
        (d10v_frame_prev_register): Replace d10v_frame_register_unwind.
index 002a306fb6259acc298b9cd160cc80ff775a4096..3050a58104df7f2c349dbf067d3792e9cc5b0566 100644 (file)
@@ -745,30 +745,40 @@ legacy_saved_regs_this_id (struct frame_info *next_frame,
                           void **this_prologue_cache,
                           struct frame_id *id)
 {
-  int fromleaf;
   CORE_ADDR base;
   CORE_ADDR pc;
 
   /* Start out by assuming it's NULL.  */
   (*id) = null_frame_id;
 
-  if (frame_relative_level (next_frame) <= 0)
-    /* FIXME: 2002-11-09: Frameless functions can occure anywhere in
-       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 (next_frame);
-  else
-    fromleaf = 0;
-
-  if (fromleaf)
-    /* A frameless inner-most frame.  The `FP' (which isn't an
-       architecture frame-pointer register!) of the caller is the same
-       as the callee.  */
-    /* FIXME: 2002-11-09: There isn't any reason to special case this
-       edge condition.  Instead the per-architecture code should hande
-       it locally.  */
-    base = get_frame_base (next_frame);
+  if (frame_relative_level (next_frame) < 0)
+    {
+      /* We're unwinding a sentinel frame, the PC of which is pointing
+        at a stack dummy.  Fake up the dummy frame's ID using the
+        same sequence as is found a traditional unwinder.  Once all
+        architectures supply the unwind_dummy_id method, this code
+        can go away.  */
+      base = read_fp ();
+      pc = read_pc ();
+    }
+  else if (frame_relative_level (next_frame) == 0
+          && FRAMELESS_FUNCTION_INVOCATION (next_frame))
+    {
+      /* FIXME: 2002-11-09: Frameless functions can occure anywhere in
+        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.  */
+      /* A frameless inner-most frame.  The `FP' (which isn't an
+        architecture frame-pointer register!) of the caller is the
+        same as the callee.  */
+      /* FIXME: 2002-11-09: There isn't any reason to special case
+        this edge condition.  Instead the per-architecture code
+        should hande it locally.  */
+      base = get_frame_base (next_frame);
+      /* FIXME: cagney/2002-06-08: This should probably return the frame's
+        function and not the PC (a.k.a. resume address).  */
+      pc = frame_pc_unwind (next_frame);
+    }
   else
     {
       /* Two macros defined in tm.h specify the machine-dependent
@@ -788,16 +798,12 @@ legacy_saved_regs_this_id (struct frame_info *next_frame,
          main.  */
       gdb_assert (FRAME_CHAIN_P ());
       base = FRAME_CHAIN (next_frame);
-
       if (!frame_chain_valid (base, next_frame))
        return;
+      /* FIXME: cagney/2002-06-08: This should probably return the
+        frame's function and not the PC (a.k.a. resume address).  */
+      pc = frame_pc_unwind (next_frame);
     }
-  if (base == 0)
-    return;
-
-  /* FIXME: cagney/2002-06-08: This should probably return the frame's
-     function and not the PC (a.k.a. resume address).  */
-  pc = frame_pc_unwind (next_frame);
   id->pc = pc;
   id->base = base;
 }
@@ -1385,97 +1391,49 @@ get_prev_frame (struct frame_info *this_frame)
                                                prev_frame->pc);
 
   /* Find the prev's frame's ID.  */
-  switch (prev_frame->type)
-    {
-    case DUMMY_FRAME:
-      /* When unwinding a normal frame, the stack structure is
-        determined by analyzing the frame's function's code (be it
-        using brute force prologue analysis, or the dwarf2 CFI).  In
-        the case of a dummy frame, that simply isn't possible.  The
-        The PC is either the program entry point, or some random
-        address on the stack.  Trying to use that PC to apply
-        standard frame ID unwind techniques is just asking for
-        trouble.  */
-      if (gdbarch_unwind_dummy_id_p (current_gdbarch))
-       {
-         /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS,
-            previously saved the dummy frame's ID.  Things only work
-            if the two return the same value.  */
-         gdb_assert (SAVE_DUMMY_FRAME_TOS_P ());
-         /* Use an architecture specific method to extract the prev's
-            dummy ID from the next frame.  Note that this method uses
-            frame_register_unwind to obtain the register values
-            needed to determine the dummy frame's ID.  */
-         prev_frame->id = gdbarch_unwind_dummy_id (current_gdbarch,
-                                                   this_frame);
-       }
-      else if (this_frame->level < 0)
-       {
-         /* We're unwinding a sentinel frame, the PC of which is
-            pointing at a stack dummy.  Fake up the dummy frame's ID
-            using the same sequence as is found a traditional
-            unwinder.  Once all architectures supply the
-            unwind_dummy_id method, this code can go away.  */
-         prev_frame->id.base = read_fp ();
-         prev_frame->id.pc = read_pc ();
-       }
-      else
-       {
-         /* Outch!  We're not on the innermost frame yet we're trying
-            to unwind to a dummy.  The architecture must provide the
-            unwind_dummy_id() method.  Abandon the unwind process but
-            only after first warning the user.  */
-         internal_warning (__FILE__, __LINE__,
-                           "Missing unwind_dummy_id architecture method");
-         return NULL;
-       }
-      break;
-    case NORMAL_FRAME:
-    case SIGTRAMP_FRAME:
-      /* The callee expects to be invoked with:
 
-        this->unwind->this_id (this->next, &this->cache, &this->id);
+  /* The callee expects to be invoked with:
 
-        The below is carefully shifted one frame `to the left' so
-        that both the unwind->this_id and unwind->prev_register
-        methods are consistently invoked with NEXT_FRAME and
-        THIS_PROLOGUE_CACHE.
+     this->unwind->this_id (this->next, &this->cache, &this->id);
+
+     The below is carefully shifted one frame `to the left' so that
+     both the unwind->this_id and unwind->prev_register methods are
+     consistently invoked with NEXT_FRAME and THIS_PROLOGUE_CACHE.
        
-        Also note that, while the PC for this new previous frame was
-        unwound first (see above), the below is the first call that
-        [potentially] requires analysis of the new previous frame's
-        prologue.  Consequently, it is this call, that typically ends
-        up initializing the previous frame's prologue cache.  */
-      prev_frame->unwind->this_id (this_frame,
-                                  &prev_frame->prologue_cache,
-                                  &prev_frame->id);
-      /* Check that the unwound ID is valid.  */
-      if (!frame_id_p (prev_frame->id))
-       {
-         if (frame_debug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "Outermost frame - unwound frame ID invalid\n");
-         return NULL;
-       }
-      /* Check that the new frame isn't inner to (younger, below,
-        next) the old frame.  If that happens the frame unwind is
-        going backwards.  */
-      /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since
-        that doesn't have a valid frame ID.  Should instead set the
-        sentinel frame's frame ID to a `sentinel'.  Leave it until
-        after the switch to storing the frame ID, instead of the
-        frame base, in the frame object.  */
-      if (this_frame->level >= 0
-         && frame_id_inner (prev_frame->id, get_frame_id (this_frame)))
-       error ("Unwound frame inner-to selected frame (corrupt stack?)");
-      /* Note that, due to frameless functions, the stronger test of
-        the new frame being outer to the old frame can't be used -
-        frameless functions differ by only their PC value.  */
-      break;
-    default:
-      internal_error (__FILE__, __LINE__, "bad switch");
+     Also note that, while the PC for this new previous frame was
+     unwound first (see above), the below is the first call that
+     [potentially] requires analysis of the new previous frame's
+     prologue.  Consequently, it is this call, that typically ends up
+     initializing the previous frame's prologue cache.  */
+  prev_frame->unwind->this_id (this_frame,
+                              &prev_frame->prologue_cache,
+                              &prev_frame->id);
+
+  /* Check that the unwound ID is valid.  */
+  if (!frame_id_p (prev_frame->id))
+    {
+      if (frame_debug)
+       fprintf_unfiltered (gdb_stdlog,
+                           "Outermost frame - unwound frame ID invalid\n");
+      return NULL;
     }
 
+  /* Check that the new frame isn't inner to (younger, below, next)
+     the old frame.  If that happens the frame unwind is going
+     backwards.  */
+  /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since that
+     doesn't have a valid frame ID.  Should instead set the sentinel
+     frame's frame ID to a true `sentinel'.  Leave it until after the
+     switch to storing the frame ID, instead of the frame base, in the
+     frame object.  */
+  if (this_frame->level >= 0
+      && frame_id_inner (prev_frame->id, get_frame_id (this_frame)))
+    error ("Unwound frame inner-to selected frame (corrupt stack?)");
+
+  /* Note that, due to frameless functions, the stronger test of the
+     new frame being outer to the old frame can't be used - frameless
+     functions differ by only their PC value.  */
+
   /* FIXME: cagney/2002-12-18: Instead of this hack, should only store
      the frame ID in PREV_FRAME.  Unfortunatly, some architectures
      (HP/UX) still reply on EXTRA_FRAME_INFO and, hence, still poke at