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

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