OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
| 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. |
| 14 |
| 15 #include "util/mach/exc_client_variants.h" |
| 16 |
| 17 #include <vector> |
| 18 |
| 19 #include "base/logging.h" |
| 20 #include "util/mach/exc.h" |
| 21 #include "util/mach/mach_exc.h" |
| 22 #include "util/mach/mach_extensions.h" |
| 23 |
| 24 namespace crashpad { |
| 25 |
| 26 kern_return_t UniversalExceptionRaise(exception_behavior_t behavior, |
| 27 exception_handler_t exception_port, |
| 28 thread_t thread, |
| 29 task_t task, |
| 30 exception_type_t exception, |
| 31 const mach_exception_data_type_t* code, |
| 32 mach_msg_type_number_t code_count, |
| 33 thread_state_flavor_t* flavor, |
| 34 const natural_t* old_state, |
| 35 mach_msg_type_number_t old_state_count, |
| 36 thread_state_t new_state, |
| 37 mach_msg_type_number_t* new_state_count) { |
| 38 // This function is similar to 10.9.4 xnu-2422.110.17/osfmk/kern/exception.c |
| 39 // exception_deliver() as far as the delivery logic is concerned. Unlike |
| 40 // exception_deliver(), this function does not get or set thread states for |
| 41 // behavior values that require this, as that is left to the caller to do if |
| 42 // needed. |
| 43 |
| 44 std::vector<exception_data_type_t> small_code_vector; |
| 45 exception_data_t small_code = NULL; |
| 46 if ((behavior & MACH_EXCEPTION_CODES) == 0 && code_count) { |
| 47 small_code_vector.reserve(code_count); |
| 48 for (size_t code_index = 0; code_index < code_count; ++code_index) { |
| 49 small_code_vector[code_index] = code[code_index]; |
| 50 } |
| 51 small_code = &small_code_vector[0]; |
| 52 } |
| 53 |
| 54 // The *exception_raise*() family has bad declarations. Their code and |
| 55 // old_state arguments aren’t pointers to const data, although they should be. |
| 56 // The generated stubs in excUser.c and mach_excUser.c make it clear that the |
| 57 // data is never modified, and these parameters could be declared with const |
| 58 // appropriately. The uses of const_cast below are thus safe. |
| 59 |
| 60 switch (behavior) { |
| 61 case EXCEPTION_DEFAULT: |
| 62 return exception_raise( |
| 63 exception_port, thread, task, exception, small_code, code_count); |
| 64 |
| 65 case EXCEPTION_STATE: |
| 66 return exception_raise_state(exception_port, |
| 67 exception, |
| 68 small_code, |
| 69 code_count, |
| 70 flavor, |
| 71 const_cast<thread_state_t>(old_state), |
| 72 old_state_count, |
| 73 new_state, |
| 74 new_state_count); |
| 75 |
| 76 case EXCEPTION_STATE_IDENTITY: |
| 77 return exception_raise_state_identity( |
| 78 exception_port, |
| 79 thread, |
| 80 task, |
| 81 exception, |
| 82 small_code, |
| 83 code_count, |
| 84 flavor, |
| 85 const_cast<thread_state_t>(old_state), |
| 86 old_state_count, |
| 87 new_state, |
| 88 new_state_count); |
| 89 |
| 90 case EXCEPTION_DEFAULT | kMachExceptionCodes: |
| 91 return mach_exception_raise(exception_port, |
| 92 thread, |
| 93 task, |
| 94 exception, |
| 95 const_cast<mach_exception_data_type_t*>(code), |
| 96 code_count); |
| 97 |
| 98 case EXCEPTION_STATE | kMachExceptionCodes: |
| 99 return mach_exception_raise_state( |
| 100 exception_port, |
| 101 exception, |
| 102 const_cast<mach_exception_data_type_t*>(code), |
| 103 code_count, |
| 104 flavor, |
| 105 const_cast<thread_state_t>(old_state), |
| 106 old_state_count, |
| 107 new_state, |
| 108 new_state_count); |
| 109 |
| 110 case EXCEPTION_STATE_IDENTITY | kMachExceptionCodes: |
| 111 return mach_exception_raise_state_identity( |
| 112 exception_port, |
| 113 thread, |
| 114 task, |
| 115 exception, |
| 116 const_cast<mach_exception_data_type_t*>(code), |
| 117 code_count, |
| 118 flavor, |
| 119 const_cast<thread_state_t>(old_state), |
| 120 old_state_count, |
| 121 new_state, |
| 122 new_state_count); |
| 123 |
| 124 default: |
| 125 NOTREACHED(); |
| 126 return KERN_INVALID_ARGUMENT; |
| 127 } |
| 128 } |
| 129 |
| 130 } // namespace crashpad |
OLD | NEW |