Add brace missing from previous delta.
[deliverable/binutils-gdb.git] / gdb / m3-nat.c
index 60659b9f45bfc4efe4a5ef1627e4e382e7b2b9ec..c1719450adb7c9a9e00e1cf01df6f81bec4ce231 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 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>
@@ -54,8 +54,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "target.h"
 #include "wait.h"
 #include "gdbcmd.h"
+#include "gdbcore.h"
 
+#if 0
 #include <servers/machid_lib.h>
+#else
+#define        MACH_TYPE_TASK                  1
+#define MACH_TYPE_THREAD               2
+#endif
 
 /* Included only for signal names and NSIG
  *
@@ -253,6 +259,9 @@ int must_suspend_thread = 0;
 #define NULL_CLEANUP (struct cleanup *)0
 struct cleanup *cleanup_step = NULL_CLEANUP;
 
+\f
+extern struct target_ops m3_ops;
+static void m3_kill_inferior ();
 \f
 #if 0
 #define MACH_TYPE_EXCEPTION_PORT       -1
@@ -313,7 +322,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));
@@ -609,6 +618,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;
@@ -743,6 +754,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--;
        }
            
@@ -986,7 +1014,7 @@ select_thread (task, thread_id, flag)
   if (ret != KERN_SUCCESS)
     {
       warning ("Can not select a thread from a dead task");
-      kill_inferior ();
+      m3_kill_inferior ();
       return KERN_FAILURE;
     }
 
@@ -1074,12 +1102,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;
@@ -1113,12 +1138,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))
@@ -1146,6 +1173,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 ()
@@ -1209,14 +1238,14 @@ int mach_really_waiting;
    There is no other way to exit this loop.
 
    Returns the inferior_pid for rest of gdb.
-   Side effects: Set unix exit value to *w.
- */
+   Side effects: Set *OURSTATUS.  */
 int
-mach_really_wait (w)
-     WAITTYPE *w;
+mach_really_wait (pid, ourstatus)
+     int pid;
+     struct target_waitstatus *ourstatus;
 {
-  int pid;
   kern_return_t ret;
+  int w;
 
   struct msg {
     mach_msg_header_t    header;
@@ -1258,7 +1287,7 @@ mach_really_wait (w)
            {
              /* Collect Unix exit status for gdb */
 
-             wait3(w, WNOHANG, 0);
+             wait3(&w, WNOHANG, 0);
 
              /* This mess is here to check that the rest of
               * gdb knows that the inferior died. It also
@@ -1267,25 +1296,26 @@ mach_really_wait (w)
               * has happened to it's children when mach-magic
               * is applied on them.
               */
-             if ((!WIFEXITED(*w) && WIFSTOPPED(*w))         ||
-                 (WIFEXITED(*w)  && WEXITSTATUS(*w) > 0377))
+             if ((!WIFEXITED(w) && WIFSTOPPED(w))         ||
+                 (WIFEXITED(w)  && WEXITSTATUS(w) > 0377))
                {
-                 WSETEXIT(*w, 0);
+                 WSETEXIT(w, 0);
                  warning ("Using exit value 0 for terminated task");
                }
-             else if (!WIFEXITED(*w))
+             else if (!WIFEXITED(w))
                {
-                 int sig = WTERMSIG(*w);
+                 int sig = WTERMSIG(w);
 
                  /* Signals cause problems. Warn the user. */
                  if (sig != SIGKILL) /* Bad luck if garbage matches this */
                    warning ("The terminating signal stuff may be nonsense");
                  else if (sig > NSIG)
                    {
-                     WSETEXIT(*w, 0);
+                     WSETEXIT(w, 0);
                      warning ("Using exit value 0 for terminated task");
                    }
                }
+             store_waitstatus (ourstatus, w);
              return inferior_pid;
            }
        }
@@ -1316,10 +1346,11 @@ mach_really_wait (w)
       if (stopped_in_exception)
        {
          /* Get unix state. May be changed in mach3_exception_actions() */
-         wait3(w, WNOHANG, 0);
+         wait3(&w, WNOHANG, 0);
 
-         mach3_exception_actions (w, FALSE, "Task");
+         mach3_exception_actions (&w, FALSE, "Task");
 
+         store_waitstatus (ourstatus, w);
          return inferior_pid;
        }
     }
@@ -1363,6 +1394,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.
@@ -1375,6 +1409,7 @@ mach3_request_quit ()
   if (mach_really_waiting)
     immediate_quit = 1;
 }      
+#endif
 
 /*
  * Gdb message server.
@@ -1782,7 +1817,7 @@ mach3_read_inferior (addr, myaddr, length)
 
       if (! port_valid (inferior_task, MACH_PORT_TYPE_SEND))
        {
-         kill_inferior ();
+         m3_kill_inferior ();
          error ("Inferior killed (task port invalid)");
        }
       else
@@ -2102,7 +2137,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)
@@ -2131,7 +2166,7 @@ fetch_thread_info (task, mthreads_out)
     {
       warning ("Error getting inferior's thread list:%s",
               mach_error_string(ret));
-      kill_inferior ();
+      m3_kill_inferior ();
       return -1;
     }
   
@@ -2277,6 +2312,8 @@ map_cprocs_to_kernel_threads (cprocs, mthreads, thread_count)
   int index;
   gdb_thread_t scan;
   boolean_t all_mapped = TRUE;
+  LONGEST stack_base;
+  LONGEST stack_size;
 
   for (scan = cprocs; scan; scan = scan->next)
     {
@@ -2286,11 +2323,11 @@ map_cprocs_to_kernel_threads (cprocs, mthreads, thread_count)
       /* Check if the cproc is found by its stack */
       for (index = 0; index < thread_count; index++)
        {
-         LONGEST stack_base =
-           extract_signed_integer (scan.raw_cproc + CPROC_BASE_OFFSET,
+         stack_base =
+           extract_signed_integer (scan->raw_cproc + CPROC_BASE_OFFSET,
                                    CPROC_BASE_SIZE);
-         LONGEST stack_size = 
-           extract_signed_integer (scan.raw_cproc + CPROC_SIZE_OFFSET,
+         stack_size = 
+           extract_signed_integer (scan->raw_cproc + CPROC_SIZE_OFFSET,
                                    CPROC_SIZE_SIZE);
          if ((mthreads + index)->sp > stack_base &&
              (mthreads + index)->sp <= stack_base + stack_size)
@@ -2351,13 +2388,23 @@ map_cprocs_to_kernel_threads (cprocs, mthreads, thread_count)
                       * the user stack pointer saved in the
                       * emulator.
                       */
-                     if (scan->reverse_map == -1 &&
-                         usp > scan->stack_base &&
-                         usp <= scan->stack_base + scan->stack_size)
+                     if (scan->reverse_map == -1)
                        {
-                         mthread->cproc = scan;
-                         scan->reverse_map = index;
-                         break;
+                         stack_base =
+                           extract_signed_integer
+                             (scan->raw_cproc + CPROC_BASE_OFFSET,
+                              CPROC_BASE_SIZE);
+                         stack_size = 
+                           extract_signed_integer
+                             (scan->raw_cproc + CPROC_SIZE_OFFSET,
+                              CPROC_SIZE_SIZE);
+                         if (usp > stack_base &&
+                             usp <= stack_base + stack_size)
+                           {
+                             mthread->cproc = scan;
+                             scan->reverse_map = index;
+                             break;
+                           }
                        }
                    }
                }
@@ -2417,10 +2464,10 @@ 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 = msymbol->address;
+       symaddr = SYMBOL_VALUE_ADDRESS (msymbol);
     }
 
   return symaddr;
@@ -2483,16 +2530,15 @@ get_cprocs()
                                                 sizeof (struct gdb_thread));
 
       if (!mach3_read_inferior (their_cprocs,
-                               &cproc_copy.raw_cproc[0],
+                               &cproc_copy->raw_cproc[0],
                                CPROC_SIZE))
        error("Can't read next cproc at 0x%x.", their_cprocs);
-      cproc_copy = extract_address (buf, TARGET_PTR_BIT / HOST_CHAR_BIT);
 
       their_cprocs =
-       extract_address (cproc_copy.raw_cproc + CPROC_LIST_OFFSET,
+       extract_address (cproc_copy->raw_cproc + CPROC_LIST_OFFSET,
                         CPROC_LIST_SIZE);
       cproc_copy_incarnation =
-       extract_address (cproc_copy.raw_cproc + CPROC_INCARNATION_OFFSET,
+       extract_address (cproc_copy->raw_cproc + CPROC_INCARNATION_OFFSET,
                         CPROC_INCARNATION_SIZE);
 
       if (cproc_copy_incarnation == (CORE_ADDR)0)
@@ -2547,12 +2593,14 @@ mach3_cproc_state (mthread)
 {
   int context;
 
-  if (! mthread || !mthread->cproc || !mthread->cproc->context)
+  if (! mthread || !mthread->cproc)
     return -1;
 
   context = extract_signed_integer
     (mthread->cproc->raw_cproc + CPROC_CONTEXT_OFFSET,
      CPROC_CONTEXT_SIZE);
+  if (context == 0)
+    return -1;
 
   mthread->sp = context + MACHINE_CPROC_SP_OFFSET;
 
@@ -2623,6 +2671,9 @@ thread_list_command()
       int mid;
       char buf[10];
       char slot[3];
+      int cproc_state =
+       extract_signed_integer
+         (scan->raw_cproc + CPROC_STATE_OFFSET, CPROC_STATE_SIZE);
       
       selected = ' ';
       
@@ -2676,7 +2727,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,
@@ -2685,7 +2735,7 @@ thread_list_command()
                           kthread->in_emulator ? "E" : "",
                           translate_state (ths.run_state),
                           buf,
-                          translate_cstate (scan->state),
+                          translate_cstate (cproc_state),
                           wired);
          print_tl_address (gdb_stdout, kthread->pc);
        }
@@ -2704,7 +2754,6 @@ thread_list_command()
            continue; /* EMcM */
 #endif
 
-         /* FIXME: May run afloul of arbitrary limit in printf_filtered.  */
          printf_filtered (TL_FORMAT,
                           "-",
                           -neworder,   /* Pseudo MID */
@@ -2713,7 +2762,7 @@ thread_list_command()
                           "",
                           "-", /* kernel state */
                           "",
-                          translate_cstate (scan->state),
+                          translate_cstate (cproc_state),
                           "");
          state.cproc = scan;
 
@@ -2776,7 +2825,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,
@@ -2917,8 +2965,8 @@ suspend_all_threads (from_tty)
   if (ret != KERN_SUCCESS)
     {
       warning ("Could not suspend inferior threads.");
-      kill_inferior ();
-      return_to_top_level ();
+      m3_kill_inferior ();
+      return_to_top_level (RETURN_ERROR);
     }
   
   for (index = 0; index < thread_count; index++)
@@ -3020,7 +3068,7 @@ resume_all_threads (from_tty)
     ret = task_threads (inferior_task, &thread_list, &thread_count);
     if (ret != KERN_SUCCESS)
       {
-       kill_inferior ();
+       m3_kill_inferior ();
        error("task_threads", mach_error_string( ret));
       }
 
@@ -3092,7 +3140,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,
@@ -3464,7 +3512,7 @@ mach3_exception_actions (w, force_print_only, who)
 
   if (exception_map[stop_exception].print || force_print)
     {
-      int giveback = grab_terminal ();
+      target_terminal_ours ();
       
       printf_filtered ("\n%s received %s exception : ",
                       who,
@@ -3501,9 +3549,6 @@ mach3_exception_actions (w, force_print_only, who)
       default:
        fatal ("Unknown exception");
       }
-      
-      if (giveback)
-       terminal_inferior ();
     }
 }
 \f
@@ -3639,8 +3684,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
@@ -3666,10 +3709,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);
@@ -3877,7 +3925,7 @@ m3_create_inferior (exec_file, allargs, env)
      char *allargs;
      char **env;
 {
-  fork_inferior (exec_file, allargs, env, m3_trace_m3, m3_trace_him);
+  fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL);
   /* We are at the first instruction we care about.  */
   /* Pedal to the metal... */
   proceed ((CORE_ADDR) -1, 0, 0);
@@ -3908,7 +3956,7 @@ void
 m3_resume (pid, step, signal)
      int pid;
      int step;
-     int signal;
+     enum target_signal signal;
 {
   kern_return_t        ret;
 
@@ -3938,7 +3986,7 @@ m3_resume (pid, step, signal)
   vm_read_cache_valid = FALSE;
 
   if (signal && inferior_pid > 0) /* Do not signal, if attached by MID */
-    kill (inferior_pid, signal);
+    kill (inferior_pid, target_signal_to_host (signal));
 
   if (step)
     {
@@ -4091,7 +4139,7 @@ m3_attach (args, from_tty)
 
   m3_do_attach (pid);
   inferior_pid = pid;
-  push_target (&procfs_ops);
+  push_target (&m3_ops);
 }
 \f
 void
@@ -4223,6 +4271,39 @@ m3_detach (args, from_tty)
 }
 #endif /* ATTACH_DETACH */
 
+/* Get ready to modify the registers array.  On machines which store
+   individual registers, this doesn't need to do anything.  On machines
+   which store all the registers in one fell swoop, this makes sure
+   that registers contains all the registers from the program being
+   debugged.  */
+
+static void
+m3_prepare_to_store ()
+{
+#ifdef CHILD_PREPARE_TO_STORE
+  CHILD_PREPARE_TO_STORE ();
+#endif
+}
+
+/* Print status information about what we're accessing.  */
+
+static void
+m3_files_info (ignore)
+     struct target_ops *ignore;
+{
+  /* FIXME: should print MID and all that crap.  */
+  printf_unfiltered ("\tUsing the running image of %s %s.\n",
+                      attach_flag? "attached": "child", target_pid_to_str (inferior_pid));
+}
+
+static void
+m3_open (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  error ("Use the \"run\" command to start a Unix child process.");
+}
+
 #ifdef DUMP_SYSCALL
 #ifdef __STDC__
 #define STR(x) #x
@@ -4439,11 +4520,17 @@ char    *p;
 }
 #endif  DUMP_SYSCALL
 
+static void
+m3_stop ()
+{
+  error ("to_stop target function not implemented");
+}
+
 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 */
+  m3_open,                     /* to_open */
   0,                           /* to_close */
   m3_attach,                   /* to_attach */
   m3_detach,           /* to_detach */
@@ -4451,12 +4538,9 @@ struct target_ops m3_ops = {
   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_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 */
-
+  m3_files_info,               /* to_files_info */
   memory_insert_breakpoint,    /* to_insert_breakpoint */
   memory_remove_breakpoint,    /* to_remove_breakpoint */
   terminal_init_inferior,      /* to_terminal_init */
@@ -4472,6 +4556,8 @@ struct target_ops m3_ops = {
   m3_mourn_inferior,   /* to_mourn_inferior */
   m3_can_run,          /* to_can_run */
   0,                           /* to_notice_signals */
+  0,                           /* to_thread_alive */
+  m3_stop,                     /* to_stop */
   process_stratum,             /* to_stratum */
   0,                           /* to_next */
   1,                           /* to_has_all_memory */
This page took 0.034678 seconds and 4 git commands to generate.