* procfs.c (procfs_wait): handle syscall events first.

* procfs.c (GDB_GREGSET_TYPE, GDB_FPREGSET_TYPE): new macros.
        * config/sparc/xm-sun4sol2.h: use them.
        * core-sol2.c: don't #undef gregset_t and fpregset_t.
        * sol-thread.c: ditto.
        * sparc-tdep.c: ditto.
This commit is contained in:
Felix Lee 1998-11-24 14:51:13 +00:00
parent afcad54a90
commit 15af627cc0
7 changed files with 1466 additions and 67 deletions

View File

@ -1,3 +1,13 @@
1998-11-24 Felix Lee <flee@cygnus.com>
* procfs.c (procfs_wait): handle syscall events first.
* procfs.c (GDB_GREGSET_TYPE, GDB_FPREGSET_TYPE): new macros.
* config/sparc/xm-sun4sol2.h: use them.
* core-sol2.c: don't #undef gregset_t and fpregset_t.
* sol-thread.c: ditto.
* sparc-tdep.c: ditto.
Tue Nov 24 14:13:10 1998 Andrew Cagney <cagney@chook> Tue Nov 24 14:13:10 1998 Andrew Cagney <cagney@chook>
* breakpoint.c (memory_breakpoint_size): Delete global. * breakpoint.c (memory_breakpoint_size): Delete global.

View File

@ -25,11 +25,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "xm-sysv4.h" #include "xm-sysv4.h"
/* SVR4's can't seem to agree on what to call the type that contains the /* gdb wants to use the prgregset_t interface rather than
general registers. Kludge around it with a #define. */ the gregset_t interface, partly because that's what's
used in core-sol2.c */
#define gregset_t prgregset_t #define GDB_GREGSET_TYPE prgregset_t
#define fpregset_t prfpregset_t #define GDB_FPREGSET_TYPE prfpregset_t
/* These are not currently used in SVR4 (but should be, FIXME!). */ /* These are not currently used in SVR4 (but should be, FIXME!). */
#undef DO_DEFERRED_STORES #undef DO_DEFERRED_STORES

View File

@ -26,9 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
and sparc-nat.c to be able to read both flavours. */ and sparc-nat.c to be able to read both flavours. */
#include "defs.h" #include "defs.h"
#undef gregset_t
#undef fpregset_t
#include <time.h> #include <time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/regset.h> #include <sys/regset.h>

114
gdb/merge-syscalls.sh Executable file
View File

@ -0,0 +1,114 @@
#!/bin/sh
# Copyright 1998 Free Software Foundation, Inc.
#
# This file is part of GDB.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
################
# Usage: merge-syscalls syscall.tab [HEADER-FILE ...]
#
# This will scan every HEADER-FILE
# (default is /usr/include/sys/syscall.h)
# for #define SYS_xxx directives,
# recursively scanning #included files.
#
# Then it updates "syscall.tab", which is a file that has a
# C fragment to initialize a table of known syscall names.
# Any syscalls already in "syscall.tab" will be kept.
#
# In principle, you don't need to run this unless you're
# porting gdb to a new host that uses procfs.c.
#
# FIXME: perhaps use gcc -E -dM instead.
# FIXME: perhaps track which hosts have which syscalls.
DEST=$1; shift
WS=`printf "[\t ]*" 2>/dev/null || echo '[ ]*'`
scan_all () {
for file
do
scan_one $file
done
}
scan_one () {
echo >&2 "scanning $1..."
<$1 sed -n -e "
/^#${WS}define${WS}SYS_[_a-zA-Z0-9]${WS}/ {
s/^${WS}#${WS}define${WS}\(SYS_[_a-zA-Z0-9]*\)${WS}.*/\1/
p
}
/${WS}syscall_table${WS}\[SYS_[_a-zA-Z0-9]*\]/ {
s/^.*${WS}syscall_table${WS}\[\(SYS_[_a-zA-Z0-9]*\)\].*/\1/
p
}
" $1 &&
includes=`
<$1 sed -n -e "
/^${WS}#${WS}include${WS}</{
s/^${WS}#${WS}include${WS}<\([^>]*\)>.*/\1/
p
}
" |
while read inc; do
for dir in /usr/include; do
if [ -f "$dir/$inc" ]; then
echo $dir/$inc
fi
done
done
` &&
scan_all $includes
}
case $# in
0)
set -- /usr/include/sys/syscall.h
;;
esac
scan_all $DEST "$@" |
sort -u |
(
echo "/* This file is semi-automatically updated by `basename $0` */"
while read sys; do
tail=`echo "$sys" | sed 's/^SYS_//'`
echo "#if defined ($sys)"
echo " syscall_table[$sys] = "\""$tail"\"";"
echo "#endif"
done
) > tmp$$ || exit 1
if cmp -s $DEST tmp$$; then
echo "$DEST unchanged"
rm -f tmp$$
else
echo "creating new $DEST..."
if [ -f $DEST ]; then
mv $DEST $DEST.orig || exit 1
echo " (original moved to $DEST.orig)"
fi
mv tmp$$ $DEST
fi

View File

@ -116,6 +116,25 @@ regardless of whether or not the actual target has floating point hardware.
# endif # endif
#endif /* HAVE_MULTIPLE_PROC_FDS */ #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") #define MAX_PROC_NAME_SIZE sizeof("/proc/1234567890/status")
extern struct target_ops procfs_ops; /* Forward declaration */ extern struct target_ops procfs_ops; /* Forward declaration */
@ -149,13 +168,13 @@ struct proc_ctl {
/* set general registers */ /* set general registers */
struct greg_ctl { struct greg_ctl {
int cmd; int cmd;
gregset_t gregset; gdb_gregset_t gregset;
}; };
/* set fp registers */ /* set fp registers */
struct fpreg_ctl { struct fpreg_ctl {
int cmd; int cmd;
fpregset_t fpregset; gdb_fpregset_t fpregset;
}; };
/* set signals to be traced */ /* set signals to be traced */
@ -221,6 +240,8 @@ struct procinfo {
currently installed */ currently installed */
/* Pointer to list of syscall trap handlers */ /* Pointer to list of syscall trap handlers */
struct procfs_syscall_handler *syscall_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 */ int new_child; /* Non-zero if it's a new thread */
}; };
@ -635,14 +656,14 @@ static void procfs_resume PARAMS ((int pid, int step,
/* External function prototypes that can't be easily included in any /* External function prototypes that can't be easily included in any
header file because the args are typedefs in system include files. */ 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 #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 #endif
/* /*
@ -1997,7 +2018,7 @@ procfs_store_registers (regno)
procfs_read_status (pi); procfs_read_status (pi);
memcpy ((char *) &greg.gregset, memcpy ((char *) &greg.gregset,
(char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs, (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs,
sizeof (gregset_t)); sizeof (gdb_gregset_t));
} }
fill_gregset (&greg.gregset, regno); fill_gregset (&greg.gregset, regno);
greg.cmd = PCSREG; greg.cmd = PCSREG;
@ -2023,7 +2044,7 @@ procfs_store_registers (regno)
procfs_read_status (pi); procfs_read_status (pi);
memcpy ((char *) &fpreg.fpregset, memcpy ((char *) &fpreg.fpregset,
(char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs, (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs,
sizeof (fpregset_t)); sizeof (gdb_fpregset_t));
} }
fill_fpregset (&fpreg.fpregset, regno); fill_fpregset (&fpreg.fpregset, regno);
fpreg.cmd = PCSFPREG; fpreg.cmd = PCSFPREG;
@ -3359,31 +3380,68 @@ procfs_wait (pid, ourstatus)
struct procinfo *pi; struct procinfo *pi;
struct proc_ctl pctl; struct proc_ctl pctl;
if (pid != -1) /* Non-specific process? */ scan_again:
pi = NULL;
else /* handle all syscall events first, otherwise we might not
for (pi = procinfo_list; pi; pi = pi->next) notice a thread was created until too late. */
if (pi->had_event)
break; for (pi = procinfo_list; pi; pi = pi->next)
{
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;
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;
}
if (!found_handler)
{
if (why == PR_SYSENTRY)
error ("PR_SYSENTRY, unhandled system call %d", what);
else
error ("PR_SYSEXIT, unhandled system call %d", what);
}
}
}
/* find a relevant process with an event */
for (pi = procinfo_list; pi; pi = pi->next)
if (pi->had_event && (pid == -1 || pi->pid == pid))
break;
if (!pi) if (!pi)
{ {
wait_again: wait_fd ();
goto scan_again;
if (pi)
pi->had_event = 0;
pi = wait_fd ();
} }
if (pid != -1)
for (pi = procinfo_list; pi; pi = pi->next)
if (pi->pid == pid && pi->had_event)
break;
if (!pi && !checkerr)
goto wait_again;
#ifdef UNIXWARE #ifdef UNIXWARE
if (!checkerr && !(pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP))) if (!checkerr && !(pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)))
#else #else
@ -3438,27 +3496,8 @@ procfs_wait (pid, ourstatus)
break; break;
case PR_SYSENTRY: case PR_SYSENTRY:
case PR_SYSEXIT: case PR_SYSEXIT:
{ rtnval = pi->saved_rtnval;
int i; statval = pi->saved_statval;
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);
}
break; break;
case PR_REQUESTED: case PR_REQUESTED:
statval = (SIGSTOP << 8) | 0177; statval = (SIGSTOP << 8) | 0177;

View File

@ -46,17 +46,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
procfs.c. */ procfs.c. */
#include "defs.h" #include "defs.h"
/* Undefine gregset_t and fpregset_t to avoid conflict with defs in xm file. */
#ifdef gregset_t
#undef gregset_t
#endif
#ifdef fpregset_t
#undef fpregset_t
#endif
#include <thread.h> #include <thread.h>
#include <proc_service.h> #include <proc_service.h>
#include <thread_db.h> #include <thread_db.h>

1249
gdb/syscall.tab Normal file

File diff suppressed because it is too large Load Diff