* target.c (memory_xfer_partial): Accesses to unmapped overlay
[deliverable/binutils-gdb.git] / gdb / target.c
index 7861372fc78aec29df371f54c26f4d199d532904..92a4d6ac2c98c51f335ca4d8e49e861c08470f04 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
+   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
@@ -39,6 +39,8 @@
 #include "regcache.h"
 #include "gdb_assert.h"
 #include "gdbcore.h"
+#include "exceptions.h"
+#include "target-descriptions.h"
 
 static void target_info (char *, int);
 
@@ -104,11 +106,11 @@ static void debug_to_resume (ptid_t, int, enum target_signal);
 
 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 *);
 
@@ -167,7 +169,7 @@ static void debug_to_stop (void);
 struct target_ops deprecated_child_ops;
 
 /* Pointer to array of target architecture structures; the size of the
-   array; the current index into the array; the allocated size of the 
+   array; the current index into the array; the allocated size of the
    array.  */
 struct target_ops **target_structs;
 unsigned target_struct_size;
@@ -377,7 +379,7 @@ update_current_target (void)
 {
   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) \
@@ -411,6 +413,7 @@ update_current_target (void)
       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);
@@ -463,7 +466,11 @@ update_current_target (void)
       INHERIT (to_find_memory_regions, t);
       INHERIT (to_make_corefile_notes, t);
       INHERIT (to_get_thread_local_address, t);
+      /* Do not inherit to_read_description.  */
       INHERIT (to_magic, t);
+      /* Do not inherit to_memory_map.  */
+      /* Do not inherit to_flash_erase.  */
+      /* Do not inherit to_flash_done.  */
     }
 #undef INHERIT
 
@@ -475,44 +482,44 @@ update_current_target (void)
   if (!current_target.field)               \
     current_target.field = value
 
-  de_fault (to_open, 
-           (void (*) (char *, int)) 
+  de_fault (to_open,
+           (void (*) (char *, int))
            tcomplain);
-  de_fault (to_close, 
-           (void (*) (int)) 
+  de_fault (to_close,
+           (void (*) (int))
            target_ignore);
-  de_fault (to_attach, 
+  de_fault (to_attach,
            maybe_kill_then_attach);
-  de_fault (to_post_attach, 
-           (void (*) (int)) 
+  de_fault (to_post_attach,
+           (void (*) (int))
            target_ignore);
-  de_fault (to_detach, 
-           (void (*) (char *, int)) 
+  de_fault (to_detach,
+           (void (*) (char *, int))
            target_ignore);
-  de_fault (to_resume, 
-           (void (*) (ptid_t, int, enum target_signal)) 
+  de_fault (to_resume,
+           (void (*) (ptid_t, int, enum target_signal))
            noprocess);
-  de_fault (to_wait, 
-           (ptid_t (*) (ptid_t, struct target_waitstatus *)) 
+  de_fault (to_wait,
+           (ptid_t (*) (ptid_t, struct target_waitstatus *))
            noprocess);
-  de_fault (to_fetch_registers, 
-           (void (*) (int)) 
+  de_fault (to_fetch_registers,
+           (void (*) (struct regcache *, int))
            target_ignore);
-  de_fault (to_store_registers, 
-           (void (*) (int)) 
+  de_fault (to_store_registers,
+           (void (*) (struct regcache *, int))
            noprocess);
-  de_fault (to_prepare_to_store, 
-           (void (*) (void)) 
+  de_fault (to_prepare_to_store,
+           (void (*) (struct regcache *))
            noprocess);
-  de_fault (deprecated_xfer_memory, 
-           (int (*) (CORE_ADDR, gdb_byte *, int, int, struct mem_attrib *, struct target_ops *)) 
+  de_fault (deprecated_xfer_memory,
+           (int (*) (CORE_ADDR, gdb_byte *, int, int, struct mem_attrib *, struct target_ops *))
            nomemory);
-  de_fault (to_files_info, 
-           (void (*) (struct target_ops *)) 
+  de_fault (to_files_info,
+           (void (*) (struct target_ops *))
            target_ignore);
-  de_fault (to_insert_breakpoint, 
+  de_fault (to_insert_breakpoint,
            memory_insert_breakpoint);
-  de_fault (to_remove_breakpoint, 
+  de_fault (to_remove_breakpoint,
            memory_remove_breakpoint);
   de_fault (to_can_use_hw_breakpoint,
            (int (*) (int, int, int))
@@ -537,106 +544,107 @@ update_current_target (void)
            return_zero);
   de_fault (to_region_ok_for_hw_watchpoint,
            default_region_ok_for_hw_watchpoint);
-  de_fault (to_terminal_init, 
-           (void (*) (void)) 
+  de_fault (to_terminal_init,
+           (void (*) (void))
            target_ignore);
-  de_fault (to_terminal_inferior, 
-           (void (*) (void)) 
+  de_fault (to_terminal_inferior,
+           (void (*) (void))
            target_ignore);
-  de_fault (to_terminal_ours_for_output, 
-           (void (*) (void)) 
+  de_fault (to_terminal_ours_for_output,
+           (void (*) (void))
            target_ignore);
-  de_fault (to_terminal_ours, 
-           (void (*) (void)) 
+  de_fault (to_terminal_ours,
+           (void (*) (void))
            target_ignore);
-  de_fault (to_terminal_save_ours, 
-           (void (*) (void)) 
+  de_fault (to_terminal_save_ours,
+           (void (*) (void))
            target_ignore);
-  de_fault (to_terminal_info, 
+  de_fault (to_terminal_info,
            default_terminal_info);
-  de_fault (to_kill, 
-           (void (*) (void)) 
+  de_fault (to_kill,
+           (void (*) (void))
            noprocess);
-  de_fault (to_load, 
-           (void (*) (char *, int)) 
+  de_fault (to_load,
+           (void (*) (char *, int))
            tcomplain);
-  de_fault (to_lookup_symbol, 
-           (int (*) (char *, CORE_ADDR *)) 
+  de_fault (to_lookup_symbol,
+           (int (*) (char *, CORE_ADDR *))
            nosymbol);
-  de_fault (to_create_inferior, 
+  de_fault (to_create_inferior,
            maybe_kill_then_create_inferior);
-  de_fault (to_post_startup_inferior, 
-           (void (*) (ptid_t)) 
+  de_fault (to_post_startup_inferior,
+           (void (*) (ptid_t))
            target_ignore);
-  de_fault (to_acknowledge_created_inferior, 
-           (void (*) (int)) 
+  de_fault (to_acknowledge_created_inferior,
+           (void (*) (int))
            target_ignore);
-  de_fault (to_insert_fork_catchpoint, 
-           (void (*) (int)) 
+  de_fault (to_insert_fork_catchpoint,
+           (void (*) (int))
            tcomplain);
-  de_fault (to_remove_fork_catchpoint, 
-           (int (*) (int)) 
+  de_fault (to_remove_fork_catchpoint,
+           (int (*) (int))
            tcomplain);
-  de_fault (to_insert_vfork_catchpoint, 
-           (void (*) (int)) 
+  de_fault (to_insert_vfork_catchpoint,
+           (void (*) (int))
            tcomplain);
-  de_fault (to_remove_vfork_catchpoint, 
-           (int (*) (int)) 
+  de_fault (to_remove_vfork_catchpoint,
+           (int (*) (int))
            tcomplain);
-  de_fault (to_insert_exec_catchpoint, 
-           (void (*) (int)) 
+  de_fault (to_insert_exec_catchpoint,
+           (void (*) (int))
            tcomplain);
-  de_fault (to_remove_exec_catchpoint, 
-           (int (*) (int)) 
+  de_fault (to_remove_exec_catchpoint,
+           (int (*) (int))
            tcomplain);
-  de_fault (to_reported_exec_events_per_exec_call, 
-           (int (*) (void)) 
+  de_fault (to_reported_exec_events_per_exec_call,
+           (int (*) (void))
            return_one);
-  de_fault (to_has_exited, 
-           (int (*) (int, int, int *)) 
+  de_fault (to_has_exited,
+           (int (*) (int, int, int *))
            return_zero);
-  de_fault (to_mourn_inferior, 
-           (void (*) (void)) 
+  de_fault (to_mourn_inferior,
+           (void (*) (void))
            noprocess);
-  de_fault (to_can_run, 
+  de_fault (to_can_run,
            return_zero);
-  de_fault (to_notice_signals, 
-           (void (*) (ptid_t)) 
+  de_fault (to_notice_signals,
+           (void (*) (ptid_t))
            target_ignore);
-  de_fault (to_thread_alive, 
-           (int (*) (ptid_t)) 
+  de_fault (to_thread_alive,
+           (int (*) (ptid_t))
            return_zero);
-  de_fault (to_find_new_threads, 
-           (void (*) (void)) 
+  de_fault (to_find_new_threads,
+           (void (*) (void))
            target_ignore);
-  de_fault (to_extra_thread_info, 
-           (char *(*) (struct thread_info *)) 
+  de_fault (to_extra_thread_info,
+           (char *(*) (struct thread_info *))
            return_zero);
-  de_fault (to_stop, 
-           (void (*) (void)) 
+  de_fault (to_stop,
+           (void (*) (void))
            target_ignore);
   current_target.to_xfer_partial = current_xfer_partial;
-  de_fault (to_rcmd, 
-           (void (*) (char *, struct ui_file *)) 
+  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)) 
+  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)) 
+  de_fault (to_get_current_exception_event,
+           (struct exception_event_record * (*) (void))
            nosupport_runtime);
-  de_fault (to_pid_to_exec_file, 
-           (char *(*) (int)) 
+  de_fault (to_pid_to_exec_file,
+           (char *(*) (int))
            return_zero);
-  de_fault (to_can_async_p, 
-           (int (*) (void)) 
+  de_fault (to_can_async_p,
+           (int (*) (void))
            return_zero);
-  de_fault (to_is_async_p, 
-           (int (*) (void)) 
+  de_fault (to_is_async_p,
+           (int (*) (void))
            return_zero);
-  de_fault (to_async, 
-           (void (*) (void (*) (enum inferior_event_type, void*), void*)) 
+  de_fault (to_async,
+           (void (*) (void (*) (enum inferior_event_type, void*), void*))
            tcomplain);
+  current_target.to_read_description = NULL;
 #undef de_fault
 
   /* Finally, position the target-stack beneath the squashed
@@ -645,6 +653,56 @@ update_current_target (void)
   current_target.beneath = target_stack;
 }
 
+/* Mark OPS as a running target.  This reverses the effect
+   of target_mark_exited.  */
+
+void
+target_mark_running (struct target_ops *ops)
+{
+  struct target_ops *t;
+
+  for (t = target_stack; t != NULL; t = t->beneath)
+    if (t == ops)
+      break;
+  if (t == NULL)
+    internal_error (__FILE__, __LINE__,
+                   "Attempted to mark unpushed target \"%s\" as running",
+                   ops->to_shortname);
+
+  ops->to_has_execution = 1;
+  ops->to_has_all_memory = 1;
+  ops->to_has_memory = 1;
+  ops->to_has_stack = 1;
+  ops->to_has_registers = 1;
+
+  update_current_target ();
+}
+
+/* Mark OPS as a non-running target.  This reverses the effect
+   of target_mark_running.  */
+
+void
+target_mark_exited (struct target_ops *ops)
+{
+  struct target_ops *t;
+
+  for (t = target_stack; t != NULL; t = t->beneath)
+    if (t == ops)
+      break;
+  if (t == NULL)
+    internal_error (__FILE__, __LINE__,
+                   "Attempted to mark unpushed target \"%s\" as running",
+                   ops->to_shortname);
+
+  ops->to_has_execution = 0;
+  ops->to_has_all_memory = 0;
+  ops->to_has_memory = 0;
+  ops->to_has_stack = 0;
+  ops->to_has_registers = 0;
+
+  update_current_target ();
+}
+
 /* Push a new target type into the stack of the existing target accessors,
    possibly superseding some of the existing accessors.
 
@@ -703,7 +761,7 @@ push_target (struct target_ops *t)
   return (t != target_stack);
 }
 
-/* Remove a target_ops vector from the stack, wherever it may be. 
+/* Remove a target_ops vector from the stack, wherever it may be.
    Return how many times it was removed (0 or 1).  */
 
 int
@@ -755,6 +813,92 @@ pop_target (void)
   internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
 }
 
+/* Using the objfile specified in BATON, 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)
+{
+  volatile CORE_ADDR addr = 0;
+
+  if (target_get_thread_local_address_p ()
+      && gdbarch_fetch_tls_load_module_address_p (current_gdbarch))
+    {
+      ptid_t ptid = inferior_ptid;
+      volatile struct gdb_exception ex;
+
+      TRY_CATCH (ex, RETURN_MASK_ALL)
+       {
+         CORE_ADDR lm_addr;
+         
+         /* Fetch the load module address for this objfile.  */
+         lm_addr = gdbarch_fetch_tls_load_module_address (current_gdbarch,
+                                                          objfile);
+         /* If it's 0, throw the appropriate exception.  */
+         if (lm_addr == 0)
+           throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
+                        _("TLS load module not found"));
+
+         addr = target_get_thread_local_address (ptid, lm_addr, offset);
+       }
+      /* If an error occurred, print TLS related messages here.  Otherwise,
+         throw the error to some higher catcher.  */
+      if (ex.reason < 0)
+       {
+         int objfile_is_library = (objfile->flags & OBJF_SHARED);
+
+         switch (ex.error)
+           {
+           case TLS_NO_LIBRARY_SUPPORT_ERROR:
+             error (_("Cannot find thread-local variables in this thread library."));
+             break;
+           case TLS_LOAD_MODULE_NOT_FOUND_ERROR:
+             if (objfile_is_library)
+               error (_("Cannot find shared library `%s' in dynamic"
+                        " linker's load module list"), objfile->name);
+             else
+               error (_("Cannot find executable file `%s' in dynamic"
+                        " linker's load module list"), objfile->name);
+             break;
+           case TLS_NOT_ALLOCATED_YET_ERROR:
+             if (objfile_is_library)
+               error (_("The inferior has not yet allocated storage for"
+                        " thread-local variables in\n"
+                        "the shared library `%s'\n"
+                        "for %s"),
+                      objfile->name, target_pid_to_str (ptid));
+             else
+               error (_("The inferior has not yet allocated storage for"
+                        " thread-local variables in\n"
+                        "the executable `%s'\n"
+                        "for %s"),
+                      objfile->name, target_pid_to_str (ptid));
+             break;
+           case TLS_GENERIC_ERROR:
+             if (objfile_is_library)
+               error (_("Cannot find thread-local storage for %s, "
+                        "shared library %s:\n%s"),
+                      target_pid_to_str (ptid),
+                      objfile->name, ex.message);
+             else
+               error (_("Cannot find thread-local storage for %s, "
+                        "executable file %s:\n%s"),
+                      target_pid_to_str (ptid),
+                      objfile->name, ex.message);
+             break;
+           default:
+             throw_exception (ex);
+             break;
+           }
+       }
+    }
+  /* It wouldn't be wrong here to try a gdbarch method, too; finding
+     TLS is an ABI-specific thing.  But we don't do that yet.  */
+  else
+    error (_("Cannot find thread-local variables on this target"));
+
+  return addr;
+}
+
 #undef MIN
 #define MIN(A, B) (((A) <= (B)) ? (A) : (B))
 
@@ -873,9 +1017,18 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
        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);
-  if (memaddr + len < region->hi)
+  /* region->hi == 0 means there's no upper bound.  */
+  if (memaddr + len < region->hi || region->hi == 0)
     reg_len = len;
   else
     reg_len = region->hi - memaddr;
@@ -891,6 +1044,15 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
       if (readbuf != NULL)
        return -1;
       break;
+
+    case MEM_FLASH:
+      /* We only support writing to flash during "load" for now.  */
+      if (writebuf != NULL)
+       error (_("Writing to flash memory forbidden in this context"));
+      break;
+
+    case MEM_NONE:
+      return -1;
     }
 
   if (region->attrib.cache)
@@ -926,10 +1088,15 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
   do
     {
       res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
-                                 readbuf, writebuf, memaddr, len);
+                                 readbuf, writebuf, memaddr, reg_len);
       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);
@@ -986,7 +1153,7 @@ target_xfer_partial (struct target_ops *ops,
       if (retval > 0 && myaddr != NULL)
        {
          int i;
-         
+
          fputs_unfiltered (", bytes =", gdb_stdlog);
          for (i = 0; i < retval; i++)
            {
@@ -999,11 +1166,11 @@ target_xfer_partial (struct target_ops *ops,
                    }
                  fprintf_unfiltered (gdb_stdlog, "\n");
                }
-             
+
              fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff);
            }
        }
-      
+
       fputc_unfiltered ('\n', gdb_stdlog);
     }
   return retval;
@@ -1040,6 +1207,89 @@ target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
     return EIO;
 }
 
+/* Fetch the target's memory map.  */
+
+VEC(mem_region_s) *
+target_memory_map (void)
+{
+  VEC(mem_region_s) *result;
+  struct mem_region *last_one, *this_one;
+  int ix;
+  struct target_ops *t;
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog, "target_memory_map ()\n");
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_memory_map != NULL)
+      break;
+
+  if (t == NULL)
+    return NULL;
+
+  result = t->to_memory_map (t);
+  if (result == NULL)
+    return NULL;
+
+  qsort (VEC_address (mem_region_s, result),
+        VEC_length (mem_region_s, result),
+        sizeof (struct mem_region), mem_region_cmp);
+
+  /* Check that regions do not overlap.  Simultaneously assign
+     a numbering for the "mem" commands to use to refer to
+     each region.  */
+  last_one = NULL;
+  for (ix = 0; VEC_iterate (mem_region_s, result, ix, this_one); ix++)
+    {
+      this_one->number = ix;
+
+      if (last_one && last_one->hi > this_one->lo)
+       {
+         warning (_("Overlapping regions in memory map: ignoring"));
+         VEC_free (mem_region_s, result);
+         return NULL;
+       }
+      last_one = this_one;
+    }
+
+  return result;
+}
+
+void
+target_flash_erase (ULONGEST address, LONGEST length)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_flash_erase != NULL)
+       {
+         if (targetdebug)
+           fprintf_unfiltered (gdb_stdlog, "target_flash_erase (%s, %s)\n",
+                                paddr (address), phex (length, 0));
+         t->to_flash_erase (t, address, length);
+         return;
+       }
+
+  tcomplain ();
+}
+
+void
+target_flash_done (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_flash_done != NULL)
+       {
+         if (targetdebug)
+           fprintf_unfiltered (gdb_stdlog, "target_flash_done\n");
+         t->to_flash_done (t);
+         return;
+       }
+
+  tcomplain ();
+}
+
 #ifndef target_stopped_data_address_p
 int
 target_stopped_data_address_p (struct target_ops *target)
@@ -1068,7 +1318,7 @@ Mode for reading from readonly sections is %s.\n"),
 
 static LONGEST
 default_xfer_partial (struct target_ops *ops, enum target_object object,
-                     const char *annex, gdb_byte *readbuf, 
+                     const char *annex, gdb_byte *readbuf,
                      const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
 {
   if (object == TARGET_OBJECT_MEMORY
@@ -1180,6 +1430,11 @@ target_write_with_progress (struct target_ops *ops,
                            void (*progress) (ULONGEST, void *), void *baton)
 {
   LONGEST xfered = 0;
+
+  /* Give the progress callback a chance to set up.  */
+  if (progress)
+    (*progress) (0, baton);
+
   while (xfered < len)
     {
       LONGEST xfer = target_write_partial (ops, object, annex,
@@ -1356,6 +1611,20 @@ target_info (char *args, int from_tty)
     }
 }
 
+/* This function is called before any new inferior is created, e.g.
+   by running a program, attaching, or connecting to a target.
+   It cleans up any state from previous invocations which might
+   change between runs.  This is a subset of what target_preopen
+   resets (things which might change between targets).  */
+
+void
+target_pre_inferior (int from_tty)
+{
+  invalidate_target_mem_regions ();
+
+  target_clear_description ();
+}
+
 /* This is to be called by the open routine before it does
    anything.  */
 
@@ -1378,6 +1647,8 @@ target_preopen (int from_tty)
 
   if (target_has_execution)
     pop_target ();
+
+  target_pre_inferior (from_tty);
 }
 
 /* Detach a target after doing deferred register stores.  */
@@ -1439,6 +1710,27 @@ target_follow_fork (int follow_child)
                  "could not find a target to follow fork");
 }
 
+/* Look for a target which can describe architectural features, starting
+   from TARGET.  If we find one, return its description.  */
+
+const struct target_desc *
+target_read_description (struct target_ops *target)
+{
+  struct target_ops *t;
+
+  for (t = target; t != NULL; t = t->beneath)
+    if (t->to_read_description != NULL)
+      {
+       const struct target_desc *tdesc;
+
+       tdesc = t->to_read_description (t);
+       if (tdesc)
+         return tdesc;
+      }
+
+  return NULL;
+}
+
 /* 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.
@@ -1547,7 +1839,7 @@ target_resize_to_sections (struct target_ops *target, int num_added)
 
   /* Check to see if anyone else was pointing to this structure.
      If old_value was null, then no one was. */
-     
+
   if (old_value)
     {
       for (t = target_structs; t < target_structs + target_struct_size;
@@ -1567,7 +1859,7 @@ target_resize_to_sections (struct target_ops *target, int num_added)
          current_target.to_sections_end = target->to_sections_end;
        }
     }
-  
+
   return old_count;
 
 }
@@ -1691,19 +1983,12 @@ generic_mourn_inferior (void)
     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)
 {
-#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;
@@ -1878,53 +2163,57 @@ debug_to_wait (ptid_t ptid, struct target_waitstatus *status)
 }
 
 static void
-debug_print_register (const char * func, int regno)
+debug_print_register (const char * func,
+                     struct regcache *regcache, int regno)
 {
   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 (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));
   else
     fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
   if (regno >= 0)
     {
-      int i;
+      int i, size = register_size (current_gdbarch, regno);
       unsigned char buf[MAX_REGISTER_SIZE];
-      deprecated_read_register_gen (regno, buf);
+      regcache_cooked_read (regcache, regno, buf);
       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]);
        }
-      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",
-                             paddr_nz (read_register (regno)),
-                             paddr_d (read_register (regno)));
+                             paddr_nz (val), paddr_d (val));
        }
     }
   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
-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
-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");
 }
@@ -1960,7 +2249,7 @@ deprecated_debug_xfer_memory (CORE_ADDR memaddr, bfd_byte *myaddr, int len,
                }
              fprintf_unfiltered (gdb_stdlog, "\n");
            }
-         
+
          fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff);
        }
     }
@@ -2110,10 +2399,10 @@ debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type)
 {
   int retval;
 
-  retval = debug_target.to_insert_watchpoint (addr, len, type);
+  retval = debug_target.to_remove_watchpoint (addr, len, type);
 
   fprintf_unfiltered (gdb_stdlog,
-                     "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n",
+                     "target_remove_watchpoint (0x%lx, %d, %d) = %ld\n",
                      (unsigned long) addr, len, type, (unsigned long) retval);
   return retval;
 }
@@ -2493,6 +2782,21 @@ do_monitor_command (char *cmd,
   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)
 {
@@ -2512,7 +2816,7 @@ command."),
                            show_targetdebug,
                            &setdebuglist, &showdebuglist);
 
-  add_setshow_boolean_cmd ("trust-readonly-sections", class_support, 
+  add_setshow_boolean_cmd ("trust-readonly-sections", class_support,
                           &trust_readonly, _("\
 Set mode for reading from readonly sections."), _("\
 Show mode for reading from readonly sections."), _("\
@@ -2526,5 +2830,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_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 ();
 }
This page took 0.03598 seconds and 4 git commands to generate.