summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64/trap.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1995-10-09 04:36:01 +0000
committerbde <bde@FreeBSD.org>1995-10-09 04:36:01 +0000
commit73cb54f1d4a5afa3c27cae749a2988da87012131 (patch)
tree519b3d1da5d3e2975958d071af28fbe4ec3433dd /sys/amd64/amd64/trap.c
parentf6872ed68c5f59797d857340755b0ab9ef61135e (diff)
downloadFreeBSD-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/amd64/amd64/trap.c')
-rw-r--r--sys/amd64/amd64/trap.c95
1 files changed, 48 insertions, 47 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
OpenPOWER on IntegriCloud