ld/
[deliverable/binutils-gdb.git] / gdb / target.c
index 7133ebe85999fa08eb894360acad0b890c7c5c87..87ddf249e0a8eeff0ce2c373083fa5538df15467 100644 (file)
@@ -1,7 +1,7 @@
 /* Select target systems and architectures at runtime for GDB.
 
 /* 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
+   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
    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
 
    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,
    (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
    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>
 
 #include "defs.h"
 #include <errno.h>
@@ -106,11 +104,11 @@ static void debug_to_resume (ptid_t, int, enum target_signal);
 
 static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
 
 
 static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
 
-static void debug_to_fetch_registers (int);
+static void debug_to_fetch_registers (struct regcache *, int);
 
 
-static void debug_to_store_registers (int);
+static void debug_to_store_registers (struct regcache *, int);
 
 
-static void debug_to_prepare_to_store (void);
+static void debug_to_prepare_to_store (struct regcache *);
 
 static void debug_to_files_info (struct target_ops *);
 
 
 static void debug_to_files_info (struct target_ops *);
 
@@ -379,7 +377,7 @@ update_current_target (void)
 {
   struct target_ops *t;
 
 {
   struct target_ops *t;
 
-  /* First, reset curren'ts contents.  */
+  /* First, reset current's contents.  */
   memset (&current_target, 0, sizeof (current_target));
 
 #define INHERIT(FIELD, TARGET) \
   memset (&current_target, 0, sizeof (current_target));
 
 #define INHERIT(FIELD, TARGET) \
@@ -413,6 +411,7 @@ update_current_target (void)
       INHERIT (to_remove_watchpoint, t);
       INHERIT (to_stopped_data_address, t);
       INHERIT (to_stopped_by_watchpoint, t);
       INHERIT (to_remove_watchpoint, t);
       INHERIT (to_stopped_data_address, t);
       INHERIT (to_stopped_by_watchpoint, t);
+      INHERIT (to_have_steppable_watchpoint, t);
       INHERIT (to_have_continuable_watchpoint, t);
       INHERIT (to_region_ok_for_hw_watchpoint, t);
       INHERIT (to_terminal_init, t);
       INHERIT (to_have_continuable_watchpoint, t);
       INHERIT (to_region_ok_for_hw_watchpoint, t);
       INHERIT (to_terminal_init, t);
@@ -446,9 +445,8 @@ update_current_target (void)
       INHERIT (to_stop, t);
       /* Do not inherit to_xfer_partial.  */
       INHERIT (to_rcmd, t);
       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_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);
       INHERIT (to_stratum, t);
       INHERIT (to_has_all_memory, t);
       INHERIT (to_has_memory, t);
@@ -502,13 +500,13 @@ update_current_target (void)
            (ptid_t (*) (ptid_t, struct target_waitstatus *))
            noprocess);
   de_fault (to_fetch_registers,
            (ptid_t (*) (ptid_t, struct target_waitstatus *))
            noprocess);
   de_fault (to_fetch_registers,
-           (void (*) (int))
+           (void (*) (struct regcache *, int))
            target_ignore);
   de_fault (to_store_registers,
            target_ignore);
   de_fault (to_store_registers,
-           (void (*) (int))
+           (void (*) (struct regcache *, int))
            noprocess);
   de_fault (to_prepare_to_store,
            noprocess);
   de_fault (to_prepare_to_store,
-           (void (*) (void))
+           (void (*) (struct regcache *))
            noprocess);
   de_fault (deprecated_xfer_memory,
            (int (*) (CORE_ADDR, gdb_byte *, int, int, struct mem_attrib *, struct target_ops *))
            noprocess);
   de_fault (deprecated_xfer_memory,
            (int (*) (CORE_ADDR, gdb_byte *, int, int, struct mem_attrib *, struct target_ops *))
@@ -625,12 +623,6 @@ update_current_target (void)
   de_fault (to_rcmd,
            (void (*) (char *, struct ui_file *))
            tcomplain);
   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);
   de_fault (to_pid_to_exec_file,
            (char *(*) (int))
            return_zero);
@@ -650,6 +642,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;
      "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
 }
 
 /* Mark OPS as a running target.  This reverses the effect
@@ -753,9 +748,6 @@ push_target (struct target_ops *t)
 
   update_current_target ();
 
 
   update_current_target ();
 
-  if (targetdebug)
-    setup_target_debug ();
-
   /* Not on top?  */
   return (t != target_stack);
 }
   /* Not on top?  */
   return (t != target_stack);
 }
@@ -812,7 +804,7 @@ pop_target (void)
   internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
 }
 
   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)
    current thread's thread-local storage with offset OFFSET.  */
 CORE_ADDR
 target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
@@ -918,6 +910,8 @@ target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
   char *bufptr;
   unsigned int nbytes_read = 0;
 
   char *bufptr;
   unsigned int nbytes_read = 0;
 
+  gdb_assert (string);
+
   /* Small for testing.  */
   buffer_allocated = 4;
   buffer = xmalloc (buffer_allocated);
   /* Small for testing.  */
   buffer_allocated = 4;
   buffer = xmalloc (buffer_allocated);
@@ -967,10 +961,9 @@ target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
       nbytes_read += tlen;
     }
 done:
       nbytes_read += tlen;
     }
 done:
+  *string = buffer;
   if (errnop != NULL)
     *errnop = errcode;
   if (errnop != NULL)
     *errnop = errcode;
-  if (string != NULL)
-    *string = buffer;
   return nbytes_read;
 }
 
   return nbytes_read;
 }
 
@@ -1016,6 +1009,14 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
        return xfer_memory (memaddr, readbuf, len, 0, NULL, ops);
     }
 
        return xfer_memory (memaddr, readbuf, len, 0, NULL, ops);
     }
 
+  /* Likewise for accesses to unmapped overlay sections.  */
+  if (readbuf != NULL && overlay_debugging)
+    {
+      asection *section = find_pc_overlay (memaddr);
+      if (pc_in_unmapped_range (memaddr, section))
+       return xfer_memory (memaddr, readbuf, len, 0, NULL, ops);
+    }
+
   /* Try GDB's internal data cache.  */
   region = lookup_mem_region (memaddr);
   /* region->hi == 0 means there's no upper bound.  */
   /* Try GDB's internal data cache.  */
   region = lookup_mem_region (memaddr);
   /* region->hi == 0 means there's no upper bound.  */
@@ -1083,6 +1084,11 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
       if (res > 0)
        return res;
 
       if (res > 0)
        return res;
 
+      /* 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;
+
       ops = ops->beneath;
     }
   while (ops != NULL);
       ops = ops->beneath;
     }
   while (ops != NULL);
@@ -1252,7 +1258,8 @@ target_flash_erase (ULONGEST address, LONGEST length)
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog, "target_flash_erase (%s, %s)\n",
                                 paddr (address), phex (length, 0));
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog, "target_flash_erase (%s, %s)\n",
                                 paddr (address), phex (length, 0));
-         return t->to_flash_erase (t, address, length);
+         t->to_flash_erase (t, address, length);
+         return;
        }
 
   tcomplain ();
        }
 
   tcomplain ();
@@ -1268,7 +1275,8 @@ target_flash_done (void)
        {
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog, "target_flash_done\n");
        {
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog, "target_flash_done\n");
-         return t->to_flash_done (t);
+         t->to_flash_done (t);
+         return;
        }
 
   tcomplain ();
        }
 
   tcomplain ();
@@ -1322,8 +1330,8 @@ default_xfer_partial (struct target_ops *ops, enum target_object object,
          do_cleanups (cleanup);
        }
       if (readbuf != NULL)
          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)
       if (xfered > 0)
        return xfered;
       else if (xfered == 0 && errno == 0)
@@ -1967,19 +1975,12 @@ generic_mourn_inferior (void)
     deprecated_detach_hook ();
 }
 \f
     deprecated_detach_hook ();
 }
 \f
-/* Helper function for child_wait and the Lynx derivatives of child_wait.
+/* Helper function for child_wait and the derivatives of child_wait.
    HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
    translation of that in OURSTATUS.  */
 void
 store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
 {
    HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
    translation of that in OURSTATUS.  */
 void
 store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
 {
-#ifdef CHILD_SPECIAL_WAITSTATUS
-  /* CHILD_SPECIAL_WAITSTATUS should return nonzero and set *OURSTATUS
-     if it wants to deal with hoststatus.  */
-  if (CHILD_SPECIAL_WAITSTATUS (ourstatus, hoststatus))
-    return;
-#endif
-
   if (WIFEXITED (hoststatus))
     {
       ourstatus->kind = TARGET_WAITKIND_EXITED;
   if (WIFEXITED (hoststatus))
     {
       ourstatus->kind = TARGET_WAITKIND_EXITED;
@@ -2154,53 +2155,58 @@ debug_to_wait (ptid_t ptid, struct target_waitstatus *status)
 }
 
 static void
 }
 
 static void
-debug_print_register (const char * func, int regno)
+debug_print_register (const char * func,
+                     struct regcache *regcache, int regno)
 {
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   fprintf_unfiltered (gdb_stdlog, "%s ", func);
   fprintf_unfiltered (gdb_stdlog, "%s ", func);
-  if (regno >= 0 && regno < NUM_REGS + NUM_PSEUDO_REGS
-      && REGISTER_NAME (regno) != NULL && REGISTER_NAME (regno)[0] != '\0')
-    fprintf_unfiltered (gdb_stdlog, "(%s)", REGISTER_NAME (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)
     {
   else
     fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
   if (regno >= 0)
     {
-      int i;
+      int i, size = register_size (gdbarch, regno);
       unsigned char buf[MAX_REGISTER_SIZE];
       unsigned char buf[MAX_REGISTER_SIZE];
-      deprecated_read_register_gen (regno, buf);
+      regcache_cooked_read (regcache, regno, buf);
       fprintf_unfiltered (gdb_stdlog, " = ");
       fprintf_unfiltered (gdb_stdlog, " = ");
-      for (i = 0; i < register_size (current_gdbarch, regno); i++)
+      for (i = 0; i < size; i++)
        {
          fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
        }
        {
          fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
        }
-      if (register_size (current_gdbarch, regno) <= sizeof (LONGEST))
+      if (size <= sizeof (LONGEST))
        {
        {
+         ULONGEST val = extract_unsigned_integer (buf, size);
          fprintf_unfiltered (gdb_stdlog, " 0x%s %s",
          fprintf_unfiltered (gdb_stdlog, " 0x%s %s",
-                             paddr_nz (read_register (regno)),
-                             paddr_d (read_register (regno)));
+                             paddr_nz (val), paddr_d (val));
        }
     }
   fprintf_unfiltered (gdb_stdlog, "\n");
 }
 
 static void
        }
     }
   fprintf_unfiltered (gdb_stdlog, "\n");
 }
 
 static void
-debug_to_fetch_registers (int regno)
+debug_to_fetch_registers (struct regcache *regcache, int regno)
 {
 {
-  debug_target.to_fetch_registers (regno);
-  debug_print_register ("target_fetch_registers", regno);
+  debug_target.to_fetch_registers (regcache, regno);
+  debug_print_register ("target_fetch_registers", regcache, regno);
 }
 
 static void
 }
 
 static void
-debug_to_store_registers (int regno)
+debug_to_store_registers (struct regcache *regcache, int regno)
 {
 {
-  debug_target.to_store_registers (regno);
-  debug_print_register ("target_store_registers", regno);
+  debug_target.to_store_registers (regcache, regno);
+  debug_print_register ("target_store_registers", regcache, regno);
   fprintf_unfiltered (gdb_stdlog, "\n");
 }
 
 static void
   fprintf_unfiltered (gdb_stdlog, "\n");
 }
 
 static void
-debug_to_prepare_to_store (void)
+debug_to_prepare_to_store (struct regcache *regcache)
 {
 {
-  debug_target.to_prepare_to_store ();
+  debug_target.to_prepare_to_store (regcache);
 
   fprintf_unfiltered (gdb_stdlog, "target_prepare_to_store ()\n");
 }
 
   fprintf_unfiltered (gdb_stdlog, "target_prepare_to_store ()\n");
 }
@@ -2658,26 +2664,6 @@ debug_to_rcmd (char *command,
   fprintf_unfiltered (gdb_stdlog, "target_rcmd (%s, ...)\n", 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)
 {
 static char *
 debug_to_pid_to_exec_file (int pid)
 {
@@ -2745,8 +2731,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_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
   current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
 }
 \f
@@ -2769,6 +2753,21 @@ do_monitor_command (char *cmd,
   target_rcmd (cmd, gdb_stdtarg);
 }
 
   target_rcmd (cmd, gdb_stdtarg);
 }
 
+/* Print the name of each layers of our target stack.  */
+
+static void
+maintenance_print_target_stack (char *cmd, int from_tty)
+{
+  struct target_ops *t;
+
+  printf_filtered (_("The current target stack is:\n"));
+
+  for (t = target_stack; t != NULL; t = t->beneath)
+    {
+      printf_filtered ("  - %s (%s)\n", t->to_shortname, t->to_longname);
+    }
+}
+
 void
 initialize_targets (void)
 {
 void
 initialize_targets (void)
 {
@@ -2802,5 +2801,9 @@ result in significant performance improvement for remote targets."),
   add_com ("monitor", class_obscure, do_monitor_command,
           _("Send a command to the remote monitor (remote targets only)."));
 
   add_com ("monitor", class_obscure, do_monitor_command,
           _("Send a command to the remote monitor (remote targets only)."));
 
+  add_cmd ("target-stack", class_maintenance, maintenance_print_target_stack,
+           _("Print the name of each layer of the internal target stack."),
+           &maintenanceprintlist);
+
   target_dcache = dcache_init ();
 }
   target_dcache = dcache_init ();
 }
This page took 0.02838 seconds and 4 git commands to generate.