S390: Restructure s390_push_dummy_call
[deliverable/binutils-gdb.git] / gdb / frame.c
index cbff25fcb45f195d2f9ba9758abf080046054a38..b3cbf234bd7465aa8020fcf220c18a3556ed9f3f 100644 (file)
@@ -1,6 +1,6 @@
 /* Cache and manage frames for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+   Copyright (C) 1986-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -23,8 +23,6 @@
 #include "value.h"
 #include "inferior.h"  /* for inferior_ptid */
 #include "regcache.h"
-#include "gdb_assert.h"
-#include <string.h>
 #include "user-regs.h"
 #include "gdb_obstack.h"
 #include "dummy-frame.h"
@@ -38,7 +36,6 @@
 #include "gdbcmd.h"
 #include "observer.h"
 #include "objfiles.h"
-#include "exceptions.h"
 #include "gdbthread.h"
 #include "block.h"
 #include "inline-frame.h"
@@ -145,6 +142,10 @@ struct frame_info
   /* The reason why we could not set PREV, or UNWIND_NO_REASON if we
      could.  Only valid when PREV_P is set.  */
   enum unwind_stop_reason stop_reason;
+
+  /* A frame specific string describing the STOP_REASON in more detail.
+     Only valid when PREV_P is set, but even then may still be NULL.  */
+  const char *stop_string;
 };
 
 /* A frame stash used to speed up frame lookups.  Create a hash table
@@ -613,7 +614,7 @@ frame_id_eq (struct frame_id l, struct frame_id r)
        outer_frame_id.  */
     eq = 1;
   else if (l.stack_status == FID_STACK_INVALID
-          || l.stack_status == FID_STACK_INVALID)
+          || r.stack_status == FID_STACK_INVALID)
     /* Like a NaN, if either ID is invalid, the result is false.
        Note that a frame ID is invalid iff it is the null frame ID.  */
     eq = 0;
@@ -695,7 +696,7 @@ frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r)
           && l.special_addr == r.special_addr)
     {
       /* Same function, different inlined functions.  */
-      struct block *lb, *rb;
+      const struct block *lb, *rb;
 
       gdb_assert (l.code_addr_p && r.code_addr_p);
 
@@ -752,9 +753,9 @@ frame_find_by_id (struct frame_id id)
 
   for (frame = get_current_frame (); ; frame = prev_frame)
     {
-      struct frame_id this = get_frame_id (frame);
+      struct frame_id self = get_frame_id (frame);
 
-      if (frame_id_eq (id, this))
+      if (frame_id_eq (id, self))
        /* An exact match.  */
        return frame;
 
@@ -768,7 +769,7 @@ frame_find_by_id (struct frame_id id)
         frame in the current frame chain can have this ID.  See the
         comment at frame_id_inner for details.   */
       if (get_frame_type (frame) == NORMAL_FRAME
-         && !frame_id_inner (get_frame_arch (frame), id, this)
+         && !frame_id_inner (get_frame_arch (frame), id, self)
          && frame_id_inner (get_frame_arch (prev_frame), id,
                             get_frame_id (prev_frame)))
        return NULL;
@@ -783,9 +784,9 @@ frame_unwind_pc (struct frame_info *this_frame)
     {
       if (gdbarch_unwind_pc_p (frame_unwind_arch (this_frame)))
        {
-         volatile struct gdb_exception ex;
          struct gdbarch *prev_gdbarch;
          CORE_ADDR pc = 0;
+         int pc_p = 0;
 
          /* The right way.  The `pure' way.  The one true way.  This
             method depends solely on the register-unwind code to
@@ -805,11 +806,12 @@ frame_unwind_pc (struct frame_info *this_frame)
             different ways that a PC could be unwound.  */
          prev_gdbarch = frame_unwind_arch (this_frame);
 
-         TRY_CATCH (ex, RETURN_MASK_ERROR)
+         TRY
            {
              pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
+             pc_p = 1;
            }
-         if (ex.reason < 0)
+         CATCH (ex, RETURN_MASK_ERROR)
            {
              if (ex.error == NOT_AVAILABLE_ERROR)
                {
@@ -834,7 +836,9 @@ frame_unwind_pc (struct frame_info *this_frame)
              else
                throw_exception (ex);
            }
-         else
+         END_CATCH
+
+         if (pc_p)
            {
              this_frame->prev_pc.value = pc;
              this_frame->prev_pc.status = CC_VALUE;
@@ -956,7 +960,7 @@ frame_pop (struct frame_info *this_frame)
     {
       /* Popping a dummy frame involves restoring more than just registers.
         dummy_frame_pop does all the work.  */
-      dummy_frame_pop (get_frame_id (this_frame));
+      dummy_frame_pop (get_frame_id (this_frame), inferior_ptid);
       return;
     }
 
@@ -1599,13 +1603,13 @@ select_frame (struct frame_info *fi)
         block.  */
       if (get_frame_address_in_block_if_available (fi, &pc))
        {
-         struct symtab *s = find_pc_symtab (pc);
+         struct compunit_symtab *cust = find_pc_compunit_symtab (pc);
 
-         if (s
-             && s->language != current_language->la_language
-             && s->language != language_unknown
+         if (cust != NULL
+             && compunit_language (cust) != current_language->la_language
+             && compunit_language (cust) != language_unknown
              && language_mode == language_mode_auto)
-           set_language (s->language);
+           set_language (compunit_language (cust));
        }
     }
 }
@@ -1798,14 +1802,12 @@ get_prev_frame_if_no_cycle (struct frame_info *this_frame)
   return prev_frame;
 }
 
-/* Return a "struct frame_info" corresponding to the frame that called
-   THIS_FRAME.  Returns NULL if there is no such frame.
+/* Helper function for get_prev_frame_always, this is called inside a
+   TRY_CATCH block.  Return the frame that called THIS_FRAME or NULL if
+   there is no such frame.  This may throw an exception.  */
 
-   Unlike get_prev_frame, this function always tries to unwind the
-   frame.  */
-
-struct frame_info *
-get_prev_frame_always (struct frame_info *this_frame)
+static struct frame_info *
+get_prev_frame_always_1 (struct frame_info *this_frame)
 {
   struct gdbarch *gdbarch;
 
@@ -1955,6 +1957,50 @@ get_prev_frame_always (struct frame_info *this_frame)
   return get_prev_frame_if_no_cycle (this_frame);
 }
 
+/* Return a "struct frame_info" corresponding to the frame that called
+   THIS_FRAME.  Returns NULL if there is no such frame.
+
+   Unlike get_prev_frame, this function always tries to unwind the
+   frame.  */
+
+struct frame_info *
+get_prev_frame_always (struct frame_info *this_frame)
+{
+  struct frame_info *prev_frame = NULL;
+
+  TRY
+    {
+      prev_frame = get_prev_frame_always_1 (this_frame);
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      if (ex.error == MEMORY_ERROR)
+       {
+         this_frame->stop_reason = UNWIND_MEMORY_ERROR;
+         if (ex.message != NULL)
+           {
+             char *stop_string;
+             size_t size;
+
+             /* The error needs to live as long as the frame does.
+                Allocate using stack local STOP_STRING then assign the
+                pointer to the frame, this allows the STOP_STRING on the
+                frame to be of type 'const char *'.  */
+             size = strlen (ex.message) + 1;
+             stop_string = frame_obstack_zalloc (size);
+             memcpy (stop_string, ex.message, size);
+             this_frame->stop_string = stop_string;
+           }
+         prev_frame = NULL;
+       }
+      else
+       throw_exception (ex);
+    }
+  END_CATCH
+
+  return prev_frame;
+}
+
 /* Construct a new "struct frame_info" and link it previous to
    this_frame.  */
 
@@ -2179,21 +2225,21 @@ get_frame_pc (struct frame_info *frame)
 int
 get_frame_pc_if_available (struct frame_info *frame, CORE_ADDR *pc)
 {
-  volatile struct gdb_exception ex;
 
   gdb_assert (frame->next != NULL);
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  TRY
     {
       *pc = frame_unwind_pc (frame->next);
     }
-  if (ex.reason < 0)
+  CATCH (ex, RETURN_MASK_ERROR)
     {
       if (ex.error == NOT_AVAILABLE_ERROR)
        return 0;
       else
        throw_exception (ex);
     }
+  END_CATCH
 
   return 1;
 }
@@ -2264,18 +2310,20 @@ int
 get_frame_address_in_block_if_available (struct frame_info *this_frame,
                                         CORE_ADDR *pc)
 {
-  volatile struct gdb_exception ex;
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  TRY
     {
       *pc = get_frame_address_in_block (this_frame);
     }
-  if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
-    return 0;
-  else if (ex.reason < 0)
-    throw_exception (ex);
-  else
-    return 1;
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      if (ex.error == NOT_AVAILABLE_ERROR)
+       return 0;
+      throw_exception (ex);
+    }
+  END_CATCH
+
+  return 1;
 }
 
 void
@@ -2303,7 +2351,7 @@ find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal)
       init_sal (sal);
       if (SYMBOL_LINE (sym) != 0)
        {
-         sal->symtab = SYMBOL_SYMTAB (sym);
+         sal->symtab = symbol_symtab (sym);
          sal->line = SYMBOL_LINE (sym);
        }
       else
@@ -2561,7 +2609,7 @@ get_frame_unwind_stop_reason (struct frame_info *frame)
 /* Return a string explaining REASON.  */
 
 const char *
-frame_stop_reason_string (enum unwind_stop_reason reason)
+unwind_stop_reason_to_string (enum unwind_stop_reason reason)
 {
   switch (reason)
     {
@@ -2576,6 +2624,20 @@ frame_stop_reason_string (enum unwind_stop_reason reason)
     }
 }
 
+const char *
+frame_stop_reason_string (struct frame_info *fi)
+{
+  gdb_assert (fi->prev_p);
+  gdb_assert (fi->prev == NULL);
+
+  /* Return the specific string if we have one.  */
+  if (fi->stop_string != NULL)
+    return fi->stop_string;
+
+  /* Return the generic string if we have nothing better.  */
+  return unwind_stop_reason_to_string (fi->stop_reason);
+}
+
 /* Return the enum symbol name of REASON as a string, to use in debug
    output.  */
 
@@ -2647,7 +2709,8 @@ static struct cmd_list_element *show_backtrace_cmdlist;
 static void
 set_backtrace_cmd (char *args, int from_tty)
 {
-  help_list (set_backtrace_cmdlist, "set backtrace ", -1, gdb_stdout);
+  help_list (set_backtrace_cmdlist, "set backtrace ", all_commands,
+            gdb_stdout);
 }
 
 static void
This page took 0.028593 seconds and 4 git commands to generate.