1999-01-19 Fernando Nasser <fnasser@totem.to.cygnus.com>
[deliverable/binutils-gdb.git] / gdb / m3-nat.c
index 5de95719555193393c7cf8fbcf9cbae75c7d9108..4614f6565505208f8468b037d5dc47ddf32148fd 100644 (file)
@@ -1,7 +1,7 @@
 /* Interface GDB to Mach 3.0 operating systems.
    (Most) Mach 3.0 related routines live in this file.
 
-   Copyright (C) 1992 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1996, 1999 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -17,7 +17,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
  * Author: Jukka Virtanen <jtv@hut.fi>
@@ -260,7 +260,9 @@ int must_suspend_thread = 0;
 struct cleanup *cleanup_step = NULL_CLEANUP;
 
 \f
-extern struct target_ops m3_ops;
+static struct target_ops m3_ops;
+
+static void m3_kill_inferior ();
 \f
 #if 0
 #define MACH_TYPE_EXCEPTION_PORT       -1
@@ -321,7 +323,7 @@ port_chain_insert (list, name, type)
        }
     }
   else
-    mid = 3735928559;  /* 0x? :-) */
+    abort ();
 
   new = (port_chain_t) obstack_alloc (port_chain_obstack,
                                      sizeof (struct port_chain));
@@ -617,6 +619,8 @@ void
 intercept_exec_calls (exec_counter)
      int exec_counter;
 {
+  int terminal_initted = 0;
+
   struct syscall_msg_t {
     mach_msg_header_t  header;
     mach_msg_type_t    type;
@@ -751,6 +755,23 @@ intercept_exec_calls (exec_counter)
              original_exec_reply = syscall_in.header.msgh_remote_port;
              syscall_in.header.msgh_remote_port = exec_reply_send;
            }
+
+         if (!terminal_initted)
+           {
+             /* Now that the child has exec'd we know it has already set its
+                process group.  On POSIX systems, tcsetpgrp will fail with
+                EPERM if we try it before the child's setpgid.  */
+
+             /* Set up the "saved terminal modes" of the inferior
+                based on what modes we are starting it with.  */
+             target_terminal_init ();
+
+             /* Install inferior's terminal modes.  */
+             target_terminal_inferior ();
+
+             terminal_initted = 1;
+           }
+
          exec_counter--;
        }
            
@@ -1082,12 +1103,9 @@ select_thread (task, thread_id, flag)
       CHK ("Could not abort system calls when selecting a thread", ret);
 
       stop_pc = read_pc();
-      set_current_frame (create_new_frame (read_register (FP_REGNUM),
-                                          stop_pc));
+      flush_cached_frames ();
 
       select_frame (get_current_frame (), 0);
-
-      stop_frame_address = FRAME_FP (get_current_frame ());
     }
 
   return KERN_SUCCESS;
@@ -1121,12 +1139,14 @@ 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.
  */
-static void
+static int
 m3_trace_him (pid)
      int pid;
 {
   kern_return_t ret;
 
+  push_target (&m3_ops);
+
   inferior_task = task_by_pid (pid);
 
   if (! MACH_PORT_VALID (inferior_task))
@@ -1154,6 +1174,8 @@ m3_trace_him (pid)
 
   /* One trap to exec the shell, one to exec the program being debugged.  */
   intercept_exec_calls (2);
+
+  return pid;
 }
 
 setup_exception_port ()
@@ -1219,10 +1241,10 @@ int mach_really_waiting;
    Returns the inferior_pid for rest of gdb.
    Side effects: Set *OURSTATUS.  */
 int
-mach_really_wait (ourstatus)
+mach_really_wait (pid, ourstatus)
+     int pid;
      struct target_waitstatus *ourstatus;
 {
-  int pid;
   kern_return_t ret;
   int w;
 
@@ -1373,6 +1395,9 @@ mach3_quit ()
   return;
 }
 
+#if 0
+/* bogus bogus bogus.  It is NOT OK to quit out of target_wait.  */
+
 /* If ^C is typed when we are waiting for a message
  * and your Unix server is able to notice that we 
  * should quit now.
@@ -1385,6 +1410,7 @@ mach3_request_quit ()
   if (mach_really_waiting)
     immediate_quit = 1;
 }      
+#endif
 
 /*
  * Gdb message server.
@@ -2112,7 +2138,7 @@ get_thread_name (one_cproc, id)
        sprintf(buf, "_t%d", id);
       }
     else
-      return (one_cproc->cthread->name);
+      return (char *)(one_cproc->cthread->name);
   else
     {
       if (id < 0)
@@ -2439,7 +2465,7 @@ lookup_address_of_variable (name)
 
   if (! symaddr)
     {
-      msymbol = lookup_minimal_symbol (name, (struct objfile *) NULL);
+      msymbol = lookup_minimal_symbol (name, NULL, NULL);
 
       if (msymbol && msymbol->type == mst_data)
        symaddr = SYMBOL_VALUE_ADDRESS (msymbol);
@@ -2702,7 +2728,6 @@ thread_list_command()
          if (ths.flags & TH_FLAGS_IDLE)
            strcat (buf, "I");
 
-         /* FIXME: May run afloul of arbitrary limit in printf_filtered.  */
          printf_filtered (TL_FORMAT,
                           slot,
                           mid,
@@ -2730,7 +2755,6 @@ thread_list_command()
            continue; /* EMcM */
 #endif
 
-         /* FIXME: May run afloul of arbitrary limit in printf_filtered.  */
          printf_filtered (TL_FORMAT,
                           "-",
                           -neworder,   /* Pseudo MID */
@@ -2802,7 +2826,6 @@ thread_list_command()
          if (ths.flags & TH_FLAGS_IDLE)
            strcat (buf, "I");
 
-         /* FIXME: May run afloul of arbitrary limit in printf_filtered.  */
          printf_filtered (TL_FORMAT,
                           slot,
                           mid,
@@ -2944,7 +2967,7 @@ suspend_all_threads (from_tty)
     {
       warning ("Could not suspend inferior threads.");
       m3_kill_inferior ();
-      return_to_top_level ();
+      return_to_top_level (RETURN_ERROR);
     }
   
   for (index = 0; index < thread_count; index++)
@@ -3118,7 +3141,7 @@ thread_resume_command (args, from_tty)
       {
        if (current_thread)
          current_thread = saved_thread;
-       return_to_top_level ();
+       return_to_top_level (RETURN_ERROR);
       }
 
   ret = thread_info (current_thread,
@@ -3662,8 +3685,6 @@ task_command (arg, from_tty)
 
 add_mach_specific_commands ()
 {
-  extern void condition_thread ();
-
   /* Thread handling commands */
 
   /* FIXME: Move our thread support into the generic thread.c stuff so we
@@ -3689,10 +3710,15 @@ add_mach_specific_commands ()
   add_cmd ("kill", class_run, thread_kill_command,
           "Kill the specified thread MID from inferior task.",
           &cmd_thread_list);
+#if 0
+  /* The rest of this support (condition_thread) was not merged.  It probably
+     should not be merged in this form, but instead added to the generic GDB
+     thread support.  */
   add_cmd ("break", class_breakpoint, condition_thread,
           "Breakpoint N will only be effective for thread MID or @SLOT\n\
            If MID/@SLOT is omitted allow all threads to break at breakpoint",
           &cmd_thread_list);
+#endif
   /* Thread command shorthands (for backward compatibility) */
   add_alias_cmd ("ts", "mthread select", 0, 0, &cmdlist);
   add_alias_cmd ("tl", "mthread list",   0, 0, &cmdlist);
@@ -3900,7 +3926,7 @@ m3_create_inferior (exec_file, allargs, env)
      char *allargs;
      char **env;
 {
-  fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL);
+  fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL, NULL);
   /* We are at the first instruction we care about.  */
   /* Pedal to the metal... */
   proceed ((CORE_ADDR) -1, 0, 0);
@@ -4495,53 +4521,64 @@ char    *p;
 }
 #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 */
-  m3_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 */
-  m3_prepare_to_store, /* to_prepare_to_store */
-  m3_xfer_memory,              /* to_xfer_memory */
-  m3_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 */
-};
+static void
+m3_stop ()
+{
+  error ("to_stop target function not implemented");
+}
+
+static char *
+m3_pid_to_exec_file (pid)
+int  pid;
+{
+  error ("to_pid_to_exec_file target function not implemented");
+  return NULL;  /* To keep all compilers happy. */
+}
+
+static void
+init_m3_ops ()
+{
+  m3_ops.to_shortname = "mach";
+  m3_ops.to_longname = "Mach child process";
+  m3_ops.to_doc = "Mach child process (started by the \"run\" command).";
+  m3_ops.to_open = m3_open;
+  m3_ops.to_attach = m3_attach;
+  m3_ops.to_detach = m3_detach;
+  m3_ops.to_resume = m3_resume;
+  m3_ops.to_wait = mach_really__wait;
+  m3_ops.to_fetch_registers = fetch_inferior_registers;
+  m3_ops.to_store_registers = store_inferior_registers;
+  m3_ops.to_prepare_to_store = m3_prepare_to_store;
+  m3_ops.to_xfer_memory = m3_xfer_memory;
+  m3_ops.to_files_info = m3_files_info;
+  m3_ops.to_insert_breakpoint = memory_insert_breakpoint;
+  m3_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  m3_ops.to_terminal_init = terminal_init_inferior;
+  m3_ops.to_terminal_inferior = terminal_inferior;
+  m3_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+  m3_ops.to_terminal_ours = terminal_ours;
+  m3_ops.to_terminal_info = child_terminal_info;
+  m3_ops.to_kill = m3_kill_inferior;
+  m3_ops.to_create_inferior = m3_create_inferior;
+  m3_ops.to_mourn_inferior = m3_mourn_inferior;
+  m3_ops.to_can_run = m3_can_run;
+  m3_ops.to_stop = m3_stop;
+  m3_ops.to_pid_to_exec_file = m3_pid_to_exec_file;
+  m3_ops.to_stratum = process_stratum;
+  m3_ops.to_has_all_memory = 1;
+  m3_ops.to_has_memory = 1;
+  m3_ops.to_has_stack = 1;
+  m3_ops.to_has_registers = 1;
+  m3_ops.to_has_execution = 1;
+  m3_ops.to_magic = OPS_MAGIC;
+}
 
 void
 _initialize_m3_nat ()
 {
   kern_return_t ret;
 
+  init_m3_ops ();
   add_target (&m3_ops);
 
   ret = mach_port_allocate(mach_task_self(), 
This page took 0.027208 seconds and 4 git commands to generate.