From 00c6cadad3396d723b9a89413a466d7e6dfbcf5e Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Wed, 4 Oct 1995 07:08:04 +0000 Subject: [PATCH] Submitted by: Juergen Lock Obtained from: other people on the net ? 1. stepping over syscalls (gdb ni) sends you to DDB, and returned to the wrong address afterwards, with or without DDB. patch in i386/i386/trap.c below. 2. the linux emulator (modload'ed) still causes panics with DIAGNOSTIC, re-applied a patch posted to one of the lists... --- sys/amd64/amd64/trap.c | 38 ++++++++++++++++++++++++++++++++--- sys/compat/linux/linux_misc.c | 36 +++++++++++++++++++++++---------- sys/i386/i386/trap.c | 38 ++++++++++++++++++++++++++++++++--- sys/i386/linux/linux_misc.c | 36 +++++++++++++++++++++++---------- sys/kern/subr_trap.c | 38 ++++++++++++++++++++++++++++++++--- 5 files changed, 155 insertions(+), 31 deletions(-) diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 37d8e2e26d2c..ec1e9378e8ba 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.58 1995/07/30 17:49:24 davidg Exp $ + * $Id: trap.c,v 1.59 1995/08/21 18:06:48 davidg Exp $ */ /* @@ -78,6 +78,11 @@ 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[] = { "", /* 0 unused */ @@ -351,14 +356,23 @@ trap(frame) #ifdef DDB case T_BPTFLT: +#ifndef DDB_NO_LCALLS case T_TRCTRAP: +#endif if (kdb_trap (type, 0, &frame)) return; break; -#else +#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? */ - frame.tf_eflags &= ~PSL_T; +#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 @@ -887,6 +901,15 @@ syscall(frame) break; } +#if 1 + if (frame.tf_eflags & PSL_T) { + /* traced syscall, raise sig */ + frame.tf_eflags &= ~PSL_T; + if (ISPL(frame.tf_cs) == SEL_UPL) { + trapsignal(p, SIGTRAP, 0); + } + } +#endif userret(p, &frame, sticks); #ifdef KTRACE @@ -980,6 +1003,15 @@ linux_syscall(frame) break; } +#if 1 + if (frame.tf_eflags & PSL_T) { + /* traced syscall, raise sig */ + frame.tf_eflags &= ~PSL_T; + if (ISPL(frame.tf_cs) == SEL_UPL) { + trapsignal(p, SIGTRAP, 0); + } + } +#endif userret(p, &frame, sticks); #ifdef KTRACE diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index bf40786e28a8..a9f7e0b594fd 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_misc.c,v 1.4 1995/06/08 13:50:52 sos Exp $ + * $Id: linux_misc.c,v 1.1 1995/06/25 17:32:37 sos Exp $ */ #include @@ -188,7 +188,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path); #endif - NDINIT(&ni, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p); + NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); if (error = namei(&ni)) return error; @@ -196,25 +196,39 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) if (vnodep == NULL) return ENOEXEC; - if (vnodep->v_writecount) + if (vnodep->v_writecount) { + VOP_UNLOCK(vnodep); return ETXTBSY; + } - if (error = VOP_GETATTR(vnodep, &attr, p->p_ucred, p)) - return error; + if (error = VOP_GETATTR(vnodep, &attr, p->p_ucred, p)) { + VOP_UNLOCK(vnodep); + return error; + } if ((vnodep->v_mount->mnt_flag & MNT_NOEXEC) || ((attr.va_mode & 0111) == 0) - || (attr.va_type != VREG)) + || (attr.va_type != VREG)) { + VOP_UNLOCK(vnodep); return ENOEXEC; + } - if (attr.va_size == 0) + if (attr.va_size == 0) { + VOP_UNLOCK(vnodep); return ENOEXEC; + } - if (error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p)) + if (error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p)) { + VOP_UNLOCK(vnodep); return error; + } - if (error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p)) + if (error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p)) { + VOP_UNLOCK(vnodep); return error; + } + + VOP_UNLOCK(vnodep); /* lock no longer needed */ error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, 1024, VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vnodep, 0); @@ -225,7 +239,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) * Is it a Linux binary ? */ if (((a_out->a_magic >> 16) & 0xff) != 0x64) - return -1; + return ENOEXEC; /* * Set file/virtual offset based on a.out variant. @@ -240,7 +254,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) file_offset = 0; break; default: - return (-1); + return ENOEXEC; } vnodep->v_flag |= VTEXT; diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 37d8e2e26d2c..ec1e9378e8ba 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.58 1995/07/30 17:49:24 davidg Exp $ + * $Id: trap.c,v 1.59 1995/08/21 18:06:48 davidg Exp $ */ /* @@ -78,6 +78,11 @@ 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[] = { "", /* 0 unused */ @@ -351,14 +356,23 @@ trap(frame) #ifdef DDB case T_BPTFLT: +#ifndef DDB_NO_LCALLS case T_TRCTRAP: +#endif if (kdb_trap (type, 0, &frame)) return; break; -#else +#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? */ - frame.tf_eflags &= ~PSL_T; +#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 @@ -887,6 +901,15 @@ syscall(frame) break; } +#if 1 + if (frame.tf_eflags & PSL_T) { + /* traced syscall, raise sig */ + frame.tf_eflags &= ~PSL_T; + if (ISPL(frame.tf_cs) == SEL_UPL) { + trapsignal(p, SIGTRAP, 0); + } + } +#endif userret(p, &frame, sticks); #ifdef KTRACE @@ -980,6 +1003,15 @@ linux_syscall(frame) break; } +#if 1 + if (frame.tf_eflags & PSL_T) { + /* traced syscall, raise sig */ + frame.tf_eflags &= ~PSL_T; + if (ISPL(frame.tf_cs) == SEL_UPL) { + trapsignal(p, SIGTRAP, 0); + } + } +#endif userret(p, &frame, sticks); #ifdef KTRACE diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c index bf40786e28a8..a9f7e0b594fd 100644 --- a/sys/i386/linux/linux_misc.c +++ b/sys/i386/linux/linux_misc.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_misc.c,v 1.4 1995/06/08 13:50:52 sos Exp $ + * $Id: linux_misc.c,v 1.1 1995/06/25 17:32:37 sos Exp $ */ #include @@ -188,7 +188,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path); #endif - NDINIT(&ni, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p); + NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); if (error = namei(&ni)) return error; @@ -196,25 +196,39 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) if (vnodep == NULL) return ENOEXEC; - if (vnodep->v_writecount) + if (vnodep->v_writecount) { + VOP_UNLOCK(vnodep); return ETXTBSY; + } - if (error = VOP_GETATTR(vnodep, &attr, p->p_ucred, p)) - return error; + if (error = VOP_GETATTR(vnodep, &attr, p->p_ucred, p)) { + VOP_UNLOCK(vnodep); + return error; + } if ((vnodep->v_mount->mnt_flag & MNT_NOEXEC) || ((attr.va_mode & 0111) == 0) - || (attr.va_type != VREG)) + || (attr.va_type != VREG)) { + VOP_UNLOCK(vnodep); return ENOEXEC; + } - if (attr.va_size == 0) + if (attr.va_size == 0) { + VOP_UNLOCK(vnodep); return ENOEXEC; + } - if (error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p)) + if (error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p)) { + VOP_UNLOCK(vnodep); return error; + } - if (error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p)) + if (error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p)) { + VOP_UNLOCK(vnodep); return error; + } + + VOP_UNLOCK(vnodep); /* lock no longer needed */ error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, 1024, VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vnodep, 0); @@ -225,7 +239,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) * Is it a Linux binary ? */ if (((a_out->a_magic >> 16) & 0xff) != 0x64) - return -1; + return ENOEXEC; /* * Set file/virtual offset based on a.out variant. @@ -240,7 +254,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) file_offset = 0; break; default: - return (-1); + return ENOEXEC; } vnodep->v_flag |= VTEXT; diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 37d8e2e26d2c..ec1e9378e8ba 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.58 1995/07/30 17:49:24 davidg Exp $ + * $Id: trap.c,v 1.59 1995/08/21 18:06:48 davidg Exp $ */ /* @@ -78,6 +78,11 @@ 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[] = { "", /* 0 unused */ @@ -351,14 +356,23 @@ trap(frame) #ifdef DDB case T_BPTFLT: +#ifndef DDB_NO_LCALLS case T_TRCTRAP: +#endif if (kdb_trap (type, 0, &frame)) return; break; -#else +#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? */ - frame.tf_eflags &= ~PSL_T; +#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 @@ -887,6 +901,15 @@ syscall(frame) break; } +#if 1 + if (frame.tf_eflags & PSL_T) { + /* traced syscall, raise sig */ + frame.tf_eflags &= ~PSL_T; + if (ISPL(frame.tf_cs) == SEL_UPL) { + trapsignal(p, SIGTRAP, 0); + } + } +#endif userret(p, &frame, sticks); #ifdef KTRACE @@ -980,6 +1003,15 @@ linux_syscall(frame) break; } +#if 1 + if (frame.tf_eflags & PSL_T) { + /* traced syscall, raise sig */ + frame.tf_eflags &= ~PSL_T; + if (ISPL(frame.tf_cs) == SEL_UPL) { + trapsignal(p, SIGTRAP, 0); + } + } +#endif userret(p, &frame, sticks); #ifdef KTRACE