fix regressions with target-async
[deliverable/binutils-gdb.git] / gdb / target.c
index 5b8c591b1ce871b7bd209420a013e0b389148572..0d222970c415e1d25b9ec26c09ce459aceaf2d31 100644 (file)
@@ -44,6 +44,7 @@
 #include "tracepoint.h"
 #include "gdb/fileio.h"
 #include "agent.h"
+#include "auxv.h"
 
 static void target_info (char *, int);
 
@@ -65,20 +66,23 @@ static int default_follow_fork (struct target_ops *self, int follow_child,
 
 static void default_mourn_inferior (struct target_ops *self);
 
-static void tcomplain (void) ATTRIBUTE_NORETURN;
+static int default_search_memory (struct target_ops *ops,
+                                 CORE_ADDR start_addr,
+                                 ULONGEST search_space_len,
+                                 const gdb_byte *pattern,
+                                 ULONGEST pattern_len,
+                                 CORE_ADDR *found_addrp);
 
-static int nomemory (CORE_ADDR, char *, int, int, struct target_ops *);
+static void tcomplain (void) ATTRIBUTE_NORETURN;
 
-static int return_zero (void);
+static int return_zero (struct target_ops *);
 
-void target_ignore (void);
+static int return_zero_has_execution (struct target_ops *, ptid_t);
 
 static void target_command (char *, int);
 
 static struct target_ops *find_default_run_target (char *);
 
-static target_xfer_partial_ftype default_xfer_partial;
-
 static struct gdbarch *default_thread_architecture (struct target_ops *ops,
                                                    ptid_t ptid);
 
@@ -91,13 +95,12 @@ static char *dummy_make_corefile_notes (struct target_ops *self,
 
 static char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
 
-static int find_default_can_async_p (struct target_ops *ignore);
-
-static int find_default_is_async_p (struct target_ops *ignore);
-
 static enum exec_direction_kind default_execution_direction
     (struct target_ops *self);
 
+static CORE_ADDR default_target_decr_pc_after_break (struct target_ops *ops,
+                                                    struct gdbarch *gdbarch);
+
 #include "target-delegates.c"
 
 static void init_dummy_target (void);
@@ -364,23 +367,27 @@ void
 complete_target_initialization (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 (t->to_has_all_memory == NULL)
-    t->to_has_all_memory = (int (*) (struct target_ops *)) return_zero;
+    t->to_has_all_memory = return_zero;
 
   if (t->to_has_memory == NULL)
-    t->to_has_memory = (int (*) (struct target_ops *)) return_zero;
+    t->to_has_memory = return_zero;
 
   if (t->to_has_stack == NULL)
-    t->to_has_stack = (int (*) (struct target_ops *)) return_zero;
+    t->to_has_stack = return_zero;
 
   if (t->to_has_registers == NULL)
-    t->to_has_registers = (int (*) (struct target_ops *)) return_zero;
+    t->to_has_registers = return_zero;
 
   if (t->to_has_execution == NULL)
-    t->to_has_execution = (int (*) (struct target_ops *, ptid_t)) return_zero;
+    t->to_has_execution = return_zero_has_execution;
+
+  /* These methods can be called on an unpushed target and so require
+     a default implementation if the target might plausibly be the
+     default run target.  */
+  gdb_assert (t->to_can_run == NULL || (t->to_can_async_p != NULL
+                                       && t->to_supports_non_stop != NULL));
 
   install_delegators (t);
 }
@@ -451,11 +458,6 @@ add_deprecated_target_alias (struct target_ops *t, char *alias)
 
 /* Stub functions */
 
-void
-target_ignore (void)
-{
-}
-
 void
 target_kill (void)
 {
@@ -472,29 +474,6 @@ target_load (char *arg, int from_tty)
   (*current_target.to_load) (&current_target, arg, from_tty);
 }
 
-void
-target_create_inferior (char *exec_file, char *args,
-                       char **env, int from_tty)
-{
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_create_inferior != NULL)       
-       {
-         t->to_create_inferior (t, exec_file, args, env, from_tty);
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_create_inferior (%s, %s, xxx, %d)\n",
-                               exec_file, args, from_tty);
-         return;
-       }
-    }
-
-  internal_error (__FILE__, __LINE__,
-                 _("could not find a target to create inferior"));
-}
-
 void
 target_terminal_inferior (void)
 {
@@ -510,14 +489,6 @@ target_terminal_inferior (void)
   (*current_target.to_terminal_inferior) (&current_target);
 }
 
-static int
-nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-         struct target_ops *t)
-{
-  errno = EIO;                 /* Can't read/write this location.  */
-  return 0;                    /* No bytes handled.  */
-}
-
 static void
 tcomplain (void)
 {
@@ -584,169 +555,25 @@ update_current_target (void)
   /* Install the delegators.  */
   install_delegators (&current_target);
 
+  current_target.to_stratum = target_stack->to_stratum;
+
 #define INHERIT(FIELD, TARGET) \
       if (!current_target.FIELD) \
        current_target.FIELD = (TARGET)->FIELD
 
+  /* Do not add any new INHERITs here.  Instead, use the delegation
+     mechanism provided by make-target-delegates.  */
   for (t = target_stack; t; t = t->beneath)
     {
       INHERIT (to_shortname, t);
       INHERIT (to_longname, t);
-      INHERIT (to_doc, t);
-      /* Do not inherit to_open.  */
-      /* Do not inherit to_close.  */
-      /* Do not inherit to_attach.  */
-      /* Do not inherit to_post_attach.  */
       INHERIT (to_attach_no_wait, t);
-      /* Do not inherit to_detach.  */
-      /* Do not inherit to_disconnect.  */
-      /* Do not inherit to_resume.  */
-      /* Do not inherit to_wait.  */
-      /* Do not inherit to_fetch_registers.  */
-      /* Do not inherit to_store_registers.  */
-      /* Do not inherit to_prepare_to_store.  */
-      INHERIT (deprecated_xfer_memory, t);
-      /* Do not inherit to_files_info.  */
-      /* Do not inherit to_insert_breakpoint.  */
-      /* Do not inherit to_remove_breakpoint.  */
-      /* Do not inherit to_can_use_hw_breakpoint.  */
-      /* Do not inherit to_insert_hw_breakpoint.  */
-      /* Do not inherit to_remove_hw_breakpoint.  */
-      /* Do not inherit to_ranged_break_num_registers.  */
-      /* Do not inherit to_insert_watchpoint.  */
-      /* Do not inherit to_remove_watchpoint.  */
-      /* Do not inherit to_insert_mask_watchpoint.  */
-      /* Do not inherit to_remove_mask_watchpoint.  */
-      /* Do not inherit to_stopped_data_address.  */
       INHERIT (to_have_steppable_watchpoint, t);
       INHERIT (to_have_continuable_watchpoint, t);
-      /* Do not inherit to_stopped_by_watchpoint.  */
-      /* Do not inherit to_watchpoint_addr_within_range.  */
-      /* Do not inherit to_region_ok_for_hw_watchpoint.  */
-      /* Do not inherit to_can_accel_watchpoint_condition.  */
-      /* Do not inherit to_masked_watch_num_registers.  */
-      /* Do not inherit to_terminal_init.  */
-      /* Do not inherit to_terminal_inferior.  */
-      /* Do not inherit to_terminal_ours_for_output.  */
-      /* Do not inherit to_terminal_ours.  */
-      /* Do not inherit to_terminal_save_ours.  */
-      /* Do not inherit to_terminal_info.  */
-      /* Do not inherit to_kill.  */
-      /* Do not inherit to_load.  */
-      /* Do no inherit to_create_inferior.  */
-      /* Do not inherit to_post_startup_inferior.  */
-      /* Do not inherit to_insert_fork_catchpoint.  */
-      /* Do not inherit to_remove_fork_catchpoint.  */
-      /* Do not inherit to_insert_vfork_catchpoint.  */
-      /* Do not inherit to_remove_vfork_catchpoint.  */
-      /* Do not inherit to_follow_fork.  */
-      /* Do not inherit to_insert_exec_catchpoint.  */
-      /* Do not inherit to_remove_exec_catchpoint.  */
-      /* Do not inherit to_set_syscall_catchpoint.  */
-      /* Do not inherit to_has_exited.  */
-      /* Do not inherit to_mourn_inferior.  */
-      INHERIT (to_can_run, t);
-      /* Do not inherit to_pass_signals.  */
-      /* Do not inherit to_program_signals.  */
-      /* Do not inherit to_thread_alive.  */
-      /* Do not inherit to_find_new_threads.  */
-      /* Do not inherit to_pid_to_str.  */
-      /* Do not inherit to_extra_thread_info.  */
-      /* Do not inherit to_thread_name.  */
-      /* Do not inherit to_stop.  */
-      /* Do not inherit to_xfer_partial.  */
-      /* Do not inherit to_rcmd.  */
-      /* Do not inherit to_pid_to_exec_file.  */
-      /* Do not inherit to_log_command.  */
-      INHERIT (to_stratum, t);
-      /* Do not inherit to_has_all_memory.  */
-      /* Do not inherit to_has_memory.  */
-      /* Do not inherit to_has_stack.  */
-      /* Do not inherit to_has_registers.  */
-      /* Do not inherit to_has_execution.  */
       INHERIT (to_has_thread_control, t);
-      /* Do not inherit to_can_async_p.  */
-      /* Do not inherit to_is_async_p.  */
-      /* Do not inherit to_async.  */
-      /* Do not inherit to_find_memory_regions.  */
-      /* Do not inherit to_make_corefile_notes.  */
-      /* Do not inherit to_get_bookmark.  */
-      /* Do not inherit to_goto_bookmark.  */
-      /* Do not inherit to_get_thread_local_address.  */
-      /* Do not inherit to_can_execute_reverse.  */
-      /* Do not inherit to_execution_direction.  */
-      /* Do not inherit to_thread_architecture.  */
-      /* Do not inherit to_read_description.  */
-      /* Do not inherit to_get_ada_task_ptid.  */
-      /* Do not inherit to_search_memory.  */
-      /* Do not inherit to_supports_multi_process.  */
-      /* Do not inherit to_supports_enable_disable_tracepoint.  */
-      /* Do not inherit to_supports_string_tracing.  */
-      /* Do not inherit to_trace_init.  */
-      /* Do not inherit to_download_tracepoint.  */
-      /* Do not inherit to_can_download_tracepoint.  */
-      /* Do not inherit to_download_trace_state_variable.  */
-      /* Do not inherit to_enable_tracepoint.  */
-      /* Do not inherit to_disable_tracepoint.  */
-      /* Do not inherit to_trace_set_readonly_regions.  */
-      /* Do not inherit to_trace_start.  */
-      /* Do not inherit to_get_trace_status.  */
-      /* Do not inherit to_get_tracepoint_status.  */
-      /* Do not inherit to_trace_stop.  */
-      /* Do not inherit to_trace_find.  */
-      /* Do not inherit to_get_trace_state_variable_value.  */
-      /* Do not inherit to_save_trace_data.  */
-      /* Do not inherit to_upload_tracepoints.  */
-      /* Do not inherit to_upload_trace_state_variables.  */
-      /* Do not inherit to_get_raw_trace_data.  */
-      /* Do not inherit to_get_min_fast_tracepoint_insn_len.  */
-      /* Do not inherit to_set_disconnected_tracing.  */
-      /* Do not inherit to_set_circular_trace_buffer.  */
-      /* Do not inherit to_set_trace_buffer_size.  */
-      /* Do not inherit to_set_trace_notes.  */
-      /* Do not inherit to_get_tib_address.  */
-      /* Do not inherit to_set_permissions.  */
-      /* Do not inherit to_static_tracepoint_marker_at.  */
-      /* Do not inherit to_static_tracepoint_markers_by_strid.  */
-      /* Do not inherit to_traceframe_info.  */
-      /* Do not inherit to_use_agent.  */
-      /* Do not inherit to_can_use_agent.  */
-      /* Do not inherit to_augmented_libraries_svr4_read.  */
-      INHERIT (to_magic, t);
-      /* Do not inherit
-        to_supports_evaluation_of_breakpoint_conditions.  */
-      /* Do not inherit to_can_run_breakpoint_commands.  */
-      /* Do not inherit to_memory_map.  */
-      /* Do not inherit to_flash_erase.  */
-      /* Do not inherit to_flash_done.  */
     }
 #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 (!current_target.field)               \
-    current_target.field = value
-
-  de_fault (to_open,
-           (void (*) (char *, int))
-           tcomplain);
-  de_fault (to_close,
-           (void (*) (struct target_ops *))
-           target_ignore);
-  de_fault (deprecated_xfer_memory,
-           (int (*) (CORE_ADDR, gdb_byte *, int, int,
-                     struct mem_attrib *, struct target_ops *))
-           nomemory);
-  de_fault (to_can_run,
-           (int (*) (struct target_ops *))
-           return_zero);
-  current_target.to_read_description = NULL;
-
-#undef de_fault
-
   /* 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.  */
@@ -995,13 +822,13 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
 }
 
 const char *
-target_xfer_status_to_string (enum target_xfer_status err)
+target_xfer_status_to_string (enum target_xfer_status status)
 {
 #define CASE(X) case X: return #X
-  switch (err)
+  switch (status)
     {
       CASE(TARGET_XFER_E_IO);
-      CASE(TARGET_XFER_E_UNAVAILABLE);
+      CASE(TARGET_XFER_UNAVAILABLE);
     default:
       return "<unknown>";
     }
@@ -1214,7 +1041,7 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
        break;
 
       /* Stop if the target reports that the memory is not available.  */
-      if (res == TARGET_XFER_E_UNAVAILABLE)
+      if (res == TARGET_XFER_UNAVAILABLE)
        break;
 
       /* We want to continue past core files to executables, but not
@@ -1226,6 +1053,23 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
     }
   while (ops != NULL);
 
+  /* The cache works at the raw memory level.  Make sure the cache
+     gets updated with raw contents no matter what kind of memory
+     object was originally being written.  Note we do write-through
+     first, so that if it fails, we don't write to the cache contents
+     that never made it to the target.  */
+  if (writebuf != NULL
+      && !ptid_equal (inferior_ptid, null_ptid)
+      && target_dcache_init_p ()
+      && (stack_cache_enabled_p () || code_cache_enabled_p ()))
+    {
+      DCACHE *dcache = target_dcache_get ();
+
+      /* Note that writing to an area of memory which wasn't present
+        in the cache doesn't cause it to be loaded in.  */
+      dcache_update (dcache, res, memaddr, writebuf, *xfered_len);
+    }
+
   return res;
 }
 
@@ -1327,7 +1171,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
                  /* No use trying further, we know some memory starting
                     at MEMADDR isn't available.  */
                  *xfered_len = len;
-                 return TARGET_XFER_E_UNAVAILABLE;
+                 return TARGET_XFER_UNAVAILABLE;
                }
            }
 
@@ -1377,6 +1221,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
     inf = NULL;
 
   if (inf != NULL
+      && readbuf != NULL
       /* The dcache reads whole cache lines; that doesn't play well
         with reading from a trace buffer, because reading outside of
         the collected memory range fails.  */
@@ -1386,23 +1231,9 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
          || (code_cache_enabled_p () && object == TARGET_OBJECT_CODE_MEMORY)))
     {
       DCACHE *dcache = target_dcache_get_or_init ();
-      int l;
 
-      if (readbuf != NULL)
-       l = dcache_xfer_memory (ops, dcache, memaddr, readbuf, reg_len, 0);
-      else
-       /* FIXME drow/2006-08-09: If we're going to preserve const
-          correctness dcache_xfer_memory should take readbuf and
-          writebuf.  */
-       l = dcache_xfer_memory (ops, dcache, memaddr, (void *) writebuf,
-                                 reg_len, 1);
-      if (l <= 0)
-       return TARGET_XFER_E_IO;
-      else
-       {
-         *xfered_len = (ULONGEST) l;
-         return TARGET_XFER_OK;
-       }
+      return dcache_read_memory_partial (ops, dcache, memaddr, readbuf,
+                                        reg_len, xfered_len);
     }
 
   /* If none of those methods found the memory we wanted, fall back
@@ -1418,23 +1249,6 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
   res = raw_memory_xfer_partial (ops, readbuf, writebuf, memaddr, reg_len,
                                 xfered_len);
 
-  /* Make sure the cache gets updated no matter what - if we are writing
-     to the stack.  Even if this write is not tagged as such, we still need
-     to update the cache.  */
-
-  if (res == TARGET_XFER_OK
-      && inf != NULL
-      && writebuf != NULL
-      && target_dcache_init_p ()
-      && !region->attrib.cache
-      && ((stack_cache_enabled_p () && object != TARGET_OBJECT_STACK_MEMORY)
-         || (code_cache_enabled_p () && object != TARGET_OBJECT_CODE_MEMORY)))
-    {
-      DCACHE *dcache = target_dcache_get ();
-
-      dcache_update (dcache, memaddr, (void *) writebuf, reg_len);
-    }
-
   /* If we still haven't got anything, return the last error.  We
      give up.  */
   return res;
@@ -1463,7 +1277,7 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
                                   xfered_len);
 
       if (res == TARGET_XFER_OK && !show_memory_breakpoints)
-       breakpoint_xfer_memory (readbuf, NULL, NULL, memaddr, res);
+       breakpoint_xfer_memory (readbuf, NULL, NULL, memaddr, *xfered_len);
     }
   else
     {
@@ -1594,7 +1408,7 @@ target_xfer_partial (struct target_ops *ops,
   /* Check implementations of to_xfer_partial update *XFERED_LEN
      properly.  Do assertion after printing debug messages, so that we
      can find more clues on assertion failure from debugging messages.  */
-  if (retval == TARGET_XFER_OK || retval == TARGET_XFER_E_UNAVAILABLE)
+  if (retval == TARGET_XFER_OK || retval == TARGET_XFER_UNAVAILABLE)
     gdb_assert (*xfered_len > 0);
 
   return retval;
@@ -1719,14 +1533,7 @@ target_memory_map (void)
   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);
+  result = current_target.to_memory_map (&current_target);
   if (result == NULL)
     return NULL;
 
@@ -1780,56 +1587,6 @@ show_trust_readonly (struct ui_file *file, int from_tty,
                    value);
 }
 
-/* More generic transfers.  */
-
-static enum target_xfer_status
-default_xfer_partial (struct target_ops *ops, enum target_object object,
-                     const char *annex, gdb_byte *readbuf,
-                     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-                     ULONGEST *xfered_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)
-       {
-         *xfered_len = (ULONGEST) xfered;
-         return TARGET_XFER_E_IO;
-       }
-      else if (xfered == 0 && errno == 0)
-       /* "deprecated_xfer_memory" uses 0, cross checked against
-           ERRNO as one indication of an error.  */
-       return TARGET_XFER_EOF;
-      else
-       return TARGET_XFER_E_IO;
-    }
-  else
-    {
-      gdb_assert (ops->beneath != NULL);
-      return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-                                           readbuf, writebuf, offset, len,
-                                           xfered_len);
-    }
-}
-
 /* Target vector read/write partial wrapper functions.  */
 
 static enum target_xfer_status
@@ -2124,12 +1881,9 @@ target_write_with_progress (struct target_ops *ops,
                                     offset + xfered, len - xfered,
                                     &xfered_len);
 
-      if (status == TARGET_XFER_EOF)
-       return xfered;
-      if (TARGET_XFER_STATUS_ERROR_P (status))
-       return -1;
+      if (status != TARGET_XFER_OK)
+       return status == TARGET_XFER_EOF ? xfered : -1;
 
-      gdb_assert (status == TARGET_XFER_OK);
       if (progress)
        (*progress) (xfered_len, baton);
 
@@ -2469,24 +2223,15 @@ target_detach (const char *args, int from_tty)
 void
 target_disconnect (char *args, int from_tty)
 {
-  struct target_ops *t;
-
   /* If we're in breakpoints-always-inserted mode or if breakpoints
      are global across processes, we have to remove them before
      disconnecting.  */
   remove_breakpoints ();
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_disconnect != NULL)
-       {
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n",
-                               args, from_tty);
-         t->to_disconnect (t, args, from_tty);
-         return;
-       }
-
-  tcomplain ();
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n",
+                       args, from_tty);
+  current_target.to_disconnect (&current_target, args, from_tty);
 }
 
 ptid_t
@@ -2641,23 +2386,10 @@ target_mourn_inferior (void)
 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;
+  return target->to_read_description (target);
 }
 
-/* The default implementation of to_search_memory.
-   This implements a basic search of memory, reading target memory and
+/* This implements a basic search of memory, reading target memory and
    performing the search here (as opposed to performing the search in on the
    target side with, for example, gdbserver).  */
 
@@ -2764,6 +2496,20 @@ simple_search_memory (struct target_ops *ops,
   return 0;
 }
 
+/* Default implementation of memory-searching.  */
+
+static int
+default_search_memory (struct target_ops *self,
+                      CORE_ADDR start_addr, ULONGEST search_space_len,
+                      const gdb_byte *pattern, ULONGEST pattern_len,
+                      CORE_ADDR *found_addrp)
+{
+  /* Start over from the top of the target stack.  */
+  return simple_search_memory (current_target.beneath,
+                              start_addr, search_space_len,
+                              pattern, pattern_len, found_addrp);
+}
+
 /* Search SEARCH_SPACE_LEN bytes beginning at START_ADDR for the
    sequence of bytes in PATTERN with length PATTERN_LEN.
 
@@ -2776,34 +2522,15 @@ target_search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
                      const gdb_byte *pattern, ULONGEST pattern_len,
                      CORE_ADDR *found_addrp)
 {
-  struct target_ops *t;
   int found;
 
-  /* We don't use INHERIT to set current_target.to_search_memory,
-     so we have to scan the target stack and handle targetdebug
-     ourselves.  */
-
   if (targetdebug)
     fprintf_unfiltered (gdb_stdlog, "target_search_memory (%s, ...)\n",
                        hex_string (start_addr));
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_search_memory != NULL)
-      break;
-
-  if (t != NULL)
-    {
-      found = t->to_search_memory (t, start_addr, search_space_len,
-                                  pattern, pattern_len, found_addrp);
-    }
-  else
-    {
-      /* If a special version of to_search_memory isn't available, use the
-        simple version.  */
-      found = simple_search_memory (current_target.beneath,
-                                   start_addr, search_space_len,
-                                   pattern, pattern_len, found_addrp);
-    }
+  found = current_target.to_search_memory (&current_target, start_addr,
+                                          search_space_len,
+                                          pattern, pattern_len, found_addrp);
 
   if (targetdebug)
     fprintf_unfiltered (gdb_stdlog, "  = %d\n", found);
@@ -2866,7 +2593,7 @@ find_default_run_target (char *do_mesg)
   for (t = target_structs; t < target_structs + target_struct_size;
        ++t)
     {
-      if ((*t)->to_can_run && target_can_run (*t))
+      if ((*t)->to_can_run != delegate_can_run && target_can_run (*t))
        {
          runable = *t;
          ++count;
@@ -2884,79 +2611,46 @@ find_default_run_target (char *do_mesg)
   return runable;
 }
 
-void
-find_default_attach (struct target_ops *ops, char *args, int from_tty)
-{
-  struct target_ops *t;
-
-  t = find_default_run_target ("attach");
-  (t->to_attach) (t, args, from_tty);
-  return;
-}
+/* See target.h.  */
 
-void
-find_default_create_inferior (struct target_ops *ops,
-                             char *exec_file, char *allargs, char **env,
-                             int from_tty)
+struct target_ops *
+find_attach_target (void)
 {
   struct target_ops *t;
 
-  t = find_default_run_target ("run");
-  (t->to_create_inferior) (t, exec_file, allargs, env, from_tty);
-  return;
-}
+  /* If a target on the current stack can attach, use it.  */
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_attach != NULL)
+       break;
+    }
 
-static int
-find_default_can_async_p (struct target_ops *ignore)
-{
-  struct target_ops *t;
+  /* Otherwise, use the default run target for attaching.  */
+  if (t == NULL)
+    t = find_default_run_target ("attach");
 
-  /* This may be called before the target is pushed on the stack;
-     look for the default process stratum.  If there's none, gdb isn't
-     configured with a native debugger, and target remote isn't
-     connected yet.  */
-  t = find_default_run_target (NULL);
-  if (t && t->to_can_async_p != delegate_can_async_p)
-    return (t->to_can_async_p) (t);
-  return 0;
+  return t;
 }
 
-static int
-find_default_is_async_p (struct target_ops *ignore)
-{
-  struct target_ops *t;
-
-  /* This may be called before the target is pushed on the stack;
-     look for the default process stratum.  If there's none, gdb isn't
-     configured with a native debugger, and target remote isn't
-     connected yet.  */
-  t = find_default_run_target (NULL);
-  if (t && t->to_is_async_p != delegate_is_async_p)
-    return (t->to_is_async_p) (t);
-  return 0;
-}
+/* See target.h.  */
 
-static int
-find_default_supports_non_stop (struct target_ops *self)
+struct target_ops *
+find_run_target (void)
 {
   struct target_ops *t;
 
-  t = find_default_run_target (NULL);
-  if (t && t->to_supports_non_stop)
-    return (t->to_supports_non_stop) (t);
-  return 0;
-}
-
-int
-target_supports_non_stop (void)
-{
-  struct target_ops *t;
+  /* If a target on the current stack can attach, use it.  */
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_create_inferior != NULL)
+       break;
+    }
 
-  for (t = &current_target; t != NULL; t = t->beneath)
-    if (t->to_supports_non_stop)
-      return t->to_supports_non_stop (t);
+  /* Otherwise, use the default run target.  */
+  if (t == NULL)
+    t = find_default_run_target ("run");
 
-  return 0;
+  return t;
 }
 
 /* Implement the "info proc" command.  */
@@ -3392,7 +3086,13 @@ default_thread_architecture (struct target_ops *ops, ptid_t ptid)
 }
 
 static int
-return_zero (void)
+return_zero (struct target_ops *ignore)
+{
+  return 0;
+}
+
+static int
+return_zero_has_execution (struct target_ops *ignore, ptid_t ignore2)
 {
   return 0;
 }
@@ -3502,17 +3202,14 @@ init_dummy_target (void)
   dummy_target.to_shortname = "None";
   dummy_target.to_longname = "None";
   dummy_target.to_doc = "";
-  dummy_target.to_create_inferior = find_default_create_inferior;
-  dummy_target.to_supports_non_stop = find_default_supports_non_stop;
   dummy_target.to_supports_disable_randomization
     = find_default_supports_disable_randomization;
   dummy_target.to_stratum = dummy_stratum;
-  dummy_target.to_has_all_memory = (int (*) (struct target_ops *)) return_zero;
-  dummy_target.to_has_memory = (int (*) (struct target_ops *)) return_zero;
-  dummy_target.to_has_stack = (int (*) (struct target_ops *)) return_zero;
-  dummy_target.to_has_registers = (int (*) (struct target_ops *)) return_zero;
-  dummy_target.to_has_execution
-    = (int (*) (struct target_ops *, ptid_t)) return_zero;
+  dummy_target.to_has_all_memory = return_zero;
+  dummy_target.to_has_memory = return_zero;
+  dummy_target.to_has_stack = return_zero;
+  dummy_target.to_has_registers = return_zero;
+  dummy_target.to_has_execution = return_zero_has_execution;
   dummy_target.to_magic = OPS_MAGIC;
 
   install_dummy_methods (&dummy_target);
@@ -3540,36 +3237,17 @@ target_close (struct target_ops *targ)
     fprintf_unfiltered (gdb_stdlog, "target_close ()\n");
 }
 
-void
-target_attach (char *args, int from_tty)
-{
-  current_target.to_attach (&current_target, args, from_tty);
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_attach (%s, %d)\n",
-                       args, from_tty);
-}
-
 int
 target_thread_alive (ptid_t ptid)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_thread_alive != NULL)
-       {
-         int retval;
-
-         retval = t->to_thread_alive (t, ptid);
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
-                               ptid_get_pid (ptid), retval);
+  int retval;
 
-         return retval;
-       }
-    }
+  retval = current_target.to_thread_alive (&current_target, ptid);
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
+                       ptid_get_pid (ptid), retval);
 
-  return 0;
+  return retval;
 }
 
 void
@@ -3799,14 +3477,7 @@ target_ranged_break_num_registers (void)
 struct btrace_target_info *
 target_enable_btrace (ptid_t ptid)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_enable_btrace != NULL)
-      return t->to_enable_btrace (t, ptid);
-
-  tcomplain ();
-  return NULL;
+  return current_target.to_enable_btrace (&current_target, ptid);
 }
 
 /* See target.h.  */
@@ -3814,16 +3485,7 @@ target_enable_btrace (ptid_t ptid)
 void
 target_disable_btrace (struct btrace_target_info *btinfo)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_disable_btrace != NULL)
-      {
-       t->to_disable_btrace (t, btinfo);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_disable_btrace (&current_target, btinfo);
 }
 
 /* See target.h.  */
@@ -3831,16 +3493,7 @@ target_disable_btrace (struct btrace_target_info *btinfo)
 void
 target_teardown_btrace (struct btrace_target_info *btinfo)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_teardown_btrace != NULL)
-      {
-       t->to_teardown_btrace (t, btinfo);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_teardown_btrace (&current_target, btinfo);
 }
 
 /* See target.h.  */
@@ -3850,14 +3503,7 @@ target_read_btrace (VEC (btrace_block_s) **btrace,
                    struct btrace_target_info *btinfo,
                    enum btrace_read_type type)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_read_btrace != NULL)
-      return t->to_read_btrace (t, btrace, btinfo, type);
-
-  tcomplain ();
-  return BTRACE_ERR_NOT_SUPPORTED;
+  return current_target.to_read_btrace (&current_target, btrace, btinfo, type);
 }
 
 /* See target.h.  */
@@ -3865,16 +3511,7 @@ target_read_btrace (VEC (btrace_block_s) **btrace,
 void
 target_stop_recording (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_stop_recording != NULL)
-      {
-       t->to_stop_recording (t);
-       return;
-      }
-
-  /* This is optional.  */
+  current_target.to_stop_recording (&current_target);
 }
 
 /* See target.h.  */
@@ -3899,16 +3536,7 @@ target_info_record (void)
 void
 target_save_record (const char *filename)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_save_record != NULL)
-      {
-       t->to_save_record (t, filename);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_save_record (&current_target, filename);
 }
 
 /* See target.h.  */
@@ -4026,13 +3654,7 @@ debug_to_prepare_to_store (struct target_ops *self, struct regcache *regcache)
 const struct frame_unwind *
 target_get_unwinder (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_get_unwinder != NULL)
-      return t->to_get_unwinder;
-
-  return NULL;
+  return current_target.to_get_unwinder (&current_target);
 }
 
 /* See target.h.  */
@@ -4040,25 +3662,15 @@ target_get_unwinder (void)
 const struct frame_unwind *
 target_get_tailcall_unwinder (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_get_tailcall_unwinder != NULL)
-      return t->to_get_tailcall_unwinder;
-
-  return NULL;
+  return current_target.to_get_tailcall_unwinder (&current_target);
 }
 
-/* See target.h.  */
+/* Default implementation of to_decr_pc_after_break.  */
 
-CORE_ADDR
-forward_target_decr_pc_after_break (struct target_ops *ops,
+static CORE_ADDR
+default_target_decr_pc_after_break (struct target_ops *ops,
                                    struct gdbarch *gdbarch)
 {
-  for (; ops != NULL; ops = ops->beneath)
-    if (ops->to_decr_pc_after_break != NULL)
-      return ops->to_decr_pc_after_break (ops, gdbarch);
-
   return gdbarch_decr_pc_after_break (gdbarch);
 }
 
@@ -4067,48 +3679,7 @@ forward_target_decr_pc_after_break (struct target_ops *ops,
 CORE_ADDR
 target_decr_pc_after_break (struct gdbarch *gdbarch)
 {
-  return forward_target_decr_pc_after_break (current_target.beneath, gdbarch);
-}
-
-static int
-deprecated_debug_xfer_memory (CORE_ADDR memaddr, bfd_byte *myaddr, int len,
-                             int write, struct mem_attrib *attrib,
-                             struct target_ops *target)
-{
-  int retval;
-
-  retval = debug_target.deprecated_xfer_memory (memaddr, myaddr, len, write,
-                                               attrib, target);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_xfer_memory (%s, xxx, %d, %s, xxx) = %d",
-                     paddress (target_gdbarch (), memaddr), len,
-                     write ? "write" : "read", retval);
-
-  if (retval > 0)
-    {
-      int i;
-
-      fputs_unfiltered (", bytes =", gdb_stdlog);
-      for (i = 0; i < retval; i++)
-       {
-         if ((((intptr_t) &(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;
+  return current_target.to_decr_pc_after_break (&current_target, gdbarch);
 }
 
 static void
@@ -4539,7 +4110,6 @@ setup_target_debug (void)
   current_target.to_open = debug_to_open;
   current_target.to_post_attach = debug_to_post_attach;
   current_target.to_prepare_to_store = debug_to_prepare_to_store;
-  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;
This page took 0.036718 seconds and 4 git commands to generate.