2000-02-16 Mark Kettenis <kettenis@gnu.org>
[deliverable/binutils-gdb.git] / gdb / target.c
index 3a6e423d75ad8e7851c610a5755179017c4ae546..fa9cf88a1083a8c73d92ae0141a19f45df0ed778 100644 (file)
@@ -1,5 +1,5 @@
 /* Select target systems and architectures at runtime for GDB.
-   Copyright 1990, 1992-1995, 1998, 1999 Free Software Foundation, Inc.
+   Copyright 1990, 1992-1995, 1998-2000 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
    This file is part of GDB.
@@ -30,7 +30,7 @@
 #include "bfd.h"
 #include "symfile.h"
 #include "objfiles.h"
-#include "wait.h"
+#include "gdb_wait.h"
 #include <signal.h>
 
 extern int errno;
@@ -78,7 +78,7 @@ static void
 target_command PARAMS ((char *, int));
 
 static struct target_ops *
-  find_default_run_target PARAMS ((char *));
+find_default_run_target PARAMS ((char *));
 
 static void
 update_current_target PARAMS ((void));
@@ -397,69 +397,181 @@ cleanup_target (t)
 {
 
 #define de_fault(field, value) \
-  if (!t->field)       t->field = value
-
-  /*        FIELD                       DEFAULT VALUE        */
-
-  de_fault (to_open, (void (*)PARAMS ((char *, int))) tcomplain);
-  de_fault (to_close, (void (*)PARAMS ((int))) target_ignore);
-  de_fault (to_attach, maybe_kill_then_attach);
-  de_fault (to_post_attach, (void (*)PARAMS ((int))) target_ignore);
-  de_fault (to_require_attach, maybe_kill_then_attach);
-  de_fault (to_detach, (void (*)PARAMS ((char *, int))) target_ignore);
-  de_fault (to_require_detach, (void (*)PARAMS ((int, char *, int))) target_ignore);
-  de_fault (to_resume, (void (*)PARAMS ((int, int, enum target_signal))) noprocess);
-  de_fault (to_wait, (int (*)PARAMS ((int, struct target_waitstatus *))) noprocess);
-  de_fault (to_post_wait, (void (*)PARAMS ((int, int))) target_ignore);
-  de_fault (to_fetch_registers, (void (*)PARAMS ((int))) target_ignore);
-  de_fault (to_store_registers, (void (*)PARAMS ((int))) noprocess);
-  de_fault (to_prepare_to_store, (void (*)PARAMS ((void))) noprocess);
-  de_fault (to_xfer_memory, (int (*)PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *))) nomemory);
-  de_fault (to_files_info, (void (*)PARAMS ((struct target_ops *))) target_ignore);
-  de_fault (to_insert_breakpoint, memory_insert_breakpoint);
-  de_fault (to_remove_breakpoint, memory_remove_breakpoint);
-  de_fault (to_terminal_init, (void (*)PARAMS ((void))) target_ignore);
-  de_fault (to_terminal_inferior, (void (*)PARAMS ((void))) target_ignore);
-  de_fault (to_terminal_ours_for_output, (void (*)PARAMS ((void))) target_ignore);
-  de_fault (to_terminal_ours, (void (*)PARAMS ((void))) target_ignore);
-  de_fault (to_terminal_info, default_terminal_info);
-  de_fault (to_kill, (void (*)PARAMS ((void))) noprocess);
-  de_fault (to_load, (void (*)PARAMS ((char *, int))) tcomplain);
-  de_fault (to_lookup_symbol, (int (*)PARAMS ((char *, CORE_ADDR *))) nosymbol);
-  de_fault (to_create_inferior, maybe_kill_then_create_inferior);
-  de_fault (to_post_startup_inferior, (void (*)PARAMS ((int))) target_ignore);
-  de_fault (to_acknowledge_created_inferior, (void (*)PARAMS ((int))) target_ignore);
-  de_fault (to_clone_and_follow_inferior, default_clone_and_follow_inferior);
-  de_fault (to_post_follow_inferior_by_clone, (void (*)PARAMS ((void))) target_ignore);
-  de_fault (to_insert_fork_catchpoint, (int (*)PARAMS ((int))) tcomplain);
-  de_fault (to_remove_fork_catchpoint, (int (*)PARAMS ((int))) tcomplain);
-  de_fault (to_insert_vfork_catchpoint, (int (*)PARAMS ((int))) tcomplain);
-  de_fault (to_remove_vfork_catchpoint, (int (*)PARAMS ((int))) tcomplain);
-  de_fault (to_has_forked, (int (*)PARAMS ((int, int *))) return_zero);
-  de_fault (to_has_vforked, (int (*)PARAMS ((int, int *))) return_zero);
-  de_fault (to_can_follow_vfork_prior_to_exec, (int (*)PARAMS ((void))) return_zero);
-  de_fault (to_post_follow_vfork, (void (*)PARAMS ((int, int, int, int))) target_ignore);
-  de_fault (to_insert_exec_catchpoint, (int (*)PARAMS ((int))) tcomplain);
-  de_fault (to_remove_exec_catchpoint, (int (*)PARAMS ((int))) tcomplain);
-  de_fault (to_has_execd, (int (*)PARAMS ((int, char **))) return_zero);
-  de_fault (to_reported_exec_events_per_exec_call, (int (*)PARAMS ((void))) return_one);
-  de_fault (to_has_syscall_event, (int (*)PARAMS ((int, enum target_waitkind *, int *))) return_zero);
-  de_fault (to_has_exited, (int (*)PARAMS ((int, int, int *))) return_zero);
-  de_fault (to_mourn_inferior, (void (*)PARAMS ((void))) noprocess);
-  de_fault (to_can_run, return_zero);
-  de_fault (to_notice_signals, (void (*)PARAMS ((int))) target_ignore);
-  de_fault (to_thread_alive, (int (*)PARAMS ((int))) target_ignore);
-  de_fault (to_stop, (void (*)PARAMS ((void))) target_ignore);
-  de_fault (to_query, (int (*)PARAMS ((int /*char */ , char *, char *, int *))) target_ignore);
-  de_fault (to_rcmd, (void (*) (char *, struct gdb_file *)) tcomplain);
-  de_fault (to_enable_exception_callback, (struct symtab_and_line * (*)PARAMS ((enum exception_event_kind, int))) nosupport_runtime);
-  de_fault (to_get_current_exception_event, (struct exception_event_record * (*)PARAMS ((void))) nosupport_runtime);
-
-  de_fault (to_pid_to_exec_file, (char *(*)PARAMS ((int))) return_zero);
-  de_fault (to_core_file_to_sym_file, (char *(*)PARAMS ((char *))) return_zero);
-  de_fault (to_can_async_p, (int (*) (void)) return_zero);
-  de_fault (to_is_async_p, (int (*) (void)) return_zero);
-  de_fault (to_async, (void (*) (void (*) (enum inferior_event_type, void*), void*)) tcomplain);
+  if (!t->field)               \
+    t->field = value
+
+  de_fault (to_open, 
+           (void (*) (char *, int)) 
+           tcomplain);
+  de_fault (to_close, 
+           (void (*) (int)) 
+           target_ignore);
+  de_fault (to_attach, 
+           maybe_kill_then_attach);
+  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_resume, 
+           (void (*) (int, int, enum target_signal)) 
+           noprocess);
+  de_fault (to_wait, 
+           (int (*) (int, struct target_waitstatus *)) 
+           noprocess);
+  de_fault (to_post_wait, 
+           (void (*) (int, int)) 
+           target_ignore);
+  de_fault (to_fetch_registers, 
+           (void (*) (int)) 
+           target_ignore);
+  de_fault (to_store_registers, 
+           (void (*) (int)) 
+           noprocess);
+  de_fault (to_prepare_to_store, 
+           (void (*) (void)) 
+           noprocess);
+  de_fault (to_xfer_memory, 
+           (int (*) (CORE_ADDR, char *, int, int, struct target_ops *)) 
+           nomemory);
+  de_fault (to_files_info, 
+           (void (*) (struct target_ops *)) 
+           target_ignore);
+  de_fault (to_insert_breakpoint, 
+           memory_insert_breakpoint);
+  de_fault (to_remove_breakpoint, 
+           memory_remove_breakpoint);
+  de_fault (to_terminal_init, 
+           (void (*) (void)) 
+           target_ignore);
+  de_fault (to_terminal_inferior, 
+           (void (*) (void)) 
+           target_ignore);
+  de_fault (to_terminal_ours_for_output, 
+           (void (*) (void)) 
+           target_ignore);
+  de_fault (to_terminal_ours, 
+           (void (*) (void)) 
+           target_ignore);
+  de_fault (to_terminal_info, 
+           default_terminal_info);
+  de_fault (to_kill, 
+           (void (*) (void)) 
+           noprocess);
+  de_fault (to_load, 
+           (void (*) (char *, int)) 
+           tcomplain);
+  de_fault (to_lookup_symbol, 
+           (int (*) (char *, CORE_ADDR *)) 
+           nosymbol);
+  de_fault (to_create_inferior, 
+           maybe_kill_then_create_inferior);
+  de_fault (to_post_startup_inferior, 
+           (void (*) (int)) 
+           target_ignore);
+  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)) 
+           tcomplain);
+  de_fault (to_remove_fork_catchpoint, 
+           (int (*) (int)) 
+           tcomplain);
+  de_fault (to_insert_vfork_catchpoint, 
+           (int (*) (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)) 
+           target_ignore);
+  de_fault (to_insert_exec_catchpoint, 
+           (int (*) (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);
+  de_fault (to_mourn_inferior, 
+           (void (*) (void)) 
+           noprocess);
+  de_fault (to_can_run, 
+           return_zero);
+  de_fault (to_notice_signals, 
+           (void (*) (int)) 
+           target_ignore);
+  de_fault (to_thread_alive, 
+           (int (*) (int)) 
+           return_zero);
+  de_fault (to_find_new_threads, 
+           (void (*) (void)) 
+           target_ignore);
+  de_fault (to_extra_thread_info, 
+           (char *(*) (struct thread_info *)) 
+           return_zero);
+  de_fault (to_stop, 
+           (void (*) (void)) 
+           target_ignore);
+  de_fault (to_query, 
+           (int (*) (int, char *, char *, int *)) 
+           return_zero);
+  de_fault (to_rcmd, 
+           (void (*) (char *, struct ui_file *)) 
+           tcomplain);
+  de_fault (to_enable_exception_callback, 
+           (struct symtab_and_line * (*) (enum exception_event_kind, int)) 
+           nosupport_runtime);
+  de_fault (to_get_current_exception_event, 
+           (struct exception_event_record * (*) (void)) 
+           nosupport_runtime);
+  de_fault (to_pid_to_exec_file, 
+           (char *(*) (int)) 
+           return_zero);
+  de_fault (to_core_file_to_sym_file, 
+           (char *(*) (char *)) 
+           return_zero);
+  de_fault (to_can_async_p, 
+           (int (*) (void)) 
+           return_zero);
+  de_fault (to_is_async_p, 
+           (int (*) (void)) 
+           return_zero);
+  de_fault (to_async, 
+           (void (*) (void (*) (enum inferior_event_type, void*), void*)) 
+           tcomplain);
 #undef de_fault
 }
 
@@ -536,6 +648,8 @@ update_current_target ()
       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);
@@ -556,6 +670,7 @@ update_current_target ()
       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
@@ -1046,6 +1161,14 @@ target_link (modname, t_reloc)
     *t_reloc = (CORE_ADDR) -1;
 }
 
+int
+target_async_mask (int mask)
+{
+  int saved_async_masked_status = target_async_mask_value;
+  target_async_mask_value = mask;
+  return saved_async_masked_status;
+}
+
 /* Look through the list of possible targets for a target that can
    execute a run or attach command without any other data.  This is
    used to locate the default process stratum.
@@ -1226,6 +1349,9 @@ find_run_target ()
   return (count == 1 ? runable : NULL);
 }
 
+/* Find a single core_stratum target in the list of targets and return it.
+   If for some reason there is more than one, return NULL.  */
+
 struct target_ops *
 find_core_target ()
 {
@@ -1247,6 +1373,27 @@ find_core_target ()
 
   return (count == 1 ? runable : NULL);
 }
+
+/*
+ * Find the next target down the stack from the specified target.
+ */
+
+struct target_ops *
+find_target_beneath (t)
+     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;
+}
+
 \f
 /* The inferior process has died.  Long live the inferior!  */
 
@@ -1675,10 +1822,16 @@ target_signal_from_host (hostsig)
   return TARGET_SIGNAL_UNKNOWN;
 }
 
-int
-target_signal_to_host (oursig)
-     enum target_signal oursig;
+/* Convert a OURSIG (an enum target_signal) to the form used by the
+   target operating system (refered to as the ``host'') or zero if the
+   equivalent host signal is not available.  Set/clear OURSIG_OK
+   accordingly. */
+
+static int
+do_target_signal_to_host (enum target_signal oursig,
+                         int *oursig_ok)
 {
+  *oursig_ok = 1;
   switch (oursig)
     {
     case TARGET_SIGNAL_0:
@@ -1869,8 +2022,6 @@ target_signal_to_host (oursig)
       return SIGPRIO;
 #endif
 
-    case TARGET_SIGNAL_REALTIME_32: return 32; /* by definition */ 
-
       /* Mach exceptions.  Assumes that the values for EXC_ are positive! */
 #if defined (EXC_BAD_ACCESS) && defined (_NSIG)
     case TARGET_EXC_BAD_ACCESS:
@@ -1907,18 +2058,50 @@ target_signal_to_host (oursig)
       if (oursig >= TARGET_SIGNAL_REALTIME_33
          && oursig <= TARGET_SIGNAL_REALTIME_63)
        {
+         /* This block of signals is continuous, and
+             TARGET_SIGNAL_REALTIME_33 is 33 by definition.  */
          int retsig =
-         (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + REALTIME_LO;
-         if (retsig < REALTIME_HI)
+           (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + 33;
+         if (retsig >= REALTIME_LO && retsig < REALTIME_HI)
            return retsig;
        }
+#if (REALTIME_LO < 33)
+      else if (oursig == TARGET_SIGNAL_REALTIME_32)
+       {
+         /* TARGET_SIGNAL_REALTIME_32 isn't contiguous with
+             TARGET_SIGNAL_REALTIME_33.  It is 32 by definition.  */
+         return 32;
+       }
 #endif
+#endif
+      *oursig_ok = 0;
+      return 0;
+    }
+}
+
+int
+target_signal_to_host_p (enum target_signal oursig)
+{
+  int oursig_ok;
+  do_target_signal_to_host (oursig, &oursig_ok);
+  return oursig_ok;
+}
+
+int
+target_signal_to_host (enum target_signal oursig)
+{
+  int oursig_ok;
+  int targ_signo = do_target_signal_to_host (oursig, &oursig_ok);
+  if (!oursig_ok)
+    {
       /* The user might be trying to do "signal SIGSAK" where this system
          doesn't have SIGSAK.  */
       warning ("Signal %s does not exist on this system.\n",
               target_signal_to_name (oursig));
       return 0;
     }
+  else
+    return targ_signo;
 }
 
 /* Helper function for child_wait and the Lynx derivatives of child_wait.
@@ -2025,6 +2208,7 @@ init_dummy_target ()
   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_magic = OPS_MAGIC;
 }
@@ -2682,6 +2866,14 @@ debug_to_thread_alive (pid)
   return retval;
 }
 
+static void
+debug_to_find_new_threads ()
+{
+  debug_target.to_find_new_threads ();
+
+  fputs_unfiltered ("target_find_new_threads ()\n", gdb_stdlog);
+}
+
 static void
 debug_to_stop ()
 {
@@ -2708,7 +2900,7 @@ debug_to_query (type, req, resp, siz)
 
 static void
 debug_to_rcmd (char *command,
-              struct gdb_file *outbuf)
+              struct ui_file *outbuf)
 {
   debug_target.to_rcmd (command, outbuf);
   fprintf_unfiltered (gdb_stdlog, "target_rcmd (%s, ...)\n", command);
@@ -2817,6 +3009,7 @@ setup_target_debug ()
   current_target.to_can_run = debug_to_can_run;
   current_target.to_notice_signals = debug_to_notice_signals;
   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;
This page took 0.102676 seconds and 4 git commands to generate.