1999-01-19 Fernando Nasser <fnasser@totem.to.cygnus.com>
[deliverable/binutils-gdb.git] / gdb / procfs.c
index 2d24d9cb84ac43faf3be3f0d53cdbbffbd874402..83c0c328d08ce2d156df14d9785d65f70eb7cbb8 100644 (file)
@@ -116,6 +116,25 @@ regardless of whether or not the actual target has floating point hardware.
 #  endif
 #endif /* HAVE_MULTIPLE_PROC_FDS */
 
+
+/* These #ifdefs are for sol2.x in particular.  sol2.x has
+   both a "gregset_t" and a "prgregset_t", which have
+   similar uses but different layouts.  sol2.x gdb tries to
+   use prgregset_t (and prfpregset_t) everywhere. */
+
+#ifdef GDB_GREGSET_TYPE
+  typedef GDB_GREGSET_TYPE gdb_gregset_t;
+#else
+  typedef gregset_t gdb_gregset_t;
+#endif
+
+#ifdef GDB_FPREGSET_TYPE
+  typedef GDB_FPREGSET_TYPE gdb_fpregset_t;
+#else
+  typedef fpregset_t gdb_fpregset_t;
+#endif
+
+
 #define MAX_PROC_NAME_SIZE sizeof("/proc/1234567890/status")
 
 extern struct target_ops procfs_ops;           /* Forward declaration */
@@ -149,13 +168,13 @@ struct proc_ctl {
 /* set general registers */
 struct greg_ctl {
         int             cmd;
-        gregset_t       gregset;
+        gdb_gregset_t  gregset;
 };
 
 /* set fp registers */
 struct fpreg_ctl {
         int             cmd;
-        fpregset_t      fpregset;
+        gdb_fpregset_t fpregset;
 };
 
 /* set signals to be traced */
@@ -221,6 +240,8 @@ struct procinfo {
                                   currently installed */
                                /* Pointer to list of syscall trap handlers */
   struct procfs_syscall_handler *syscall_handlers; 
+  int saved_rtnval;            /* return value and status for wait(), */
+  int saved_statval;           /*  as supplied by a syscall handler. */
   int new_child;               /* Non-zero if it's a new thread */
 };
 
@@ -513,7 +534,7 @@ static void procfs_attach PARAMS ((char *, int));
 
 static void proc_set_exec_trap PARAMS ((void));
 
-static int procfs_init_inferior PARAMS ((int));
+static void  procfs_init_inferior PARAMS ((int));
 
 static struct procinfo *create_procinfo PARAMS ((int));
 
@@ -635,14 +656,14 @@ static void procfs_resume PARAMS ((int pid, int step,
 /* External function prototypes that can't be easily included in any
    header file because the args are typedefs in system include files. */
 
-extern void supply_gregset PARAMS ((gregset_t *));
+extern void supply_gregset PARAMS ((gdb_gregset_t *));
 
-extern void fill_gregset PARAMS ((gregset_t *, int));
+extern void fill_gregset PARAMS ((gdb_gregset_t *, int));
 
 #ifdef FP0_REGNUM
-extern void supply_fpregset PARAMS ((fpregset_t *));
+extern void supply_fpregset PARAMS ((gdb_fpregset_t *));
 
-extern void fill_fpregset PARAMS ((fpregset_t *, int));
+extern void fill_fpregset PARAMS ((gdb_fpregset_t *, int));
 #endif
 
 /*
@@ -1997,7 +2018,7 @@ procfs_store_registers (regno)
       procfs_read_status (pi);
       memcpy ((char *) &greg.gregset,
          (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs,
-         sizeof (gregset_t));
+         sizeof (gdb_gregset_t));
     }
   fill_gregset (&greg.gregset, regno);
   greg.cmd = PCSREG;
@@ -2023,7 +2044,7 @@ procfs_store_registers (regno)
       procfs_read_status (pi);
       memcpy ((char *) &fpreg.fpregset,
           (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs,
-          sizeof (fpregset_t));
+          sizeof (gdb_fpregset_t));
     }
   fill_fpregset (&fpreg.fpregset, regno);
   fpreg.cmd = PCSFPREG;
@@ -2498,7 +2519,7 @@ LOCAL FUNCTION
 
 SYNOPSIS
 
-       int procfs_init_inferior (int pid)
+       void procfs_init_inferior (int pid)
 
 DESCRIPTION
 
@@ -2516,7 +2537,7 @@ NOTES
 
  */
 
-static int
+static void 
 procfs_init_inferior (pid)
      int pid;
 {
@@ -2542,8 +2563,6 @@ procfs_init_inferior (pid)
   /* One trap to exec the shell, one to exec the program being debugged.  */
   startup_inferior (2);
 #endif
-
-  return pid;
 }
 
 /*
@@ -2750,6 +2769,8 @@ proc_set_exec_trap ()
 
   modify_run_on_last_close_flag (fd, 1);
 
+#ifndef UNIXWARE       /* since this is a solaris-ism, we don't want it */
+                       /* NOTE: revisit when doing thread support for UW */
 #ifdef PR_ASYNC
   {
     long pr_flags;
@@ -2769,6 +2790,7 @@ proc_set_exec_trap ()
 #endif
   }
 #endif /* PR_ASYNC */
+#endif /* !UNIXWARE */
 }
 
 /*
@@ -3356,30 +3378,67 @@ procfs_wait (pid, ourstatus)
   struct procinfo *pi;
   struct proc_ctl pctl;
 
-  if (pid != -1)               /* Non-specific process? */
-    pi = NULL;
-  else
-    for (pi = procinfo_list; pi; pi = pi->next)
-      if (pi->had_event)
-       break;
+scan_again:
 
-  if (!pi)
+  /* handle all syscall events first, otherwise we might not
+     notice a thread was created until too late. */
+
+  for (pi = procinfo_list; pi; pi = pi->next)
     {
-    wait_again:
+      if (!pi->had_event)
+       continue;
+
+#ifdef UNIXWARE
+      if (! (pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)) )
+       continue;
+
+      why = pi->prstatus.pr_lwp.pr_why;
+      what = pi->prstatus.pr_lwp.pr_what;
+#else
+      if (! (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)) )
+       continue;
+
+      why = pi->prstatus.pr_why;
+      what = pi->prstatus.pr_what;
+#endif
+      if (why == PR_SYSENTRY || why == PR_SYSEXIT)
+       {
+         int i;
+         int found_handler = 0;
 
-      if (pi)
-       pi->had_event = 0;
+         for (i = 0; i < pi->num_syscall_handlers; i++)
+           if (pi->syscall_handlers[i].syscall_num == what)
+             {
+               found_handler = 1;
+               pi->saved_rtnval = pi->pid;
+               pi->saved_statval = 0;
+               if (!pi->syscall_handlers[i].func
+                   (pi, what, why, &pi->saved_rtnval, &pi->saved_statval))
+                 pi->had_event = 0;
+               break;
+             }
 
-      pi = wait_fd ();
+         if (!found_handler)
+           {
+             if (why == PR_SYSENTRY)
+               error ("PR_SYSENTRY, unhandled system call %d", what);
+             else
+               error ("PR_SYSEXIT, unhandled system call %d", what);
+           }
+       }
     }
 
-  if (pid != -1)
-    for (pi = procinfo_list; pi; pi = pi->next)
-      if (pi->pid == pid && pi->had_event)
-       break;
+  /* find a relevant process with an event */
 
-  if (!pi && !checkerr)
-    goto wait_again;
+  for (pi = procinfo_list; pi; pi = pi->next)
+    if (pi->had_event && (pid == -1 || pi->pid == pid))
+      break;
+
+  if (!pi)
+    {
+      wait_fd ();
+      goto scan_again;
+    }
 
 #ifdef UNIXWARE
   if (!checkerr && !(pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)))
@@ -3435,27 +3494,8 @@ procfs_wait (pid, ourstatus)
          break;
        case PR_SYSENTRY:
        case PR_SYSEXIT:
-         {
-           int i;
-           int found_handler = 0;
-
-           for (i = 0; i < pi->num_syscall_handlers; i++)
-             if (pi->syscall_handlers[i].syscall_num == what)
-               {
-                 found_handler = 1;
-                 if (!pi->syscall_handlers[i].func (pi, what, why,
-                                                    &rtnval, &statval))
-                   goto wait_again;
-
-                 break;
-               }
-
-           if (!found_handler)
-             if (why == PR_SYSENTRY)
-               error ("PR_SYSENTRY, unhandled system call %d", what);
-             else
-               error ("PR_SYSEXIT, unhandled system call %d", what);
-         }
+         rtnval = pi->saved_rtnval;
+         statval = pi->saved_statval;
          break;
        case PR_REQUESTED:
          statval = (SIGSTOP << 8) | 0177;
@@ -5533,7 +5573,7 @@ procfs_create_inferior (exec_file, allargs, env)
     }
 
   fork_inferior (exec_file, allargs, env,
-                proc_set_exec_trap, procfs_init_inferior, shell_file);
+                proc_set_exec_trap, procfs_init_inferior, NULL, shell_file);
 
   /* We are at the first instruction we care about.  */
   /* Pedal to the metal... */
@@ -5712,48 +5752,7 @@ procfs_pid_to_str (pid)
 }
 #endif /* TIDGET */
 \f
-struct target_ops procfs_ops = {
-  "procfs",                    /* to_shortname */
-  "Unix /proc child process",  /* to_longname */
-  "Unix /proc child process (started by the \"run\" command).",        /* to_doc */
-  procfs_open,                 /* to_open */
-  0,                           /* to_close */
-  procfs_attach,                       /* to_attach */
-  procfs_detach,               /* to_detach */
-  procfs_resume,                       /* to_resume */
-  procfs_wait,                 /* to_wait */
-  procfs_fetch_registers,      /* to_fetch_registers */
-  procfs_store_registers,      /* to_store_registers */
-  procfs_prepare_to_store,     /* to_prepare_to_store */
-  procfs_xfer_memory,          /* to_xfer_memory */
-  procfs_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 */
-  procfs_kill_inferior,                /* to_kill */
-  0,                           /* to_load */
-  0,                           /* to_lookup_symbol */
-  procfs_create_inferior,      /* to_create_inferior */
-  procfs_mourn_inferior,       /* to_mourn_inferior */
-  procfs_can_run,              /* to_can_run */
-  procfs_notice_signals,       /* to_notice_signals */
-  procfs_thread_alive,         /* to_thread_alive */
-  procfs_stop,                 /* to_stop */
-  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 */
-};
+struct target_ops procfs_ops;
 
 void
 _initialize_procfs ()
@@ -5770,6 +5769,48 @@ _initialize_procfs ()
     return;
   close (fd);
 #endif
+  procfs_ops.to_shortname = "procfs";
+  procfs_ops.to_longname = "Unix /proc child process";
+  procfs_ops.to_doc = "Unix /proc child process (started by the \"run\" command).";
+  procfs_ops.to_open = procfs_open;
+  procfs_ops.to_close = 0;
+  procfs_ops.to_attach = procfs_attach;
+  procfs_ops.to_require_attach = procfs_attach;
+  procfs_ops.to_detach = procfs_detach;
+  procfs_ops.to_require_detach = procfs_detach;
+  procfs_ops.to_resume = procfs_resume;
+  procfs_ops.to_wait = procfs_wait;
+  procfs_ops.to_fetch_registers = procfs_fetch_registers;
+  procfs_ops.to_store_registers = procfs_store_registers;
+  procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
+  procfs_ops.to_xfer_memory = procfs_xfer_memory;
+  procfs_ops.to_files_info = procfs_files_info;
+  procfs_ops.to_insert_breakpoint = memory_insert_breakpoint;
+  procfs_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  procfs_ops.to_terminal_init = terminal_init_inferior;
+  procfs_ops.to_terminal_inferior = terminal_inferior;
+  procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+  procfs_ops.to_terminal_ours = terminal_ours;
+  procfs_ops.to_terminal_info = child_terminal_info;
+  procfs_ops.to_kill = procfs_kill_inferior;
+  procfs_ops.to_load = 0;
+  procfs_ops.to_lookup_symbol = 0;
+  procfs_ops.to_create_inferior = procfs_create_inferior;
+  procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
+  procfs_ops.to_can_run = procfs_can_run;
+  procfs_ops.to_notice_signals = procfs_notice_signals;
+  procfs_ops.to_thread_alive = procfs_thread_alive;
+  procfs_ops.to_stop = procfs_stop;
+  procfs_ops.to_stratum = process_stratum;
+  procfs_ops.to_has_all_memory = 1;
+  procfs_ops.to_has_memory = 1;
+  procfs_ops.to_has_stack = 1;
+  procfs_ops.to_has_registers = 1;
+  procfs_ops.to_has_execution = 1;
+  procfs_ops.to_has_thread_control = tc_none;
+  procfs_ops.to_sections = 0;
+  procfs_ops.to_sections_end = 0;
+  procfs_ops.to_magic = OPS_MAGIC;
 
   add_target (&procfs_ops);
 
This page took 0.028275 seconds and 4 git commands to generate.