# 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 */
/* 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 */
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 */
};
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));
/* 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
/*
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;
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;
SYNOPSIS
- int procfs_init_inferior (int pid)
+ void procfs_init_inferior (int pid)
DESCRIPTION
*/
-static int
+static void
procfs_init_inferior (pid)
int pid;
{
/* One trap to exec the shell, one to exec the program being debugged. */
startup_inferior (2);
#endif
-
- return pid;
}
/*
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)))
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;
}
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... */
}
#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 ()
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);