$NetBSD: patch-aa,v 1.3 2005/12/09 10:56:47 joerg Exp $ --- lrmi.c.orig 2003-05-14 03:18:12.000000000 +0000 +++ lrmi.c @@ -23,7 +23,7 @@ ARISING FROM, OUT OF OR IN CONNECTION WI OTHER DEALINGS IN THE SOFTWARE. */ -#if (defined(__linux__) || defined(__NetBSD__) || defined(__FreeBSD__)) && \ +#if (defined(__linux__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)) && \ defined(__i386__) #include @@ -37,7 +37,7 @@ OTHER DEALINGS IN THE SOFTWARE. #include #endif -#elif defined(__NetBSD__) || defined(__FreeBSD__) +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) #include #include @@ -203,7 +203,7 @@ LRMI_free_real(void *m) #if defined(__linux__) #define DEFAULT_VM86_FLAGS (IF_MASK | IOPL_MASK) -#elif defined(__NetBSD__) || defined(__FreeBSD__) +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) #define DEFAULT_VM86_FLAGS (PSL_I | PSL_IOPL) #define TF_MASK PSL_T #define VIF_MASK PSL_VIF @@ -211,13 +211,27 @@ LRMI_free_real(void *m) #define DEFAULT_STACK_SIZE 0x1000 #define RETURN_TO_32_INT 255 +#if defined(__NetBSD__) && defined(SA_SIGINFO) +struct gregset_overlay { + int gs, fs, es, ds; + int edi, esi, ebp, esp, ebx, edx, ecx, eax; + int _trapno, _err; + int eip, cs, eflags, uesp, ss; +}; +#endif + #if defined(__linux__) #define CONTEXT_REGS context.vm.regs #define REG(x) x #elif defined(__NetBSD__) +#if defined(SA_SIGINFO) +#define CONTEXT_REGS (*(struct gregset_overlay *)&context.vm.substr.regs) +#define REG(x) x +#else #define CONTEXT_REGS context.vm.substr.regs #define REG(x) vmsc.sc_ ## x -#elif defined(__FreeBSD__) +#endif /* SA_SIGINFO */ +#elif defined(__FreeBSD__) || defined(__DragonFly__) #define CONTEXT_REGS context.vm.uc #define REG(x) uc_mcontext.mc_ ## x #endif @@ -228,16 +242,17 @@ static struct { unsigned short stack_seg, stack_off; #if defined(__linux__) || defined(__NetBSD__) struct vm86_struct vm; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__DragonFly__) struct { struct vm86_init_args init; ucontext_t uc; } vm; #endif -#if defined(__NetBSD__) || defined(__FreeBSD__) +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) int success; jmp_buf env; - void *old_sighandler; + struct sigaction old_sighandler; + int sh_installed; int vret; #endif } context = { 0 }; @@ -354,7 +369,7 @@ LRMI_init(void) set_bit(RETURN_TO_32_INT, &context.vm.int_revectored); #elif defined(__NetBSD__) set_bit(RETURN_TO_32_INT, &context.vm.int_byuser); -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__DragonFly__) set_bit(RETURN_TO_32_INT, &context.vm.init.int_map); #endif @@ -805,13 +820,25 @@ run_vm86(void) return 0; } -#elif defined(__NetBSD__) || defined(__FreeBSD__) +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) #if defined(__NetBSD__) static void -vm86_callback(int sig, int code, struct sigcontext *sc) +vm86_callback(int sig, +#if defined(SA_SIGINFO) + siginfo_t *info, void *vctx +#else + int code, struct sigcontext *sc +#endif + ) { /* Sync our context with what the kernel develivered to us. */ +#if defined(SA_SIGINFO) + int code = info->si_trap; + ucontext_t *ctx = vctx; + memcpy(&CONTEXT_REGS, &ctx->uc_mcontext.__gregs, sizeof(CONTEXT_REGS)); +#else memcpy(&CONTEXT_REGS, sc, sizeof(*sc)); +#endif switch (VM86_TYPE(code)) { case VM86_INTx: @@ -850,9 +877,13 @@ vm86_callback(int sig, int code, struct } /* ...and sync our context back to the kernel. */ +#if defined(SA_SIGINFO) + memcpy(&ctx->uc_mcontext.__gregs, &CONTEXT_REGS, sizeof(CONTEXT_REGS)); +#else memcpy(sc, &CONTEXT_REGS, sizeof(*sc)); +#endif } -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__DragonFly__) static void vm86_callback(int sig, int code, struct sigcontext *sc) { @@ -899,34 +930,44 @@ vm86_callback(int sig, int code, struct static int run_vm86(void) { - if (context.old_sighandler) { + struct sigaction sa; + int res; + + if (context.sh_installed) { #ifdef LRMI_DEBUG fprintf(stderr, "run_vm86: callback already installed\n"); #endif return (0); } + memset(&sa, 0, sizeof(sa)); +#if defined(__NetBSD__) && defined(SA_SIGINFO) + sa.sa_sigaction = vm86_callback; + sa.sa_flags = SA_SIGINFO; +#else + sa.sa_handler = (void (*)(int))vm86_callback; +#endif #if defined(__NetBSD__) - context.old_sighandler = signal(SIGURG, (void (*)(int))vm86_callback); -#elif defined(__FreeBSD__) - context.old_sighandler = signal(SIGBUS, (void (*)(int))vm86_callback); + res = sigaction(SIGURG, &sa, &context.old_sighandler); +#elif defined(__FreeBSD__) || defined(__DragonFly__) + res = sigaction(SIGBUS, &sa, &context.old_sighandler); #endif - if (context.old_sighandler == (void *)-1) { - context.old_sighandler = NULL; + if (res < 0) { #ifdef LRMI_DEBUG fprintf(stderr, "run_vm86: cannot install callback\n"); #endif return (0); } + context.sh_installed = 1; if (setjmp(context.env)) { #if defined(__NetBSD__) - (void) signal(SIGURG, context.old_sighandler); -#elif defined(__FreeBSD__) - (void) signal(SIGBUS, context.old_sighandler); + sigaction(SIGURG, &context.old_sighandler, 0); +#elif defined(__FreeBSD__) || defined(__DragonFly__) + sigaction(SIGBUS, &context.old_sighandler, 0); #endif - context.old_sighandler = NULL; + context.sh_installed = 0; if (context.success) return (1); @@ -937,7 +978,7 @@ run_vm86(void) #if defined(__NetBSD__) if (i386_vm86(&context.vm) == -1) return (0); -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__DragonFly__) if (i386_vm86(VM86_INIT, &context.vm.init)) return 0;