Annotation of hatari/src/cpu/jit/exception_handler.c, revision 1.1.1.3

1.1       root        1: /*************************************************************************
                      2: * Handling mistaken direct memory access                                *
                      3: *************************************************************************/
                      4: 
                      5: #ifdef NATMEM_OFFSET
                      6: #ifdef _WIN32 // %%% BRIAN KING WAS HERE %%%
                      7: #include <winbase.h>
                      8: #else
                      9: #ifndef __USE_GNU
                     10: #define __USE_GNU
                     11: #endif
                     12: #include <sys/ucontext.h>
                     13: #endif
                     14: #include <signal.h>
                     15: 
                     16: #define SIG_READ 1
                     17: #define SIG_WRITE 2
                     18: 
                     19: static int in_handler = 0;
                     20: static uae_u8 *veccode;
                     21: 
                     22: #if defined(JIT_DEBUG)
                     23: #define DEBUG_ACCESS
                     24: #endif
                     25: 
                     26: #if defined(_WIN32) && defined(CPU_x86_64)
                     27: 
                     28: typedef LPEXCEPTION_POINTERS CONTEXT_T;
                     29: #define HAVE_CONTEXT_T 1
                     30: #define CONTEXT_RIP(context) (context->ContextRecord->Rip)
                     31: #define CONTEXT_RAX(context) (context->ContextRecord->Rax)
                     32: #define CONTEXT_RCX(context) (context->ContextRecord->Rcx)
                     33: #define CONTEXT_RDX(context) (context->ContextRecord->Rdx)
                     34: #define CONTEXT_RBX(context) (context->ContextRecord->Rbx)
                     35: #define CONTEXT_RSP(context) (context->ContextRecord->Rsp)
                     36: #define CONTEXT_RBP(context) (context->ContextRecord->Rbp)
                     37: #define CONTEXT_RSI(context) (context->ContextRecord->Rsi)
                     38: #define CONTEXT_RDI(context) (context->ContextRecord->Rdi)
                     39: #define CONTEXT_R8(context)  (context->ContextRecord->R8)
                     40: #define CONTEXT_R9(context)  (context->ContextRecord->R9)
                     41: #define CONTEXT_R10(context) (context->ContextRecord->R10)
                     42: #define CONTEXT_R11(context) (context->ContextRecord->R11)
                     43: #define CONTEXT_R12(context) (context->ContextRecord->R12)
                     44: #define CONTEXT_R13(context) (context->ContextRecord->R13)
                     45: #define CONTEXT_R14(context) (context->ContextRecord->R14)
                     46: #define CONTEXT_R15(context) (context->ContextRecord->R15)
                     47: 
                     48: #elif defined(_WIN32) && defined(CPU_i386)
                     49: 
                     50: typedef LPEXCEPTION_POINTERS CONTEXT_T;
                     51: #define HAVE_CONTEXT_T 1
                     52: #define CONTEXT_RIP(context) (context->ContextRecord->Eip)
                     53: #define CONTEXT_RAX(context) (context->ContextRecord->Eax)
                     54: #define CONTEXT_RCX(context) (context->ContextRecord->Ecx)
                     55: #define CONTEXT_RDX(context) (context->ContextRecord->Edx)
                     56: #define CONTEXT_RBX(context) (context->ContextRecord->Ebx)
                     57: #define CONTEXT_RSP(context) (context->ContextRecord->Esp)
                     58: #define CONTEXT_RBP(context) (context->ContextRecord->Ebp)
                     59: #define CONTEXT_RSI(context) (context->ContextRecord->Esi)
                     60: #define CONTEXT_RDI(context) (context->ContextRecord->Edi)
                     61: 
                     62: #elif defined(HAVE_STRUCT_UCONTEXT_UC_MCONTEXT_GREGS) && defined(CPU_x86_64)
                     63: 
                     64: typedef void *CONTEXT_T;
                     65: #define HAVE_CONTEXT_T 1
                     66: #define CONTEXT_RIP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_RIP])
                     67: #define CONTEXT_RAX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_RAX])
                     68: #define CONTEXT_RCX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_RCX])
                     69: #define CONTEXT_RDX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_RDX])
                     70: #define CONTEXT_RBX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_RBX])
                     71: #define CONTEXT_RSP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_RSP])
                     72: #define CONTEXT_RBP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_RBP])
                     73: #define CONTEXT_RSI(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_RSI])
                     74: #define CONTEXT_RDI(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_RDI])
                     75: #define CONTEXT_R8(context)  (((struct ucontext *) context)->uc_mcontext.gregs[REG_R8])
                     76: #define CONTEXT_R9(context)  (((struct ucontext *) context)->uc_mcontext.gregs[REG_R9])
                     77: #define CONTEXT_R10(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_R10])
                     78: #define CONTEXT_R11(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_R11])
                     79: #define CONTEXT_R12(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_R12])
                     80: #define CONTEXT_R13(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_R13])
                     81: #define CONTEXT_R14(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_R14])
                     82: #define CONTEXT_R15(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_R15])
                     83: 
                     84: #elif defined(HAVE_STRUCT_UCONTEXT_UC_MCONTEXT_GREGS) && defined(CPU_i386)
                     85: 
                     86: typedef void *CONTEXT_T;
                     87: #define HAVE_CONTEXT_T 1
                     88: #define CONTEXT_RIP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EIP])
                     89: #define CONTEXT_RAX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EAX])
                     90: #define CONTEXT_RCX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_ECX])
                     91: #define CONTEXT_RDX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EDX])
                     92: #define CONTEXT_RBX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EBX])
                     93: #define CONTEXT_RSP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_ESP])
                     94: #define CONTEXT_RBP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EBP])
                     95: #define CONTEXT_RSI(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_ESI])
                     96: #define CONTEXT_RDI(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EDI])
                     97: 
                     98: #elif defined(__DARWIN_UNIX03) && defined(CPU_x86_64)
                     99: 
                    100: typedef void *CONTEXT_T;
                    101: #define HAVE_CONTEXT_T 1
                    102: #define CONTEXT_RIP(context) (*((unsigned long *) &((ucontext_t *) context)->uc_mcontext->__ss.__rip))
                    103: #define CONTEXT_RAX(context) (((ucontext_t *) context)->uc_mcontext->__ss.__rax)
                    104: #define CONTEXT_RCX(context) (((ucontext_t *) context)->uc_mcontext->__ss.__rcx)
                    105: #define CONTEXT_RDX(context) (((ucontext_t *) context)->uc_mcontext->__ss.__rdx)
                    106: #define CONTEXT_RBX(context) (((ucontext_t *) context)->uc_mcontext->__ss.__rbx)
                    107: #define CONTEXT_RSP(context) (*((unsigned long *) &((ucontext_t *) context)->uc_mcontext->__ss.__rsp))
                    108: #define CONTEXT_RBP(context) (((ucontext_t *) context)->uc_mcontext->__ss.__rbp)
                    109: #define CONTEXT_RSI(context) (((ucontext_t *) context)->uc_mcontext->__ss.__rsi)
                    110: #define CONTEXT_RDI(context) (((ucontext_t *) context)->uc_mcontext->__ss.__rdi)
                    111: #define CONTEXT_R8(context) (((ucontext_t *)  context)->uc_mcontext->__ss.__r8)
                    112: #define CONTEXT_R9(context) (((ucontext_t *)  context)->uc_mcontext->__ss.__r9)
                    113: #define CONTEXT_R10(context) (((ucontext_t *) context)->uc_mcontext->__ss.__r10)
                    114: #define CONTEXT_R11(context) (((ucontext_t *) context)->uc_mcontext->__ss.__r11)
                    115: #define CONTEXT_R12(context) (((ucontext_t *) context)->uc_mcontext->__ss.__r12)
                    116: #define CONTEXT_R13(context) (((ucontext_t *) context)->uc_mcontext->__ss.__r13)
                    117: #define CONTEXT_R14(context) (((ucontext_t *) context)->uc_mcontext->__ss.__r14)
                    118: #define CONTEXT_R15(context) (((ucontext_t *) context)->uc_mcontext->__ss.__r15)
                    119: 
                    120: #elif defined(__DARWIN_UNIX03) && defined(CPU_i386)
                    121: 
                    122: typedef void *CONTEXT_T;
                    123: #define HAVE_CONTEXT_T 1
                    124: #define CONTEXT_RIP(context) (*((unsigned long *) &((ucontext_t *) context)->uc_mcontext->__ss.__eip))
                    125: #define CONTEXT_RAX(context) (((ucontext_t *) context)->uc_mcontext->__ss.__eax)
                    126: #define CONTEXT_RCX(context) (((ucontext_t *) context)->uc_mcontext->__ss.__ecx)
                    127: #define CONTEXT_RDX(context) (((ucontext_t *) context)->uc_mcontext->__ss.__edx)
                    128: #define CONTEXT_RBX(context) (((ucontext_t *) context)->uc_mcontext->__ss.__ebx)
                    129: #define CONTEXT_RSP(context) (*((unsigned long *) &((ucontext_t *) context)->uc_mcontext->__ss.__esp))
                    130: #define CONTEXT_RBP(context) (((ucontext_t *) context)->uc_mcontext->__ss.__ebp)
                    131: #define CONTEXT_RSI(context) (((ucontext_t *) context)->uc_mcontext->__ss.__esi)
                    132: #define CONTEXT_RDI(context) (((ucontext_t *) context)->uc_mcontext->__ss.__edi)
                    133: 
                    134: #endif
                    135: 
                    136: #define CONTEXT_PC(context) CONTEXT_RIP(context)
                    137: 
                    138: /* FIXME: replace usage with bswap16, move fallback defition to header */
                    139: static inline uae_u16 swap16(uae_u16 x)
                    140: {
                    141:        return ((x & 0xff00) >> 8) | ((x & 0x00ff) << 8);
                    142: }
                    143: 
                    144: /* FIXME: replace usage with bswap32, move fallback defition to header */
                    145: static inline uae_u32 swap32(uae_u32 x)
                    146: {
                    147:        return ((x & 0x0000ff00) << 8) | ((x & 0x00ff0000) << 24) |
                    148:                   ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
                    149: }
                    150: 
                    151: static int delete_trigger(blockinfo *bi, void *pc)
                    152: {
                    153:        while (bi) {
                    154:                if (bi->handler && (uae_u8*)bi->direct_handler <= pc &&
                    155:                                (uae_u8*)bi->nexthandler > pc) {
                    156: #ifdef DEBUG_ACCESS
                    157:                        write_log(_T("JIT: Deleted trigger (%p < %p < %p) %p\n"),
                    158:                                        bi->handler, pc, bi->nexthandler, bi->pc_p);
                    159: #endif
                    160:                        invalidate_block(bi);
                    161:                        raise_in_cl_list(bi);
                    162:                        set_special(0);
                    163:                        return 1;
                    164:                }
                    165:                bi = bi->next;
                    166:        }
                    167:        return 0;
                    168: }
                    169: 
                    170: /* Opcode register id list:
                    171:  *
                    172:  * 8 Bit:               16 Bit:               32 Bit:
                    173:  *
                    174:  *     0: AL                 0: AX                 0: EAX
                    175:  *     1: CL                 1: CX                 1: ECX
                    176:  *     2: DL                 2: DX                 2: EDX
                    177:  *     3: BL                 3: BX                 3: EBX
                    178:  *     4: AH (SPL, if REX)   4: SP                 4: ESP
                    179:  *     5: CH (BPL, if REX)   5: BP                 5: EBP
                    180:  *     6: DH (SIL, if REX)   6: SI                 6: ESI
                    181:  *     7: BH (DIL, if REX)   7: DI                 7: EDI
                    182:  *     8: R8L                8: R8W                8: R8D
                    183:  *     9: R9L                9: R9W                9: R9D
                    184:  *    10: R10L              10: R10W              10: R10D
                    185:  *    11: R11L              11: R11W              11: R11D
                    186:  *    12: R12L              12: R12W              12: R12D
                    187:  *    13: R13L              13: R13W              13: R13D
                    188:  *    14: R14L              14: R14W              14: R14D
                    189:  *    15: R15L              15: R15W              15: R15D
                    190:  */
                    191: 
                    192: static bool decode_instruction(
                    193:                uae_u8 *pc, int *r, int *dir, int *size, int *len, int *rex)
                    194: {
                    195:        *r = -1;
                    196:        *size = 4;
                    197:        *dir = -1;
                    198:        *len = 0;
                    199:        *rex = 0;
                    200: 
                    201: #ifdef CPU_x86_64
                    202:        /* Skip address-size override prefix. */
                    203:        if (*pc == 0x67) {
                    204:                pc += 1;
                    205:                *len += 1;
                    206:        }
                    207: #endif
                    208:        /* Operand size override prefix. */
                    209:        if (*pc == 0x66) {
                    210:                pc += 1;
                    211:                *size = 2;
                    212:                *len += 1;
                    213:        }
                    214: #ifdef CPU_x86_64
                    215:        /* Handle x86-64 REX prefix. */
                    216:        if ((pc[0] & 0xf0) == 0x40) {
                    217:                *rex = pc[0];
                    218:                pc += 1;
                    219:                *len += 1;
                    220:                if (*rex & (1 << 3)) {
                    221:                        *size = 8;
                    222:                        /* 64-bit operand size not supported. */
                    223:                        return 0;
                    224:                }
                    225:        }
                    226: #endif
                    227: 
                    228:        switch (pc[0]) {
                    229:        case 0x8a: /* MOV r8, m8 */
                    230:                if ((pc[1] & 0xc0) == 0x80) {
                    231:                        *r = (pc[1] >> 3) & 7;
                    232:                        *dir = SIG_READ;
                    233:                        *size = 1;
                    234:                        *len += 6;
                    235:                        break;
                    236:                }
                    237:                break;
                    238:        case 0x88: /* MOV m8, r8 */
                    239:                if ((pc[1] & 0xc0) == 0x80) {
                    240:                        *r = (pc[1] >> 3) & 7;
                    241:                        *dir = SIG_WRITE;
                    242:                        *size = 1;
                    243:                        *len += 6;
                    244:                        break;
                    245:                }
                    246:                break;
                    247:        case 0x8b: /* MOV r32, m32 */
                    248:                switch (pc[1] & 0xc0) {
                    249:                case 0x80:
                    250:                        *r = (pc[1] >> 3) & 7;
                    251:                        *dir = SIG_READ;
                    252:                        *len += 6;
                    253:                        break;
                    254:                case 0x40:
                    255:                        *r = (pc[1] >> 3) & 7;
                    256:                        *dir = SIG_READ;
                    257:                        *len += 3;
                    258:                        break;
                    259:                case 0x00:
                    260:                        *r = (pc[1] >> 3) & 7;
                    261:                        *dir = SIG_READ;
                    262:                        *len += 2;
                    263:                        break;
                    264:                default:
                    265:                        break;
                    266:                }
                    267:                break;
                    268:        case 0x89: /* MOV m32, r32 */
                    269:                switch (pc[1] & 0xc0) {
                    270:                case 0x80:
                    271:                        *r = (pc[1] >> 3) & 7;
                    272:                        *dir = SIG_WRITE;
                    273:                        *len += 6;
                    274:                        break;
                    275:                case 0x40:
                    276:                        *r = (pc[1] >> 3) & 7;
                    277:                        *dir = SIG_WRITE;
                    278:                        *len += 3;
                    279:                        break;
                    280:                case 0x00:
                    281:                        *r = (pc[1] >> 3) & 7;
                    282:                        *dir = SIG_WRITE;
                    283:                        *len += 2;
                    284:                        break;
                    285:                }
                    286:                break;
                    287:        }
                    288: #ifdef CPU_x86_64
                    289:        if (*rex & (1 << 2)) {
                    290:                /* Use x86-64 extended registers R8..R15. */
                    291:                *r += 8;
                    292:        }
                    293: #endif
                    294:        return *r != -1;
                    295: }
                    296: 
                    297: #ifdef HAVE_CONTEXT_T
                    298: 
                    299: static void *get_pr_from_context(CONTEXT_T context, int r, int size, int rex)
                    300: {
                    301:        switch (r) {
                    302:        case 0:
                    303:                return &(CONTEXT_RAX(context));
                    304:        case 1:
                    305:                return &(CONTEXT_RCX(context));
                    306:        case 2:
                    307:                return &(CONTEXT_RDX(context));
                    308:        case 3:
                    309:                return &(CONTEXT_RBX(context));
                    310:        case 4:
                    311:                if (size > 1 || rex) {
                    312:                        return NULL;
                    313:                } else {
                    314:                        return (((uae_u8 *) &(CONTEXT_RAX(context))) + 1); /* AH */
                    315:                }
                    316:        case 5:
                    317:                if (size > 1 || rex) {
                    318:                        return &(CONTEXT_RBP(context));
                    319:                } else {
                    320:                        return (((uae_u8 *) &(CONTEXT_RCX(context))) + 1); /* CH */
                    321:                }
                    322:        case 6:
                    323:                if (size > 1 || rex) {
                    324:                        return &(CONTEXT_RSI(context));
                    325:                } else {
                    326:                        return (((uae_u8 *) &(CONTEXT_RDX(context))) + 1); /* DH */
                    327:                }
                    328:        case 7:
                    329:                if (size > 1 || rex) {
                    330:                        return &(CONTEXT_RDI(context));
                    331:                } else {
                    332:                        return (((uae_u8 *) &(CONTEXT_RBX(context))) + 1); /* BH */
                    333:                }
                    334: #ifdef CPU_x86_64
                    335:        case 8:
                    336:                return &(CONTEXT_R8(context));
                    337:        case 9:
                    338:                return &(CONTEXT_R9(context));
                    339:        case 10:
                    340:                return &(CONTEXT_R10(context));
                    341:        case 11:
                    342:                return &(CONTEXT_R11(context));
                    343:        case 12:
                    344:                return &(CONTEXT_R12(context));
                    345:        case 13:
                    346:                return &(CONTEXT_R13(context));
                    347:        case 14:
                    348:                return &(CONTEXT_R14(context));
                    349:        case 15:
                    350:                return &(CONTEXT_R15(context));
                    351: #endif
                    352:        default:
                    353:                abort ();
                    354:        }
                    355: }
                    356: 
                    357: static void log_unhandled_access(uae_u8 *fault_pc)
                    358: {
                    359:        write_log(_T("JIT: Can't handle access PC=%p!\n"), fault_pc);
                    360:        if (fault_pc) {
                    361:                write_log(_T("JIT: Instruction bytes"));
                    362:                for (int j = 0; j < 10; j++) {
                    363:                        write_log(_T(" %02x"), fault_pc[j]);
                    364:                }
                    365:                write_log(_T("\n"));
                    366:        }
                    367: }
                    368: 
                    369: /*
                    370:  * Try to handle faulted memory access in compiled code
                    371:  *
                    372:  * Returns 1 if handled, 0 otherwise
                    373:  */
                    374: static int handle_access(uintptr_t fault_addr, CONTEXT_T context)
                    375: {
                    376:        uae_u8 *fault_pc = (uae_u8 *) CONTEXT_PC(context);
                    377: #ifdef CPU_64_BIT
                    378: #if 0
                    379:        if ((fault_addr & 0xffffffff00000000) == 0xffffffff00000000) {
                    380:                fault_addr &= 0xffffffff;
                    381:        }
                    382: #endif
                    383:        if (fault_addr > (uintptr_t) 0xffffffff) {
                    384:                return 0;
                    385:        }
                    386: #endif
                    387: 
                    388: #ifdef DEBUG_ACCESS
                    389:        write_log(_T("JIT: Fault address is 0x%lx at PC=%p\n"), fault_addr, fault_pc);
                    390: #endif
                    391:        if (!canbang || !currprefs.cachesize)
                    392:                return 0;
                    393: 
                    394:        if (in_handler)
                    395:                write_log(_T("JIT: Argh --- Am already in a handler. Shouldn't happen!\n"));
                    396: 
                    397:        if (fault_pc < compiled_code || fault_pc > current_compile_p) {
                    398:                return 0;
                    399:        }
                    400: 
                    401:        int r = -1, size = 4, dir = -1, len = 0, rex = 0;
                    402:        decode_instruction(fault_pc, &r, &dir, &size, &len, &rex);
                    403:        if (r == -1) {
                    404:                log_unhandled_access(fault_pc);
                    405:                return 0;
                    406:        }
                    407: 
                    408: #ifdef DEBUG_ACCESS
                    409:        write_log (_T("JIT: Register was %d, direction was %d, size was %d\n"),
                    410:                           r, dir, size);
                    411: #endif
                    412: 
                    413:        void *pr = get_pr_from_context(context, r, size, rex);
                    414:        if (pr == NULL) {
                    415:                log_unhandled_access(fault_pc);
                    416:                return 0;
                    417:        }
                    418: 
                    419:        uae_u32 addr = uae_p32(fault_addr) - uae_p32(NATMEM_OFFSET);
                    420: #ifdef DEBUG_ACCESS
1.1.1.2   root      421:        if (addr >= 0x80000000) {
1.1       root      422:                        write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"), addr);
                    423:        }
                    424:        addrbank *ab = &get_mem_bank(addr);
                    425:        if (ab)
                    426:                write_log(_T("JIT: Address bank: %s, address %08x\n"), ab->name ? ab->name : _T("NONE"), addr);
                    427: #endif
                    428: 
                    429:        uae_u8* original_target = target;
                    430:        target = (uae_u8*) CONTEXT_PC(context);
                    431: 
                    432:        uae_u8 vecbuf[5];
                    433:        for (int i = 0; i < 5; i++) {
                    434:                vecbuf[i] = target[i];
                    435:        }
                    436:        raw_jmp(uae_p32(veccode));
                    437: 
                    438: #ifdef DEBUG_ACCESS
                    439:        write_log(_T("JIT: Create jump to %p\n"), veccode);
                    440:        write_log(_T("JIT: Handled one access!\n"));
                    441: #endif
                    442: 
                    443:        target = veccode;
                    444:        if (dir == SIG_READ) {
                    445:                switch (size) {
                    446:                case 1:
                    447:                        raw_mov_b_ri(r, get_byte(addr));
                    448:                        break;
                    449:                case 2:
                    450:                        raw_mov_w_ri(r, swap16(get_word(addr)));
                    451:                        break;
                    452:                case 4:
                    453:                        raw_mov_l_ri(r, swap32(get_long(addr)));
                    454:                        break;
                    455:                default:
                    456:                        abort();
                    457:                }
                    458:        } else {
                    459:                switch (size) {
                    460:                case 1:
                    461:                        put_byte(addr, *((uae_u8 *) pr));
                    462:                        break;
                    463:                case 2:
                    464:                        put_word(addr, swap16(*((uae_u16 *) pr)));
                    465:                        break;
                    466:                case 4:
                    467:                        put_long(addr, swap32(*((uae_u32 *) pr)));
                    468:                        break;
                    469:                default: abort();
                    470:                }
                    471:        }
                    472:        for (int i = 0; i < 5; i++) {
                    473:                raw_mov_b_mi(CONTEXT_PC(context) + i, vecbuf[i]);
                    474:        }
                    475:        raw_mov_l_mi(uae_p32(&in_handler), 0);
                    476:        raw_jmp(uae_p32(CONTEXT_PC(context)) + len);
                    477: 
                    478:        in_handler = 1;
                    479:        target = original_target;
                    480:        if (delete_trigger(active, fault_pc)) {
                    481:                return 1;
                    482:        }
                    483:        /* Not found in the active list. Might be a rom routine that
                    484:         * is in the dormant list */
                    485:        if (delete_trigger(dormant, fault_pc)) {
                    486:                return 1;
                    487:        }
                    488: #ifdef DEBUG_ACCESS
                    489:        write_log (_T("JIT: Huh? Could not find trigger!\n"));
                    490: #endif
                    491:        return 1;
                    492: }
                    493: 
                    494: #endif /* CONTEXT_T */
                    495: 
                    496: #ifdef _WIN32
                    497: 
                    498: LONG WINAPI EvalException(LPEXCEPTION_POINTERS info)
                    499: {
                    500:        DWORD code = info->ExceptionRecord->ExceptionCode;
                    501:        if (code != STATUS_ACCESS_VIOLATION || !canbang || currprefs.cachesize == 0)
                    502:                return EXCEPTION_CONTINUE_SEARCH;
                    503: 
                    504:        uintptr_t address = info->ExceptionRecord->ExceptionInformation[1];
                    505:        if (handle_access(address, info)) {
                    506:                return EXCEPTION_CONTINUE_EXECUTION;
                    507:        }
1.1.1.3 ! root      508:        if (currprefs.comp_catchfault) {
        !           509:                // setup fake exception
        !           510:                exception2_setup(uae_p32(address) - uae_p32(NATMEM_OFFSET), info->ExceptionRecord->ExceptionInformation[0] == 0, 1, regs.s ? 4 : 0);
        !           511:                return EXCEPTION_EXECUTE_HANDLER;
        !           512:        }
1.1       root      513:        return EXCEPTION_CONTINUE_SEARCH;
                    514: }
                    515: 
                    516: static void *installed_vector_handler;
                    517: 
                    518: static LONG CALLBACK JITVectoredHandler(PEXCEPTION_POINTERS info)
                    519: {
                    520: //     write_log(_T("JitVectoredHandler\n"));
                    521:        return EvalException(info);
                    522: }
                    523: 
                    524: #elif defined(HAVE_CONTEXT_T)
                    525: 
                    526: static void sigsegv_handler(int signum, siginfo_t *info, void *context)
                    527: {
                    528:        uae_u8 *i = (uae_u8 *) CONTEXT_PC(context);
                    529:        uintptr_t address = (uintptr_t) info->si_addr;
                    530: 
                    531:        if (i >= compiled_code) {
                    532:                if (handle_access(address, context)) {
                    533:                        return;
                    534:                }
                    535:        } else {
                    536:                write_log ("Caught illegal access to %08lx at eip=%p\n", address, i);
                    537:        }
                    538: 
                    539:        exit (EXIT_FAILURE);
                    540: }
                    541: 
                    542: #endif
                    543: 
                    544: // #define TEST_EXCEPTION_HANDLER
                    545: 
                    546: #ifdef TEST_EXCEPTION_HANDLER
                    547: #include "test_exception_handler.cpp"
                    548: #endif
                    549: 
                    550: static void install_exception_handler(void)
                    551: {
                    552: #ifdef TEST_EXCEPTION_HANDLER
                    553:        test_exception_handler();
                    554: #endif
                    555: 
                    556: #ifdef JIT_EXCEPTION_HANDLER
                    557:        if (veccode == NULL) {
                    558:                veccode = (uae_u8 *) uae_vm_alloc(256, UAE_VM_32BIT, UAE_VM_READ_WRITE_EXECUTE);
                    559:        }
                    560: #endif
                    561: #ifdef USE_STRUCTURED_EXCEPTION_HANDLING
                    562:        /* Structured exception handler is installed in main.cpp */
                    563: #elif defined(_WIN32)
                    564: #if 1
                    565:        write_log(_T("JIT: Installing vectored exception handler\n"));
                    566:        installed_vector_handler = AddVectoredExceptionHandler(
                    567:                0, JITVectoredHandler);
                    568: #else
                    569:        write_log(_T("JIT: Installing unhandled exception filter\n"));
                    570:        SetUnhandledExceptionFilter(EvalException);
                    571: #endif
                    572: #elif defined(HAVE_CONTEXT_T)
                    573:        write_log (_T("JIT: Installing segfault handler\n"));
                    574:        struct sigaction act;
                    575:        act.sa_sigaction = (void (*)(int, siginfo_t*, void*)) sigsegv_handler;
                    576:        sigemptyset (&act.sa_mask);
                    577:        act.sa_flags = SA_SIGINFO;
                    578:        sigaction(SIGSEGV, &act, NULL);
                    579: #ifdef MACOSX
                    580:        sigaction(SIGBUS, &act, NULL);
                    581: #endif
                    582: #else
                    583:        write_log (_T("JIT: No segfault handler installed\n"));
                    584: #endif
                    585: }
                    586: 
                    587: #endif /* NATMEM_OFFSET */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.