Replace clear_hook_in_cleanup with scoped_restore_hook_in
[deliverable/binutils-gdb.git] / gdb / frame.c
index 54dc833202ad8c36b892f78c5b37bf3e0d150cdd..f100da356ab6a1aa4fe87fae98fc5e1f4f7511cf 100644 (file)
@@ -1,6 +1,6 @@
 /* Cache and manage frames for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2016 Free Software Foundation, Inc.
+   Copyright (C) 1986-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -1107,7 +1107,10 @@ frame_register_unwind (struct frame_info *frame, int regnum,
   *unavailablep = !value_entirely_available (value);
   *lvalp = VALUE_LVAL (value);
   *addrp = value_address (value);
-  *realnump = VALUE_REGNUM (value);
+  if (*lvalp == lval_register)
+    *realnump = VALUE_REGNUM (value);
+  else
+    *realnump = -1;
 
   if (bufferp)
     {
@@ -1249,10 +1252,27 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  struct value *value = frame_unwind_register_value (frame, regnum);
+
+  gdb_assert (value != NULL);
+
+  if (value_optimized_out (value))
+    {
+      throw_error (OPTIMIZED_OUT_ERROR,
+                  _("Register %d was not saved"), regnum);
+    }
+  if (!value_entirely_available (value))
+    {
+      throw_error (NOT_AVAILABLE_ERROR,
+                  _("Register %d is not available"), regnum);
+    }
+
+  LONGEST r = extract_signed_integer (value_contents_all (value), size,
+                                     byte_order);
 
-  frame_unwind_register (frame, regnum, buf);
-  return extract_signed_integer (buf, size, byte_order);
+  release_value (value);
+  value_free (value);
+  return r;
 }
 
 LONGEST
@@ -1267,10 +1287,27 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  struct value *value = frame_unwind_register_value (frame, regnum);
 
-  frame_unwind_register (frame, regnum, buf);
-  return extract_unsigned_integer (buf, size, byte_order);
+  gdb_assert (value != NULL);
+
+  if (value_optimized_out (value))
+    {
+      throw_error (OPTIMIZED_OUT_ERROR,
+                  _("Register %d was not saved"), regnum);
+    }
+  if (!value_entirely_available (value))
+    {
+      throw_error (NOT_AVAILABLE_ERROR,
+                  _("Register %d is not available"), regnum);
+    }
+
+  ULONGEST r = extract_unsigned_integer (value_contents_all (value), size,
+                                        byte_order);
+
+  release_value (value);
+  value_free (value);
+  return r;
 }
 
 ULONGEST
@@ -1407,16 +1444,21 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
        }
       else
        {
-         gdb_byte buf[MAX_REGISTER_SIZE];
-         enum lval_type lval;
-         CORE_ADDR addr;
-         int realnum;
+         struct value *value = frame_unwind_register_value (frame->next,
+                                                            regnum);
+         gdb_assert (value != NULL);
+         *optimizedp = value_optimized_out (value);
+         *unavailablep = !value_entirely_available (value);
 
-         frame_register (frame, regnum, optimizedp, unavailablep,
-                         &lval, &addr, &realnum, buf);
          if (*optimizedp || *unavailablep)
-           return 0;
-         memcpy (myaddr, buf + offset, curr_len);
+           {
+             release_value (value);
+             value_free (value);
+             return 0;
+           }
+         memcpy (myaddr, value_contents_all (value) + offset, curr_len);
+         release_value (value);
+         value_free (value);
        }
 
       myaddr += curr_len;
@@ -1457,11 +1499,15 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
        }
       else
        {
-         gdb_byte buf[MAX_REGISTER_SIZE];
-
-         deprecated_frame_register_read (frame, regnum, buf);
-         memcpy (buf + offset, myaddr, curr_len);
-         put_frame_register (frame, regnum, buf);
+         struct value *value = frame_unwind_register_value (frame->next,
+                                                            regnum);
+         gdb_assert (value != NULL);
+
+         memcpy ((char *) value_contents_writeable (value) + offset, myaddr,
+                 curr_len);
+         put_frame_register (frame, regnum, value_contents_raw (value));
+         release_value (value);
+         value_free (value);
        }
 
       myaddr += curr_len;
@@ -1675,6 +1721,23 @@ select_frame (struct frame_info *fi)
     }
 }
 
+#if GDB_SELF_TEST
+struct frame_info *
+create_test_frame (struct regcache *regcache)
+{
+  struct frame_info *this_frame = XCNEW (struct frame_info);
+
+  sentinel_frame = create_sentinel_frame (NULL, regcache);
+  sentinel_frame->prev = this_frame;
+  sentinel_frame->prev_p = 1;;
+  this_frame->prev_arch.p = 1;
+  this_frame->prev_arch.arch = get_regcache_arch (regcache);
+  this_frame->next = sentinel_frame;
+
+  return this_frame;
+}
+#endif
+
 /* Create an arbitrary (i.e. address specified by user) or innermost frame.
    Always returns a non-NULL value.  */
 
@@ -2220,6 +2283,17 @@ get_prev_frame (struct frame_info *this_frame)
      something should be calling get_selected_frame() or
      get_current_frame().  */
   gdb_assert (this_frame != NULL);
+  
+  /* If this_frame is the current frame, then compute and stash
+     its frame id prior to fetching and computing the frame id of the
+     previous frame.  Otherwise, the cycle detection code in
+     get_prev_frame_if_no_cycle() will not work correctly.  When
+     get_frame_id() is called later on, an assertion error will
+     be triggered in the event of a cycle between the current
+     frame and its previous frame.  */
+  if (this_frame->level == 0)
+    get_frame_id (this_frame);
+
   frame_pc_p = get_frame_pc_if_available (this_frame, &frame_pc);
 
   /* tausq/2004-12-07: Dummy frames are skipped because it doesn't make much
@@ -2305,6 +2379,22 @@ get_prev_frame (struct frame_info *this_frame)
   return get_prev_frame_always (this_frame);
 }
 
+struct frame_id
+get_prev_frame_id_by_id (struct frame_id id)
+{
+  struct frame_id prev_id;
+  struct frame_info *frame;
+  
+  frame = frame_find_by_id (id);
+
+  if (frame != NULL)
+    prev_id = get_frame_id (get_prev_frame (frame));
+  else
+    prev_id = null_frame_id;
+
+  return prev_id;
+}
+
 CORE_ADDR
 get_frame_pc (struct frame_info *frame)
 {
@@ -2416,8 +2506,8 @@ get_frame_address_in_block_if_available (struct frame_info *this_frame,
   return 1;
 }
 
-void
-find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal)
+symtab_and_line
+find_frame_sal (frame_info *frame)
 {
   struct frame_info *next_frame;
   int notcurrent;
@@ -2438,21 +2528,21 @@ find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal)
 
       /* If frame is inline, it certainly has symbols.  */
       gdb_assert (sym);
-      init_sal (sal);
+
+      symtab_and_line sal;
       if (SYMBOL_LINE (sym) != 0)
        {
-         sal->symtab = symbol_symtab (sym);
-         sal->line = SYMBOL_LINE (sym);
+         sal.symtab = symbol_symtab (sym);
+         sal.line = SYMBOL_LINE (sym);
        }
       else
        /* If the symbol does not have a location, we don't know where
           the call site is.  Do not pretend to.  This is jarring, but
           we can't do much better.  */
-       sal->pc = get_frame_pc (frame);
+       sal.pc = get_frame_pc (frame);
 
-      sal->pspace = get_frame_program_space (frame);
-
-      return;
+      sal.pspace = get_frame_program_space (frame);
+      return sal;
     }
 
   /* If FRAME is not the innermost frame, that normally means that
@@ -2465,13 +2555,10 @@ find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal)
      instruction/line, consequently, for such cases, want to get the
      line containing fi->pc.  */
   if (!get_frame_pc_if_available (frame, &pc))
-    {
-      init_sal (sal);
-      return;
-    }
+    return {};
 
   notcurrent = (pc != get_frame_address_in_block (frame));
-  (*sal) = find_pc_line (pc, notcurrent);
+  return find_pc_line (pc, notcurrent);
 }
 
 /* Per "frame.h", return the ``address'' of the frame.  Code should
@@ -2840,8 +2927,6 @@ frame_prepare_for_sniffer (struct frame_info *frame,
   return make_cleanup (frame_cleanup_after_sniffer, frame);
 }
 
-extern initialize_file_ftype _initialize_frame; /* -Wmissing-prototypes */
-
 static struct cmd_list_element *set_backtrace_cmdlist;
 static struct cmd_list_element *show_backtrace_cmdlist;
 
This page took 0.027227 seconds and 4 git commands to generate.