Move 'is_regular_file' from common-utils.c to filestuff.c
[deliverable/binutils-gdb.git] / gdb / frame.c
index 17f7397aeebe8054c1ca7c49885f2bb18cabe14f..0dc2cb7e7160189ad188f52121f49ac6b76c7e3e 100644 (file)
@@ -1,6 +1,6 @@
 /* Cache and manage frames for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2017 Free Software Foundation, Inc.
+   Copyright (C) 1986-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -34,7 +34,7 @@
 #include "frame-base.h"
 #include "command.h"
 #include "gdbcmd.h"
-#include "observer.h"
+#include "observable.h"
 #include "objfiles.h"
 #include "gdbthread.h"
 #include "block.h"
@@ -99,7 +99,7 @@ struct frame_info
   struct program_space *pspace;
 
   /* The frame's address space.  */
-  struct address_space *aspace;
+  const address_space *aspace;
 
   /* The frame's low-level unwinder and corresponding cache.  The
      low-level unwinder is responsible for unwinding register values
@@ -269,6 +269,22 @@ frame_stash_invalidate (void)
   htab_empty (frame_stash);
 }
 
+/* See frame.h  */
+scoped_restore_selected_frame::scoped_restore_selected_frame ()
+{
+  m_fid = get_frame_id (get_selected_frame (NULL));
+}
+
+/* See frame.h  */
+scoped_restore_selected_frame::~scoped_restore_selected_frame ()
+{
+  frame_info *frame = frame_find_by_id (m_fid);
+  if (frame == NULL)
+    warning (_("Unable to restore previously selected frame."));
+  else
+    select_frame (frame);
+}
+
 /* Flag to control debugging.  */
 
 unsigned int frame_debug;
@@ -1008,23 +1024,20 @@ get_frame_func (struct frame_info *this_frame)
   return pc;
 }
 
-static enum register_status
-do_frame_register_read (void *src, int regnum, gdb_byte *buf)
-{
-  if (!deprecated_frame_register_read ((struct frame_info *) src, regnum, buf))
-    return REG_UNAVAILABLE;
-  else
-    return REG_VALID;
-}
-
-std::unique_ptr<struct regcache>
+std::unique_ptr<readonly_detached_regcache>
 frame_save_as_regcache (struct frame_info *this_frame)
 {
-  struct address_space *aspace = get_frame_address_space (this_frame);
-  std::unique_ptr<struct regcache> regcache
-    (new struct regcache (get_frame_arch (this_frame), aspace));
+  auto cooked_read = [this_frame] (int regnum, gdb_byte *buf)
+    {
+      if (!deprecated_frame_register_read (this_frame, regnum, buf))
+       return REG_UNAVAILABLE;
+      else
+       return REG_VALID;
+    };
+
+  std::unique_ptr<readonly_detached_regcache> regcache
+    (new readonly_detached_regcache (get_frame_arch (this_frame), cooked_read));
 
-  regcache_save (regcache.get (), do_frame_register_read, this_frame);
   return regcache;
 }
 
@@ -1037,7 +1050,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), inferior_ptid);
+      dummy_frame_pop (get_frame_id (this_frame), inferior_thread ());
       return;
     }
 
@@ -1058,7 +1071,7 @@ frame_pop (struct frame_info *this_frame)
      Save them in a scratch buffer so that there isn't a race between
      trying to extract the old values from the current regcache while
      at the same time writing new values into that same cache.  */
-  std::unique_ptr<struct regcache> scratch
+  std::unique_ptr<readonly_detached_regcache> scratch
     = frame_save_as_regcache (prev_frame);
 
   /* FIXME: cagney/2003-03-16: It should be possible to tell the
@@ -1069,9 +1082,8 @@ frame_pop (struct frame_info *this_frame)
      Unfortunately, they don't implement it.  Their lack of a formal
      definition can lead to targets writing back bogus values
      (arguably a bug in the target code mind).  */
-  /* Now copy those saved registers into the current regcache.
-     Here, regcache_cpy() calls regcache_restore().  */
-  regcache_cpy (get_current_regcache (), scratch.get ());
+  /* Now copy those saved registers into the current regcache.  */
+  get_current_regcache ()->restore (scratch.get ());
 
   /* We've made right mess of GDB's local state, just discard
      everything.  */
@@ -1079,7 +1091,7 @@ frame_pop (struct frame_info *this_frame)
 }
 
 void
-frame_register_unwind (struct frame_info *frame, int regnum,
+frame_register_unwind (frame_info *next_frame, int regnum,
                       int *optimizedp, int *unavailablep,
                       enum lval_type *lvalp, CORE_ADDR *addrp,
                       int *realnump, gdb_byte *bufferp)
@@ -1094,7 +1106,7 @@ frame_register_unwind (struct frame_info *frame, int regnum,
   gdb_assert (realnump != NULL);
   /* gdb_assert (bufferp != NULL); */
 
-  value = frame_unwind_register_value (frame, regnum);
+  value = frame_unwind_register_value (next_frame, regnum);
 
   gdb_assert (value != NULL);
 
@@ -1119,7 +1131,6 @@ frame_register_unwind (struct frame_info *frame, int regnum,
   /* Dispose of the new value.  This prevents watchpoints from
      trying to watch the saved frame pointer.  */
   release_value (value);
-  value_free (value);
 }
 
 void
@@ -1143,7 +1154,7 @@ frame_register (struct frame_info *frame, int regnum,
 }
 
 void
-frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf)
+frame_unwind_register (frame_info *next_frame, int regnum, gdb_byte *buf)
 {
   int optimized;
   int unavailable;
@@ -1151,7 +1162,7 @@ frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf)
   int realnum;
   enum lval_type lval;
 
-  frame_register_unwind (frame, regnum, &optimized, &unavailable,
+  frame_register_unwind (next_frame, regnum, &optimized, &unavailable,
                         &lval, &addr, &realnum, buf);
 
   if (optimized)
@@ -1170,29 +1181,31 @@ get_frame_register (struct frame_info *frame,
 }
 
 struct value *
-frame_unwind_register_value (struct frame_info *frame, int regnum)
+frame_unwind_register_value (frame_info *next_frame, int regnum)
 {
   struct gdbarch *gdbarch;
   struct value *value;
 
-  gdb_assert (frame != NULL);
-  gdbarch = frame_unwind_arch (frame);
+  gdb_assert (next_frame != NULL);
+  gdbarch = frame_unwind_arch (next_frame);
 
   if (frame_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
                          "{ frame_unwind_register_value "
                          "(frame=%d,regnum=%d(%s),...) ",
-                         frame->level, regnum,
+                         next_frame->level, regnum,
                          user_reg_map_regnum_to_name (gdbarch, regnum));
     }
 
   /* Find the unwinder.  */
-  if (frame->unwind == NULL)
-    frame_unwind_find_by_frame (frame, &frame->prologue_cache);
+  if (next_frame->unwind == NULL)
+    frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache);
 
   /* Ask this frame to unwind its register.  */
-  value = frame->unwind->prev_register (frame, &frame->prologue_cache, regnum);
+  value = next_frame->unwind->prev_register (next_frame,
+                                            &next_frame->prologue_cache,
+                                            regnum);
 
   if (frame_debug)
     {
@@ -1242,12 +1255,12 @@ get_frame_register_value (struct frame_info *frame, int regnum)
 }
 
 LONGEST
-frame_unwind_register_signed (struct frame_info *frame, int regnum)
+frame_unwind_register_signed (frame_info *next_frame, int regnum)
 {
-  struct gdbarch *gdbarch = frame_unwind_arch (frame);
+  struct gdbarch *gdbarch = frame_unwind_arch (next_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  struct value *value = frame_unwind_register_value (frame, regnum);
+  struct value *value = frame_unwind_register_value (next_frame, regnum);
 
   gdb_assert (value != NULL);
 
@@ -1266,7 +1279,6 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum)
                                      byte_order);
 
   release_value (value);
-  value_free (value);
   return r;
 }
 
@@ -1277,12 +1289,12 @@ get_frame_register_signed (struct frame_info *frame, int regnum)
 }
 
 ULONGEST
-frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
+frame_unwind_register_unsigned (frame_info *next_frame, int regnum)
 {
-  struct gdbarch *gdbarch = frame_unwind_arch (frame);
+  struct gdbarch *gdbarch = frame_unwind_arch (next_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  struct value *value = frame_unwind_register_value (frame, regnum);
+  struct value *value = frame_unwind_register_value (next_frame, regnum);
 
   gdb_assert (value != NULL);
 
@@ -1301,7 +1313,6 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
                                         byte_order);
 
   release_value (value);
-  value_free (value);
   return r;
 }
 
@@ -1354,7 +1365,7 @@ put_frame_register (struct frame_info *frame, int regnum,
        break;
       }
     case lval_register:
-      regcache_cooked_write (get_current_regcache (), realnum, buf);
+      get_current_regcache ()->cooked_write (realnum, buf);
       break;
     default:
       error (_("Attempt to assign to an unmodifiable value."));
@@ -1448,12 +1459,10 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
          if (*optimizedp || *unavailablep)
            {
              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;
@@ -1502,7 +1511,6 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
                  curr_len);
          put_frame_register (frame, regnum, value_contents_raw (value));
          release_value (value);
-         value_free (value);
        }
 
       myaddr += curr_len;
@@ -1521,7 +1529,7 @@ create_sentinel_frame (struct program_space *pspace, struct regcache *regcache)
 
   frame->level = -1;
   frame->pspace = pspace;
-  frame->aspace = get_regcache_aspace (regcache);
+  frame->aspace = regcache->aspace ();
   /* Explicitly initialize the sentinel frame's cache.  Provide it
      with the underlying regcache.  In the future additional
      information, such as the frame's thread will be added.  */
@@ -1616,15 +1624,16 @@ has_stack_frames (void)
   if (get_traceframe_number () < 0)
     {
       /* No current inferior, no frame.  */
-      if (ptid_equal (inferior_ptid, null_ptid))
+      if (inferior_ptid == null_ptid)
        return 0;
 
+      thread_info *tp = inferior_thread ();
       /* Don't try to read from a dead thread.  */
-      if (is_exited (inferior_ptid))
+      if (tp->state == THREAD_EXITED)
        return 0;
 
       /* ... or from a spinning thread.  */
-      if (is_executing (inferior_ptid))
+      if (tp->executing)
        return 0;
     }
 
@@ -1863,22 +1872,6 @@ frame_register_unwind_location (struct frame_info *this_frame, int regnum,
     }
 }
 
-/* Called during frame unwinding to remove a previous frame pointer from a
-   frame passed in ARG.  */
-
-static void
-remove_prev_frame (void *arg)
-{
-  struct frame_info *this_frame, *prev_frame;
-
-  this_frame = (struct frame_info *) arg;
-  prev_frame = this_frame->prev;
-  gdb_assert (prev_frame != NULL);
-
-  prev_frame->next = NULL;
-  this_frame->prev = NULL;
-}
-
 /* Get the previous raw frame, and check that it is not identical to
    same other frame frame already in the chain.  If it is, there is
    most likely a stack cycle, so we discard it, and mark THIS_FRAME as
@@ -1891,7 +1884,6 @@ static struct frame_info *
 get_prev_frame_if_no_cycle (struct frame_info *this_frame)
 {
   struct frame_info *prev_frame;
-  struct cleanup *prev_frame_cleanup;
 
   prev_frame = get_prev_frame_raw (this_frame);
 
@@ -1907,29 +1899,35 @@ get_prev_frame_if_no_cycle (struct frame_info *this_frame)
   if (prev_frame->level == 0)
     return prev_frame;
 
-  /* The cleanup will remove the previous frame that get_prev_frame_raw
-     linked onto THIS_FRAME.  */
-  prev_frame_cleanup = make_cleanup (remove_prev_frame, this_frame);
-
-  compute_frame_id (prev_frame);
-  if (!frame_stash_add (prev_frame))
+  TRY
     {
-      /* Another frame with the same id was already in the stash.  We just
-        detected a cycle.  */
-      if (frame_debug)
+      compute_frame_id (prev_frame);
+      if (!frame_stash_add (prev_frame))
        {
-         fprintf_unfiltered (gdb_stdlog, "-> ");
-         fprint_frame (gdb_stdlog, NULL);
-         fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
+         /* Another frame with the same id was already in the stash.  We just
+            detected a cycle.  */
+         if (frame_debug)
+           {
+             fprintf_unfiltered (gdb_stdlog, "-> ");
+             fprint_frame (gdb_stdlog, NULL);
+             fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
+           }
+         this_frame->stop_reason = UNWIND_SAME_ID;
+         /* Unlink.  */
+         prev_frame->next = NULL;
+         this_frame->prev = NULL;
+         prev_frame = NULL;
        }
-      this_frame->stop_reason = UNWIND_SAME_ID;
-      /* Unlink.  */
+    }
+  CATCH (ex, RETURN_MASK_ALL)
+    {
       prev_frame->next = NULL;
       this_frame->prev = NULL;
-      prev_frame = NULL;
+
+      throw_exception (ex);
     }
+  END_CATCH
 
-  discard_cleanups (prev_frame_cleanup);
   return prev_frame;
 }
 
@@ -2225,7 +2223,7 @@ inside_main_func (struct frame_info *this_frame)
      returned.  */
   maddr = gdbarch_convert_from_func_ptr_addr (get_frame_arch (this_frame),
                                              BMSYMBOL_VALUE_ADDRESS (msymbol),
-                                             &current_target);
+                                             current_top_target ());
   return maddr == get_frame_func (this_frame);
 }
 
@@ -2502,7 +2500,7 @@ find_frame_sal (frame_info *frame)
       if (next_frame)
        sym = get_frame_function (next_frame);
       else
-       sym = inline_skipped_symbol (inferior_ptid);
+       sym = inline_skipped_symbol (inferior_thread ());
 
       /* If frame is inline, it certainly has symbols.  */
       gdb_assert (sym);
@@ -2643,7 +2641,7 @@ frame_unwind_program_space (struct frame_info *this_frame)
   return this_frame->pspace;
 }
 
-struct address_space *
+const address_space *
 get_frame_address_space (struct frame_info *frame)
 {
   return frame->aspace;
@@ -2906,14 +2904,14 @@ static struct cmd_list_element *set_backtrace_cmdlist;
 static struct cmd_list_element *show_backtrace_cmdlist;
 
 static void
-set_backtrace_cmd (char *args, int from_tty)
+set_backtrace_cmd (const char *args, int from_tty)
 {
   help_list (set_backtrace_cmdlist, "set backtrace ", all_commands,
             gdb_stdout);
 }
 
 static void
-show_backtrace_cmd (char *args, int from_tty)
+show_backtrace_cmd (const char *args, int from_tty)
 {
   cmd_show_list (show_backtrace_cmdlist, from_tty, "");
 }
@@ -2925,7 +2923,7 @@ _initialize_frame (void)
 
   frame_stash_create ();
 
-  observer_attach_target_changed (frame_observer_target_changed);
+  gdb::observers::target_changed.attach (frame_observer_target_changed);
 
   add_prefix_cmd ("backtrace", class_maintenance, set_backtrace_cmd, _("\
 Set backtrace specific variables.\n\
This page took 0.031296 seconds and 4 git commands to generate.