libvx32/Linux: switch to vx32_getcontext - vx32 - Local 9vx git repository for patches.
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit d310b6b9fb6a6310f566a854538a05f269a27080
 (DIR) parent f042e1f5454c68291e03d96be8a4e2f19cbdf1b3
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Sat, 28 Jun 2008 21:37:44 -0400
       
       libvx32/Linux: switch to vx32_getcontext
       
       Diffstat:
         src/libvx32/Makefrag                |       4 ++++
         src/libvx32/emu.c                   |       4 ++--
         src/libvx32/linux-asm.S             |      51 +++++++++++++++++++++++++++++++
         src/libvx32/linux.c                 |      12 ++++--------
         src/libvx32/vx32impl.h              |       5 ++++-
       
       5 files changed, 65 insertions(+), 11 deletions(-)
       ---
 (DIR) diff --git a/src/libvx32/Makefrag b/src/libvx32/Makefrag
       @@ -8,6 +8,10 @@ ifeq ($(OS),darwin)
        VX32_RUN := $(VX32_RUN) darwin-asm.o
        endif
        
       +ifeq ($(OS),linux)
       +VX32_RUN := $(VX32_RUN) linux-asm.o
       +endif
       +
        VX32_OBJS = \
                $(addprefix libvx32/, \
                        chunk.o \
 (DIR) diff --git a/src/libvx32/emu.c b/src/libvx32/emu.c
       @@ -1801,9 +1801,9 @@ int vxproc_run(struct vxproc *vxp)
                emu->trapenv = &env;
                if(vx32_getcontext(&env)){
        #else
       -        sigjmp_buf env;
       +        mcontext_t env;
                emu->trapenv = &env;
       -        if(sigsetjmp(env, 1)){
       +        if(vx32_getcontext(&env)){
        #endif
                        if(vx32_debugxlate) vxprint("VX trap %x err %x va %08x "
                                        "veip %08x veflags %08x\n",
 (DIR) diff --git a/src/libvx32/linux-asm.S b/src/libvx32/linux-asm.S
       @@ -0,0 +1,51 @@
       +// Context routines for Linux
       +
       +// vx32_getcontext(struct mcontext_t *ss);  
       +// see /usr/include/sys/ucontext.h for layout.
       +// notice that we don't set the floating-point state.
       +// notice also that unlike the linux getcontext,
       +// we *do* copy the segment registers
       +
       +.globl vx32_getcontext
       +vx32_getcontext:
       +        movl 4(%esp), %eax
       +        
       +        movl %ecx, 40(%eax)
       +        movl $0, %ecx
       +        movw %gs, %cx
       +        movl %ecx, 0(%eax)
       +        movw %fs, %cx
       +        movl %ecx, 4(%eax)
       +        movw %es, %cx
       +        movl %ecx, 8(%eax)
       +        movw %ds, %cx
       +        movl %ecx, 12(%eax)
       +        movl %edi, 16(%eax)
       +        movl %esi, 20(%eax)
       +        movl %ebp, 24(%eax)
       +        /* 28(%eax) is esp */
       +        movl %ebx, 32(%eax)
       +        movl %edx, 36(%eax)
       +        /* 40(%eax) is ecx, saved above */
       +        movl $1, 44(%eax)        /* eax */
       +        movl $0, 48(%eax)        /* trapno */
       +        movl $0, 52(%eax)        /* err */
       +        /* 56(%eax) is eip */
       +        movw %cs, %cx
       +        movl %ecx, 60(%eax)
       +        pushfl
       +        popl 64(%eax)
       +        /* 68(%eax) is another esp */
       +        movw %ss, %cx
       +        movl %ecx, 72(%eax)
       +        
       +        movl 0(%esp), %ecx                /* %eip */
       +        movl %ecx, 56(%eax)
       +        leal 4(%esp), %ecx                /* %esp */
       +        movl %ecx, 28(%eax)
       +        movl %ecx, 68(%eax)
       +        
       +        movl 40(%eax), %ecx                /* restore %ecx */
       +        movl $0, %eax
       +        ret
       +
 (DIR) diff --git a/src/libvx32/linux.c b/src/libvx32/linux.c
       @@ -1,10 +1,12 @@
        // Code specific to x86 hosts running Linux.
        
       +#define _GNU_SOURCE
        #include <stdio.h>
        #include <string.h>
        #include <signal.h>
        #include <assert.h>
        #include <ucontext.h>
       +#include <sys/ucontext.h>
        #include <asm/ldt.h>
        
        #include "vx32.h"
       @@ -319,14 +321,8 @@ int vx32_sighandler(int signo, siginfo_t *si, void *v)
                                return 0;
                        emu->cpu.traperr = ctx->err;
                        emu->cpu.trapva = ctx->cr2;
       -
       -                /*
       -                 * Linux helpfully reset the floating point state
       -                 * before entering the signal hander, so change it back.
       -                  */
       -                if(ctx->fpstate)
       -                        fprestore(ctx->fpstate);
       -                siglongjmp(*emu->trapenv, 1);
       +                memmove(mc->gregs, emu->trapenv->gregs, 19*4);
       +                return 1;
                }
        
                // The signal handler is confused; so are we.
 (DIR) diff --git a/src/libvx32/vx32impl.h b/src/libvx32/vx32impl.h
       @@ -119,6 +119,9 @@ typedef struct vxentry {
        struct i386_thread_state;
        int vx32_getcontext(struct i386_thread_state*);
        #endif
       +#ifdef __linux__
       +int vx32_getcontext(mcontext_t*);
       +#endif
        
        // Emulation state for vx32-to-x86 translation.
        // This is the header for a variable-length structure;
       @@ -156,7 +159,7 @@ struct vxemu {
                uint32_t        saved_trap;        // trap to trigger after single-step
                int        nsinglestep;
        
       -#if defined(__FreeBSD__)
       +#if defined(__FreeBSD__) || defined(__linux__)
                mcontext_t                *trapenv;
        #elif defined(__APPLE__)
                struct i386_thread_state *trapenv;