* 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>
* 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"
/* SVR4's can't seem to agree on what to call the type that contains the
general registers. Kludge around it with a #define. */
/* gdb wants to use the prgregset_t interface rather than
the gregset_t interface, partly because that's what's
used in core-sol2.c */
#define gregset_t prgregset_t
#define fpregset_t prfpregset_t
#define GDB_GREGSET_TYPE prgregset_t
#define GDB_FPREGSET_TYPE prfpregset_t
/* These are not currently used in SVR4 (but should be, FIXME!). */
#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. */
#include "defs.h"
#undef gregset_t
#undef fpregset_t
#include <time.h>
#include <sys/types.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 /* 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 */
};
@ -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;
@ -3359,31 +3380,68 @@ 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:
/* 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)
{
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)
{
wait_again:
if (pi)
pi->had_event = 0;
pi = wait_fd ();
wait_fd ();
goto scan_again;
}
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
if (!checkerr && !(pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)))
#else
@ -3438,27 +3496,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;

View File

@ -46,17 +46,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
procfs.c. */
#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 <proc_service.h>
#include <thread_db.h>

1249
gdb/syscall.tab Normal file

File diff suppressed because it is too large Load Diff