diff options
author | grog <grog@FreeBSD.org> | 1999-03-28 08:54:03 +0000 |
---|---|---|
committer | grog <grog@FreeBSD.org> | 1999-03-28 08:54:03 +0000 |
commit | 6457f5694b7bd92936437c7ba6736333f0ad38dd (patch) | |
tree | 7a1996ef2ddd8987a876c09703e2840cd5a629b8 /sys | |
parent | 1df24b0ec01dc81c9f600594f0e1470572b81fde (diff) | |
download | FreeBSD-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.c | 55 |
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) |