Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/arm Check alignment of the fault PC before de-r...
details: https://anonhg.NetBSD.org/src/rev/995616bda32a
branches: trunk
changeset: 555334:995616bda32a
user: scw <scw%NetBSD.org@localhost>
date: Fri Nov 14 19:03:17 2003 +0000
description:
Check alignment of the fault PC before de-referencing it.
Give the process a Illegal Instruction fault if the PC is misaligned.
diffstat:
sys/arch/arm/arm/syscall.c | 27 +++++++++++++++++++++++++--
sys/arch/arm/arm/undefined.c | 32 ++++++++++++++++++++++++--------
2 files changed, 49 insertions(+), 10 deletions(-)
diffs (121 lines):
diff -r 2603d0b24196 -r 995616bda32a sys/arch/arm/arm/syscall.c
--- a/sys/arch/arm/arm/syscall.c Fri Nov 14 19:00:03 2003 +0000
+++ b/sys/arch/arm/arm/syscall.c Fri Nov 14 19:03:17 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: syscall.c,v 1.23 2003/10/31 03:28:12 simonb Exp $ */
+/* $NetBSD: syscall.c,v 1.24 2003/11/14 19:03:17 scw Exp $ */
/*-
* Copyright (c) 2000, 2003 The NetBSD Foundation, Inc.
@@ -82,7 +82,7 @@
#include <sys/param.h>
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.23 2003/10/31 03:28:12 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.24 2003/11/14 19:03:17 scw Exp $");
#include <sys/device.h>
#include <sys/errno.h>
@@ -134,6 +134,29 @@
frame->tf_pc += INSN_SIZE;
#endif
+ /*
+ * Make sure the program counter is correctly aligned so we
+ * don't take an alignment fault trying to read the opcode.
+ */
+ if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
+ ksiginfo_t ksi;
+ /* Give the user an illegal instruction signal. */
+ KSI_INIT_TRAP(&ksi);
+ ksi.ksi_signo = SIGILL;
+ ksi.ksi_code = ILL_ILLOPC;
+ ksi.ksi_addr = (u_int32_t *)(intptr_t) (frame->tf_pc-INSN_SIZE);
+ KERNEL_PROC_LOCK(l->l_proc);
+#if 0
+ /* maybe one day we'll do emulations */
+ (*l->l_proc->p_emul->e_trapsignal)(l, &ksi);
+#else
+ trapsignal(l, &ksi);
+#endif
+ KERNEL_PROC_UNLOCK(l->l_proc);
+ userret(l);
+ return;
+ }
+
/* XXX fuword? */
#ifdef __PROG32
insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE);
diff -r 2603d0b24196 -r 995616bda32a sys/arch/arm/arm/undefined.c
--- a/sys/arch/arm/arm/undefined.c Fri Nov 14 19:00:03 2003 +0000
+++ b/sys/arch/arm/arm/undefined.c Fri Nov 14 19:03:17 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: undefined.c,v 1.20 2003/10/31 16:44:35 cl Exp $ */
+/* $NetBSD: undefined.c,v 1.21 2003/11/14 19:03:17 scw Exp $ */
/*
* Copyright (c) 2001 Ben Harris.
@@ -54,7 +54,7 @@
#include <sys/kgdb.h>
#endif
-__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.20 2003/10/31 16:44:35 cl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.21 2003/11/14 19:03:17 scw Exp $");
#include <sys/malloc.h>
#include <sys/queue.h>
@@ -171,7 +171,6 @@
void
undefinedinstruction(trapframe_t *frame)
{
- struct proc *p;
struct lwp *l;
u_int fault_pc;
int fault_instruction;
@@ -201,6 +200,27 @@
fault_pc = frame->tf_pc;
#endif
+ /* Get the current lwp/proc structure or lwp0/proc0 if there is none. */
+ l = curlwp == NULL ? &lwp0 : curlwp;
+
+ /*
+ * Make sure the program counter is correctly aligned so we
+ * don't take an alignment fault trying to read the opcode.
+ */
+ if (__predict_false((fault_pc & 3) != 0)) {
+ ksiginfo_t ksi;
+ /* Give the user an illegal instruction signal. */
+ KSI_INIT_TRAP(&ksi);
+ ksi.ksi_signo = SIGILL;
+ ksi.ksi_code = ILL_ILLOPC;
+ ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc;
+ KERNEL_PROC_LOCK(l);
+ trapsignal(l, &ksi);
+ KERNEL_PROC_UNLOCK(l);
+ userret(l);
+ return;
+ }
+
/*
* Should use fuword() here .. but in the interests of squeezing every
* bit of speed we will just use ReadWord(). We know the instruction
@@ -228,10 +248,6 @@
else
coprocessor = 0;
- /* Get the current lwp/proc structure or lwp0/proc0 if there is none. */
- l = curlwp == NULL ? &lwp0 : curlwp;
- p = l->l_proc;
-
#ifdef __PROG26
if ((frame->tf_r15 & R15_MODE) == R15_MODE_USR) {
#else
@@ -321,6 +337,6 @@
}
#else
- userret(p);
+ userret(l);
#endif
}
Home |
Main Index |
Thread Index |
Old Index