2005-02-02 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / target.c
index 1a8723c37e569cd2b1a3918329a0805631e88038..5a050afcb6f329cced8074c6357cd6fbc3fccbf3 100644 (file)
@@ -1,6 +1,8 @@
 /* Select target systems and architectures at runtime for GDB.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001 Free Software Foundation, Inc.
+
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
    Contributed by Cygnus Support.
 
    This file is part of GDB.
 #include "dcache.h"
 #include <signal.h>
 #include "regcache.h"
-
-extern int errno;
+#include "gdb_assert.h"
+#include "gdbcore.h"
 
 static void target_info (char *, int);
 
-static void cleanup_target (struct target_ops *);
-
-static void maybe_kill_then_create_inferior (char *, char *, char **);
-
-static void default_clone_and_follow_inferior (int, int *);
-
 static void maybe_kill_then_attach (char *, int);
 
 static void kill_or_be_killed (int);
 
 static void default_terminal_info (char *, int);
 
+static int default_region_size_ok_for_hw_watchpoint (int);
+
 static int nosymbol (char *, CORE_ADDR *);
 
 static void tcomplain (void);
@@ -61,17 +59,21 @@ static int return_zero (void);
 
 static int return_one (void);
 
+static int return_minus_one (void);
+
 void target_ignore (void);
 
 static void target_command (char *, int);
 
 static struct target_ops *find_default_run_target (char *);
 
-static void update_current_target (void);
-
 static void nosupport_runtime (void);
 
-static void normal_target_post_startup_inferior (ptid_t ptid);
+static LONGEST default_xfer_partial (struct target_ops *ops,
+                                    enum target_object object,
+                                    const char *annex, void *readbuf,
+                                    const void *writebuf,
+                                    ULONGEST offset, LONGEST len);
 
 /* Transfer LEN bytes between target address MEMADDR and GDB address
    MYADDR.  Returns 0 for success, errno code for failure (which
@@ -79,11 +81,13 @@ static void normal_target_post_startup_inferior (ptid_t ptid);
    partial transfers, try either target_read_memory_partial or
    target_write_memory_partial).  */
 
-static int
-target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write);
+static int target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+                              int write);
 
 static void init_dummy_target (void);
 
+static struct target_ops debug_target;
+
 static void debug_to_open (char *, int);
 
 static void debug_to_close (int);
@@ -92,6 +96,8 @@ static void debug_to_attach (char *, int);
 
 static void debug_to_detach (char *, int);
 
+static void debug_to_disconnect (char *, int);
+
 static void debug_to_resume (ptid_t, int, enum target_signal);
 
 static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
@@ -102,9 +108,9 @@ static void debug_to_store_registers (int);
 
 static void debug_to_prepare_to_store (void);
 
-static int
-debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *, 
-                     struct target_ops *);
+static int deprecated_debug_xfer_memory (CORE_ADDR, char *, int, int,
+                                        struct mem_attrib *,
+                                        struct target_ops *);
 
 static void debug_to_files_info (struct target_ops *);
 
@@ -112,12 +118,30 @@ static int debug_to_insert_breakpoint (CORE_ADDR, char *);
 
 static int debug_to_remove_breakpoint (CORE_ADDR, char *);
 
+static int debug_to_can_use_hw_breakpoint (int, int, int);
+
+static int debug_to_insert_hw_breakpoint (CORE_ADDR, char *);
+
+static int debug_to_remove_hw_breakpoint (CORE_ADDR, char *);
+
+static int debug_to_insert_watchpoint (CORE_ADDR, int, int);
+
+static int debug_to_remove_watchpoint (CORE_ADDR, int, int);
+
+static int debug_to_stopped_by_watchpoint (void);
+
+static int debug_to_stopped_data_address (struct target_ops *, CORE_ADDR *);
+
+static int debug_to_region_size_ok_for_hw_watchpoint (int);
+
 static void debug_to_terminal_init (void);
 
 static void debug_to_terminal_inferior (void);
 
 static void debug_to_terminal_ours_for_output (void);
 
+static void debug_to_terminal_save_ours (void);
+
 static void debug_to_terminal_ours (void);
 
 static void debug_to_terminal_info (char *, int);
@@ -128,8 +152,6 @@ static void debug_to_load (char *, int);
 
 static int debug_to_lookup_symbol (char *, CORE_ADDR *);
 
-static void debug_to_create_inferior (char *, char *, char **);
-
 static void debug_to_mourn_inferior (void);
 
 static int debug_to_can_run (void);
@@ -140,7 +162,11 @@ static int debug_to_thread_alive (ptid_t);
 
 static void debug_to_stop (void);
 
-static int debug_to_query (int /*char */ , char *, char *, int *);
+/* NOTE: cagney/2004-09-29: Many targets reference this variable in
+   wierd and mysterious ways.  Putting the variable here lets those
+   wierd and mysterious ways keep building while they are being
+   converted to the inferior inheritance structure.  */
+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 
@@ -158,7 +184,7 @@ static struct target_ops dummy_target;
 
 /* Top of target stack.  */
 
-struct target_stack_item *target_stack;
+static struct target_ops *target_stack;
 
 /* The target structure we are currently using to talk to a process
    or file or whatever "inferior" we have.  */
@@ -184,7 +210,6 @@ DCACHE *target_dcache;
 
 /* The user just typed 'target' without the name of a target.  */
 
-/* ARGSUSED */
 static void
 target_command (char *arg, int from_tty)
 {
@@ -197,6 +222,10 @@ target_command (char *arg, int from_tty)
 void
 add_target (struct target_ops *t)
 {
+  /* Provide default values for all "must have" methods.  */
+  if (t->to_xfer_partial == NULL)
+    t->to_xfer_partial = default_xfer_partial;
+
   if (!target_structs)
     {
       target_struct_allocsize = DEFAULT_ALLOCSIZE;
@@ -211,7 +240,6 @@ add_target (struct target_ops *t)
                  target_struct_allocsize * sizeof (*target_structs));
     }
   target_structs[target_struct_size++] = t;
-/*  cleanup_target (t); */
 
   if (targetlist == NULL)
     add_prefix_cmd ("target", class_run, target_command,
@@ -238,7 +266,6 @@ target_load (char *arg, int from_tty)
   (*current_target.to_load) (arg, from_tty);
 }
 
-/* ARGSUSED */
 static int
 nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write,
          struct target_ops *t)
@@ -260,14 +287,12 @@ noprocess (void)
   error ("You can't do that without a process to debug.");
 }
 
-/* ARGSUSED */
 static int
 nosymbol (char *name, CORE_ADDR *addrp)
 {
   return 1;                    /* Symbol does not exist in target env */
 }
 
-/* ARGSUSED */
 static void
 nosupport_runtime (void)
 {
@@ -278,7 +303,6 @@ nosupport_runtime (void)
 }
 
 
-/* ARGSUSED */
 static void
 default_terminal_info (char *args, int from_tty)
 {
@@ -320,28 +344,127 @@ maybe_kill_then_attach (char *args, int from_tty)
 }
 
 static void
-maybe_kill_then_create_inferior (char *exec, char *args, char **env)
+maybe_kill_then_create_inferior (char *exec, char *args, char **env,
+                                int from_tty)
 {
   kill_or_be_killed (0);
-  target_create_inferior (exec, args, env);
+  target_create_inferior (exec, args, env, from_tty);
 }
 
-static void
-default_clone_and_follow_inferior (int child_pid, int *followed_child)
-{
-  target_clone_and_follow_inferior (child_pid, followed_child);
-}
+/* Go through the target stack from top to bottom, copying over zero
+   entries in current_target, then filling in still empty entries.  In
+   effect, we are doing class inheritance through the pushed target
+   vectors.
 
-/* Clean up a target struct so it no longer has any zero pointers in it.
-   We default entries, at least to stubs that print error messages.  */
+   NOTE: cagney/2003-10-17: The problem with this inheritance, as it
+   is currently implemented, is that it discards any knowledge of
+   which target an inherited method originally belonged to.
+   Consequently, new new target methods should instead explicitly and
+   locally search the target stack for the target that can handle the
+   request.  */
 
 static void
-cleanup_target (struct target_ops *t)
+update_current_target (void)
 {
+  struct target_ops *t;
+
+  /* First, reset curren'ts contents.  */
+  memset (&current_target, 0, sizeof (current_target));
+
+#define INHERIT(FIELD, TARGET) \
+      if (!current_target.FIELD) \
+       current_target.FIELD = (TARGET)->FIELD
+
+  for (t = target_stack; t; t = t->beneath)
+    {
+      INHERIT (to_shortname, t);
+      INHERIT (to_longname, t);
+      INHERIT (to_doc, t);
+      INHERIT (to_open, t);
+      INHERIT (to_close, t);
+      INHERIT (to_attach, t);
+      INHERIT (to_post_attach, t);
+      INHERIT (to_detach, t);
+      INHERIT (to_disconnect, t);
+      INHERIT (to_resume, t);
+      INHERIT (to_wait, t);
+      INHERIT (to_fetch_registers, t);
+      INHERIT (to_store_registers, t);
+      INHERIT (to_prepare_to_store, t);
+      INHERIT (deprecated_xfer_memory, t);
+      INHERIT (to_files_info, t);
+      INHERIT (to_insert_breakpoint, t);
+      INHERIT (to_remove_breakpoint, t);
+      INHERIT (to_can_use_hw_breakpoint, t);
+      INHERIT (to_insert_hw_breakpoint, t);
+      INHERIT (to_remove_hw_breakpoint, t);
+      INHERIT (to_insert_watchpoint, t);
+      INHERIT (to_remove_watchpoint, t);
+      INHERIT (to_stopped_data_address, t);
+      INHERIT (to_stopped_by_watchpoint, t);
+      INHERIT (to_have_continuable_watchpoint, t);
+      INHERIT (to_region_size_ok_for_hw_watchpoint, t);
+      INHERIT (to_terminal_init, t);
+      INHERIT (to_terminal_inferior, t);
+      INHERIT (to_terminal_ours_for_output, t);
+      INHERIT (to_terminal_ours, t);
+      INHERIT (to_terminal_save_ours, t);
+      INHERIT (to_terminal_info, t);
+      INHERIT (to_kill, t);
+      INHERIT (to_load, t);
+      INHERIT (to_lookup_symbol, t);
+      INHERIT (to_create_inferior, t);
+      INHERIT (to_post_startup_inferior, t);
+      INHERIT (to_acknowledge_created_inferior, t);
+      INHERIT (to_insert_fork_catchpoint, t);
+      INHERIT (to_remove_fork_catchpoint, t);
+      INHERIT (to_insert_vfork_catchpoint, t);
+      INHERIT (to_remove_vfork_catchpoint, t);
+      INHERIT (to_follow_fork, t);
+      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);
+      INHERIT (to_notice_signals, t);
+      INHERIT (to_thread_alive, t);
+      INHERIT (to_find_new_threads, t);
+      INHERIT (to_pid_to_str, t);
+      INHERIT (to_extra_thread_info, 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_stratum, t);
+      INHERIT (to_has_all_memory, t);
+      INHERIT (to_has_memory, t);
+      INHERIT (to_has_stack, t);
+      INHERIT (to_has_registers, t);
+      INHERIT (to_has_execution, t);
+      INHERIT (to_has_thread_control, t);
+      INHERIT (to_sections, t);
+      INHERIT (to_sections_end, t);
+      INHERIT (to_can_async_p, t);
+      INHERIT (to_is_async_p, t);
+      INHERIT (to_async, t);
+      INHERIT (to_async_mask_value, t);
+      INHERIT (to_find_memory_regions, t);
+      INHERIT (to_make_corefile_notes, t);
+      INHERIT (to_get_thread_local_address, t);
+      INHERIT (to_magic, t);
+    }
+#undef INHERIT
+
+  /* Clean up a target struct so it no longer has any zero pointers in
+     it.  Some entries are defaulted to a method that print an error,
+     others are hard-wired to a standard recursive default.  */
 
 #define de_fault(field, value) \
-  if (!t->field)               \
-    t->field = value
+  if (!current_target.field)               \
+    current_target.field = value
 
   de_fault (to_open, 
            (void (*) (char *, int)) 
@@ -354,23 +477,18 @@ cleanup_target (struct target_ops *t)
   de_fault (to_post_attach, 
            (void (*) (int)) 
            target_ignore);
-  de_fault (to_require_attach, 
-           maybe_kill_then_attach);
   de_fault (to_detach, 
            (void (*) (char *, int)) 
            target_ignore);
-  de_fault (to_require_detach
-           (void (*) (int, char *, int)) 
-           target_ignore);
+  de_fault (to_disconnect
+           (void (*) (char *, int)) 
+           tcomplain);
   de_fault (to_resume, 
            (void (*) (ptid_t, int, enum target_signal)) 
            noprocess);
   de_fault (to_wait, 
            (ptid_t (*) (ptid_t, struct target_waitstatus *)) 
            noprocess);
-  de_fault (to_post_wait, 
-           (void (*) (ptid_t, int)) 
-           target_ignore);
   de_fault (to_fetch_registers, 
            (void (*) (int)) 
            target_ignore);
@@ -380,7 +498,7 @@ cleanup_target (struct target_ops *t)
   de_fault (to_prepare_to_store, 
            (void (*) (void)) 
            noprocess);
-  de_fault (to_xfer_memory, 
+  de_fault (deprecated_xfer_memory, 
            (int (*) (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *)) 
            nomemory);
   de_fault (to_files_info, 
@@ -390,6 +508,29 @@ cleanup_target (struct target_ops *t)
            memory_insert_breakpoint);
   de_fault (to_remove_breakpoint, 
            memory_remove_breakpoint);
+  de_fault (to_can_use_hw_breakpoint,
+           (int (*) (int, int, int))
+           return_zero);
+  de_fault (to_insert_hw_breakpoint,
+           (int (*) (CORE_ADDR, char *))
+           return_minus_one);
+  de_fault (to_remove_hw_breakpoint,
+           (int (*) (CORE_ADDR, char *))
+           return_minus_one);
+  de_fault (to_insert_watchpoint,
+           (int (*) (CORE_ADDR, int, int))
+           return_minus_one);
+  de_fault (to_remove_watchpoint,
+           (int (*) (CORE_ADDR, int, int))
+           return_minus_one);
+  de_fault (to_stopped_by_watchpoint,
+           (int (*) (void))
+           return_zero);
+  de_fault (to_stopped_data_address,
+           (int (*) (struct target_ops *, CORE_ADDR *))
+           return_zero);
+  de_fault (to_region_size_ok_for_hw_watchpoint,
+           default_region_size_ok_for_hw_watchpoint);
   de_fault (to_terminal_init, 
            (void (*) (void)) 
            target_ignore);
@@ -402,6 +543,9 @@ cleanup_target (struct target_ops *t)
   de_fault (to_terminal_ours, 
            (void (*) (void)) 
            target_ignore);
+  de_fault (to_terminal_save_ours, 
+           (void (*) (void)) 
+           target_ignore);
   de_fault (to_terminal_info, 
            default_terminal_info);
   de_fault (to_kill, 
@@ -421,50 +565,30 @@ cleanup_target (struct target_ops *t)
   de_fault (to_acknowledge_created_inferior, 
            (void (*) (int)) 
            target_ignore);
-  de_fault (to_clone_and_follow_inferior, 
-           default_clone_and_follow_inferior);
-  de_fault (to_post_follow_inferior_by_clone, 
-           (void (*) (void)) 
-           target_ignore);
   de_fault (to_insert_fork_catchpoint, 
-           (int (*) (int)) 
+           (void (*) (int)) 
            tcomplain);
   de_fault (to_remove_fork_catchpoint, 
            (int (*) (int)) 
            tcomplain);
   de_fault (to_insert_vfork_catchpoint, 
-           (int (*) (int)) 
+           (void (*) (int)) 
            tcomplain);
   de_fault (to_remove_vfork_catchpoint, 
            (int (*) (int)) 
            tcomplain);
-  de_fault (to_has_forked, 
-           (int (*) (int, int *)) 
-           return_zero);
-  de_fault (to_has_vforked, 
-           (int (*) (int, int *)) 
-           return_zero);
-  de_fault (to_can_follow_vfork_prior_to_exec, 
-           (int (*) (void)) 
-           return_zero);
-  de_fault (to_post_follow_vfork, 
-           (void (*) (int, int, int, int)) 
+  de_fault (to_follow_fork,
+           (int (*) (int)) 
            target_ignore);
   de_fault (to_insert_exec_catchpoint, 
-           (int (*) (int)) 
+           (void (*) (int)) 
            tcomplain);
   de_fault (to_remove_exec_catchpoint, 
            (int (*) (int)) 
            tcomplain);
-  de_fault (to_has_execd, 
-           (int (*) (int, char **)) 
-           return_zero);
   de_fault (to_reported_exec_events_per_exec_call, 
            (int (*) (void)) 
            return_one);
-  de_fault (to_has_syscall_event, 
-           (int (*) (int, enum target_waitkind *, int *)) 
-           return_zero);
   de_fault (to_has_exited, 
            (int (*) (int, int, int *)) 
            return_zero);
@@ -488,6 +612,7 @@ cleanup_target (struct target_ops *t)
   de_fault (to_stop, 
            (void (*) (void)) 
            target_ignore);
+  current_target.to_xfer_partial = default_xfer_partial;
   de_fault (to_rcmd, 
            (void (*) (char *, struct ui_file *)) 
            tcomplain);
@@ -510,107 +635,11 @@ cleanup_target (struct target_ops *t)
            (void (*) (void (*) (enum inferior_event_type, void*), void*)) 
            tcomplain);
 #undef de_fault
-}
-
-/* Go through the target stack from top to bottom, copying over zero entries in
-   current_target.  In effect, we are doing class inheritance through the
-   pushed target vectors.  */
-
-static void
-update_current_target (void)
-{
-  struct target_stack_item *item;
-  struct target_ops *t;
-
-  /* First, reset current_target */
-  memset (&current_target, 0, sizeof current_target);
-
-  for (item = target_stack; item; item = item->next)
-    {
-      t = item->target_ops;
-
-#define INHERIT(FIELD, TARGET) \
-      if (!current_target.FIELD) \
-       current_target.FIELD = TARGET->FIELD
-
-      INHERIT (to_shortname, t);
-      INHERIT (to_longname, t);
-      INHERIT (to_doc, t);
-      INHERIT (to_open, t);
-      INHERIT (to_close, t);
-      INHERIT (to_attach, t);
-      INHERIT (to_post_attach, t);
-      INHERIT (to_require_attach, t);
-      INHERIT (to_detach, t);
-      INHERIT (to_require_detach, t);
-      INHERIT (to_resume, t);
-      INHERIT (to_wait, t);
-      INHERIT (to_post_wait, t);
-      INHERIT (to_fetch_registers, t);
-      INHERIT (to_store_registers, t);
-      INHERIT (to_prepare_to_store, t);
-      INHERIT (to_xfer_memory, t);
-      INHERIT (to_files_info, t);
-      INHERIT (to_insert_breakpoint, t);
-      INHERIT (to_remove_breakpoint, t);
-      INHERIT (to_terminal_init, t);
-      INHERIT (to_terminal_inferior, t);
-      INHERIT (to_terminal_ours_for_output, t);
-      INHERIT (to_terminal_ours, t);
-      INHERIT (to_terminal_info, t);
-      INHERIT (to_kill, t);
-      INHERIT (to_load, t);
-      INHERIT (to_lookup_symbol, t);
-      INHERIT (to_create_inferior, t);
-      INHERIT (to_post_startup_inferior, t);
-      INHERIT (to_acknowledge_created_inferior, t);
-      INHERIT (to_clone_and_follow_inferior, t);
-      INHERIT (to_post_follow_inferior_by_clone, t);
-      INHERIT (to_insert_fork_catchpoint, t);
-      INHERIT (to_remove_fork_catchpoint, t);
-      INHERIT (to_insert_vfork_catchpoint, t);
-      INHERIT (to_remove_vfork_catchpoint, t);
-      INHERIT (to_has_forked, t);
-      INHERIT (to_has_vforked, t);
-      INHERIT (to_can_follow_vfork_prior_to_exec, t);
-      INHERIT (to_post_follow_vfork, t);
-      INHERIT (to_insert_exec_catchpoint, t);
-      INHERIT (to_remove_exec_catchpoint, t);
-      INHERIT (to_has_execd, t);
-      INHERIT (to_reported_exec_events_per_exec_call, t);
-      INHERIT (to_has_syscall_event, t);
-      INHERIT (to_has_exited, t);
-      INHERIT (to_mourn_inferior, t);
-      INHERIT (to_can_run, t);
-      INHERIT (to_notice_signals, t);
-      INHERIT (to_thread_alive, t);
-      INHERIT (to_find_new_threads, t);
-      INHERIT (to_pid_to_str, t);
-      INHERIT (to_extra_thread_info, t);
-      INHERIT (to_stop, t);
-      INHERIT (to_query, t);
-      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_stratum, t);
-      INHERIT (DONT_USE, t);
-      INHERIT (to_has_all_memory, t);
-      INHERIT (to_has_memory, t);
-      INHERIT (to_has_stack, t);
-      INHERIT (to_has_registers, t);
-      INHERIT (to_has_execution, t);
-      INHERIT (to_has_thread_control, t);
-      INHERIT (to_sections, t);
-      INHERIT (to_sections_end, t);
-      INHERIT (to_can_async_p, t);
-      INHERIT (to_is_async_p, t);
-      INHERIT (to_async, t);
-      INHERIT (to_async_mask_value, t);
-      INHERIT (to_magic, t);
 
-#undef INHERIT
-    }
+  /* Finally, position the target-stack beneath the squashed
+     "current_target".  That way code looking for a non-inherited
+     target method can quickly and simply find it.  */
+  current_target.beneath = target_stack;
 }
 
 /* Push a new target type into the stack of the existing target accessors,
@@ -626,7 +655,7 @@ update_current_target (void)
 int
 push_target (struct target_ops *t)
 {
-  struct target_stack_item *cur, *prev, *tmp;
+  struct target_ops **cur;
 
   /* Check magic number.  If wrong, it probably means someone changed
      the struct definition, but not all the places that initialize one.  */
@@ -638,51 +667,37 @@ push_target (struct target_ops *t)
       internal_error (__FILE__, __LINE__, "failed internal consistency check");
     }
 
-  /* Find the proper stratum to install this target in. */
-
-  for (prev = NULL, cur = target_stack; cur; prev = cur, cur = cur->next)
+  /* Find the proper stratum to install this target in.  */
+  for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath)
     {
-      if ((int) (t->to_stratum) >= (int) (cur->target_ops->to_stratum))
+      if ((int) (t->to_stratum) >= (int) (*cur)->to_stratum)
        break;
     }
 
-  /* If there's already targets at this stratum, remove them. */
-
-  if (cur)
-    while (t->to_stratum == cur->target_ops->to_stratum)
-      {
-       /* There's already something on this stratum.  Close it off.  */
-       if (cur->target_ops->to_close)
-         (cur->target_ops->to_close) (0);
-       if (prev)
-         prev->next = cur->next;       /* Unchain old target_ops */
-       else
-         target_stack = cur->next;     /* Unchain first on list */
-       tmp = cur->next;
-       xfree (cur);
-       cur = tmp;
-      }
+  /* If there's already targets at this stratum, remove them.  */
+  /* FIXME: cagney/2003-10-15: I think this should be poping all
+     targets to CUR, and not just those at this stratum level.  */
+  while ((*cur) != NULL && t->to_stratum == (*cur)->to_stratum)
+    {
+      /* There's already something at this stratum level.  Close it,
+         and un-hook it from the stack.  */
+      struct target_ops *tmp = (*cur);
+      (*cur) = (*cur)->beneath;
+      tmp->beneath = NULL;
+      target_close (tmp, 0);
+    }
 
   /* We have removed all targets in our stratum, now add the new one.  */
-
-  tmp = (struct target_stack_item *)
-    xmalloc (sizeof (struct target_stack_item));
-  tmp->next = cur;
-  tmp->target_ops = t;
-
-  if (prev)
-    prev->next = tmp;
-  else
-    target_stack = tmp;
+  t->beneath = (*cur);
+  (*cur) = t;
 
   update_current_target ();
 
-  cleanup_target (&current_target);    /* Fill in the gaps */
-
   if (targetdebug)
     setup_target_debug ();
 
-  return prev != 0;
+  /* Not on top?  */
+  return (t != target_stack);
 }
 
 /* Remove a target_ops vector from the stack, wherever it may be. 
@@ -691,32 +706,35 @@ push_target (struct target_ops *t)
 int
 unpush_target (struct target_ops *t)
 {
-  struct target_stack_item *cur, *prev;
-
-  if (t->to_close)
-    t->to_close (0);           /* Let it clean up */
+  struct target_ops **cur;
+  struct target_ops *tmp;
 
   /* Look for the specified target.  Note that we assume that a target
      can only occur once in the target stack. */
 
-  for (cur = target_stack, prev = NULL; cur; prev = cur, cur = cur->next)
-    if (cur->target_ops == t)
-      break;
+  for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath)
+    {
+      if ((*cur) == t)
+       break;
+    }
 
-  if (!cur)
+  if ((*cur) == NULL)
     return 0;                  /* Didn't find target_ops, quit now */
 
-  /* Unchain the target */
+  /* NOTE: cagney/2003-12-06: In '94 the close call was made
+     unconditional by moving it to before the above check that the
+     target was in the target stack (something about "Change the way
+     pushing and popping of targets work to support target overlays
+     and inheritance").  This doesn't make much sense - only open
+     targets should be closed.  */
+  target_close (t, 0);
 
-  if (!prev)
-    target_stack = cur->next;
-  else
-    prev->next = cur->next;
-
-  xfree (cur);                 /* Release the target_stack_item */
+  /* Unchain the target */
+  tmp = (*cur);
+  (*cur) = (*cur)->beneath;
+  tmp->beneath = NULL;
 
   update_current_target ();
-  cleanup_target (&current_target);
 
   return 1;
 }
@@ -724,8 +742,8 @@ unpush_target (struct target_ops *t)
 void
 pop_target (void)
 {
-  (current_target.to_close) (0);       /* Let it clean up */
-  if (unpush_target (target_stack->target_ops) == 1)
+  target_close (&current_target, 0);   /* Let it clean up */
+  if (unpush_target (target_stack) == 1)
     return;
 
   fprintf_unfiltered (gdb_stderr,
@@ -766,7 +784,7 @@ target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
       tlen = MIN (len, 4 - (memaddr & 3));
       offset = memaddr & 3;
 
-      errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0);
+      errcode = target_read_memory (memaddr & ~3, buf, 4);
       if (errcode != 0)
        {
          /* The transfer request might have crossed the boundary to an
@@ -774,7 +792,7 @@ target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
             a single byte.  */
          tlen = 1;
          offset = 0;
-         errcode = target_xfer_memory (memaddr, buf, 1, 0);
+         errcode = target_read_memory (memaddr, buf, 1);
          if (errcode != 0)
            goto done;
        }
@@ -810,6 +828,162 @@ done:
   return nbytes_read;
 }
 
+/* Find a section containing ADDR.  */
+struct section_table *
+target_section_by_addr (struct target_ops *target, CORE_ADDR addr)
+{
+  struct section_table *secp;
+  for (secp = target->to_sections;
+       secp < target->to_sections_end;
+       secp++)
+    {
+      if (addr >= secp->addr && addr < secp->endaddr)
+       return secp;
+    }
+  return NULL;
+}
+
+/* Return non-zero when the target vector has supplied an xfer_partial
+   method and it, rather than xfer_memory, should be used.  */
+static int
+target_xfer_partial_p (void)
+{
+  return (target_stack != NULL
+         && target_stack->to_xfer_partial != default_xfer_partial);
+}
+
+static LONGEST
+target_xfer_partial (struct target_ops *ops,
+                    enum target_object object, const char *annex,
+                    void *readbuf, const void *writebuf,
+                    ULONGEST offset, LONGEST len)
+{
+  LONGEST retval;
+
+  gdb_assert (ops->to_xfer_partial != NULL);
+  retval = ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
+                                offset, len);
+  if (targetdebug)
+    {
+      const unsigned char *myaddr = NULL;
+
+      fprintf_unfiltered (gdb_stdlog,
+                         "%s:target_xfer_partial (%d, %s, 0x%lx,  0x%lx,  0x%s, %s) = %s",
+                         ops->to_shortname,
+                         (int) object,
+                         (annex ? annex : "(null)"),
+                         (long) readbuf, (long) writebuf,
+                         paddr_nz (offset), paddr_d (len), paddr_d (retval));
+
+      if (readbuf)
+       myaddr = readbuf;
+      if (writebuf)
+       myaddr = writebuf;
+      if (retval > 0 && myaddr != NULL)
+       {
+         int i;
+         
+         fputs_unfiltered (", bytes =", gdb_stdlog);
+         for (i = 0; i < retval; i++)
+           {
+             if ((((long) &(myaddr[i])) & 0xf) == 0)
+               {
+                 if (targetdebug < 2 && i > 0)
+                   {
+                     fprintf_unfiltered (gdb_stdlog, " ...");
+                     break;
+                   }
+                 fprintf_unfiltered (gdb_stdlog, "\n");
+               }
+             
+             fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff);
+           }
+       }
+      
+      fputc_unfiltered ('\n', gdb_stdlog);
+    }
+  return retval;
+}
+
+/* Attempt a transfer all LEN bytes starting at OFFSET between the
+   inferior's KIND:ANNEX space and GDB's READBUF/WRITEBUF buffer.  If
+   the transfer succeeds, return zero, otherwize the host ERRNO is
+   returned.
+
+   The inferior is formed from several layers.  In the case of
+   corefiles, inf-corefile is layered above inf-exec and a request for
+   text (corefiles do not include text pages) will be first sent to
+   the core-stratum, fail, and then sent to the object-file where it
+   will succeed.
+
+   NOTE: cagney/2004-09-30:
+
+   The old code tried to use four separate mechanisms for mapping an
+   object:offset:len tuple onto an inferior and its address space: the
+   target stack; the inferior's TO_SECTIONS; solib's SO_LIST;
+   overlays.
+
+   This is stupid.
+
+   The code below is instead using a single mechanism (currently
+   strata).  If that mechanism proves insufficient then re-factor it
+   implementing another singluar mechanism (for instance, a generic
+   object:annex onto inferior:object:annex say).  */
+
+static LONGEST
+xfer_using_stratum (enum target_object object, const char *annex,
+                   ULONGEST offset, LONGEST len, void *readbuf,
+                   const void *writebuf)
+{
+  LONGEST xfered;
+  struct target_ops *target;
+
+  /* Always successful.  */
+  if (len == 0)
+    return 0;
+  /* Never successful.  */
+  if (target_stack == NULL)
+    return EIO;
+
+  target = target_stack;
+  while (1)
+    {
+      xfered = target_xfer_partial (target, object, annex,
+                                   readbuf, writebuf, offset, len);
+      if (xfered > 0)
+       {
+         /* The partial xfer succeeded, update the counts, check that
+            the xfer hasn't finished and if it hasn't set things up
+            for the next round.  */
+         len -= xfered;
+         if (len <= 0)
+           return 0;
+         offset += xfered;
+         if (readbuf != NULL)
+           readbuf = (bfd_byte *) readbuf + xfered;
+         if (writebuf != NULL)
+           writebuf = (bfd_byte *) writebuf + xfered;
+         target = target_stack;
+       }
+      else if (xfered < 0)
+       {
+         /* Something totally screwed up, abandon the attempt to
+            xfer.  */
+         if (errno)
+           return errno;
+         else
+           return EIO;
+       }
+      else
+       {
+         /* This "stratum" didn't work, try the next one down.  */
+         target = target->beneath;
+         if (target == NULL)
+           return EIO;
+       }
+    }
+}
+
 /* Read LEN bytes of target memory at address MEMADDR, placing the results in
    GDB's memory at MYADDR.  Returns either 0 for success or an errno value
    if any error occurs.
@@ -821,16 +995,43 @@ done:
    deal with partial reads should call target_read_memory_partial. */
 
 int
-target_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
+target_read_memory (CORE_ADDR memaddr, bfd_byte *myaddr, int len)
+{
+  if (target_xfer_partial_p ())
+    return xfer_using_stratum (TARGET_OBJECT_MEMORY, NULL,
+                              memaddr, len, myaddr, NULL);
+  else
+    return target_xfer_memory (memaddr, myaddr, len, 0);
+}
+
+int
+target_write_memory (CORE_ADDR memaddr, const bfd_byte *myaddr, int len)
 {
-  return target_xfer_memory (memaddr, myaddr, len, 0);
+  bfd_byte *bytes = alloca (len);
+  memcpy (bytes, myaddr, len);
+  if (target_xfer_partial_p ())
+    return xfer_using_stratum (TARGET_OBJECT_MEMORY, NULL,
+                              memaddr, len, NULL, bytes);
+  else
+    return target_xfer_memory (memaddr, bytes, len, 1);
 }
 
+#ifndef target_stopped_data_address_p
 int
-target_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
+target_stopped_data_address_p (struct target_ops *target)
 {
-  return target_xfer_memory (memaddr, myaddr, len, 1);
+  if (target->to_stopped_data_address
+      == (int (*) (struct target_ops *, CORE_ADDR *)) return_zero)
+    return 0;
+  if (target->to_stopped_data_address == debug_to_stopped_data_address
+      && (debug_target.to_stopped_data_address
+         == (int (*) (struct target_ops *, CORE_ADDR *)) return_zero))
+    return 0;
+  return 1;
 }
+#endif
+
+static int trust_readonly = 0;
 
 /* Move memory to or from the targets.  The top target gets priority;
    if it cannot handle it, it is offered to the next one down, etc.
@@ -844,30 +1045,41 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
   int res;
   int done = 0;
   struct target_ops *t;
-  struct target_stack_item *item;
 
   /* Zero length requests are ok and require no work.  */
   if (len == 0)
     return 0;
 
-  /* to_xfer_memory is not guaranteed to set errno, even when it returns
-     0.  */
+  /* deprecated_xfer_memory is not guaranteed to set errno, even when
+     it returns 0.  */
   errno = 0;
 
+  if (!write && trust_readonly)
+    {
+      struct section_table *secp;
+      /* User-settable option, "trust-readonly-sections".  If true,
+         then memory from any SEC_READONLY bfd section may be read
+         directly from the bfd file.  */
+      secp = target_section_by_addr (&current_target, memaddr);
+      if (secp != NULL
+         && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
+             & SEC_READONLY))
+       return xfer_memory (memaddr, myaddr, len, 0, attrib, &current_target);
+    }
+
   /* The quick case is that the top target can handle the transfer.  */
-  res = current_target.to_xfer_memory
+  res = current_target.deprecated_xfer_memory
     (memaddr, myaddr, len, write, attrib, &current_target);
 
   /* If res <= 0 then we call it again in the loop.  Ah well. */
   if (res <= 0)
     {
-      for (item = target_stack; item; item = item->next)
+      for (t = target_stack; t != NULL; t = t->beneath)
        {
-         t = item->target_ops;
          if (!t->to_has_memory)
            continue;
 
-         res = t->to_xfer_memory (memaddr, myaddr, len, write, attrib, t);
+         res = t->deprecated_xfer_memory (memaddr, myaddr, len, write, attrib, t);
          if (res > 0)
            break;              /* Handled all or part of xfer */
          if (t->to_has_all_memory)
@@ -924,10 +1136,10 @@ target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
       while (reg_len > 0)
        {
          if (region->attrib.cache)
-           res = dcache_xfer_memory(target_dcache, memaddr, myaddr,
+           res = dcache_xfer_memory (target_dcache, memaddr, myaddr,
                                     reg_len, write);
          else
-           res = do_xfer_memory(memaddr, myaddr, reg_len, write,
+           res = do_xfer_memory (memaddr, myaddr, reg_len, write,
                                 &region->attrib);
              
          if (res <= 0)
@@ -1019,38 +1231,170 @@ target_xfer_memory_partial (CORE_ADDR memaddr, char *myaddr, int len,
   return res;
 }
 
-int
-target_read_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
+int
+target_read_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
+{
+  if (target_xfer_partial_p ())
+    return target_xfer_partial (target_stack, TARGET_OBJECT_MEMORY, NULL,
+                               buf, NULL, memaddr, len);
+  else
+    return target_xfer_memory_partial (memaddr, buf, len, 0, err);
+}
+
+int
+target_write_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
+{
+  if (target_xfer_partial_p ())
+    return target_xfer_partial (target_stack, TARGET_OBJECT_MEMORY, NULL,
+                               NULL, buf, memaddr, len);
+  else
+    return target_xfer_memory_partial (memaddr, buf, len, 1, err);
+}
+
+/* More generic transfers.  */
+
+static LONGEST
+default_xfer_partial (struct target_ops *ops, enum target_object object,
+                     const char *annex, void *readbuf, 
+                     const void *writebuf, ULONGEST offset, LONGEST len)
+{
+  if (object == TARGET_OBJECT_MEMORY
+      && ops->deprecated_xfer_memory != NULL)
+    /* If available, fall back to the target's
+       "deprecated_xfer_memory" method.  */
+    {
+      int xfered = -1;
+      errno = 0;
+      if (writebuf != NULL)
+       {
+         void *buffer = xmalloc (len);
+         struct cleanup *cleanup = make_cleanup (xfree, buffer);
+         memcpy (buffer, writebuf, len);
+         xfered = ops->deprecated_xfer_memory (offset, buffer, len,
+                                               1/*write*/, NULL, ops);
+         do_cleanups (cleanup);
+       }
+      if (readbuf != NULL)
+       xfered = ops->deprecated_xfer_memory (offset, readbuf, len, 0/*read*/,
+                                             NULL, ops);
+      if (xfered > 0)
+       return xfered;
+      else if (xfered == 0 && errno == 0)
+       /* "deprecated_xfer_memory" uses 0, cross checked against
+           ERRNO as one indication of an error.  */
+       return 0;
+      else
+       return -1;
+    }
+  else if (ops->beneath != NULL)
+    return target_xfer_partial (ops->beneath, object, annex,
+                               readbuf, writebuf, offset, len);
+  else
+    return -1;
+}
+
+/* Target vector read/write partial wrapper functions.
+
+   NOTE: cagney/2003-10-21: I wonder if having "to_xfer_partial
+   (inbuf, outbuf)", instead of separate read/write methods, make life
+   easier.  */
+
+LONGEST
+target_read_partial (struct target_ops *ops,
+                    enum target_object object,
+                    const char *annex, void *buf,
+                    ULONGEST offset, LONGEST len)
+{
+  return target_xfer_partial (ops, object, annex, buf, NULL, offset, len);
+}
+
+LONGEST
+target_write_partial (struct target_ops *ops,
+                     enum target_object object,
+                     const char *annex, const void *buf,
+                     ULONGEST offset, LONGEST len)
+{
+  return target_xfer_partial (ops, object, annex, NULL, buf, offset, len);
+}
+
+/* Wrappers to perform the full transfer.  */
+LONGEST
+target_read (struct target_ops *ops,
+            enum target_object object,
+            const char *annex, void *buf,
+            ULONGEST offset, LONGEST len)
+{
+  LONGEST xfered = 0;
+  while (xfered < len)
+    {
+      LONGEST xfer = target_read_partial (ops, object, annex,
+                                         (bfd_byte *) buf + xfered,
+                                         offset + xfered, len - xfered);
+      /* Call an observer, notifying them of the xfer progress?  */
+      if (xfer <= 0)
+       /* Call memory_error?  */
+       return -1;
+      xfered += xfer;
+      QUIT;
+    }
+  return len;
+}
+
+LONGEST
+target_write (struct target_ops *ops,
+             enum target_object object,
+             const char *annex, const void *buf,
+             ULONGEST offset, LONGEST len)
+{
+  LONGEST xfered = 0;
+  while (xfered < len)
+    {
+      LONGEST xfer = target_write_partial (ops, object, annex,
+                                          (bfd_byte *) buf + xfered,
+                                          offset + xfered, len - xfered);
+      /* Call an observer, notifying them of the xfer progress?  */
+      if (xfer <= 0)
+       /* Call memory_error?  */
+       return -1;
+      xfered += xfer;
+      QUIT;
+    }
+  return len;
+}
+
+/* Memory transfer methods.  */
+
+void
+get_target_memory (struct target_ops *ops, CORE_ADDR addr, void *buf,
+                  LONGEST len)
 {
-  return target_xfer_memory_partial (memaddr, buf, len, 0, err);
+  if (target_read (ops, TARGET_OBJECT_MEMORY, NULL, buf, addr, len)
+      != len)
+    memory_error (EIO, addr);
 }
 
-int
-target_write_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
+ULONGEST
+get_target_memory_unsigned (struct target_ops *ops,
+                           CORE_ADDR addr, int len)
 {
-  return target_xfer_memory_partial (memaddr, buf, len, 1, err);
+  char buf[sizeof (ULONGEST)];
+
+  gdb_assert (len <= sizeof (buf));
+  get_target_memory (ops, addr, buf, len);
+  return extract_unsigned_integer (buf, len);
 }
 
-/* ARGSUSED */
 static void
 target_info (char *args, int from_tty)
 {
   struct target_ops *t;
-  struct target_stack_item *item;
   int has_all_mem = 0;
 
   if (symfile_objfile != NULL)
     printf_unfiltered ("Symbols from \"%s\".\n", symfile_objfile->name);
 
-#ifdef FILES_INFO_HOOK
-  if (FILES_INFO_HOOK ())
-    return;
-#endif
-
-  for (item = target_stack; item; item = item->next)
+  for (t = target_stack; t != NULL; t = t->beneath)
     {
-      t = item->target_ops;
-
       if (!t->to_has_memory)
        continue;
 
@@ -1093,17 +1437,19 @@ target_preopen (int from_tty)
 void
 target_detach (char *args, int from_tty)
 {
-  /* Handle any optimized stores to the inferior.  */
-#ifdef DO_DEFERRED_STORES
-  DO_DEFERRED_STORES;
-#endif
   (current_target.to_detach) (args, from_tty);
 }
 
+void
+target_disconnect (char *args, int from_tty)
+{
+  (current_target.to_disconnect) (args, from_tty);
+}
+
 void
 target_link (char *modname, CORE_ADDR *t_reloc)
 {
-  if (STREQ (current_target.to_shortname, "rombug"))
+  if (DEPRECATED_STREQ (current_target.to_shortname, "rombug"))
     {
       (current_target.to_lookup_symbol) (modname, t_reloc);
       if (*t_reloc == 0)
@@ -1163,43 +1509,20 @@ find_default_attach (char *args, int from_tty)
 }
 
 void
-find_default_require_attach (char *args, int from_tty)
-{
-  struct target_ops *t;
-
-  t = find_default_run_target ("require_attach");
-  (t->to_require_attach) (args, from_tty);
-  return;
-}
-
-void
-find_default_require_detach (int pid, char *args, int from_tty)
-{
-  struct target_ops *t;
-
-  t = find_default_run_target ("require_detach");
-  (t->to_require_detach) (pid, args, from_tty);
-  return;
-}
-
-void
-find_default_create_inferior (char *exec_file, char *allargs, char **env)
+find_default_create_inferior (char *exec_file, char *allargs, char **env,
+                             int from_tty)
 {
   struct target_ops *t;
 
   t = find_default_run_target ("run");
-  (t->to_create_inferior) (exec_file, allargs, env);
+  (t->to_create_inferior) (exec_file, allargs, env, from_tty);
   return;
 }
 
-void
-find_default_clone_and_follow_inferior (int child_pid, int *followed_child)
+static int
+default_region_size_ok_for_hw_watchpoint (int byte_count)
 {
-  struct target_ops *t;
-
-  t = find_default_run_target ("run");
-  (t->to_clone_and_follow_inferior) (child_pid, followed_child);
-  return;
+  return (byte_count <= TYPE_LENGTH (builtin_type_void_data_ptr));
 }
 
 static int
@@ -1214,6 +1537,12 @@ return_one (void)
   return 1;
 }
 
+static int
+return_minus_one (void)
+{
+  return -1;
+}
+
 /*
  * Resize the to_sections pointer.  Also make sure that anyone that
  * was holding on to an old value of it gets updated.
@@ -1258,6 +1587,13 @@ target_resize_to_sections (struct target_ops *target, int num_added)
              (*t)->to_sections_end = target->to_sections_end;
            }
        }
+      /* There is a flattened view of the target stack in current_target,
+        so its to_sections pointer might also need updating. */
+      if (current_target.to_sections == old_value)
+       {
+         current_target.to_sections = target->to_sections;
+         current_target.to_sections_end = target->to_sections_end;
+       }
     }
   
   return old_count;
@@ -1353,16 +1689,7 @@ find_core_target (void)
 struct target_ops *
 find_target_beneath (struct target_ops *t)
 {
-  struct target_stack_item *cur;
-
-  for (cur = target_stack; cur; cur = cur->next)
-    if (cur->target_ops == t)
-      break;
-
-  if (cur == NULL || cur->next == NULL)
-    return NULL;
-  else
-    return cur->next->target_ops;
+  return t->beneath;
 }
 
 \f
@@ -1378,11 +1705,6 @@ generic_mourn_inferior (void)
   breakpoint_init_inferior (inf_exited);
   registers_changed ();
 
-#ifdef CLEAR_DEFERRED_STORES
-  /* Delete any pending stores to the inferior... */
-  CLEAR_DEFERRED_STORES;
-#endif
-
   reopen_exec_file ();
   reinit_frame_cache ();
 
@@ -1393,8 +1715,8 @@ generic_mourn_inferior (void)
   if (!show_breakpoint_hit_counts)
     breakpoint_clear_ignore_counts ();
 
-  if (detach_hook)
-    detach_hook ();
+  if (deprecated_detach_hook)
+    deprecated_detach_hook ();
 }
 \f
 /* Helper function for child_wait and the Lynx derivatives of child_wait.
@@ -1443,22 +1765,18 @@ normal_pid_to_str (ptid_t ptid)
   return buf;
 }
 
-/* Some targets (such as ttrace-based HPUX) don't allow us to request
-   notification of inferior events such as fork and vork immediately
-   after the inferior is created.  (This because of how gdb gets an
-   inferior created via invoking a shell to do it.  In such a scenario,
-   if the shell init file has commands in it, the shell will fork and
-   exec for each of those commands, and we will see each such fork
-   event.  Very bad.)
+/* Error-catcher for target_find_memory_regions */
+static int dummy_find_memory_regions (int (*ignore1) (), void *ignore2)
+{
+  error ("No target.");
+  return 0;
+}
 
-   This function is used by all targets that allow us to request
-   notification of forks, etc at inferior creation time; e.g., in
-   target_acknowledge_forked_child.
- */
-static void
-normal_target_post_startup_inferior (ptid_t ptid)
+/* Error-catcher for target_make_corefile_notes */
+static char * dummy_make_corefile_notes (bfd *ignore1, int *ignore2)
 {
-  /* This space intentionally left blank. */
+  error ("No target.");
+  return NULL;
 }
 
 /* Set up the handful of non-empty slots needed by the dummy target
@@ -1471,18 +1789,15 @@ init_dummy_target (void)
   dummy_target.to_longname = "None";
   dummy_target.to_doc = "";
   dummy_target.to_attach = find_default_attach;
-  dummy_target.to_require_attach = find_default_require_attach;
-  dummy_target.to_require_detach = find_default_require_detach;
   dummy_target.to_create_inferior = find_default_create_inferior;
-  dummy_target.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
   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;
+  dummy_target.to_make_corefile_notes = dummy_make_corefile_notes;
+  dummy_target.to_xfer_partial = default_xfer_partial;
   dummy_target.to_magic = OPS_MAGIC;
 }
 \f
-
-static struct target_ops debug_target;
-
 static void
 debug_to_open (char *args, int from_tty)
 {
@@ -1494,11 +1809,19 @@ debug_to_open (char *args, int from_tty)
 static void
 debug_to_close (int quitting)
 {
-  debug_target.to_close (quitting);
-
+  target_close (&debug_target, quitting);
   fprintf_unfiltered (gdb_stdlog, "target_close (%d)\n", quitting);
 }
 
+void
+target_close (struct target_ops *targ, int quitting)
+{
+  if (targ->to_xclose != NULL)
+    targ->to_xclose (targ, quitting);
+  else if (targ->to_close != NULL)
+    targ->to_close (quitting);
+}
+
 static void
 debug_to_attach (char *args, int from_tty)
 {
@@ -1516,15 +1839,6 @@ debug_to_post_attach (int pid)
   fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
 }
 
-static void
-debug_to_require_attach (char *args, int from_tty)
-{
-  debug_target.to_require_attach (args, from_tty);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_require_attach (%s, %d)\n", args, from_tty);
-}
-
 static void
 debug_to_detach (char *args, int from_tty)
 {
@@ -1534,12 +1848,12 @@ debug_to_detach (char *args, int from_tty)
 }
 
 static void
-debug_to_require_detach (int pid, char *args, int from_tty)
+debug_to_disconnect (char *args, int from_tty)
 {
-  debug_target.to_require_detach (pid, args, from_tty);
+  debug_target.to_disconnect (args, from_tty);
 
-  fprintf_unfiltered (gdb_stdlog,
-              "target_require_detach (%d, %s, %d)\n", pid, args, from_tty);
+  fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n",
+                     args, from_tty);
 }
 
 static void
@@ -1601,40 +1915,47 @@ debug_to_wait (ptid_t ptid, struct target_waitstatus *status)
 }
 
 static void
-debug_to_post_wait (ptid_t ptid, int status)
+debug_print_register (const char * func, int regno)
 {
-  debug_target.to_post_wait (ptid, status);
-
-  fprintf_unfiltered (gdb_stdlog, "target_post_wait (%d, %d)\n",
-                     PIDGET (ptid), status);
+  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));
+  else
+    fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
+  if (regno >= 0)
+    {
+      int i;
+      unsigned char buf[MAX_REGISTER_SIZE];
+      deprecated_read_register_gen (regno, buf);
+      fprintf_unfiltered (gdb_stdlog, " = ");
+      for (i = 0; i < register_size (current_gdbarch, regno); i++)
+       {
+         fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
+       }
+      if (register_size (current_gdbarch, regno) <= sizeof (LONGEST))
+       {
+         fprintf_unfiltered (gdb_stdlog, " 0x%s %s",
+                             paddr_nz (read_register (regno)),
+                             paddr_d (read_register (regno)));
+       }
+    }
+  fprintf_unfiltered (gdb_stdlog, "\n");
 }
 
 static void
 debug_to_fetch_registers (int regno)
 {
   debug_target.to_fetch_registers (regno);
-
-  fprintf_unfiltered (gdb_stdlog, "target_fetch_registers (%s)",
-                     regno != -1 ? REGISTER_NAME (regno) : "-1");
-  if (regno != -1)
-    fprintf_unfiltered (gdb_stdlog, " = 0x%lx %ld",
-                       (unsigned long) read_register (regno),
-                       (unsigned long) read_register (regno));
-  fprintf_unfiltered (gdb_stdlog, "\n");
+  debug_print_register ("target_fetch_registers", regno);
 }
 
 static void
 debug_to_store_registers (int regno)
 {
   debug_target.to_store_registers (regno);
-
-  if (regno >= 0 && regno < NUM_REGS)
-    fprintf_unfiltered (gdb_stdlog, "target_store_registers (%s) = 0x%lx %ld\n",
-                       REGISTER_NAME (regno),
-                       (unsigned long) read_register (regno),
-                       (unsigned long) read_register (regno));
-  else
-    fprintf_unfiltered (gdb_stdlog, "target_store_registers (%d)\n", regno);
+  debug_print_register ("target_store_registers", regno);
+  fprintf_unfiltered (gdb_stdlog, "\n");
 }
 
 static void
@@ -1646,22 +1967,20 @@ debug_to_prepare_to_store (void)
 }
 
 static int
-debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                     struct mem_attrib *attrib,
-                     struct target_ops *target)
+deprecated_debug_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+                             int write, struct mem_attrib *attrib,
+                             struct target_ops *target)
 {
   int retval;
 
-  retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write,
-                                       attrib, target);
+  retval = debug_target.deprecated_xfer_memory (memaddr, myaddr, len, write,
+                                               attrib, target);
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
                      (unsigned int) memaddr,   /* possable truncate long long */
                      len, write ? "write" : "read", retval);
 
-
-
   if (retval > 0)
     {
       int i;
@@ -1670,7 +1989,15 @@ debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
       for (i = 0; i < retval; i++)
        {
          if ((((long) &(myaddr[i])) & 0xf) == 0)
-           fprintf_unfiltered (gdb_stdlog, "\n");
+           {
+             if (targetdebug < 2 && i > 0)
+               {
+                 fprintf_unfiltered (gdb_stdlog, " ...");
+                 break;
+               }
+             fprintf_unfiltered (gdb_stdlog, "\n");
+           }
+         
          fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff);
        }
     }
@@ -1716,6 +2043,117 @@ debug_to_remove_breakpoint (CORE_ADDR addr, char *save)
   return retval;
 }
 
+static int
+debug_to_can_use_hw_breakpoint (int type, int cnt, int from_tty)
+{
+  int retval;
+
+  retval = debug_target.to_can_use_hw_breakpoint (type, cnt, from_tty);
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "target_can_use_hw_breakpoint (%ld, %ld, %ld) = %ld\n",
+                     (unsigned long) type,
+                     (unsigned long) cnt,
+                     (unsigned long) from_tty,
+                     (unsigned long) retval);
+  return retval;
+}
+
+static int
+debug_to_region_size_ok_for_hw_watchpoint (int byte_count)
+{
+  CORE_ADDR retval;
+
+  retval = debug_target.to_region_size_ok_for_hw_watchpoint (byte_count);
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (%ld) = 0x%lx\n",
+                     (unsigned long) byte_count,
+                     (unsigned long) retval);
+  return retval;
+}
+
+static int
+debug_to_stopped_by_watchpoint (void)
+{
+  int retval;
+
+  retval = debug_target.to_stopped_by_watchpoint ();
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "STOPPED_BY_WATCHPOINT () = %ld\n",
+                     (unsigned long) retval);
+  return retval;
+}
+
+static int
+debug_to_stopped_data_address (struct target_ops *target, CORE_ADDR *addr)
+{
+  int retval;
+
+  retval = debug_target.to_stopped_data_address (target, addr);
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "target_stopped_data_address ([0x%lx]) = %ld\n",
+                     (unsigned long)*addr,
+                     (unsigned long)retval);
+  return retval;
+}
+
+static int
+debug_to_insert_hw_breakpoint (CORE_ADDR addr, char *save)
+{
+  int retval;
+
+  retval = debug_target.to_insert_hw_breakpoint (addr, save);
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "target_insert_hw_breakpoint (0x%lx, xxx) = %ld\n",
+                     (unsigned long) addr,
+                     (unsigned long) retval);
+  return retval;
+}
+
+static int
+debug_to_remove_hw_breakpoint (CORE_ADDR addr, char *save)
+{
+  int retval;
+
+  retval = debug_target.to_remove_hw_breakpoint (addr, save);
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "target_remove_hw_breakpoint (0x%lx, xxx) = %ld\n",
+                     (unsigned long) addr,
+                     (unsigned long) retval);
+  return retval;
+}
+
+static int
+debug_to_insert_watchpoint (CORE_ADDR addr, int len, int type)
+{
+  int retval;
+
+  retval = debug_target.to_insert_watchpoint (addr, len, type);
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n",
+                     (unsigned long) addr, len, type, (unsigned long) retval);
+  return retval;
+}
+
+static int
+debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type)
+{
+  int retval;
+
+  retval = debug_target.to_insert_watchpoint (addr, len, type);
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n",
+                     (unsigned long) addr, len, type, (unsigned long) retval);
+  return retval;
+}
+
 static void
 debug_to_terminal_init (void)
 {
@@ -1748,6 +2186,14 @@ debug_to_terminal_ours (void)
   fprintf_unfiltered (gdb_stdlog, "target_terminal_ours ()\n");
 }
 
+static void
+debug_to_terminal_save_ours (void)
+{
+  debug_target.to_terminal_save_ours ();
+
+  fprintf_unfiltered (gdb_stdlog, "target_terminal_save_ours ()\n");
+}
+
 static void
 debug_to_terminal_info (char *arg, int from_tty)
 {
@@ -1786,12 +2232,13 @@ debug_to_lookup_symbol (char *name, CORE_ADDR *addrp)
 }
 
 static void
-debug_to_create_inferior (char *exec_file, char *args, char **env)
+debug_to_create_inferior (char *exec_file, char *args, char **env,
+                         int from_tty)
 {
-  debug_target.to_create_inferior (exec_file, args, env);
+  debug_target.to_create_inferior (exec_file, args, env, from_tty);
 
-  fprintf_unfiltered (gdb_stdlog, "target_create_inferior (%s, %s, xxx)\n",
-                     exec_file, args);
+  fprintf_unfiltered (gdb_stdlog, "target_create_inferior (%s, %s, xxx, %d)\n",
+                     exec_file, args, from_tty);
 }
 
 static void
@@ -1813,34 +2260,12 @@ debug_to_acknowledge_created_inferior (int pid)
 }
 
 static void
-debug_to_clone_and_follow_inferior (int child_pid, int *followed_child)
-{
-  debug_target.to_clone_and_follow_inferior (child_pid, followed_child);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_clone_and_follow_inferior (%d, %d)\n",
-                     child_pid, *followed_child);
-}
-
-static void
-debug_to_post_follow_inferior_by_clone (void)
-{
-  debug_target.to_post_follow_inferior_by_clone ();
-
-  fprintf_unfiltered (gdb_stdlog, "target_post_follow_inferior_by_clone ()\n");
-}
-
-static int
 debug_to_insert_fork_catchpoint (int pid)
 {
-  int retval;
-
-  retval = debug_target.to_insert_fork_catchpoint (pid);
+  debug_target.to_insert_fork_catchpoint (pid);
 
-  fprintf_unfiltered (gdb_stdlog, "target_insert_fork_catchpoint (%d) = %d\n",
-                     pid, retval);
-
-  return retval;
+  fprintf_unfiltered (gdb_stdlog, "target_insert_fork_catchpoint (%d)\n",
+                     pid);
 }
 
 static int
@@ -1856,17 +2281,13 @@ debug_to_remove_fork_catchpoint (int pid)
   return retval;
 }
 
-static int
+static void
 debug_to_insert_vfork_catchpoint (int pid)
 {
-  int retval;
-
-  retval = debug_target.to_insert_vfork_catchpoint (pid);
+  debug_target.to_insert_vfork_catchpoint (pid);
 
-  fprintf_unfiltered (gdb_stdlog, "target_insert_vfork_catchpoint (%d)= %d\n",
-                     pid, retval);
-
-  return retval;
+  fprintf_unfiltered (gdb_stdlog, "target_insert_vfork_catchpoint (%d)\n",
+                     pid);
 }
 
 static int
@@ -1883,66 +2304,23 @@ debug_to_remove_vfork_catchpoint (int pid)
 }
 
 static int
-debug_to_has_forked (int pid, int *child_pid)
-{
-  int has_forked;
-
-  has_forked = debug_target.to_has_forked (pid, child_pid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_has_forked (%d, %d) = %d\n",
-                     pid, *child_pid, has_forked);
-
-  return has_forked;
-}
-
-static int
-debug_to_has_vforked (int pid, int *child_pid)
-{
-  int has_vforked;
-
-  has_vforked = debug_target.to_has_vforked (pid, child_pid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_has_vforked (%d, %d) = %d\n",
-                     pid, *child_pid, has_vforked);
-
-  return has_vforked;
-}
-
-static int
-debug_to_can_follow_vfork_prior_to_exec (void)
+debug_to_follow_fork (int follow_child)
 {
-  int can_immediately_follow_vfork;
+  int retval =  debug_target.to_follow_fork (follow_child);
 
-  can_immediately_follow_vfork = debug_target.to_can_follow_vfork_prior_to_exec ();
+  fprintf_unfiltered (gdb_stdlog, "target_follow_fork (%d) = %d\n",
+                     follow_child, retval);
 
-  fprintf_unfiltered (gdb_stdlog, "target_can_follow_vfork_prior_to_exec () = %d\n",
-                     can_immediately_follow_vfork);
-
-  return can_immediately_follow_vfork;
+  return retval;
 }
 
 static void
-debug_to_post_follow_vfork (int parent_pid, int followed_parent, int child_pid,
-                           int followed_child)
-{
-  debug_target.to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_post_follow_vfork (%d, %d, %d, %d)\n",
-                   parent_pid, followed_parent, child_pid, followed_child);
-}
-
-static int
 debug_to_insert_exec_catchpoint (int pid)
 {
-  int retval;
-
-  retval = debug_target.to_insert_exec_catchpoint (pid);
+  debug_target.to_insert_exec_catchpoint (pid);
 
-  fprintf_unfiltered (gdb_stdlog, "target_insert_exec_catchpoint (%d) = %d\n",
-                     pid, retval);
-
-  return retval;
+  fprintf_unfiltered (gdb_stdlog, "target_insert_exec_catchpoint (%d)\n",
+                     pid);
 }
 
 static int
@@ -1958,20 +2336,6 @@ debug_to_remove_exec_catchpoint (int pid)
   return retval;
 }
 
-static int
-debug_to_has_execd (int pid, char **execd_pathname)
-{
-  int has_execd;
-
-  has_execd = debug_target.to_has_execd (pid, execd_pathname);
-
-  fprintf_unfiltered (gdb_stdlog, "target_has_execd (%d, %s) = %d\n",
-                     pid, (*execd_pathname ? *execd_pathname : "<NULL>"),
-                     has_execd);
-
-  return has_execd;
-}
-
 static int
 debug_to_reported_exec_events_per_exec_call (void)
 {
@@ -1986,36 +2350,6 @@ debug_to_reported_exec_events_per_exec_call (void)
   return reported_exec_events;
 }
 
-static int
-debug_to_has_syscall_event (int pid, enum target_waitkind *kind,
-                           int *syscall_id)
-{
-  int has_syscall_event;
-  char *kind_spelling = "??";
-
-  has_syscall_event = debug_target.to_has_syscall_event (pid, kind, syscall_id);
-  if (has_syscall_event)
-    {
-      switch (*kind)
-       {
-       case TARGET_WAITKIND_SYSCALL_ENTRY:
-         kind_spelling = "SYSCALL_ENTRY";
-         break;
-       case TARGET_WAITKIND_SYSCALL_RETURN:
-         kind_spelling = "SYSCALL_RETURN";
-         break;
-       default:
-         break;
-       }
-    }
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_has_syscall_event (%d, %s, %d) = %d\n",
-                     pid, kind_spelling, *syscall_id, has_syscall_event);
-
-  return has_syscall_event;
-}
-
 static int
 debug_to_has_exited (int pid, int wait_status, int *exit_status)
 {
@@ -2087,18 +2421,6 @@ debug_to_stop (void)
   fprintf_unfiltered (gdb_stdlog, "target_stop ()\n");
 }
 
-static int
-debug_to_query (int type, char *req, char *resp, int *siz)
-{
-  int retval;
-
-  retval = debug_target.to_query (type, req, resp, siz);
-
-  fprintf_unfiltered (gdb_stdlog, "target_query (%c, %s, %s,  %d) = %d\n", type, req, resp, *siz, retval);
-
-  return retval;
-}
-
 static void
 debug_to_rcmd (char *command,
               struct ui_file *outbuf)
@@ -2149,23 +2471,30 @@ setup_target_debug (void)
   current_target.to_close = debug_to_close;
   current_target.to_attach = debug_to_attach;
   current_target.to_post_attach = debug_to_post_attach;
-  current_target.to_require_attach = debug_to_require_attach;
   current_target.to_detach = debug_to_detach;
-  current_target.to_require_detach = debug_to_require_detach;
+  current_target.to_disconnect = debug_to_disconnect;
   current_target.to_resume = debug_to_resume;
   current_target.to_wait = debug_to_wait;
-  current_target.to_post_wait = debug_to_post_wait;
   current_target.to_fetch_registers = debug_to_fetch_registers;
   current_target.to_store_registers = debug_to_store_registers;
   current_target.to_prepare_to_store = debug_to_prepare_to_store;
-  current_target.to_xfer_memory = debug_to_xfer_memory;
+  current_target.deprecated_xfer_memory = deprecated_debug_xfer_memory;
   current_target.to_files_info = debug_to_files_info;
   current_target.to_insert_breakpoint = debug_to_insert_breakpoint;
   current_target.to_remove_breakpoint = debug_to_remove_breakpoint;
+  current_target.to_can_use_hw_breakpoint = debug_to_can_use_hw_breakpoint;
+  current_target.to_insert_hw_breakpoint = debug_to_insert_hw_breakpoint;
+  current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint;
+  current_target.to_insert_watchpoint = debug_to_insert_watchpoint;
+  current_target.to_remove_watchpoint = debug_to_remove_watchpoint;
+  current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint;
+  current_target.to_stopped_data_address = debug_to_stopped_data_address;
+  current_target.to_region_size_ok_for_hw_watchpoint = debug_to_region_size_ok_for_hw_watchpoint;
   current_target.to_terminal_init = debug_to_terminal_init;
   current_target.to_terminal_inferior = debug_to_terminal_inferior;
   current_target.to_terminal_ours_for_output = debug_to_terminal_ours_for_output;
   current_target.to_terminal_ours = debug_to_terminal_ours;
+  current_target.to_terminal_save_ours = debug_to_terminal_save_ours;
   current_target.to_terminal_info = debug_to_terminal_info;
   current_target.to_kill = debug_to_kill;
   current_target.to_load = debug_to_load;
@@ -2173,21 +2502,14 @@ setup_target_debug (void)
   current_target.to_create_inferior = debug_to_create_inferior;
   current_target.to_post_startup_inferior = debug_to_post_startup_inferior;
   current_target.to_acknowledge_created_inferior = debug_to_acknowledge_created_inferior;
-  current_target.to_clone_and_follow_inferior = debug_to_clone_and_follow_inferior;
-  current_target.to_post_follow_inferior_by_clone = debug_to_post_follow_inferior_by_clone;
   current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint;
   current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint;
   current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint;
   current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint;
-  current_target.to_has_forked = debug_to_has_forked;
-  current_target.to_has_vforked = debug_to_has_vforked;
-  current_target.to_can_follow_vfork_prior_to_exec = debug_to_can_follow_vfork_prior_to_exec;
-  current_target.to_post_follow_vfork = debug_to_post_follow_vfork;
+  current_target.to_follow_fork = debug_to_follow_fork;
   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_has_execd = debug_to_has_execd;
   current_target.to_reported_exec_events_per_exec_call = debug_to_reported_exec_events_per_exec_call;
-  current_target.to_has_syscall_event = debug_to_has_syscall_event;
   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;
@@ -2195,7 +2517,6 @@ setup_target_debug (void)
   current_target.to_thread_alive = debug_to_thread_alive;
   current_target.to_find_new_threads = debug_to_find_new_threads;
   current_target.to_stop = debug_to_stop;
-  current_target.to_query = debug_to_query;
   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;
@@ -2233,16 +2554,28 @@ initialize_targets (void)
   add_info ("target", target_info, targ_desc);
   add_info ("files", target_info, targ_desc);
 
-  add_show_from_set (
-               add_set_cmd ("target", class_maintenance, var_zinteger,
-                            (char *) &targetdebug,
-                            "Set target debugging.\n\
-When non-zero, target debugging is enabled.", &setdebuglist),
-                     &showdebuglist);
-
+  deprecated_add_show_from_set 
+    (add_set_cmd ("target", class_maintenance, var_zinteger,
+                 (char *) &targetdebug,
+                 "Set target debugging.\n\
+When non-zero, target debugging is enabled.  Higher numbers are more\n\
+verbose.  Changes do not take effect until the next \"run\" or \"target\"\n\
+command.", &setdebuglist),
+     &showdebuglist);
+
+  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.", "\
+When this mode is on, memory reads from readonly sections (such as .text)\n\
+will be read from the object file instead of from the target.  This will\n\
+result in significant performance improvement for remote targets.", "\
+Mode for reading from readonly sections is %s.",
+                          NULL, NULL,
+                          &setlist, &showlist);
 
   add_com ("monitor", class_obscure, do_monitor_command,
           "Send a command to the remote monitor (remote targets only).");
 
-  target_dcache = dcache_init();
+  target_dcache = dcache_init ();
 }
This page took 0.050996 seconds and 4 git commands to generate.