summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgrog <grog@FreeBSD.org>1999-03-28 08:54:03 +0000
committergrog <grog@FreeBSD.org>1999-03-28 08:54:03 +0000
commit6457f5694b7bd92936437c7ba6736333f0ad38dd (patch)
tree7a1996ef2ddd8987a876c09703e2840cd5a629b8 /sys
parent1df24b0ec01dc81c9f600594f0e1470572b81fde (diff)
downloadFreeBSD-src-6457f5694b7bd92936437c7ba6736333f0ad38dd.zip
FreeBSD-src-6457f5694b7bd92936437c7ba6736333f0ad38dd.tar.gz
Add function LongJmp which checks the parameters before calling
longjmp. I suspect that the occasional double panic may be the result of incorrect parameters to longjmp. This happens, of course, like the entire file, only with -DVINUMDEBUG.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/vinum/vinummemory.c55
1 files changed, 48 insertions, 7 deletions
diff --git a/sys/dev/vinum/vinummemory.c b/sys/dev/vinum/vinummemory.c
index 7dd5c96..4b62908 100644
--- a/sys/dev/vinum/vinummemory.c
+++ b/sys/dev/vinum/vinummemory.c
@@ -33,24 +33,65 @@
* otherwise) arising in any way out of the use of this software, even if
* advised of the possibility of such damage.
*
- * $Id: vinummemory.c,v 1.19 1998/12/30 06:22:26 grog Exp grog $
+ * $Id: vinummemory.c,v 1.20 1999/03/19 03:21:08 grog Exp grog $
*/
#define REALLYKERNEL
#include "opt_vinum.h"
#include <dev/vinum/vinumhdr.h>
-extern jmp_buf command_fail; /* return on a failed command */
-
#ifdef VINUMDEBUG
+jmp_buf command_fail; /* return on a failed command */
+#undef longjmp /* this was defined as LongJmp */
+void longjmp(jmp_buf, int); /* the kernel doesn't define this */
+
#include <dev/vinum/request.h>
extern struct rqinfo rqinfo[];
extern struct rqinfo *rqip;
-#endif
-/* Why aren't these declared anywhere? XXX */
-int setjmp(jmp_buf);
-void longjmp(jmp_buf, int);
+#ifdef __i386__ /* check for validity */
+void
+LongJmp(jmp_buf buf, int retval)
+{
+/*
+ * longjmp is not documented, not even jmp_buf.
+ * This is what's in i386/i386/support.s:
+ * ENTRY(longjmp)
+ * movl 4(%esp),%eax
+ * movl (%eax),%ebx restore ebx
+ * movl 4(%eax),%esp restore esp
+ * movl 8(%eax),%ebp restore ebp
+ * movl 12(%eax),%esi restore esi
+ * movl 16(%eax),%edi restore edi
+ * movl 20(%eax),%edx get rta
+ * movl %edx,(%esp) put in return frame
+ * xorl %eax,%eax return(1);
+ * incl %eax
+ * ret
+ *
+ * from which we deduce the structure of jmp_buf:
+ */
+ struct JmpBuf {
+ int jb_ebx;
+ int jb_esp;
+ int jb_ebp;
+ int jb_esi;
+ int jb_edi;
+ int jb_eip;
+ };
+
+ struct JmpBuf *jb = (struct JmpBuf *) buf;
+
+ if ((jb->jb_esp < 0xd0000000)
+ || (jb->jb_ebp < 0xd0000000)
+ || (jb->jb_eip < 0xe0000000))
+ panic("Invalid longjmp");
+ longjmp(buf, retval);
+}
+#else
+#define LongJmp longjmp /* just use the kernel function */
+#endif
+#endif
void
expand_table(void **table, int oldsize, int newsize)
OpenPOWER on IntegriCloud