* m3-nat.c, config/nm-m3.h: Add a target_ops struct and other
authorJim Kingdon <jkingdon@engr.sgi.com>
Mon, 11 Oct 1993 22:39:54 +0000 (22:39 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Mon, 11 Oct 1993 22:39:54 +0000 (22:39 +0000)
various things to try to get this to work.

gdb/ChangeLog
gdb/config/nm-m3.h
gdb/m3-nat.c

index 668af32044ad8eb9242589f90c503ca08a1e49a3..9d88f1fbe0aff838e9c3d3943cfb3d0178bde11f 100644 (file)
@@ -1,5 +1,8 @@
 Mon Oct 11 14:27:25 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
+       * m3-nat.c, config/nm-m3.h: Add a target_ops struct and other
+       various things to try to get this to work.
+
        * symtab.h: Fix comments re headers, sharing blockvectors, etc.
 
 Mon Oct 11 11:46:06 1993  david d `zoo' zuhn  (zoo@rtl.cygnus.com)
index 8e2730f2eba9dcbbe61039d1b735e7a8788fe39d..0d12424fa8abc5c7b91a5b27be55a428c3173f5a 100644 (file)
@@ -39,18 +39,6 @@ extern thread_t current_thread;
  */
 extern int must_suspend_thread;
 
-/* Get relevant ports when creating a new inferior */
-
-#define CREATE_INFERIOR_HOOK(pid)      mach_create_inferior_hook(pid)
-
-/* wait for the inferior to change state */
-
-#define INFERIOR_WAIT_HOOK(w)  mach_really_wait(w)
-
-/* After fork() call this before exec() in the inferior task */
-
-#define PREPARE_INFERIOR prepare_inferior_task
-
 /* Startup the inferior task and suspend it after the correct code is loaded */
 
 #define STARTUP_INFERIOR(x)    intercept_exec_calls(x)
index 348b363a5fb6685d0ee5a54721f2951399248ff4..747c7b3a6717e086ea0b6a797ede36b0cd4d160e 100644 (file)
@@ -54,7 +54,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "target.h"
 #include "wait.h"
 #include "gdbcmd.h"
-#include "gdb-threads.h"
 
 #include <servers/machid_lib.h>
 
@@ -66,7 +65,27 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <signal.h>
 #define SIG_UNKNOWN 0  /* Exception that has no matching unix signal */
 
-#define private static
+#include <cthreads.h>
+
+/*
+ * Mis-use the struct cproc busy field in the copy of
+ * the cproc in gdb's address space.
+ *
+ * This *can* be done otherwise, but I'm too lazy.
+ * (Don't tell anyone :-)
+ */
+#define CPROC_REVERSE_MAP(x) ((x)->busy)
+
+/* For cproc and kernel thread mapping */
+typedef struct gdb_thread {
+  mach_port_t  name;
+  CORE_ADDR    sp;
+  CORE_ADDR    pc;
+  CORE_ADDR    fp;
+  cproc_t      cproc;
+  boolean_t     in_emulator;
+  int          slotid;
+} *gdb_thread_t;
 
 /* 
  * Actions for Mach exceptions.
@@ -344,7 +363,7 @@ int         type;
 }
 \f
 /* Guard for currently_waiting_for and singlestepped_thread_port */
-private void
+static void
 discard_single_step (thread)
      thread_t thread;
 {
@@ -444,7 +463,7 @@ setup_single_step (thread, start_step)
     }
 }
 \f
-private
+static
 request_notify (name, variant, type)
      mach_port_t       name;
      mach_msg_id_t     variant;
@@ -511,7 +530,8 @@ mach_port_t original_server_port_name = MACH_PORT_NULL;
 
 
 /* Called from inferior after FORK but before EXEC */
-prepare_inferior_task ()
+static void
+m3_trace_me ()
 {
   kern_return_t ret;
   
@@ -840,7 +860,7 @@ map_slot_to_mid (slot, threads, thread_count)
   return mid;
 }
 
-private int
+static int
 parse_thread_id (arg, thread_count, slots)
      char *arg;
      int thread_count;
@@ -1049,8 +1069,8 @@ switch_to_thread (new_thread)
 /* Do this in gdb after doing FORK but before STARTUP_INFERIOR.
  * Note that the registers are not yet valid in the inferior task.
  */
-void
-mach_create_inferior_hook (pid)
+static void
+m3_trace_him (pid)
      int pid;
 {
   kern_return_t ret;
@@ -1927,11 +1947,9 @@ mach3_write_inferior (addr, myaddr, length)
   return length;
 }
 
-/*
- * Return 0 on failure, number of bytes handled otherwise.
- */
-int
-child_xfer_memory (memaddr, myaddr, len, write, target)
+/* Return 0 on failure, number of bytes handled otherwise.  */
+static int
+m3_xfer_memory (memaddr, myaddr, len, write, target)
      CORE_ADDR memaddr;
      char *myaddr;
      int len;
@@ -1949,7 +1967,7 @@ child_xfer_memory (memaddr, myaddr, len, write, target)
 }
 
 \f
-private char *
+static char *
 translate_state(state)
 int    state;
 {
@@ -1963,7 +1981,7 @@ int       state;
   }
 }
 
-private char *
+static char *
 translate_cstate(state)
 int    state;
 {
@@ -2019,9 +2037,9 @@ map_inferior_port_name (inferior_name, type)
  * of the sequential number of such cprocs.
  */
 
-private char buf[7];
+static char buf[7];
 
-private char *
+static char *
 get_thread_name (one_cproc, id)
      cproc_t one_cproc;
      int id;
@@ -2362,7 +2380,7 @@ lookup_address_of_variable (name)
   return symaddr;
 }
 
-private cproc_t
+static cproc_t
 get_cprocs()
 {
   cproc_t their_cprocs, cproc_head, cproc_copy;
@@ -2816,7 +2834,7 @@ flush_inferior_icache(pc, amount)
 #endif FLUSH_INFERIOR_CACHE
 
 \f
-private
+static
 suspend_all_threads (from_tty)
      int from_tty;
 {
@@ -3176,7 +3194,7 @@ task_suspend_command (args, from_tty)
           mid, ta_info.suspend_count);
 }
 
-private char *
+static char *
 get_size (bytes)
      int bytes;
 {
@@ -3271,7 +3289,7 @@ task_info_command (args, from_tty)
  * exception mid [ forward | keep ]
  */
 
-private void
+static void
 exception_command (args, from_tty)
      char *args;
      int from_tty;
@@ -3320,7 +3338,7 @@ exception_command (args, from_tty)
     error ("exception action is either \"keep\" or \"forward\"");
 }
 
-private void
+static void
 print_exception_info (exception)
      int exception;
 {
@@ -3532,7 +3550,7 @@ struct cmd_list_element *cmd_thread_list;
 struct cmd_list_element *cmd_task_list;
 
 /*ARGSUSED*/
-private void
+static void
 thread_command (arg, from_tty)
      char *arg;
      int from_tty;
@@ -3542,7 +3560,7 @@ thread_command (arg, from_tty)
 }
 
 /*ARGSUSED*/
-private void
+static void
 task_command (arg, from_tty)
      char *arg;
      int from_tty;
@@ -3557,11 +3575,13 @@ add_mach_specific_commands ()
 
   /* Thread handling commands */
 
-  add_prefix_cmd ("thread", class_stack, thread_command,
-      "Generic command for handling threads in the debugged task.",
+  /* FIXME: Move our thread support into the generic thread.c stuff so we
+     can share that code.  */
+  add_prefix_cmd ("mthread", class_stack, thread_command,
+      "Generic command for handling Mach threads in the debugged task.",
       &cmd_thread_list, "thread ", 0, &cmdlist);
 
-  add_com_alias ("th", "thread", class_stack, 1);
+  add_com_alias ("th", "mthread", class_stack, 1);
 
   add_cmd ("select", class_stack, thread_select_command, 
           "Select and print MID of the selected thread",
@@ -3583,8 +3603,8 @@ add_mach_specific_commands ()
            If MID/@SLOT is omitted allow all threads to break at breakpoint",
           &cmd_thread_list);
   /* Thread command shorthands (for backward compatibility) */
-  add_alias_cmd ("ts", "thread select", 0, 0, &cmdlist);
-  add_alias_cmd ("tl", "thread list",   0, 0, &cmdlist);
+  add_alias_cmd ("ts", "mthread select", 0, 0, &cmdlist);
+  add_alias_cmd ("tl", "mthread list",   0, 0, &cmdlist);
 
   /* task handling commands */
 
@@ -3626,75 +3646,6 @@ the exception to some signal (see info exception)\n\
 Normally \"keep\" is used to return to GDB on exception.");
 }
 
-void
-_initialize_mach_os ()
-{
-  kern_return_t ret;
-
-  ret = mach_port_allocate(mach_task_self(), 
-                          MACH_PORT_RIGHT_PORT_SET,
-                          &inferior_wait_port_set);
-  if (ret != KERN_SUCCESS)
-    fatal("initial port set %s",mach_error_string(ret));
-
-  /* mach_really_wait now waits for this */
-  currently_waiting_for = inferior_wait_port_set;
-
-  ret = netname_look_up(name_server_port, hostname, "MachID", &mid_server);
-  if (ret != KERN_SUCCESS)
-    {
-      mid_server = MACH_PORT_NULL;
-      
-      message ("initialize machid: netname_lookup_up(MachID) : %s",
-              mach_error_string(ret));
-      message ("Some (most?) features disabled...");
-    }
-  
-  mid_auth = mach_privileged_host_port();
-  if (mid_auth == MACH_PORT_NULL)
-    mid_auth = mach_task_self();
-  
-  obstack_init (port_chain_obstack);
-
-  ret = mach_port_allocate (mach_task_self (), 
-                           MACH_PORT_RIGHT_RECEIVE,
-                           &thread_exception_port);
-  CHK ("Creating thread_exception_port for single stepping", ret);
-  
-  ret = mach_port_insert_right (mach_task_self (),
-                               thread_exception_port,
-                               thread_exception_port,
-                               MACH_MSG_TYPE_MAKE_SEND);
-  CHK ("Inserting send right to thread_exception_port", ret);
-
-  /* Allocate message port */
-  ret = mach_port_allocate (mach_task_self (),
-                           MACH_PORT_RIGHT_RECEIVE,
-                           &our_message_port);
-  if (ret != KERN_SUCCESS)
-    message ("Creating message port %s", mach_error_string (ret));
-  else
-    {
-      char buf[ MAX_NAME_LEN ];
-      ret = mach_port_move_member(mach_task_self (),
-                                 our_message_port,
-                                 inferior_wait_port_set);
-      if (ret != KERN_SUCCESS)
-       message ("message move member %s", mach_error_string (ret));
-
-
-      /* @@@@ No way to change message port name currently */
-      /* Foo. This assumes gdb has a unix pid */
-      sprintf (buf, "gdb-%d", getpid ());
-      gdb_register_port (buf, our_message_port);
-    }
-  
-  /* Heap for thread commands */
-  obstack_init (cproc_obstack);
-
-  add_mach_specific_commands ();
-}
-
 kern_return_t
 do_mach_notify_dead_name (notify, name)
      mach_port_t notify;
@@ -3806,7 +3757,7 @@ do_mach_notify_send_once (notify)
 }
 
 /* Kills the inferior. It's gone when you call this */
-void
+static void
 kill_inferior_fast ()
 {
   WAITTYPE w;
@@ -3831,13 +3782,44 @@ kill_inferior_fast ()
   setup_notify_port (0);
 }
 
-void
-kill_inferior ()
+static void
+m3_kill_inferior ()
 {
   kill_inferior_fast ();
   target_mourn_inferior ();
 }
 
+/* Clean up after the inferior dies.  */
+
+static void
+m3_mourn_inferior ()
+{
+  unpush_target (&m3_ops);
+  generic_mourn_inferior ();
+}
+
+\f
+/* Fork an inferior process, and start debugging it.  */
+
+static void
+m3_create_inferior (exec_file, allargs, env)
+     char *exec_file;
+     char *allargs;
+     char **env;
+{
+  fork_inferior (exec_file, allargs, env, m3_trace_m3, m3_trace_him);
+  /* We are at the first instruction we care about.  */
+  /* Pedal to the metal... */
+  proceed ((CORE_ADDR) -1, 0, 0);
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach"
+   commands.  */
+static int
+m3_can_run ()
+{
+  return 1;
+}
 \f
 /* Mach 3.0 does not need ptrace for anything
  * Make sure nobody uses it on mach.
@@ -3853,7 +3835,8 @@ int a,b,c,d;
    If SIGNAL is nonzero, give it that signal.  */
 
 void
-child_resume (step, signal)
+m3_resume (pid, step, signal)
+     int pid;
      int step;
      int signal;
 {
@@ -3971,7 +3954,8 @@ mid_attach (mid)
  * like "atta 0" or "atta foo" (equal to the previous :-) and
  * "atta pidself". Anyway, the latter is allowed by specifying a MID.
  */
-attach (pid)
+static int
+m3_do_attach (pid)
      int pid;
 {
   kern_return_t ret;
@@ -4004,6 +3988,42 @@ attach (pid)
   return inferior_pid;
 }
 
+/* Attach to process PID, then initialize for debugging it
+   and wait for the trace-trap that results from attaching.  */
+
+static void
+m3_attach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  char *exec_file;
+  int pid;
+
+  if (!args)
+    error_no_arg ("process-id to attach");
+
+  pid = atoi (args);
+
+  if (pid == getpid())         /* Trying to masturbate? */
+    error ("I refuse to debug myself!");
+
+  if (from_tty)
+    {
+      exec_file = (char *) get_exec_file (0);
+
+      if (exec_file)
+       printf ("Attaching to program `%s', %s\n", exec_file, target_pid_to_str (pid));
+      else
+       printf ("Attaching to %s\n", target_pid_to_str (pid));
+
+      fflush (stdout);
+    }
+
+  m3_do_attach (pid);
+  inferior_pid = pid;
+  push_target (&procfs_ops);
+}
+\f
 void
 deallocate_inferior_ports ()
 {
@@ -4060,8 +4080,8 @@ deallocate_inferior_ports ()
    and continue it with signal number SIGNAL.
    SIGNAL = 0 means just continue it.  */
 
-void
-detach (signal)
+static void
+m3_do_detach (signal)
      int signal;
 {
   kern_return_t ret;
@@ -4099,6 +4119,38 @@ detach (signal)
   
   attach_flag = 0;
 }
+
+/* Take a program previously attached to and detaches it.
+   The program resumes execution and will no longer stop
+   on signals, etc.  We'd better not have left any breakpoints
+   in the program or it'll die when it hits one.  For this
+   to work, it may be necessary for the process to have been
+   previously attached.  It *might* work if the program was
+   started via fork.  */
+
+static void
+m3_detach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  int siggnal = 0;
+
+  if (from_tty)
+    {
+      char *exec_file = get_exec_file (0);
+      if (exec_file == 0)
+       exec_file = "";
+      printf ("Detaching from program: %s %s\n",
+             exec_file, target_pid_to_str (inferior_pid));
+      fflush (stdout);
+    }
+  if (args)
+    siggnal = atoi (args);
+  
+  m3_do_detach (siggnal);
+  inferior_pid = 0;
+  unpush_target (&m3_ops);             /* Pop out of handling an inferior */
+}
 #endif /* ATTACH_DETACH */
 
 #ifdef DUMP_SYSCALL
@@ -4316,3 +4368,119 @@ char    *p;
   puts_filtered("\n");
 }
 #endif  DUMP_SYSCALL
+
+struct target_ops m3_ops = {
+  "mach",                      /* to_shortname */
+  "Mach child process",        /* to_longname */
+  "Mach child process (started by the \"run\" command).",      /* to_doc */
+  ??_open,                     /* to_open */
+  0,                           /* to_close */
+  m3_attach,                   /* to_attach */
+  m3_detach,           /* to_detach */
+  m3_resume,                   /* to_resume */
+  mach_really_wait,                    /* to_wait */
+  fetch_inferior_registers,    /* to_fetch_registers */
+  store_inferior_registers,    /* to_store_registers */
+  child_prepare_to_store,      /* to_prepare_to_store */
+  m3_xfer_memory,              /* to_xfer_memory */
+
+  /* FIXME: Should print MID and all that crap.  */
+  child_files_info,            /* to_files_info */
+
+  memory_insert_breakpoint,    /* to_insert_breakpoint */
+  memory_remove_breakpoint,    /* to_remove_breakpoint */
+  terminal_init_inferior,      /* to_terminal_init */
+  terminal_inferior,           /* to_terminal_inferior */
+  terminal_ours_for_output,    /* to_terminal_ours_for_output */
+  terminal_ours,               /* to_terminal_ours */
+  child_terminal_info,         /* to_terminal_info */
+  m3_kill_inferior,            /* to_kill */
+  0,                           /* to_load */
+  0,                           /* to_lookup_symbol */
+
+  m3_create_inferior,  /* to_create_inferior */
+  m3_mourn_inferior,   /* to_mourn_inferior */
+  m3_can_run,          /* to_can_run */
+  0,                           /* to_notice_signals */
+  process_stratum,             /* to_stratum */
+  0,                           /* to_next */
+  1,                           /* to_has_all_memory */
+  1,                           /* to_has_memory */
+  1,                           /* to_has_stack */
+  1,                           /* to_has_registers */
+  1,                           /* to_has_execution */
+  0,                           /* sections */
+  0,                           /* sections_end */
+  OPS_MAGIC                    /* to_magic */
+};
+
+void
+_initialize_m3_nat ()
+{
+  kern_return_t ret;
+
+  add_target (&m3_ops);
+
+  ret = mach_port_allocate(mach_task_self(), 
+                          MACH_PORT_RIGHT_PORT_SET,
+                          &inferior_wait_port_set);
+  if (ret != KERN_SUCCESS)
+    fatal("initial port set %s",mach_error_string(ret));
+
+  /* mach_really_wait now waits for this */
+  currently_waiting_for = inferior_wait_port_set;
+
+  ret = netname_look_up(name_server_port, hostname, "MachID", &mid_server);
+  if (ret != KERN_SUCCESS)
+    {
+      mid_server = MACH_PORT_NULL;
+      
+      message ("initialize machid: netname_lookup_up(MachID) : %s",
+              mach_error_string(ret));
+      message ("Some (most?) features disabled...");
+    }
+  
+  mid_auth = mach_privileged_host_port();
+  if (mid_auth == MACH_PORT_NULL)
+    mid_auth = mach_task_self();
+  
+  obstack_init (port_chain_obstack);
+
+  ret = mach_port_allocate (mach_task_self (), 
+                           MACH_PORT_RIGHT_RECEIVE,
+                           &thread_exception_port);
+  CHK ("Creating thread_exception_port for single stepping", ret);
+  
+  ret = mach_port_insert_right (mach_task_self (),
+                               thread_exception_port,
+                               thread_exception_port,
+                               MACH_MSG_TYPE_MAKE_SEND);
+  CHK ("Inserting send right to thread_exception_port", ret);
+
+  /* Allocate message port */
+  ret = mach_port_allocate (mach_task_self (),
+                           MACH_PORT_RIGHT_RECEIVE,
+                           &our_message_port);
+  if (ret != KERN_SUCCESS)
+    message ("Creating message port %s", mach_error_string (ret));
+  else
+    {
+      char buf[ MAX_NAME_LEN ];
+      ret = mach_port_move_member(mach_task_self (),
+                                 our_message_port,
+                                 inferior_wait_port_set);
+      if (ret != KERN_SUCCESS)
+       message ("message move member %s", mach_error_string (ret));
+
+
+      /* @@@@ No way to change message port name currently */
+      /* Foo. This assumes gdb has a unix pid */
+      sprintf (buf, "gdb-%d", getpid ());
+      gdb_register_port (buf, our_message_port);
+    }
+  
+  /* Heap for thread commands */
+  obstack_init (cproc_obstack);
+
+  add_mach_specific_commands ();
+}