mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
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.
This commit is contained in:
parent
4ab32c3430
commit
029b0fc88f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=11343
@ -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;
|
||||
#endif
|
||||
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
|
||||
|
||||
#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 @@ 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
|
||||
@ -919,10 +927,6 @@ syscall(frame)
|
||||
}
|
||||
|
||||
#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
|
||||
|
@ -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;
|
||||
#endif
|
||||
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
|
||||
|
||||
#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 @@ 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
|
||||
@ -919,10 +927,6 @@ syscall(frame)
|
||||
}
|
||||
|
||||
#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
|
||||
|
@ -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;
|
||||
#endif
|
||||
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
|
||||
|
||||
#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 @@ 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
|
||||
@ -919,10 +927,6 @@ syscall(frame)
|
||||
}
|
||||
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user