doc/ChangeLog:
[deliverable/binutils-gdb.git] / gdb / target.c
index 92a4d6ac2c98c51f335ca4d8e49e861c08470f04..7f53944bacdbca2589e7b3b6c9a9012a300a377d 100644 (file)
@@ -1,7 +1,7 @@
 /* Select target systems and architectures at runtime for GDB.
 
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
@@ -10,7 +10,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -19,9 +19,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include <errno.h>
@@ -41,6 +39,7 @@
 #include "gdbcore.h"
 #include "exceptions.h"
 #include "target-descriptions.h"
+#include "gdb_stdint.h"
 
 static void target_info (char *, int);
 
@@ -205,6 +204,11 @@ int attach_flag;
 
 static int trust_readonly = 0;
 
+/* Nonzero if we should show true memory content including
+   memory breakpoint inserted by gdb.  */
+
+static int show_memory_breakpoints = 0;
+
 /* Non-zero if we want to see trace of target level stuff.  */
 
 static int targetdebug = 0;
@@ -435,7 +439,6 @@ update_current_target (void)
       /* Do not inherit to_follow_fork.  */
       INHERIT (to_insert_exec_catchpoint, t);
       INHERIT (to_remove_exec_catchpoint, t);
-      INHERIT (to_reported_exec_events_per_exec_call, t);
       INHERIT (to_has_exited, t);
       INHERIT (to_mourn_inferior, t);
       INHERIT (to_can_run, t);
@@ -447,9 +450,8 @@ update_current_target (void)
       INHERIT (to_stop, t);
       /* Do not inherit to_xfer_partial.  */
       INHERIT (to_rcmd, t);
-      INHERIT (to_enable_exception_callback, t);
-      INHERIT (to_get_current_exception_event, t);
       INHERIT (to_pid_to_exec_file, t);
+      INHERIT (to_log_command, t);
       INHERIT (to_stratum, t);
       INHERIT (to_has_all_memory, t);
       INHERIT (to_has_memory, t);
@@ -462,7 +464,7 @@ update_current_target (void)
       INHERIT (to_can_async_p, t);
       INHERIT (to_is_async_p, t);
       INHERIT (to_async, t);
-      INHERIT (to_async_mask_value, t);
+      INHERIT (to_async_mask, t);
       INHERIT (to_find_memory_regions, t);
       INHERIT (to_make_corefile_notes, t);
       INHERIT (to_get_thread_local_address, t);
@@ -596,9 +598,6 @@ update_current_target (void)
   de_fault (to_remove_exec_catchpoint,
            (int (*) (int))
            tcomplain);
-  de_fault (to_reported_exec_events_per_exec_call,
-           (int (*) (void))
-           return_one);
   de_fault (to_has_exited,
            (int (*) (int, int, int *))
            return_zero);
@@ -626,12 +625,6 @@ update_current_target (void)
   de_fault (to_rcmd,
            (void (*) (char *, struct ui_file *))
            tcomplain);
-  de_fault (to_enable_exception_callback,
-           (struct symtab_and_line * (*) (enum exception_event_kind, int))
-           nosupport_runtime);
-  de_fault (to_get_current_exception_event,
-           (struct exception_event_record * (*) (void))
-           nosupport_runtime);
   de_fault (to_pid_to_exec_file,
            (char *(*) (int))
            return_zero);
@@ -644,6 +637,9 @@ update_current_target (void)
   de_fault (to_async,
            (void (*) (void (*) (enum inferior_event_type, void*), void*))
            tcomplain);
+  de_fault (to_async_mask,
+           (int (*) (int))
+           return_one);
   current_target.to_read_description = NULL;
 #undef de_fault
 
@@ -651,6 +647,9 @@ update_current_target (void)
      "current_target".  That way code looking for a non-inherited
      target method can quickly and simply find it.  */
   current_target.beneath = target_stack;
+
+  if (targetdebug)
+    setup_target_debug ();
 }
 
 /* Mark OPS as a running target.  This reverses the effect
@@ -754,9 +753,6 @@ push_target (struct target_ops *t)
 
   update_current_target ();
 
-  if (targetdebug)
-    setup_target_debug ();
-
   /* Not on top?  */
   return (t != target_stack);
 }
@@ -813,7 +809,7 @@ pop_target (void)
   internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
 }
 
-/* Using the objfile specified in BATON, find the address for the
+/* Using the objfile specified in OBJFILE, find the address for the
    current thread's thread-local storage with offset OFFSET.  */
 CORE_ADDR
 target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
@@ -919,6 +915,8 @@ target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
   char *bufptr;
   unsigned int nbytes_read = 0;
 
+  gdb_assert (string);
+
   /* Small for testing.  */
   buffer_allocated = 4;
   buffer = xmalloc (buffer_allocated);
@@ -968,10 +966,9 @@ target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
       nbytes_read += tlen;
     }
 done:
+  *string = buffer;
   if (errnop != NULL)
     *errnop = errcode;
-  if (string != NULL)
-    *string = buffer;
   return nbytes_read;
 }
 
@@ -1072,7 +1069,11 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
       if (res <= 0)
        return -1;
       else
-       return res;
+       {
+         if (readbuf && !show_memory_breakpoints)
+           breakpoint_restore_shadows (readbuf, memaddr, reg_len);
+         return res;
+       }
     }
 
   /* If none of those methods found the memory we wanted, fall back
@@ -1090,22 +1091,41 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
       res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
                                  readbuf, writebuf, memaddr, reg_len);
       if (res > 0)
-       return res;
+       break;
 
       /* We want to continue past core files to executables, but not
         past a running target's memory.  */
       if (ops->to_has_all_memory)
-       return res;
+       break;
 
       ops = ops->beneath;
     }
   while (ops != NULL);
 
+  if (readbuf && !show_memory_breakpoints)
+    breakpoint_restore_shadows (readbuf, memaddr, reg_len);
+
   /* If we still haven't got anything, return the last error.  We
      give up.  */
   return res;
 }
 
+static void
+restore_show_memory_breakpoints (void *arg)
+{
+  show_memory_breakpoints = (uintptr_t) arg;
+}
+
+struct cleanup *
+make_show_memory_breakpoints_cleanup (int show)
+{
+  int current = show_memory_breakpoints;
+  show_memory_breakpoints = show;
+
+  return make_cleanup (restore_show_memory_breakpoints,
+                      (void *) (uintptr_t) current);
+}
+
 static LONGEST
 target_xfer_partial (struct target_ops *ops,
                     enum target_object object, const char *annex,
@@ -1338,8 +1358,8 @@ default_xfer_partial (struct target_ops *ops, enum target_object object,
          do_cleanups (cleanup);
        }
       if (readbuf != NULL)
-       xfered = ops->deprecated_xfer_memory (offset, readbuf, len, 0/*read*/,
-                                             NULL, ops);
+       xfered = ops->deprecated_xfer_memory (offset, readbuf, len, 
+                                             0/*read*/, NULL, ops);
       if (xfered > 0)
        return xfered;
       else if (xfered == 0 && errno == 0)
@@ -1677,14 +1697,6 @@ target_disconnect (char *args, int from_tty)
   tcomplain ();
 }
 
-int
-target_async_mask (int mask)
-{
-  int saved_async_masked_status = target_async_mask_value;
-  target_async_mask_value = mask;
-  return saved_async_masked_status;
-}
-
 /* Look through the list of possible targets for a target that can
    follow forks.  */
 
@@ -1731,11 +1743,47 @@ target_read_description (struct target_ops *target)
   return NULL;
 }
 
+/* Look through the currently pushed targets.  If none of them will
+   be able to restart the currently running process, issue an error
+   message.  */
+
+void
+target_require_runnable (void)
+{
+  struct target_ops *t;
+
+  for (t = target_stack; t != NULL; t = t->beneath)
+    {
+      /* If this target knows how to create a new program, then
+        assume we will still be able to after killing the current
+        one.  Either killing and mourning will not pop T, or else
+        find_default_run_target will find it again.  */
+      if (t->to_create_inferior != NULL)
+       return;
+
+      /* Do not worry about thread_stratum targets that can not
+        create inferiors.  Assume they will be pushed again if
+        necessary, and continue to the process_stratum.  */
+      if (t->to_stratum == thread_stratum)
+       continue;
+
+      error (_("\
+The \"%s\" target does not support \"run\".  Try \"help target\" or \"continue\"."),
+            t->to_shortname);
+    }
+
+  /* This function is only called if the target is running.  In that
+     case there should have been a process_stratum target and it
+     should either know how to create inferiors, or not... */
+  internal_error (__FILE__, __LINE__, "No targets found");
+}
+
 /* Look through the list of possible targets for a target that can
    execute a run or attach command without any other data.  This is
    used to locate the default process stratum.
 
-   Result is always valid (error() is called for errors).  */
+   If DO_MESG is not NULL, the result is always valid (error() is
+   called for errors); else, return NULL on error.  */
 
 static struct target_ops *
 find_default_run_target (char *do_mesg)
@@ -1757,7 +1805,12 @@ find_default_run_target (char *do_mesg)
     }
 
   if (count != 1)
-    error (_("Don't know how to %s.  Try \"help target\"."), do_mesg);
+    {
+      if (do_mesg)
+       error (_("Don't know how to %s.  Try \"help target\"."), do_mesg);
+      else
+       return NULL;
+    }
 
   return runable;
 }
@@ -1783,6 +1836,36 @@ find_default_create_inferior (char *exec_file, char *allargs, char **env,
   return;
 }
 
+int
+find_default_can_async_p (void)
+{
+  struct target_ops *t;
+
+  /* This may be called before the target is pushed on the stack;
+     look for the default process stratum.  If there's none, gdb isn't
+     configured with a native debugger, and target remote isn't
+     connected yet.  */
+  t = find_default_run_target (NULL);
+  if (t && t->to_can_async_p)
+    return (t->to_can_async_p) ();
+  return 0;
+}
+
+int
+find_default_is_async_p (void)
+{
+  struct target_ops *t;
+
+  /* This may be called before the target is pushed on the stack;
+     look for the default process stratum.  If there's none, gdb isn't
+     configured with a native debugger, and target remote isn't
+     connected yet.  */
+  t = find_default_run_target (NULL);
+  if (t && t->to_is_async_p)
+    return (t->to_is_async_p) ();
+  return 0;
+}
+
 static int
 default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
@@ -2047,6 +2130,8 @@ init_dummy_target (void)
   dummy_target.to_doc = "";
   dummy_target.to_attach = find_default_attach;
   dummy_target.to_create_inferior = find_default_create_inferior;
+  dummy_target.to_can_async_p = find_default_can_async_p;
+  dummy_target.to_is_async_p = find_default_is_async_p;
   dummy_target.to_pid_to_str = normal_pid_to_str;
   dummy_target.to_stratum = dummy_stratum;
   dummy_target.to_find_memory_regions = dummy_find_memory_regions;
@@ -2166,18 +2251,19 @@ static void
 debug_print_register (const char * func,
                      struct regcache *regcache, int regno)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   fprintf_unfiltered (gdb_stdlog, "%s ", func);
-  if (regno >= 0 && regno < gdbarch_num_regs (current_gdbarch)
-                           + gdbarch_num_pseudo_regs (current_gdbarch)
-      && gdbarch_register_name (current_gdbarch, regno) != NULL
-      && gdbarch_register_name (current_gdbarch, regno)[0] != '\0')
-    fprintf_unfiltered (gdb_stdlog, "(%s)", gdbarch_register_name
-                                             (current_gdbarch, regno));
+  if (regno >= 0 && regno < gdbarch_num_regs (gdbarch)
+                           + gdbarch_num_pseudo_regs (gdbarch)
+      && gdbarch_register_name (gdbarch, regno) != NULL
+      && gdbarch_register_name (gdbarch, regno)[0] != '\0')
+    fprintf_unfiltered (gdb_stdlog, "(%s)",
+                       gdbarch_register_name (gdbarch, regno));
   else
     fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
   if (regno >= 0)
     {
-      int i, size = register_size (current_gdbarch, regno);
+      int i, size = register_size (gdbarch, regno);
       unsigned char buf[MAX_REGISTER_SIZE];
       regcache_cooked_read (regcache, regno, buf);
       fprintf_unfiltered (gdb_stdlog, " = ");
@@ -2578,20 +2664,6 @@ debug_to_remove_exec_catchpoint (int pid)
   return retval;
 }
 
-static int
-debug_to_reported_exec_events_per_exec_call (void)
-{
-  int reported_exec_events;
-
-  reported_exec_events = debug_target.to_reported_exec_events_per_exec_call ();
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_reported_exec_events_per_exec_call () = %d\n",
-                     reported_exec_events);
-
-  return reported_exec_events;
-}
-
 static int
 debug_to_has_exited (int pid, int wait_status, int *exit_status)
 {
@@ -2671,26 +2743,6 @@ debug_to_rcmd (char *command,
   fprintf_unfiltered (gdb_stdlog, "target_rcmd (%s, ...)\n", command);
 }
 
-static struct symtab_and_line *
-debug_to_enable_exception_callback (enum exception_event_kind kind, int enable)
-{
-  struct symtab_and_line *result;
-  result = debug_target.to_enable_exception_callback (kind, enable);
-  fprintf_unfiltered (gdb_stdlog,
-                     "target get_exception_callback_sal (%d, %d)\n",
-                     kind, enable);
-  return result;
-}
-
-static struct exception_event_record *
-debug_to_get_current_exception_event (void)
-{
-  struct exception_event_record *result;
-  result = debug_target.to_get_current_exception_event ();
-  fprintf_unfiltered (gdb_stdlog, "target get_current_exception_event ()\n");
-  return result;
-}
-
 static char *
 debug_to_pid_to_exec_file (int pid)
 {
@@ -2749,7 +2801,6 @@ setup_target_debug (void)
   current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint;
   current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint;
   current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint;
-  current_target.to_reported_exec_events_per_exec_call = debug_to_reported_exec_events_per_exec_call;
   current_target.to_has_exited = debug_to_has_exited;
   current_target.to_mourn_inferior = debug_to_mourn_inferior;
   current_target.to_can_run = debug_to_can_run;
@@ -2758,8 +2809,6 @@ setup_target_debug (void)
   current_target.to_find_new_threads = debug_to_find_new_threads;
   current_target.to_stop = debug_to_stop;
   current_target.to_rcmd = debug_to_rcmd;
-  current_target.to_enable_exception_callback = debug_to_enable_exception_callback;
-  current_target.to_get_current_exception_event = debug_to_get_current_exception_event;
   current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
 }
 \f
This page took 0.030018 seconds and 4 git commands to generate.