]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
JIT: moved exception handler into separate module, unify for Win32/Linux
authorFrode Solheim <frode@fs-uae.net>
Fri, 4 Sep 2015 21:03:15 +0000 (23:03 +0200)
committerFrode Solheim <frode@fs-uae.net>
Fri, 4 Sep 2015 21:03:15 +0000 (23:03 +0200)
jit/compemu.h
jit/compemu_codegen.h
jit/compemu_raw_x86.cpp
jit/compemu_support.cpp
jit/exception_handler.cpp [new file with mode: 0644]
main.cpp

index 8636de228580e798f5cdd8dd0bf85232339e2335..b70e99d0faebe2830f67cfe33d1d7f8ef68e49ee 100644 (file)
@@ -107,7 +107,6 @@ extern int check_for_cache_miss(void);
 
 
 extern uae_u32 needed_flags;
-extern cacheline cache_tags[];
 extern uae_u8* comp_pc_p;
 extern void* pushall_call_handler;
 
@@ -234,7 +233,6 @@ typedef struct {
     n_smallstatus  nat[N_REGS];
 } smallstate;
 
-extern bigstate live;
 extern int touchcnt;
 
 
@@ -325,6 +323,7 @@ DECLARE(setcc_m(IMM d, IMM cc));
 DECLARE(cmov_b_rr(RW1 d, R1 s, IMM cc));
 DECLARE(cmov_w_rr(RW2 d, R2 s, IMM cc));
 DECLARE(cmov_l_rr(RW4 d, R4 s, IMM cc));
+DECLARE(setzflg_l(RW4 r));
 DECLARE(cmov_l_rm(RW4 d, IMM s, IMM cc));
 DECLARE(bsf_l_rr(W4 d, R4 s));
 DECLARE(pop_m(IMM d));
@@ -580,3 +579,10 @@ void comp_fbcc_opp (uae_u32 opcode);
 void comp_fsave_opp (uae_u32 opcode);
 void comp_frestore_opp (uae_u32 opcode);
 void comp_fpp_opp (uae_u32 opcode, uae_u16 extra);
+
+#ifdef _WIN32
+LONG WINAPI EvalException(LPEXCEPTION_POINTERS info);
+#if defined(_MSC_VER) && !defined(NO_WIN32_EXCEPTION_HANDLER)
+#define USE_STRUCTURED_EXCEPTION_HANDLING
+#endif
+#endif
index 2f415d70f934a53db7b9cfcf580b866f25020ca5..ffd36e865ee64a478813ea81b159055bbbf14559 100644 (file)
@@ -160,7 +160,6 @@ extern void comp_fbcc_opp (uae_u32 opcode);
 extern void comp_fscc_opp (uae_u32 opcode, uae_u16 extra);
 
 extern uae_u32 needed_flags;
-extern cacheline cache_tags[];
 extern uae_u8* comp_pc_p;
 extern void* pushall_call_handler;
 
index 7e4d6f8af0228f5d9ec4709c57942b5b590a1fc4..41835f7bab55f36803f5892b70a458fdc5074ad8 100644 (file)
@@ -1670,564 +1670,15 @@ STATIC_INLINE void raw_inc_sp(int off)
        raw_add_l_ri(4,off);
 }
 
+
 /*************************************************************************
 * Handling mistaken direct memory access                                *
 *************************************************************************/
 
-
-#ifdef NATMEM_OFFSET
-#ifdef _WIN32 // %%% BRIAN KING WAS HERE %%%
-#include <winbase.h>
-#else
-#include <asm/sigcontext.h>
-#endif
-#include <signal.h>
-
-#define SIG_READ 1
-#define SIG_WRITE 2
-
-static int in_handler=0;
-static uae_u8 *veccode;
-
-#ifdef _WIN32
-
-#if defined(CPU_64_BIT)
-#define ctxPC (pContext->Rip)
-#else
-#define ctxPC (pContext->Eip)
-#endif
-
-int EvalException (LPEXCEPTION_POINTERS blah, int n_except)
-{
-       PEXCEPTION_RECORD pExceptRecord = NULL;
-       PCONTEXT          pContext = NULL;
-
-       uae_u8* i = NULL;
-       uae_u32 addr = 0;
-       int r=-1;
-       int size=4;
-       int dir=-1;
-       int len=0;
-
-       if (n_except != STATUS_ACCESS_VIOLATION || !canbang || currprefs.cachesize == 0)
-               return EXCEPTION_CONTINUE_SEARCH;
-
-       pExceptRecord = blah->ExceptionRecord;
-       pContext = blah->ContextRecord;
-
-       if (pContext)
-               i = (uae_u8 *)ctxPC;
-       if (pExceptRecord)
-               addr = (uae_u32)(pExceptRecord->ExceptionInformation[1]);
-#ifdef JIT_DEBUG
-       write_log (_T("JIT: fault address is 0x%x at 0x%x\n"),addr,i);
-#endif
-       if (!canbang || !currprefs.cachesize)
-               return EXCEPTION_CONTINUE_SEARCH;
-
-       if (in_handler)
-               write_log (_T("JIT: Argh --- Am already in a handler. Shouldn't happen!\n"));
-
-       if (canbang && i>=compiled_code && i<=current_compile_p) {
-               if (*i==0x66) {
-                       i++;
-                       size=2;
-                       len++;
-               }
-
-               switch(i[0]) {
-               case 0x8a:
-                       if ((i[1]&0xc0)==0x80) {
-                               r=(i[1]>>3)&7;
-                               dir=SIG_READ;
-                               size=1;
-                               len+=6;
-                               break;
-                       }
-                       break;
-               case 0x88:
-                       if ((i[1]&0xc0)==0x80) {
-                               r=(i[1]>>3)&7;
-                               dir=SIG_WRITE;
-                               size=1;
-                               len+=6;
-                               break;
-                       }
-                       break;
-               case 0x8b:
-                       switch(i[1]&0xc0) {
-                       case 0x80:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_READ;
-                               len+=6;
-                               break;
-                       case 0x40:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_READ;
-                               len+=3;
-                               break;
-                       case 0x00:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_READ;
-                               len+=2;
-                               break;
-                       default:
-                               break;
-                       }
-                       break;
-               case 0x89:
-                       switch(i[1]&0xc0) {
-                       case 0x80:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_WRITE;
-                               len+=6;
-                               break;
-                       case 0x40:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_WRITE;
-                               len+=3;
-                               break;
-                       case 0x00:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_WRITE;
-                               len+=2;
-                               break;
-                       }
-                       break;
-               }
-       }
-
-       if (r!=-1) {
-               void* pr=NULL;
-#ifdef JIT_DEBUG
-               write_log (_T("JIT: register was %d, direction was %d, size was %d\n"),r,dir,size);
+#ifdef UAE
+#include "exception_handler.cpp"
 #endif
 
-               switch(r) {
-#if defined(CPU_64_BIT)
-               case 0: pr=&(pContext->Rax); break;
-               case 1: pr=&(pContext->Rcx); break;
-               case 2: pr=&(pContext->Rdx); break;
-               case 3: pr=&(pContext->Rbx); break;
-               case 4: pr=(size>1)?NULL:(((uae_u8*)&(pContext->Rax))+1); break;
-               case 5: pr=(size>1)?
-                                       (void*)(&(pContext->Rbp)):
-                       (void*)(((uae_u8*)&(pContext->Rcx))+1); break;
-               case 6: pr=(size>1)?
-                                       (void*)(&(pContext->Rsi)):
-                       (void*)(((uae_u8*)&(pContext->Rdx))+1); break;
-               case 7: pr=(size>1)?
-                                       (void*)(&(pContext->Rdi)):
-                       (void*)(((uae_u8*)&(pContext->Rbx))+1); break;
-#else
-               case 0: pr=&(pContext->Eax); break;
-               case 1: pr=&(pContext->Ecx); break;
-               case 2: pr=&(pContext->Edx); break;
-               case 3: pr=&(pContext->Ebx); break;
-               case 4: pr=(size>1)?NULL:(((uae_u8*)&(pContext->Eax))+1); break;
-               case 5: pr=(size>1)?
-                                       (void*)(&(pContext->Ebp)):
-                       (void*)(((uae_u8*)&(pContext->Ecx))+1); break;
-               case 6: pr=(size>1)?
-                                       (void*)(&(pContext->Esi)):
-                       (void*)(((uae_u8*)&(pContext->Edx))+1); break;
-               case 7: pr=(size>1)?
-                                       (void*)(&(pContext->Edi)):
-                       (void*)(((uae_u8*)&(pContext->Ebx))+1); break;
-#endif
-               default: abort();
-               }
-               if (pr) {
-                       blockinfo* bi;
-
-                       if (currprefs.comp_oldsegv) {
-                               addr-=(uae_u32)NATMEM_OFFSET;
-
-#ifdef JIT_DEBUG
-                               if ((addr>=0x10000000 && addr<0x40000000) ||
-                                       (addr>=0x50000000)) {
-                                               write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
-                               }
-#endif
-                               if (dir==SIG_READ) {
-                                       switch (size) {
-                                       case 1: *((uae_u8*)pr)=get_byte (addr); break;
-                                       case 2: *((uae_u16*)pr)=swap16(get_word (addr)); break;
-                                       case 4: *((uae_u32*)pr)=swap32(get_long (addr)); break;
-                                       default: abort();
-                                       }
-                               }
-                               else { /* write */
-                                       switch (size) {
-                                       case 1: put_byte (addr,*((uae_u8*)pr)); break;
-                                       case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
-                                       case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
-                                       default: abort();
-                                       }
-                               }
-#ifdef JIT_DEBUG
-                               write_log (_T("JIT: Handled one access!\n"));
-#endif
-                               fflush(stdout);
-                               segvcount++;
-                               ctxPC+=len;
-                       }
-                       else {
-                               void* tmp=target;
-                               int i;
-                               uae_u8 vecbuf[5];
-
-                               addr-=(uae_u32)NATMEM_OFFSET;
-
-#ifdef JIT_DEBUG
-                               if ((addr>=0x10000000 && addr<0x40000000) ||
-                                       (addr>=0x50000000)) {
-                                               write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
-                               }
-#endif
-
-                               target=(uae_u8*)ctxPC;
-                               for (i=0;i<5;i++)
-                                       vecbuf[i]=target[i];
-                               emit_byte(0xe9);
-                               emit_long((uae_u32)veccode-(uae_u32)target-4);
-#ifdef JIT_DEBUG
-
-                               write_log (_T("JIT: Create jump to %p\n"),veccode);
-                               write_log (_T("JIT: Handled one access!\n"));
-#endif
-                               segvcount++;
-
-                               target=veccode;
-
-                               if (dir==SIG_READ) {
-                                       switch(size) {
-                                       case 1: raw_mov_b_ri(r,get_byte (addr)); break;
-                                       case 2: raw_mov_w_ri(r,swap16(get_word (addr))); break;
-                                       case 4: raw_mov_l_ri(r,swap32(get_long (addr))); break;
-                                       default: abort();
-                                       }
-                               }
-                               else { /* write */
-                                       switch(size) {
-                                       case 1: put_byte (addr,*((uae_u8*)pr)); break;
-                                       case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
-                                       case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
-                                       default: abort();
-                                       }
-                               }
-                               for (i=0;i<5;i++)
-                                       raw_mov_b_mi(ctxPC+i,vecbuf[i]);
-                               raw_mov_l_mi((uae_u32)&in_handler,0);
-                               emit_byte(0xe9);
-                               emit_long(ctxPC+len-(uae_u32)target-4);
-                               in_handler=1;
-                               target=(uae_u8*)tmp;
-                       }
-                       bi=active;
-                       while (bi) {
-                               if (bi->handler &&
-                                       (uae_u8*)bi->direct_handler<=i &&
-                                       (uae_u8*)bi->nexthandler>i) {
-#ifdef JIT_DEBUG
-                                               write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
-                                                       bi->handler,
-                                                       i,
-                                                       bi->nexthandler,
-                                                       bi->pc_p);
-#endif
-                                               invalidate_block(bi);
-                                               raise_in_cl_list(bi);
-                                               set_special(0);
-                                               return EXCEPTION_CONTINUE_EXECUTION;
-                               }
-                               bi=bi->next;
-                       }
-                       /* Not found in the active list. Might be a rom routine that
-                       is in the dormant list */
-                       bi=dormant;
-                       while (bi) {
-                               if (bi->handler &&
-                                       (uae_u8*)bi->direct_handler<=i &&
-                                       (uae_u8*)bi->nexthandler>i) {
-#ifdef JIT_DEBUG
-                                               write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
-                                                       bi->handler,
-                                                       i,
-                                                       bi->nexthandler,
-                                                       bi->pc_p);
-#endif
-                                               invalidate_block(bi);
-                                               raise_in_cl_list(bi);
-                                               set_special(0);
-                                               return EXCEPTION_CONTINUE_EXECUTION;
-                               }
-                               bi=bi->next;
-                       }
-#ifdef JIT_DEBUG
-                       write_log (_T("JIT: Huh? Could not find trigger!\n"));
-#endif
-                       return EXCEPTION_CONTINUE_EXECUTION;
-               }
-       }
-       write_log (_T("JIT: Can't handle access %08X!\n"), i);
-#if 0
-       if (i)
-       {
-               int j;
-
-               for (j=0;j<10;j++) {
-                       write_log (_T("JIT: instruction byte %2d is 0x%02x\n"),j,i[j]);
-               }
-       }
-       write_log (_T("Please send the above info (starting at \"fault address\") to\n")
-               _T("bmeyer@csse.monash.edu.au\n")
-               _T("This shouldn't happen ;-)\n"));
-#endif
-       return EXCEPTION_CONTINUE_SEARCH;
-}
-#else
-static void vec(int x, struct sigcontext sc)
-{
-       uae_u8* i=(uae_u8*)sc.eip;
-       uae_u32 addr=sc.cr2;
-       int r=-1;
-       int size=4;
-       int dir=-1;
-       int len=0;
-       int j;
-
-       write_log (_T("JIT: fault address is %08x at %08x\n"),sc.cr2,sc.eip);
-       if (!canbang)
-               write_log (_T("JIT: Not happy! Canbang is 0 in SIGSEGV handler!\n"));
-       if (in_handler)
-               write_log (_T("JIT: Argh --- Am already in a handler. Shouldn't happen!\n"));
-
-       if (canbang && i>=compiled_code && i<=current_compile_p) {
-               if (*i==0x66) {
-                       i++;
-                       size=2;
-                       len++;
-               }
-
-               switch(i[0]) {
-               case 0x8a:
-                       if ((i[1]&0xc0)==0x80) {
-                               r=(i[1]>>3)&7;
-                               dir=SIG_READ;
-                               size=1;
-                               len+=6;
-                               break;
-                       }
-                       break;
-               case 0x88:
-                       if ((i[1]&0xc0)==0x80) {
-                               r=(i[1]>>3)&7;
-                               dir=SIG_WRITE;
-                               size=1;
-                               len+=6;
-                               break;
-                       }
-                       break;
-
-               case 0x8b:
-                       switch(i[1]&0xc0) {
-                       case 0x80:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_READ;
-                               len+=6;
-                               break;
-                       case 0x40:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_READ;
-                               len+=3;
-                               break;
-                       case 0x00:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_READ;
-                               len+=2;
-                               break;
-                       default:
-                               break;
-                       }
-                       break;
-
-               case 0x89:
-                       switch(i[1]&0xc0) {
-                       case 0x80:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_WRITE;
-                               len+=6;
-                               break;
-                       case 0x40:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_WRITE;
-                               len+=3;
-                               break;
-                       case 0x00:
-                               r=(i[1]>>3)&7;
-                               dir=SIG_WRITE;
-                               len+=2;
-                               break;
-                       }
-                       break;
-               }
-       }
-
-       if (r!=-1) {
-               void* pr=NULL;
-               write_log (_T("JIT: register was %d, direction was %d, size was %d\n"),r,dir,size);
-
-               switch(r) {
-               case 0: pr=&(sc.eax); break;
-               case 1: pr=&(sc.ecx); break;
-               case 2: pr=&(sc.edx); break;
-               case 3: pr=&(sc.ebx); break;
-               case 4: pr=(size>1)?NULL:(((uae_u8*)&(sc.eax))+1); break;
-               case 5: pr=(size>1)?
-                                       (void*)(&(sc.ebp)):
-                       (void*)(((uae_u8*)&(sc.ecx))+1); break;
-               case 6: pr=(size>1)?
-                                       (void*)(&(sc.esi)):
-                       (void*)(((uae_u8*)&(sc.edx))+1); break;
-               case 7: pr=(size>1)?
-                                       (void*)(&(sc.edi)):
-                       (void*)(((uae_u8*)&(sc.ebx))+1); break;
-               default: abort();
-               }
-               if (pr) {
-                       blockinfo* bi;
-
-                       if (currprefs.comp_oldsegv) {
-                               addr-=NATMEM_OFFSET;
-
-                               if ((addr>=0x10000000 && addr<0x40000000) ||
-                                       (addr>=0x50000000)) {
-                                               write_log (_T("JIT: Suspicious address in %x SEGV handler.\n"),addr);
-                               }
-                               if (dir==SIG_READ) {
-                                       switch(size) {
-                                       case 1: *((uae_u8*)pr)=get_byte (addr); break;
-                                       case 2: *((uae_u16*)pr)=get_word (addr); break;
-                                       case 4: *((uae_u32*)pr)=get_long (addr); break;
-                                       default: abort();
-                                       }
-                               }
-                               else { /* write */
-                                       switch(size) {
-                                       case 1: put_byte (addr,*((uae_u8*)pr)); break;
-                                       case 2: put_word (addr,*((uae_u16*)pr)); break;
-                                       case 4: put_long (addr,*((uae_u32*)pr)); break;
-                                       default: abort();
-                                       }
-                               }
-                               write_log (_T("JIT: Handled one access!\n"));
-                               fflush(stdout);
-                               segvcount++;
-                               sc.eip+=len;
-                       }
-                       else {
-                               void* tmp=target;
-                               int i;
-                               uae_u8 vecbuf[5];
-
-                               addr-=NATMEM_OFFSET;
-
-                               if ((addr>=0x10000000 && addr<0x40000000) ||
-                                       (addr>=0x50000000)) {
-                                               write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
-                               }
-
-                               target=(uae_u8*)sc.eip;
-                               for (i=0;i<5;i++)
-                                       vecbuf[i]=target[i];
-                               emit_byte(0xe9);
-                               emit_long((uae_u32)veccode-(uae_u32)target-4);
-                               write_log (_T("JIT: Create jump to %p\n"),veccode);
-
-                               write_log (_T("JIT: Handled one access!\n"));
-                               segvcount++;
-
-                               target=veccode;
-
-                               if (dir==SIG_READ) {
-                                       switch(size) {
-                                       case 1: raw_mov_b_ri(r,get_byte (addr)); break;
-                                       case 2: raw_mov_w_ri(r,get_word (addr)); break;
-                                       case 4: raw_mov_l_ri(r,get_long (addr)); break;
-                                       default: abort();
-                                       }
-                               }
-                               else { /* write */
-                                       switch(size) {
-                                       case 1: put_byte (addr,*((uae_u8*)pr)); break;
-                                       case 2: put_word (addr,*((uae_u16*)pr)); break;
-                                       case 4: put_long (addr,*((uae_u32*)pr)); break;
-                                       default: abort();
-                                       }
-                               }
-                               for (i=0;i<5;i++)
-                                       raw_mov_b_mi(sc.eip+i,vecbuf[i]);
-                               raw_mov_l_mi((uae_u32)&in_handler,0);
-                               emit_byte(0xe9);
-                               emit_long(sc.eip+len-(uae_u32)target-4);
-                               in_handler=1;
-                               target=tmp;
-                       }
-                       bi=active;
-                       while (bi) {
-                               if (bi->handler &&
-                                       (uae_u8*)bi->direct_handler<=i &&
-                                       (uae_u8*)bi->nexthandler>i) {
-                                               write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
-                                                       bi->handler,
-                                                       i,
-                                                       bi->nexthandler,
-                                                       bi->pc_p);
-                                               invalidate_block(bi);
-                                               raise_in_cl_list(bi);
-                                               set_special(0);
-                                               return;
-                               }
-                               bi=bi->next;
-                       }
-                       /* Not found in the active list. Might be a rom routine that
-                       is in the dormant list */
-                       bi=dormant;
-                       while (bi) {
-                               if (bi->handler &&
-                                       (uae_u8*)bi->direct_handler<=i &&
-                                       (uae_u8*)bi->nexthandler>i) {
-                                               write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
-                                                       bi->handler,
-                                                       i,
-                                                       bi->nexthandler,
-                                                       bi->pc_p);
-                                               invalidate_block(bi);
-                                               raise_in_cl_list(bi);
-                                               set_special(0);
-                                               return;
-                               }
-                               bi=bi->next;
-                       }
-                       write_log (_T("JIT: Huh? Could not find trigger!\n"));
-                       return;
-               }
-       }
-       write_log (_T("JIT: Can't handle access!\n"));
-       for (j=0;j<10;j++) {
-               write_log (_T("JIT: instruction byte %2d is %02x\n"),j,i[j]);
-       }
-#if 0
-       write_log (_T("Please send the above info (starting at \"fault address\") to\n")
-               "bmeyer@csse.monash.edu.au\n"
-               "This shouldn't happen ;-)\n");
-       fflush(stdout);
-#endif
-       signal(SIGSEGV,SIG_DFL);  /* returning here will cause a "real" SEGV */
-}
-#endif
-#endif
 
 /*************************************************************************
 * Checking for CPU features                                             *
@@ -2322,6 +1773,8 @@ static void cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32
 {
        const int CPUID_SPACE = 4096;
        uae_u8* cpuid_space = (uae_u8*)cache_alloc(CPUID_SPACE);
+       if (cpuid_space == 0)
+               abort ();
        static uae_u32 s_op, s_eax, s_ebx, s_ecx, s_edx;
        uae_u8* tmp=get_target();
 
index 982e113529bcd2f67a10031ee390a3a21ec8c5e9..ace8ae6ba7a110de7a7e6d301622bc3fbf0cf8b0 100644 (file)
@@ -10,7 +10,7 @@
 
 #include "options.h"
 #include "events.h"
-#include "include/memory.h"
+#include "memory.h"
 #include "custom.h"
 #include "newcpu.h"
 #include "comptbl.h"
@@ -21,7 +21,7 @@
 
 // %%% BRIAN KING WAS HERE %%%
 extern bool canbang;
-#include <sys/mman.h>
+//#include <sys/mman.h>
 extern void jit_abort(const TCHAR*,...);
 compop_func *compfunctbl[65536];
 compop_func *nfcompfunctbl[65536];
@@ -5007,15 +5007,6 @@ STATIC_INLINE void writemem(int address, int source, int offset, int size, int t
 void writebyte(int address, int source, int tmp)
 {
        int distrust = currprefs.comptrustbyte;
-#if 0
-       switch (currprefs.comptrustbyte) {
-       case 0: distrust=0; break;
-       case 1: distrust=1; break;
-       case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
-       case 3: distrust=!have_done_picasso; break;
-       default: abort();
-       }
-#endif
        if ((special_mem&S_WRITE) || distrust)
                writemem_special(address,source,20,1,tmp);
        else
@@ -5026,15 +5017,6 @@ STATIC_INLINE void writeword_general(int address, int source, int tmp,
        int clobber)
 {
        int distrust = currprefs.comptrustword;
-#if 0
-       switch (currprefs.comptrustword) {
-       case 0: distrust=0; break;
-       case 1: distrust=1; break;
-       case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
-       case 3: distrust=!have_done_picasso; break;
-       default: abort();
-       }
-#endif
        if ((special_mem&S_WRITE) || distrust)
                writemem_special(address,source,16,2,tmp);
        else
@@ -5055,15 +5037,6 @@ STATIC_INLINE void writelong_general(int address, int source, int tmp,
        int clobber)
 {
        int  distrust = currprefs.comptrustlong;
-#if 0
-       switch (currprefs.comptrustlong) {
-       case 0: distrust=0; break;
-       case 1: distrust=1; break;
-       case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
-       case 3: distrust=!have_done_picasso; break;
-       default: abort();
-       }
-#endif
        if ((special_mem&S_WRITE) || distrust)
                writemem_special(address,source,12,4,tmp);
        else
@@ -5137,15 +5110,6 @@ STATIC_INLINE void readmem(int address, int dest, int offset, int size, int tmp)
 void readbyte(int address, int dest, int tmp)
 {
        int distrust = currprefs.comptrustbyte;
-#if 0
-       switch (currprefs.comptrustbyte) {
-       case 0: distrust=0; break;
-       case 1: distrust=1; break;
-       case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
-       case 3: distrust=!have_done_picasso; break;
-       default: abort();
-       }
-#endif
        if ((special_mem&S_READ) || distrust)
                readmem_special(address,dest,8,1,tmp);
        else
@@ -5155,15 +5119,6 @@ void readbyte(int address, int dest, int tmp)
 void readword(int address, int dest, int tmp)
 {
        int distrust = currprefs.comptrustword;
-#if 0
-       switch (currprefs.comptrustword) {
-       case 0: distrust=0; break;
-       case 1: distrust=1; break;
-       case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
-       case 3: distrust=!have_done_picasso; break;
-       default: abort();
-       }
-#endif
        if ((special_mem&S_READ) || distrust)
                readmem_special(address,dest,4,2,tmp);
        else
@@ -5173,15 +5128,6 @@ void readword(int address, int dest, int tmp)
 void readlong(int address, int dest, int tmp)
 {
        int distrust = currprefs.comptrustlong;
-#if 0
-       switch (currprefs.comptrustlong) {
-       case 0: distrust=0; break;
-       case 1: distrust=1; break;
-       case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
-       case 3: distrust=!have_done_picasso; break;
-       default: abort();
-       }
-#endif
        if ((special_mem&S_READ) || distrust)
                readmem_special(address,dest,0,4,tmp);
        else
@@ -5220,15 +5166,6 @@ STATIC_INLINE void get_n_addr_real(int address, int dest, int tmp)
 void get_n_addr(int address, int dest, int tmp)
 {
        int distrust = currprefs.comptrustnaddr;
-#if 0
-       switch (currprefs.comptrustnaddr) {
-       case 0: distrust=0; break;
-       case 1: distrust=1; break;
-       case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
-       case 3: distrust=!have_done_picasso; break;
-       default: abort();
-       }
-#endif
        if (special_mem || distrust)
                get_n_addr_old(address,dest,tmp);
        else
@@ -5669,10 +5606,7 @@ void build_comp(void)
 #endif
        raw_init_cpu();
 #ifdef NATMEM_OFFSET
-       write_log (_T("JIT: Setting signal handler\n"));
-#ifndef _WIN32
-       signal(SIGSEGV,vec);
-#endif
+       install_exception_handler();
 #endif
        write_log (_T("JIT: Building Compiler function table\n"));
        for (opcode = 0; opcode < 65536; opcode++) {
diff --git a/jit/exception_handler.cpp b/jit/exception_handler.cpp
new file mode 100644 (file)
index 0000000..e93ade4
--- /dev/null
@@ -0,0 +1,426 @@
+/*************************************************************************
+* Handling mistaken direct memory access                                *
+*************************************************************************/
+
+#ifdef NATMEM_OFFSET
+#ifdef _WIN32 // %%% BRIAN KING WAS HERE %%%
+#include <winbase.h>
+#else
+#ifndef __USE_GNU
+#define __USE_GNU
+#endif
+#include <sys/ucontext.h>
+#endif
+#include <signal.h>
+
+#define SIG_READ 1
+#define SIG_WRITE 2
+
+static int in_handler=0;
+static uae_u8 *veccode;
+
+#ifdef _WIN32
+
+typedef LPEXCEPTION_POINTERS CONTEXT_T;
+#define HAVE_CONTEXT_T 1
+
+#define CONTEXT_EIP(context) (context->ContextRecord->Eip)
+#define CONTEXT_EAX(context) (context->ContextRecord->Eax)
+#define CONTEXT_ECX(context) (context->ContextRecord->Ecx)
+#define CONTEXT_EDX(context) (context->ContextRecord->Edx)
+#define CONTEXT_EBX(context) (context->ContextRecord->Ebx)
+#define CONTEXT_ESP(context) (context->ContextRecord->Esp)
+#define CONTEXT_EBP(context) (context->ContextRecord->Ebp)
+#define CONTEXT_ESI(context) (context->ContextRecord->Esi)
+#define CONTEXT_EDI(context) (context->ContextRecord->Edi)
+
+#define CONTEXT_RIP(context) (context->ContextRecord->Rip)
+#define CONTEXT_RAX(context) (context->ContextRecord->Rax)
+#define CONTEXT_RCX(context) (context->ContextRecord->Rcx)
+#define CONTEXT_RDX(context) (context->ContextRecord->Rdx)
+#define CONTEXT_RBX(context) (context->ContextRecord->Rbx)
+#define CONTEXT_RSP(context) (context->ContextRecord->Rsp)
+#define CONTEXT_RBP(context) (context->ContextRecord->Rbp)
+#define CONTEXT_RSI(context) (context->ContextRecord->Rsi)
+#define CONTEXT_RDI(context) (context->ContextRecord->Rdi)
+
+#define CONTEXT_CR2(context) ((uae_u32)(context->ExceptionRecord->ExceptionInformation[1]))
+
+#elif HAVE_STRUCT_UCONTEXT_UC_MCONTEXT_GREGS
+
+typedef void *CONTEXT_T;
+#define HAVE_CONTEXT_T 1
+
+#define CONTEXT_EIP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EIP])
+#define CONTEXT_EAX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EAX])
+#define CONTEXT_ECX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_ECX])
+#define CONTEXT_EDX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EDX])
+#define CONTEXT_EBX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EBX])
+#define CONTEXT_ESP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_ESP])
+#define CONTEXT_EBP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EBP])
+#define CONTEXT_ESI(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_ESI])
+#define CONTEXT_EDI(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EDI])
+
+#define CONTEXT_CR2(context) (((struct ucontext *) context)->uc_mcontext.cr2)
+
+#endif
+
+#if defined(CPU_64_BIT)
+#ifdef CONTEXT_RIP
+#define CONTEXT_PC(context) CONTEXT_RIP(context)
+#endif
+#else
+#ifdef CONTEXT_EIP
+#define CONTEXT_PC(context) CONTEXT_EIP(context)
+#endif
+#endif
+
+#ifdef HAVE_CONTEXT_T
+/*
+ * Try to handle faulted memory access in compiled code
+ *
+ * Returns 1 if handled, 0 otherwise
+ */
+static int handle_access(CONTEXT_T context)
+{
+       uae_u8  *i    = (uae_u8 *) CONTEXT_EIP(context);
+       uae_u32  addr =            CONTEXT_CR2(context);
+
+       int r=-1;
+       int size=4;
+       int dir=-1;
+       int len=0;
+
+#ifdef JIT_DEBUG
+       write_log (_T("JIT: fault address is 0x%x at 0x%x\n"),addr,i);
+#endif
+       if (!canbang || !currprefs.cachesize)
+               return 0;
+
+       if (in_handler)
+               write_log (_T("JIT: Argh --- Am already in a handler. Shouldn't happen!\n"));
+
+       if (canbang && i>=compiled_code && i<=current_compile_p) {
+               if (*i==0x66) {
+                       i++;
+                       size=2;
+                       len++;
+               }
+
+               switch(i[0]) {
+               case 0x8a:
+                       if ((i[1]&0xc0)==0x80) {
+                               r=(i[1]>>3)&7;
+                               dir=SIG_READ;
+                               size=1;
+                               len+=6;
+                               break;
+                       }
+                       break;
+               case 0x88:
+                       if ((i[1]&0xc0)==0x80) {
+                               r=(i[1]>>3)&7;
+                               dir=SIG_WRITE;
+                               size=1;
+                               len+=6;
+                               break;
+                       }
+                       break;
+               case 0x8b:
+                       switch(i[1]&0xc0) {
+                       case 0x80:
+                               r=(i[1]>>3)&7;
+                               dir=SIG_READ;
+                               len+=6;
+                               break;
+                       case 0x40:
+                               r=(i[1]>>3)&7;
+                               dir=SIG_READ;
+                               len+=3;
+                               break;
+                       case 0x00:
+                               r=(i[1]>>3)&7;
+                               dir=SIG_READ;
+                               len+=2;
+                               break;
+                       default:
+                               break;
+                       }
+                       break;
+               case 0x89:
+                       switch(i[1]&0xc0) {
+                       case 0x80:
+                               r=(i[1]>>3)&7;
+                               dir=SIG_WRITE;
+                               len+=6;
+                               break;
+                       case 0x40:
+                               r=(i[1]>>3)&7;
+                               dir=SIG_WRITE;
+                               len+=3;
+                               break;
+                       case 0x00:
+                               r=(i[1]>>3)&7;
+                               dir=SIG_WRITE;
+                               len+=2;
+                               break;
+                       }
+                       break;
+               }
+       }
+
+       if (r!=-1) {
+               void* pr=NULL;
+#ifdef JIT_DEBUG
+               write_log (_T("JIT: register was %d, direction was %d, size was %d\n"),r,dir,size);
+#endif
+
+               switch(r) {
+#if defined(CPU_64_BIT)
+               case 0: pr = &(CONTEXT_RAX(context)); break;
+               case 1: pr = &(CONTEXT_RCX(context)); break;
+               case 2: pr = &(CONTEXT_RDX(context)); break;
+               case 3: pr = &(CONTEXT_RBX(context)); break;
+               case 4: pr = (size > 1) ? NULL
+                                       : (((uae_u8*)&(CONTEXT_RAX(context)))+1);
+                       break;
+               case 5: pr = (size > 1) ? (void*)          (&(CONTEXT_RBP(context)))
+                                       : (void*)(((uae_u8*)&(CONTEXT_RCX(context))) + 1);
+                       break;
+               case 6: pr = (size > 1) ? (void*)          (&(CONTEXT_RSI(context)))
+                                       : (void*)(((uae_u8*)&(CONTEXT_RDX(context))) + 1);
+                       break;
+               case 7: pr = (size > 1) ? (void*)          (&(CONTEXT_RDI(context)))
+                                       : (void*)(((uae_u8*)&(CONTEXT_RBX(context))) + 1);
+                       break;
+#else
+               case 0: pr = &(CONTEXT_EAX(context)); break;
+               case 1: pr = &(CONTEXT_ECX(context)); break;
+               case 2: pr = &(CONTEXT_EDX(context)); break;
+               case 3: pr = &(CONTEXT_EBX(context)); break;
+               case 4: pr = (size > 1) ? NULL
+                                       : (((uae_u8*)&(CONTEXT_EAX(context)))+1);
+                       break;
+               case 5: pr = (size > 1) ? (void*)          (&(CONTEXT_EBP(context)))
+                                       : (void*)(((uae_u8*)&(CONTEXT_ECX(context))) + 1);
+                       break;
+               case 6: pr = (size > 1) ? (void*)          (&(CONTEXT_ESI(context)))
+                                       : (void*)(((uae_u8*)&(CONTEXT_EDX(context))) + 1);
+                       break;
+               case 7: pr = (size > 1) ? (void*)          (&(CONTEXT_EDI(context)))
+                                       : (void*)(((uae_u8*)&(CONTEXT_EBX(context))) + 1);
+                       break;
+#endif
+           default:
+                   abort ();
+               }
+               if (pr) {
+                       blockinfo* bi;
+
+                       if (currprefs.comp_oldsegv) {
+                               addr-=(uae_u32)NATMEM_OFFSET;
+
+#ifdef JIT_DEBUG
+                               if ((addr>=0x10000000 && addr<0x40000000) ||
+                                       (addr>=0x50000000)) {
+                                               write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
+                               }
+#endif
+                               if (dir==SIG_READ) {
+                                       switch (size) {
+                                       case 1: *((uae_u8*)pr)=get_byte (addr); break;
+                                       case 2: *((uae_u16*)pr)=swap16(get_word (addr)); break;
+                                       case 4: *((uae_u32*)pr)=swap32(get_long (addr)); break;
+                                       default: abort();
+                                       }
+                               }
+                               else { /* write */
+                                       switch (size) {
+                                       case 1: put_byte (addr,*((uae_u8*)pr)); break;
+                                       case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
+                                       case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
+                                       default: abort();
+                                       }
+                               }
+#ifdef JIT_DEBUG
+                               write_log (_T("JIT: Handled one access!\n"));
+#endif
+                               fflush(stdout);
+                               segvcount++;
+                               CONTEXT_PC(context) += len;
+                       }
+                       else {
+                               void* tmp=target;
+                               int i;
+                               uae_u8 vecbuf[5];
+
+                               addr-=(uae_u32)NATMEM_OFFSET;
+
+#ifdef JIT_DEBUG
+                               if ((addr>=0x10000000 && addr<0x40000000) ||
+                                       (addr>=0x50000000)) {
+                                               write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
+                               }
+#endif
+
+                               target = (uae_u8*) CONTEXT_PC(context);
+                               for (i=0;i<5;i++)
+                                       vecbuf[i]=target[i];
+                               emit_byte(0xe9);
+                               emit_long((uae_u32)veccode-(uae_u32)target-4);
+#ifdef JIT_DEBUG
+
+                               write_log (_T("JIT: Create jump to %p\n"),veccode);
+                               write_log (_T("JIT: Handled one access!\n"));
+#endif
+                               segvcount++;
+
+                               target=veccode;
+
+                               if (dir==SIG_READ) {
+                                       switch(size) {
+                                       case 1: raw_mov_b_ri(r,get_byte (addr)); break;
+                                       case 2: raw_mov_w_ri(r,swap16(get_word (addr))); break;
+                                       case 4: raw_mov_l_ri(r,swap32(get_long (addr))); break;
+                                       default: abort();
+                                       }
+                               }
+                               else { /* write */
+                                       switch(size) {
+                                       case 1: put_byte (addr,*((uae_u8*)pr)); break;
+                                       case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
+                                       case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
+                                       default: abort();
+                                       }
+                               }
+                               for (i=0;i<5;i++)
+                                       raw_mov_b_mi(CONTEXT_PC(context) + i, vecbuf[i]);
+                               raw_mov_l_mi((uae_u32)&in_handler,0);
+                               emit_byte(0xe9);
+                               emit_long(CONTEXT_PC(context) + len - (uae_u32)target - 4);
+                               in_handler=1;
+                               target=(uae_u8*)tmp;
+                       }
+                       bi=active;
+                       while (bi) {
+                               if (bi->handler &&
+                                               (uae_u8*)bi->direct_handler<=i &&
+                                               (uae_u8*)bi->nexthandler>i) {
+#ifdef JIT_DEBUG
+                                       write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
+                                                       bi->handler,
+                                                       i,
+                                                       bi->nexthandler,
+                                                       bi->pc_p);
+#endif
+                                       invalidate_block(bi);
+                                       raise_in_cl_list(bi);
+                                       set_special(0);
+                                       return 1;
+                               }
+                               bi=bi->next;
+                       }
+                       /* Not found in the active list. Might be a rom routine that
+                       is in the dormant list */
+                       bi=dormant;
+                       while (bi) {
+                               if (bi->handler &&
+                                               (uae_u8*)bi->direct_handler<=i &&
+                                               (uae_u8*)bi->nexthandler>i) {
+#ifdef JIT_DEBUG
+                                       write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
+                                                       bi->handler,
+                                                       i,
+                                                       bi->nexthandler,
+                                                       bi->pc_p);
+#endif
+                                       invalidate_block(bi);
+                                       raise_in_cl_list(bi);
+                                       set_special(0);
+                                       return 1;
+                               }
+                               bi=bi->next;
+                       }
+#ifdef JIT_DEBUG
+                       write_log (_T("JIT: Huh? Could not find trigger!\n"));
+#endif
+                       return 1;
+               }
+       }
+       write_log (_T("JIT: Can't handle access %08X!\n"), i);
+#if 0
+       if (i)
+       {
+               int j;
+
+               for (j=0;j<10;j++) {
+                       write_log (_T("JIT: instruction byte %2d is 0x%02x\n"),j,i[j]);
+               }
+       }
+       write_log (_T("Please send the above info (starting at \"fault address\") to\n"));
+       write_log (_T("bmeyer@csse.monash.edu.au\n"));
+       write_log (_T("This shouldn't happen ;-)\n"));
+#endif
+       return 0;
+}
+#endif /* CONTEXT_T */
+
+#ifdef _WIN32
+
+LONG WINAPI EvalException(LPEXCEPTION_POINTERS info)
+{
+       DWORD code = info->ExceptionRecord->ExceptionCode;
+       if (code != STATUS_ACCESS_VIOLATION || !canbang || currprefs.cachesize == 0)
+               return EXCEPTION_CONTINUE_SEARCH;
+
+       if (handle_access(info)) {
+               return EXCEPTION_CONTINUE_EXECUTION;
+       }
+       return EXCEPTION_CONTINUE_SEARCH;
+}
+
+#elif defined(HAVE_CONTEXT_T)
+
+static void sigsegv_handler(int signum, struct siginfo *info, void *context)
+{
+       uae_u8  *i    = (uae_u8 *) CONTEXT_EIP(context);
+       uae_u32  addr =            CONTEXT_CR2(context);
+
+       if (i >= compiled_code) {
+               if (handle_access (context))
+                       return;
+               else {
+                       int j;
+                       write_log ("JIT: can't handle access!\n");
+                       for (j = 0 ; j < 10; j++)
+                               write_log ("JIT: instruction byte %2d is %02x\n", i, j[i]);
+               }
+       } else {
+               write_log ("Caught illegal access to %08x at eip=%08x\n", addr, i);
+       }
+
+       exit (EXIT_FAILURE);
+}
+
+#endif
+
+static void install_exception_handler(void)
+{
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
+       /* Structured exception handler is installed in main.cpp */
+#elif defined(_WIN32)
+       write_log (_T("JIT: Installing unhandled exception filter\n"));
+       SetUnhandledExceptionFilter(EvalException);
+#elif defined(HAVE_CONTEXT_T)
+       write_log (_T("JIT: Installing segfault handler\n"));
+       struct sigaction act;
+       act.sa_sigaction = (void (*)(int, siginfo_t*, void*)) sigsegv_handler;
+       sigemptyset (&act.sa_mask);
+       act.sa_flags = SA_SIGINFO;
+       sigaction(SIGSEGV, &act, NULL);
+#else
+       write_log (_T("JIT: No segfault handler installed\n"));
+#endif
+}
+
+#endif /* NATMEM_OFFSET */
index 5e77da30f8c3d9bfef8803dbf314867cd0980439..002077c27a28cf98cbea125bb3d69a7ab9cf4325 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -41,6 +41,7 @@
 #include "cpuboard.h"
 #include "uae/ppc.h"
 #include "devices.h"
+#include "jit/compemu.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #endif
@@ -684,8 +685,9 @@ void fixup_prefs (struct uae_prefs *p)
 #endif
        }
 #endif
-       if (p->maprom && !p->address_space_24)
+       if (p->maprom && !p->address_space_24) {
                p->maprom = 0x0f000000;
+       }
        if (((p->maprom & 0xff000000) && p->address_space_24) || (p->maprom && p->mbresmem_high_size >= 0x08000000)) {
                p->maprom = 0x00e00000;
        }
@@ -968,16 +970,15 @@ void do_start_program (void)
 #ifdef WITH_LUA
        uae_lua_loadall ();
 #endif
-#if (defined (_WIN32) || defined (_WIN64)) && !defined (NO_WIN32_EXCEPTION_HANDLER)
-       extern int EvalException (LPEXCEPTION_POINTERS blah, int n_except);
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
        __try
 #endif
        {
                m68k_go (1);
        }
-#if (defined (_WIN32) || defined (_WIN64)) && !defined (NO_WIN32_EXCEPTION_HANDLER)
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
 #ifdef JIT
-       __except (EvalException (GetExceptionInformation (), GetExceptionCode ()))
+       __except (EvalException(GetExceptionInformation()))
 #else
        __except (DummyException (GetExceptionInformation (), GetExceptionCode ()))
 #endif