|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.