| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include "native_client/src/trusted/service_runtime/osx/mach_exception_handler.h
" | 7 #include "native_client/src/trusted/service_runtime/osx/mach_exception_handler.h
" |
| 8 | 8 |
| 9 #include <mach/mach.h> | 9 #include <mach/mach.h> |
| 10 #include <mach/mach_vm.h> | 10 #include <mach/mach_vm.h> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 | 37 |
| 38 /* | 38 /* |
| 39 * MIG generated message pump from /usr/include/mach/exc.defs | 39 * MIG generated message pump from /usr/include/mach/exc.defs |
| 40 * Tweaked to place in an isolated namespace. | 40 * Tweaked to place in an isolated namespace. |
| 41 */ | 41 */ |
| 42 boolean_t nacl_exc_server( | 42 boolean_t nacl_exc_server( |
| 43 mach_msg_header_t *InHeadP, | 43 mach_msg_header_t *InHeadP, |
| 44 mach_msg_header_t *OutHeadP); | 44 mach_msg_header_t *OutHeadP); |
| 45 | 45 |
| 46 | 46 |
| 47 /* Exception types to intercept. */ | 47 /* Exception types to intercept. This should be a superset of what Breakpad han
dles... */ |
| 48 #define NACL_MACH_EXCEPTION_MASK \ | 48 #define NACL_MACH_EXCEPTION_MASK \ |
| 49 (EXC_MASK_BAD_ACCESS | \ | 49 (EXC_MASK_BAD_ACCESS | \ |
| 50 EXC_MASK_BAD_INSTRUCTION | \ | 50 EXC_MASK_BAD_INSTRUCTION | \ |
| 51 EXC_MASK_ARITHMETIC | \ | 51 EXC_MASK_ARITHMETIC | \ |
| 52 EXC_MASK_BREAKPOINT) | 52 EXC_MASK_BREAKPOINT) |
| 53 | 53 |
| 54 /* | 54 /* |
| 55 * <mach/mach_types.defs> says that the arrays in MachExceptionParameters have | 55 * <mach/mach_types.defs> says that the arrays in MachExceptionParameters have |
| 56 * room for 32 elements. EXC_TYPES_COUNT, a smaller value, has grown over | 56 * room for 32 elements. EXC_TYPES_COUNT, a smaller value, has grown over |
| 57 * time in major SDK releases. task_get_exception_ports expects there to be | 57 * time in major SDK releases. task_get_exception_ports expects there to be |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 * handlers don't provide a new thread state. They can set a new thread | 399 * handlers don't provide a new thread state. They can set a new thread |
| 400 * state on their own by calling thread_set_state. Returning KERN_SUCCESS | 400 * state on their own by calling thread_set_state. Returning KERN_SUCCESS |
| 401 * would allow the old state passed to | 401 * would allow the old state passed to |
| 402 * nacl_catch_exception_raise_state_identity to overwrite any new state set | 402 * nacl_catch_exception_raise_state_identity to overwrite any new state set |
| 403 * by the handler that the exception was forwarded to via exception_raise. | 403 * by the handler that the exception was forwarded to via exception_raise. |
| 404 */ | 404 */ |
| 405 return kr == KERN_SUCCESS ? MACH_RCV_PORT_DIED : kr; | 405 return kr == KERN_SUCCESS ? MACH_RCV_PORT_DIED : kr; |
| 406 } | 406 } |
| 407 | 407 |
| 408 | 408 |
| 409 static void ReportCrash(int exception_type, int is_untrusted) { |
| 410 char buf[128]; |
| 411 int len = snprintf(buf, sizeof(buf), |
| 412 "\n** Mach exception %d from %s code\n", |
| 413 exception_type, |
| 414 is_untrusted ? "untrusted" : "trusted"); |
| 415 write(2, buf, len); |
| 416 } |
| 417 |
| 418 |
| 409 kern_return_t nacl_catch_exception_raise( | 419 kern_return_t nacl_catch_exception_raise( |
| 410 mach_port_t exception_port, | 420 mach_port_t exception_port, |
| 411 mach_port_t thread, | 421 mach_port_t thread, |
| 412 mach_port_t task, | 422 mach_port_t task, |
| 413 exception_type_t exception, | 423 exception_type_t exception, |
| 414 exception_data_t code, | 424 exception_data_t code, |
| 415 mach_msg_type_number_t code_count) { | 425 mach_msg_type_number_t code_count) { |
| 416 /* MIG generated code expects this, but should never be called. */ | 426 /* MIG generated code expects this, but should never be called. */ |
| 417 UNREFERENCED_PARAMETER(exception_port); | 427 UNREFERENCED_PARAMETER(exception_port); |
| 418 UNREFERENCED_PARAMETER(thread); | 428 UNREFERENCED_PARAMETER(thread); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 * xnu-2050.18.24/osfmk/kern/exception.c. | 501 * xnu-2050.18.24/osfmk/kern/exception.c. |
| 492 * | 502 * |
| 493 * This is done instead of letting the kernel set the new thread state to | 503 * This is done instead of letting the kernel set the new thread state to |
| 494 * be the same as the old state because the kernel resets %cs to the | 504 * be the same as the old state because the kernel resets %cs to the |
| 495 * default value when setting a thread's state. This behavior is explained | 505 * default value when setting a thread's state. This behavior is explained |
| 496 * in more detail in HandleException. | 506 * in more detail in HandleException. |
| 497 */ | 507 */ |
| 498 return MACH_RCV_PORT_DIED; | 508 return MACH_RCV_PORT_DIED; |
| 499 } | 509 } |
| 500 | 510 |
| 511 ReportCrash(exception, is_untrusted); |
| 512 |
| 501 /* | 513 /* |
| 502 * Don't forward if the crash is untrusted, but unhandled. | 514 * Don't forward if the crash is untrusted, but unhandled. |
| 503 * (As we don't want things like Breakpad handling the crash.) | 515 * (As we don't want things like Breakpad handling the crash.) |
| 504 */ | 516 */ |
| 505 if (is_untrusted) { | 517 if (is_untrusted) { |
| 506 return KERN_FAILURE; | 518 return KERN_FAILURE; |
| 507 } | 519 } |
| 508 | 520 |
| 509 /* Forward on the exception to the old set of ports. */ | 521 /* Forward on the exception to the old set of ports. */ |
| 510 return ForwardException( | 522 return ForwardException( |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 if (data) { | 664 if (data) { |
| 653 if (MACH_PORT_NULL != data->exception_port) { | 665 if (MACH_PORT_NULL != data->exception_port) { |
| 654 mach_port_deallocate(current_task, data->exception_port); | 666 mach_port_deallocate(current_task, data->exception_port); |
| 655 } | 667 } |
| 656 free(data); | 668 free(data); |
| 657 } | 669 } |
| 658 return FALSE; | 670 return FALSE; |
| 659 } | 671 } |
| 660 | 672 |
| 661 #endif /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 */ | 673 #endif /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 */ |
| OLD | NEW |