diff --git a/src/arch/i386/image/com32.c b/src/arch/i386/image/com32.c index 00f75263..d1b9a59f 100644 --- a/src/arch/i386/image/com32.c +++ b/src/arch/i386/image/com32.c @@ -52,7 +52,7 @@ static int com32_exec ( struct image *image ) { int state; uint32_t avail_mem_top; - state = setjmp ( comboot_return ); + state = rmsetjmp ( comboot_return ); switch ( state ) { case 0: /* First time through; invoke COM32 program */ diff --git a/src/arch/i386/image/comboot.c b/src/arch/i386/image/comboot.c index d9b16c57..40e32185 100644 --- a/src/arch/i386/image/comboot.c +++ b/src/arch/i386/image/comboot.c @@ -133,7 +133,7 @@ static int comboot_exec ( struct image *image ) { userptr_t seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 ); int state; - state = setjmp ( comboot_return ); + state = rmsetjmp ( comboot_return ); switch ( state ) { case 0: /* First time through; invoke COMBOOT program */ diff --git a/src/arch/i386/include/comboot.h b/src/arch/i386/include/comboot.h index 6b8ea6b6..b5b1f8a0 100644 --- a/src/arch/i386/include/comboot.h +++ b/src/arch/i386/include/comboot.h @@ -78,7 +78,7 @@ extern void com32_cfarcall_wrapper ( ); extern int comboot_resolv ( const char *name, struct in_addr *address ); /* setjmp/longjmp context buffer used to return after loading an image */ -extern jmp_buf comboot_return; +extern rmjmp_buf comboot_return; /* Replacement image when exiting with COMBOOT_EXIT_RUN_KERNEL */ extern struct image *comboot_replacement_image; diff --git a/src/arch/i386/include/setjmp.h b/src/arch/i386/include/setjmp.h index 60e4b120..c18d03e1 100644 --- a/src/arch/i386/include/setjmp.h +++ b/src/arch/i386/include/setjmp.h @@ -1,12 +1,38 @@ #ifndef ETHERBOOT_SETJMP_H #define ETHERBOOT_SETJMP_H +#include +#include -/* Define a type for use by setjmp and longjmp */ -#define JBLEN 6 -typedef unsigned long jmp_buf[JBLEN]; +/** A jump buffer */ +typedef struct { + uint32_t retaddr; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; +} jmp_buf[1]; -extern int __asmcall setjmp (jmp_buf env); -extern void __asmcall longjmp (jmp_buf env, int val); +/** A real-mode-extended jump buffer */ +typedef struct { + jmp_buf env; + uint16_t rm_ss; + uint16_t rm_sp; +} rmjmp_buf[1]; + +extern int __asmcall setjmp ( jmp_buf env ); +extern void __asmcall longjmp ( jmp_buf env, int val ); + +#define rmsetjmp( _env ) ( { \ + (_env)->rm_ss = rm_ss; \ + (_env)->rm_sp = rm_sp; \ + setjmp ( (_env)->env ); } ) \ + +#define rmlongjmp( _env, _val ) do { \ + rm_ss = (_env)->rm_ss; \ + rm_sp = (_env)->rm_sp; \ + longjmp ( (_env)->env, (_val) ); \ + } while ( 0 ) #endif /* ETHERBOOT_SETJMP_H */ diff --git a/src/arch/i386/interface/syslinux/comboot_call.c b/src/arch/i386/interface/syslinux/comboot_call.c index c641c840..290d94ac 100644 --- a/src/arch/i386/interface/syslinux/comboot_call.c +++ b/src/arch/i386/interface/syslinux/comboot_call.c @@ -67,7 +67,7 @@ extern void int21_wrapper ( void ); extern void int22_wrapper ( void ); /* setjmp/longjmp context buffer used to return after loading an image */ -jmp_buf comboot_return; +rmjmp_buf comboot_return; /* Replacement image when exiting with COMBOOT_EXIT_RUN_KERNEL */ struct image *comboot_replacement_image; @@ -235,7 +235,7 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) { * Terminate program interrupt handler */ static __asmcall void int20 ( struct i386_all_regs *ix86 __unused ) { - longjmp ( comboot_return, COMBOOT_EXIT ); + rmlongjmp ( comboot_return, COMBOOT_EXIT ); } @@ -248,7 +248,7 @@ static __asmcall void int21 ( struct i386_all_regs *ix86 ) { switch ( ix86->regs.ah ) { case 0x00: case 0x4C: /* Terminate program */ - longjmp ( comboot_return, COMBOOT_EXIT ); + rmlongjmp ( comboot_return, COMBOOT_EXIT ); break; case 0x01: /* Get Key with Echo */ @@ -347,13 +347,13 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) { DBG ( "COMBOOT: executing command '%s'\n", cmd ); system ( cmd ); DBG ( "COMBOOT: exiting after executing command...\n" ); - longjmp ( comboot_return, COMBOOT_EXIT_COMMAND ); + rmlongjmp ( comboot_return, COMBOOT_EXIT_COMMAND ); } break; case 0x0004: /* Run default command */ /* FIXME: just exit for now */ - longjmp ( comboot_return, COMBOOT_EXIT_COMMAND ); + rmlongjmp ( comboot_return, COMBOOT_EXIT_COMMAND ); break; case 0x0005: /* Force text mode */ @@ -552,7 +552,7 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) { * part of the COMBOOT program's memory space. */ DBG ( "COMBOOT: exiting to run kernel...\n" ); - longjmp ( comboot_return, COMBOOT_EXIT_RUN_KERNEL ); + rmlongjmp ( comboot_return, COMBOOT_EXIT_RUN_KERNEL ); } break;