diff options
author | bde <bde@FreeBSD.org> | 1995-10-09 04:36:01 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1995-10-09 04:36:01 +0000 |
commit | 73cb54f1d4a5afa3c27cae749a2988da87012131 (patch) | |
tree | 519b3d1da5d3e2975958d071af28fbe4ec3433dd /sys | |
parent | f6872ed68c5f59797d857340755b0ab9ef61135e (diff) | |
download | FreeBSD-src-73cb54f1d4a5afa3c27cae749a2988da87012131.zip FreeBSD-src-73cb54f1d4a5afa3c27cae749a2988da87012131.tar.gz |
Fix tracing of syscalls. The previous fix required the undocumented
option DDB_NO_LCALLS to stop ddb getting control and broke all ddb
tracing. Now there is no option and no way for ddb to trace at
address _Xsyscall or to _Xsyscall, but tracing everywhere else
works. The previous fix did unnecessary things for Linux syscalls.
Don't bother checking that syscall frames are for user mode.
Make debugger traps inside the kernel (except at addresses _Xsyscall
and _Xsyscall+1) fatal if ddb is not configured. They "can't happen".
Add prototypes.
Remove stupid comments, e.g., /*ARGSUSED*/ for args that are used.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/trap.c | 95 | ||||
-rw-r--r-- | sys/i386/i386/trap.c | 95 | ||||
-rw-r--r-- | sys/kern/subr_trap.c | 95 |
3 files changed, 144 insertions, 141 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index ec1e937..3696788 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.59 1995/08/21 18:06:48 davidg Exp $ + * $Id: trap.c,v 1.60 1995/10/04 07:07:44 julian Exp $ */ /* @@ -75,13 +75,15 @@ #include "isa.h" #include "npx.h" +extern void trap __P((struct trapframe frame)); +extern int trapwrite __P((unsigned addr)); +extern void syscall __P((struct trapframe frame)); +extern void linux_syscall __P((struct trapframe frame)); + int trap_pfault __P((struct trapframe *, int)); void trap_fatal __P((struct trapframe *)); extern inthand_t IDTVEC(syscall); -#ifdef COMPAT_LINUX -extern inthand_t IDTVEC(linux_syscall); -#endif #define MAX_TRAP_MSG 27 char *trap_msg[] = { @@ -115,6 +117,9 @@ char *trap_msg[] = { "stack fault", /* 27 T_STKFLT */ }; +static void userret __P((struct proc *p, struct trapframe *frame, + u_quad_t oticks)); + static inline void userret(p, frame, oticks) struct proc *p; @@ -163,14 +168,12 @@ userret(p, frame, oticks) } /* - * trap(frame): - * Exception, fault, and trap interface to the FreeBSD kernel. + * Exception, fault, and trap interface to the FreeBSD kernel. * This common code is called from assembly language IDT gate entry * routines that prepare a suitable stack frame, and restore this * frame after the exception has been processed. */ -/*ARGSUSED*/ void trap(frame) struct trapframe frame; @@ -354,27 +357,37 @@ trap(frame) } break; -#ifdef DDB + case T_TRCTRAP: /* trace trap */ + if (frame.tf_eip == (int)IDTVEC(syscall)) { + /* + * We've just entered system mode via the + * syscall lcall. Continue single stepping + * silently until the syscall handler has + * saved the flags. + */ + return; + } + if (frame.tf_eip == (int)IDTVEC(syscall) + 1) { + /* + * The syscall handler has now saved the + * flags. Stop single stepping it. + */ + frame.tf_eflags &= ~PSL_T; + return; + } + /* + * Fall through. + */ case T_BPTFLT: -#ifndef DDB_NO_LCALLS - case T_TRCTRAP: -#endif + /* + * If DDB is enabled, let it handle the debugger trap. + * Otherwise, debugger traps "can't happen". + */ +#ifdef DDB if (kdb_trap (type, 0, &frame)) return; - break; -#endif -#if !defined (DDB) || defined (DDB_NO_LCALLS) - case T_TRCTRAP: /* trace trap -- someone single stepping lcall's */ - /* Q: how do we turn it on again? */ -#ifdef COMPAT_LINUX - if (frame.tf_eip != (int) IDTVEC(syscall) && - frame.tf_eip != (int) IDTVEC(linux_syscall)) -#else - if (frame.tf_eip != IDTVEC(syscall)) -#endif - frame.tf_eflags &= ~PSL_T; - return; #endif + break; #if NISA > 0 case T_NMI: @@ -798,11 +811,9 @@ int trapwrite(addr) } /* - * syscall(frame): - * System call request from POSIX system call gate interface to kernel. + * System call request from POSIX system call gate interface to kernel. * Like trap(), argument is call by reference. */ -/*ARGSUSED*/ void syscall(frame) struct trapframe frame; @@ -876,7 +887,7 @@ syscall(frame) p = curproc; frame.tf_eax = rval[0]; frame.tf_edx = rval[1]; - frame.tf_eflags &= ~PSL_C; /* carry bit */ + frame.tf_eflags &= ~PSL_C; break; case ERESTART: @@ -897,19 +908,16 @@ bad: else error = p->p_sysent->sv_errtbl[error]; frame.tf_eax = error; - frame.tf_eflags |= PSL_C; /* carry bit */ + frame.tf_eflags |= PSL_C; break; } -#if 1 if (frame.tf_eflags & PSL_T) { - /* traced syscall, raise sig */ + /* Traced syscall. */ frame.tf_eflags &= ~PSL_T; - if (ISPL(frame.tf_cs) == SEL_UPL) { - trapsignal(p, SIGTRAP, 0); - } + trapsignal(p, SIGTRAP, 0); } -#endif + userret(p, &frame, sticks); #ifdef KTRACE @@ -919,10 +927,6 @@ bad: } #ifdef COMPAT_LINUX -/* - * linux_syscall(frame): - */ -/*ARGSUSED*/ void linux_syscall(frame) struct trapframe frame; @@ -981,7 +985,7 @@ linux_syscall(frame) */ p = curproc; frame.tf_eax = rval[0]; - frame.tf_eflags &= ~PSL_C; /* carry bit */ + frame.tf_eflags &= ~PSL_C; break; case ERESTART: @@ -999,19 +1003,16 @@ linux_syscall(frame) else error = p->p_sysent->sv_errtbl[error]; frame.tf_eax = -error; - frame.tf_eflags |= PSL_C; /* carry bit */ + frame.tf_eflags |= PSL_C; break; } -#if 1 if (frame.tf_eflags & PSL_T) { - /* traced syscall, raise sig */ + /* Traced syscall. */ frame.tf_eflags &= ~PSL_T; - if (ISPL(frame.tf_cs) == SEL_UPL) { - trapsignal(p, SIGTRAP, 0); - } + trapsignal(p, SIGTRAP, 0); } -#endif + userret(p, &frame, sticks); #ifdef KTRACE diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index ec1e937..3696788 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.59 1995/08/21 18:06:48 davidg Exp $ + * $Id: trap.c,v 1.60 1995/10/04 07:07:44 julian Exp $ */ /* @@ -75,13 +75,15 @@ #include "isa.h" #include "npx.h" +extern void trap __P((struct trapframe frame)); +extern int trapwrite __P((unsigned addr)); +extern void syscall __P((struct trapframe frame)); +extern void linux_syscall __P((struct trapframe frame)); + int trap_pfault __P((struct trapframe *, int)); void trap_fatal __P((struct trapframe *)); extern inthand_t IDTVEC(syscall); -#ifdef COMPAT_LINUX -extern inthand_t IDTVEC(linux_syscall); -#endif #define MAX_TRAP_MSG 27 char *trap_msg[] = { @@ -115,6 +117,9 @@ char *trap_msg[] = { "stack fault", /* 27 T_STKFLT */ }; +static void userret __P((struct proc *p, struct trapframe *frame, + u_quad_t oticks)); + static inline void userret(p, frame, oticks) struct proc *p; @@ -163,14 +168,12 @@ userret(p, frame, oticks) } /* - * trap(frame): - * Exception, fault, and trap interface to the FreeBSD kernel. + * Exception, fault, and trap interface to the FreeBSD kernel. * This common code is called from assembly language IDT gate entry * routines that prepare a suitable stack frame, and restore this * frame after the exception has been processed. */ -/*ARGSUSED*/ void trap(frame) struct trapframe frame; @@ -354,27 +357,37 @@ trap(frame) } break; -#ifdef DDB + case T_TRCTRAP: /* trace trap */ + if (frame.tf_eip == (int)IDTVEC(syscall)) { + /* + * We've just entered system mode via the + * syscall lcall. Continue single stepping + * silently until the syscall handler has + * saved the flags. + */ + return; + } + if (frame.tf_eip == (int)IDTVEC(syscall) + 1) { + /* + * The syscall handler has now saved the + * flags. Stop single stepping it. + */ + frame.tf_eflags &= ~PSL_T; + return; + } + /* + * Fall through. + */ case T_BPTFLT: -#ifndef DDB_NO_LCALLS - case T_TRCTRAP: -#endif + /* + * If DDB is enabled, let it handle the debugger trap. + * Otherwise, debugger traps "can't happen". + */ +#ifdef DDB if (kdb_trap (type, 0, &frame)) return; - break; -#endif -#if !defined (DDB) || defined (DDB_NO_LCALLS) - case T_TRCTRAP: /* trace trap -- someone single stepping lcall's */ - /* Q: how do we turn it on again? */ -#ifdef COMPAT_LINUX - if (frame.tf_eip != (int) IDTVEC(syscall) && - frame.tf_eip != (int) IDTVEC(linux_syscall)) -#else - if (frame.tf_eip != IDTVEC(syscall)) -#endif - frame.tf_eflags &= ~PSL_T; - return; #endif + break; #if NISA > 0 case T_NMI: @@ -798,11 +811,9 @@ int trapwrite(addr) } /* - * syscall(frame): - * System call request from POSIX system call gate interface to kernel. + * System call request from POSIX system call gate interface to kernel. * Like trap(), argument is call by reference. */ -/*ARGSUSED*/ void syscall(frame) struct trapframe frame; @@ -876,7 +887,7 @@ syscall(frame) p = curproc; frame.tf_eax = rval[0]; frame.tf_edx = rval[1]; - frame.tf_eflags &= ~PSL_C; /* carry bit */ + frame.tf_eflags &= ~PSL_C; break; case ERESTART: @@ -897,19 +908,16 @@ bad: else error = p->p_sysent->sv_errtbl[error]; frame.tf_eax = error; - frame.tf_eflags |= PSL_C; /* carry bit */ + frame.tf_eflags |= PSL_C; break; } -#if 1 if (frame.tf_eflags & PSL_T) { - /* traced syscall, raise sig */ + /* Traced syscall. */ frame.tf_eflags &= ~PSL_T; - if (ISPL(frame.tf_cs) == SEL_UPL) { - trapsignal(p, SIGTRAP, 0); - } + trapsignal(p, SIGTRAP, 0); } -#endif + userret(p, &frame, sticks); #ifdef KTRACE @@ -919,10 +927,6 @@ bad: } #ifdef COMPAT_LINUX -/* - * linux_syscall(frame): - */ -/*ARGSUSED*/ void linux_syscall(frame) struct trapframe frame; @@ -981,7 +985,7 @@ linux_syscall(frame) */ p = curproc; frame.tf_eax = rval[0]; - frame.tf_eflags &= ~PSL_C; /* carry bit */ + frame.tf_eflags &= ~PSL_C; break; case ERESTART: @@ -999,19 +1003,16 @@ linux_syscall(frame) else error = p->p_sysent->sv_errtbl[error]; frame.tf_eax = -error; - frame.tf_eflags |= PSL_C; /* carry bit */ + frame.tf_eflags |= PSL_C; break; } -#if 1 if (frame.tf_eflags & PSL_T) { - /* traced syscall, raise sig */ + /* Traced syscall. */ frame.tf_eflags &= ~PSL_T; - if (ISPL(frame.tf_cs) == SEL_UPL) { - trapsignal(p, SIGTRAP, 0); - } + trapsignal(p, SIGTRAP, 0); } -#endif + userret(p, &frame, sticks); #ifdef KTRACE diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index ec1e937..3696788 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.59 1995/08/21 18:06:48 davidg Exp $ + * $Id: trap.c,v 1.60 1995/10/04 07:07:44 julian Exp $ */ /* @@ -75,13 +75,15 @@ #include "isa.h" #include "npx.h" +extern void trap __P((struct trapframe frame)); +extern int trapwrite __P((unsigned addr)); +extern void syscall __P((struct trapframe frame)); +extern void linux_syscall __P((struct trapframe frame)); + int trap_pfault __P((struct trapframe *, int)); void trap_fatal __P((struct trapframe *)); extern inthand_t IDTVEC(syscall); -#ifdef COMPAT_LINUX -extern inthand_t IDTVEC(linux_syscall); -#endif #define MAX_TRAP_MSG 27 char *trap_msg[] = { @@ -115,6 +117,9 @@ char *trap_msg[] = { "stack fault", /* 27 T_STKFLT */ }; +static void userret __P((struct proc *p, struct trapframe *frame, + u_quad_t oticks)); + static inline void userret(p, frame, oticks) struct proc *p; @@ -163,14 +168,12 @@ userret(p, frame, oticks) } /* - * trap(frame): - * Exception, fault, and trap interface to the FreeBSD kernel. + * Exception, fault, and trap interface to the FreeBSD kernel. * This common code is called from assembly language IDT gate entry * routines that prepare a suitable stack frame, and restore this * frame after the exception has been processed. */ -/*ARGSUSED*/ void trap(frame) struct trapframe frame; @@ -354,27 +357,37 @@ trap(frame) } break; -#ifdef DDB + case T_TRCTRAP: /* trace trap */ + if (frame.tf_eip == (int)IDTVEC(syscall)) { + /* + * We've just entered system mode via the + * syscall lcall. Continue single stepping + * silently until the syscall handler has + * saved the flags. + */ + return; + } + if (frame.tf_eip == (int)IDTVEC(syscall) + 1) { + /* + * The syscall handler has now saved the + * flags. Stop single stepping it. + */ + frame.tf_eflags &= ~PSL_T; + return; + } + /* + * Fall through. + */ case T_BPTFLT: -#ifndef DDB_NO_LCALLS - case T_TRCTRAP: -#endif + /* + * If DDB is enabled, let it handle the debugger trap. + * Otherwise, debugger traps "can't happen". + */ +#ifdef DDB if (kdb_trap (type, 0, &frame)) return; - break; -#endif -#if !defined (DDB) || defined (DDB_NO_LCALLS) - case T_TRCTRAP: /* trace trap -- someone single stepping lcall's */ - /* Q: how do we turn it on again? */ -#ifdef COMPAT_LINUX - if (frame.tf_eip != (int) IDTVEC(syscall) && - frame.tf_eip != (int) IDTVEC(linux_syscall)) -#else - if (frame.tf_eip != IDTVEC(syscall)) -#endif - frame.tf_eflags &= ~PSL_T; - return; #endif + break; #if NISA > 0 case T_NMI: @@ -798,11 +811,9 @@ int trapwrite(addr) } /* - * syscall(frame): - * System call request from POSIX system call gate interface to kernel. + * System call request from POSIX system call gate interface to kernel. * Like trap(), argument is call by reference. */ -/*ARGSUSED*/ void syscall(frame) struct trapframe frame; @@ -876,7 +887,7 @@ syscall(frame) p = curproc; frame.tf_eax = rval[0]; frame.tf_edx = rval[1]; - frame.tf_eflags &= ~PSL_C; /* carry bit */ + frame.tf_eflags &= ~PSL_C; break; case ERESTART: @@ -897,19 +908,16 @@ bad: else error = p->p_sysent->sv_errtbl[error]; frame.tf_eax = error; - frame.tf_eflags |= PSL_C; /* carry bit */ + frame.tf_eflags |= PSL_C; break; } -#if 1 if (frame.tf_eflags & PSL_T) { - /* traced syscall, raise sig */ + /* Traced syscall. */ frame.tf_eflags &= ~PSL_T; - if (ISPL(frame.tf_cs) == SEL_UPL) { - trapsignal(p, SIGTRAP, 0); - } + trapsignal(p, SIGTRAP, 0); } -#endif + userret(p, &frame, sticks); #ifdef KTRACE @@ -919,10 +927,6 @@ bad: } #ifdef COMPAT_LINUX -/* - * linux_syscall(frame): - */ -/*ARGSUSED*/ void linux_syscall(frame) struct trapframe frame; @@ -981,7 +985,7 @@ linux_syscall(frame) */ p = curproc; frame.tf_eax = rval[0]; - frame.tf_eflags &= ~PSL_C; /* carry bit */ + frame.tf_eflags &= ~PSL_C; break; case ERESTART: @@ -999,19 +1003,16 @@ linux_syscall(frame) else error = p->p_sysent->sv_errtbl[error]; frame.tf_eax = -error; - frame.tf_eflags |= PSL_C; /* carry bit */ + frame.tf_eflags |= PSL_C; break; } -#if 1 if (frame.tf_eflags & PSL_T) { - /* traced syscall, raise sig */ + /* Traced syscall. */ frame.tf_eflags &= ~PSL_T; - if (ISPL(frame.tf_cs) == SEL_UPL) { - trapsignal(p, SIGTRAP, 0); - } + trapsignal(p, SIGTRAP, 0); } -#endif + userret(p, &frame, sticks); #ifdef KTRACE |