* 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:
parent
afcad54a90
commit
15af627cc0
7 changed files with 1466 additions and 67 deletions
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
114
gdb/merge-syscalls.sh
Executable 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
|
||||||
|
|
||||||
|
|
137
gdb/procfs.c
137
gdb/procfs.c
|
@ -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;
|
||||||
|
|
|
@ -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
1249
gdb/syscall.tab
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue