20000-05-18 H.J. Lu (hjl@gnu.org)
[binutils-gdb.git] / gdb / target.c
index 1b16a2e76f5ea2bee79e7465faa2d8cf8ffebfb7..02ccc25da31b4a3629f44ca0b9d000cc1c0c3e3b 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;
@@ -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
 }
 
@@ -537,6 +649,7 @@ update_current_target ()
       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);
@@ -1212,6 +1325,39 @@ target_resize_to_sections (struct target_ops *target, int num_added)
 
 }
 
+/* Remove all target sections taken from ABFD.
+
+   Scan the current target stack for targets whose section tables
+   refer to sections from BFD, and remove those sections.  We use this
+   when we notice that the inferior has unloaded a shared object, for
+   example.  */
+void
+remove_target_sections (bfd *abfd)
+{
+  struct target_ops **t;
+
+  for (t = target_structs; t < target_structs + target_struct_size; t++)
+    {
+      struct section_table *src, *dest;
+
+      dest = (*t)->to_sections;
+      for (src = (*t)->to_sections; src < (*t)->to_sections_end; src++)
+       if (src->bfd != abfd)
+         {
+           /* Keep this section.  */
+           if (dest < src) *dest = *src;
+           dest++;
+         }
+
+      /* If we've dropped any sections, resize the section table.  */
+      if (dest < src)
+       target_resize_to_sections (*t, dest - src);
+    }
+}
+
+
+
+
 /* Find a single runnable target in the stack and return it.  If for
    some reason there is more than one, return NULL.  */
 
@@ -1909,8 +2055,6 @@ do_target_signal_to_host (enum target_signal 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:
@@ -1947,11 +2091,21 @@ do_target_signal_to_host (enum target_signal 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;
@@ -2745,6 +2899,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 ()
 {
@@ -2771,7 +2933,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);
@@ -2880,6 +3042,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;
@@ -2900,9 +3063,11 @@ static void
 do_monitor_command (char *cmd,
                 int from_tty)
 {
-  if ((current_target.to_rcmd == (void*) tcomplain)
+  if ((current_target.to_rcmd
+       == (void (*) (char *, struct ui_file *)) tcomplain)
       || (current_target.to_rcmd == debug_to_rcmd
-         && (debug_target.to_rcmd == (void*) tcomplain)))
+         && (debug_target.to_rcmd
+             == (void (*) (char *, struct ui_file *)) tcomplain)))
     {
       error ("\"monitor\" command not supported by this target.\n");
     }
@@ -2919,11 +3084,11 @@ initialize_targets ()
   add_info ("files", target_info, targ_desc);
 
   add_show_from_set (
-               add_set_cmd ("targetdebug", class_maintenance, var_zinteger,
+               add_set_cmd ("target", class_maintenance, var_zinteger,
                             (char *) &targetdebug,
                             "Set target debugging.\n\
-When non-zero, target debugging is enabled.", &setlist),
-                     &showlist);
+When non-zero, target debugging is enabled.", &setdebuglist),
+                     &showdebuglist);
 
 
   add_com ("monitor", class_obscure, do_monitor_command,