| Index: util/mach/exc_server_variants.cc
|
| diff --git a/util/mach/exc_server_variants.cc b/util/mach/exc_server_variants.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5ecd05d5f2a94d48cff5ef75669ad78abba9ee34
|
| --- /dev/null
|
| +++ b/util/mach/exc_server_variants.cc
|
| @@ -0,0 +1,674 @@
|
| +// Copyright 2014 The Crashpad Authors. All rights reserved.
|
| +//
|
| +// Licensed under the Apache License, Version 2.0 (the "License");
|
| +// you may not use this file except in compliance with the License.
|
| +// You may obtain a copy of the License at
|
| +//
|
| +// http://www.apache.org/licenses/LICENSE-2.0
|
| +//
|
| +// Unless required by applicable law or agreed to in writing, software
|
| +// distributed under the License is distributed on an "AS IS" BASIS,
|
| +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| +// See the License for the specific language governing permissions and
|
| +// limitations under the License.
|
| +
|
| +#include "util/mach/exc_server_variants.h"
|
| +
|
| +#include <algorithm>
|
| +#include <vector>
|
| +
|
| +#include "base/basictypes.h"
|
| +#include "base/logging.h"
|
| +#include "util/mach/exc.h"
|
| +#include "util/mach/excServer.h"
|
| +#include "util/mach/mach_exc.h"
|
| +#include "util/mach/mach_excServer.h"
|
| +
|
| +extern "C" {
|
| +
|
| +// These six functions are not used, and are in fact obsoleted by the other
|
| +// functionality implemented in this file. The standard MIG-generated exc_server
|
| +// (in excServer.c) and mach_exc_server (in mach_excServer.c) server dispatch
|
| +// routines usable with the standard mach_msg_server() function call out to
|
| +// these functions. exc_server() and mach_exc_server() are unused and are
|
| +// replaced by the more flexible ExcServer and MachExcServer, but the linker
|
| +// still needs to see these six function definitions.
|
| +
|
| +kern_return_t catch_exception_raise(exception_handler_t exception_port,
|
| + thread_t thread,
|
| + task_t task,
|
| + exception_type_t exception,
|
| + exception_data_t code,
|
| + mach_msg_type_number_t code_count) {
|
| + NOTREACHED();
|
| + return KERN_FAILURE;
|
| +}
|
| +
|
| +kern_return_t catch_exception_raise_state(
|
| + exception_handler_t exception_port,
|
| + exception_type_t exception,
|
| + exception_data_t code,
|
| + mach_msg_type_number_t code_count,
|
| + thread_state_flavor_t* flavor,
|
| + thread_state_t old_state,
|
| + mach_msg_type_number_t old_state_count,
|
| + thread_state_t new_state,
|
| + mach_msg_type_number_t* new_state_count) {
|
| + NOTREACHED();
|
| + return KERN_FAILURE;
|
| +}
|
| +
|
| +kern_return_t catch_exception_raise_state_identity(
|
| + exception_handler_t exception_port,
|
| + thread_t thread,
|
| + task_t task,
|
| + exception_type_t exception,
|
| + exception_data_t code,
|
| + mach_msg_type_number_t code_count,
|
| + thread_state_flavor_t* flavor,
|
| + thread_state_t old_state,
|
| + mach_msg_type_number_t old_state_count,
|
| + thread_state_t new_state,
|
| + mach_msg_type_number_t* new_state_count) {
|
| + NOTREACHED();
|
| + return KERN_FAILURE;
|
| +}
|
| +
|
| +kern_return_t catch_mach_exception_raise(exception_handler_t exception_port,
|
| + thread_t thread,
|
| + task_t task,
|
| + exception_type_t exception,
|
| + mach_exception_data_t code,
|
| + mach_msg_type_number_t code_count) {
|
| + NOTREACHED();
|
| + return KERN_FAILURE;
|
| +}
|
| +
|
| +kern_return_t catch_mach_exception_raise_state(
|
| + exception_handler_t exception_port,
|
| + exception_type_t exception,
|
| + mach_exception_data_t code,
|
| + mach_msg_type_number_t code_count,
|
| + thread_state_flavor_t* flavor,
|
| + thread_state_t old_state,
|
| + mach_msg_type_number_t old_state_count,
|
| + thread_state_t new_state,
|
| + mach_msg_type_number_t* new_state_count) {
|
| + NOTREACHED();
|
| + return KERN_FAILURE;
|
| +}
|
| +
|
| +kern_return_t catch_mach_exception_raise_state_identity(
|
| + exception_handler_t exception_port,
|
| + thread_t thread,
|
| + task_t task,
|
| + exception_type_t exception,
|
| + mach_exception_data_t code,
|
| + mach_msg_type_number_t code_count,
|
| + thread_state_flavor_t* flavor,
|
| + thread_state_t old_state,
|
| + mach_msg_type_number_t old_state_count,
|
| + thread_state_t new_state,
|
| + mach_msg_type_number_t* new_state_count) {
|
| + NOTREACHED();
|
| + return KERN_FAILURE;
|
| +}
|
| +
|
| +} // extern "C"
|
| +
|
| +namespace {
|
| +
|
| +void PrepareReplyFromRequest(const mach_msg_header_t* in_header,
|
| + mach_msg_header_t* out_header) {
|
| + out_header->msgh_bits =
|
| + MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(in_header->msgh_bits), 0);
|
| + out_header->msgh_remote_port = in_header->msgh_remote_port;
|
| + out_header->msgh_size = sizeof(mig_reply_error_t);
|
| + out_header->msgh_local_port = MACH_PORT_NULL;
|
| + out_header->msgh_id = in_header->msgh_id + 100;
|
| + reinterpret_cast<mig_reply_error_t*>(out_header)->NDR = NDR_record;
|
| +}
|
| +
|
| +void SetReplyError(mach_msg_header_t* out_header, kern_return_t error) {
|
| + reinterpret_cast<mig_reply_error_t*>(out_header)->RetCode = error;
|
| +}
|
| +
|
| +// There are no predefined constants for these.
|
| +enum MachMessageID : mach_msg_id_t {
|
| + kMachMessageIDExceptionRaise = 2401,
|
| + kMachMessageIDExceptionRaiseState = 2402,
|
| + kMachMessageIDExceptionRaiseStateIdentity = 2403,
|
| + kMachMessageIDMachExceptionRaise = 2405,
|
| + kMachMessageIDMachExceptionRaiseState = 2406,
|
| + kMachMessageIDMachExceptionRaiseStateIdentity = 2407,
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +namespace crashpad {
|
| +namespace internal {
|
| +
|
| +ExcServer::ExcServer(ExcServer::Interface* interface)
|
| + : MachMessageServer::Interface(),
|
| + interface_(interface) {
|
| +}
|
| +
|
| +bool ExcServer::MachMessageServerFunction(mach_msg_header_t* in_header,
|
| + mach_msg_header_t* out_header,
|
| + bool* destroy_complex_request) {
|
| + PrepareReplyFromRequest(in_header, out_header);
|
| +
|
| + switch (in_header->msgh_id) {
|
| + case kMachMessageIDExceptionRaise: {
|
| + // exception_raise(), catch_exception_raise().
|
| + typedef __Request__exception_raise_t Request;
|
| + Request* in_request = reinterpret_cast<Request*>(in_header);
|
| + kern_return_t kr = __MIG_check__Request__exception_raise_t(in_request);
|
| + if (kr != MACH_MSG_SUCCESS) {
|
| + SetReplyError(out_header, kr);
|
| + return true;
|
| + }
|
| +
|
| + typedef __Reply__exception_raise_t Reply;
|
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header);
|
| + out_reply->RetCode =
|
| + interface_->CatchExceptionRaise(in_header->msgh_local_port,
|
| + in_request->thread.name,
|
| + in_request->task.name,
|
| + in_request->exception,
|
| + in_request->code,
|
| + in_request->codeCnt,
|
| + destroy_complex_request);
|
| + if (out_reply->RetCode != KERN_SUCCESS) {
|
| + return true;
|
| + }
|
| +
|
| + out_header->msgh_size = sizeof(*out_reply);
|
| + return true;
|
| + }
|
| +
|
| + case kMachMessageIDExceptionRaiseState: {
|
| + // exception_raise_state(), catch_exception_raise_state().
|
| + typedef __Request__exception_raise_state_t Request;
|
| + Request* in_request = reinterpret_cast<Request*>(in_header);
|
| +
|
| + // in_request_1 is used for the portion of the request after the codes,
|
| + // which in theory can be variable-length. The check function will set it.
|
| + Request* in_request_1;
|
| + kern_return_t kr = __MIG_check__Request__exception_raise_state_t(
|
| + in_request, &in_request_1);
|
| + if (kr != MACH_MSG_SUCCESS) {
|
| + SetReplyError(out_header, kr);
|
| + return true;
|
| + }
|
| +
|
| + typedef __Reply__exception_raise_state_t Reply;
|
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header);
|
| + out_reply->new_stateCnt = arraysize(out_reply->new_state);
|
| + out_reply->RetCode =
|
| + interface_->CatchExceptionRaiseState(in_header->msgh_local_port,
|
| + in_request->exception,
|
| + in_request->code,
|
| + in_request->codeCnt,
|
| + &in_request_1->flavor,
|
| + in_request_1->old_state,
|
| + in_request_1->old_stateCnt,
|
| + out_reply->new_state,
|
| + &out_reply->new_stateCnt);
|
| + if (out_reply->RetCode != KERN_SUCCESS) {
|
| + return true;
|
| + }
|
| +
|
| + out_reply->flavor = in_request_1->flavor;
|
| + out_header->msgh_size =
|
| + sizeof(*out_reply) - sizeof(out_reply->new_state) +
|
| + sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
|
| + return true;
|
| + }
|
| +
|
| + case kMachMessageIDExceptionRaiseStateIdentity: {
|
| + // exception_raise_state_identity(),
|
| + // catch_exception_raise_state_identity().
|
| + typedef __Request__exception_raise_state_identity_t Request;
|
| + Request* in_request = reinterpret_cast<Request*>(in_header);
|
| +
|
| + // in_request_1 is used for the portion of the request after the codes,
|
| + // which in theory can be variable-length. The check function will set it.
|
| + Request* in_request_1;
|
| + kern_return_t kr = __MIG_check__Request__exception_raise_state_identity_t(
|
| + in_request, &in_request_1);
|
| + if (kr != MACH_MSG_SUCCESS) {
|
| + SetReplyError(out_header, kr);
|
| + return true;
|
| + }
|
| +
|
| + typedef __Reply__exception_raise_state_identity_t Reply;
|
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header);
|
| + out_reply->new_stateCnt = arraysize(out_reply->new_state);
|
| + out_reply->RetCode = interface_->CatchExceptionRaiseStateIdentity(
|
| + in_header->msgh_local_port,
|
| + in_request->thread.name,
|
| + in_request->task.name,
|
| + in_request->exception,
|
| + in_request->code,
|
| + in_request->codeCnt,
|
| + &in_request_1->flavor,
|
| + in_request_1->old_state,
|
| + in_request_1->old_stateCnt,
|
| + out_reply->new_state,
|
| + &out_reply->new_stateCnt,
|
| + destroy_complex_request);
|
| + if (out_reply->RetCode != KERN_SUCCESS) {
|
| + return true;
|
| + }
|
| +
|
| + out_reply->flavor = in_request_1->flavor;
|
| + out_header->msgh_size =
|
| + sizeof(*out_reply) - sizeof(out_reply->new_state) +
|
| + sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
|
| + return true;
|
| + }
|
| + }
|
| +
|
| + SetReplyError(out_header, MIG_BAD_ID);
|
| + return false;
|
| +}
|
| +
|
| +mach_msg_size_t ExcServer::MachMessageServerRequestSize() {
|
| + return sizeof(__RequestUnion__exc_subsystem);
|
| +}
|
| +
|
| +mach_msg_size_t ExcServer::MachMessageServerReplySize() {
|
| + return sizeof(__ReplyUnion__exc_subsystem);
|
| +}
|
| +
|
| +MachExcServer::MachExcServer(MachExcServer::Interface* interface)
|
| + : MachMessageServer::Interface(),
|
| + interface_(interface) {
|
| +}
|
| +
|
| +bool MachExcServer::MachMessageServerFunction(mach_msg_header_t* in_header,
|
| + mach_msg_header_t* out_header,
|
| + bool* destroy_complex_request) {
|
| + PrepareReplyFromRequest(in_header, out_header);
|
| +
|
| + switch (in_header->msgh_id) {
|
| + case kMachMessageIDMachExceptionRaise: {
|
| + // mach_exception_raise(), catch_mach_exception_raise().
|
| + typedef __Request__mach_exception_raise_t Request;
|
| + Request* in_request = reinterpret_cast<Request*>(in_header);
|
| + kern_return_t kr =
|
| + __MIG_check__Request__mach_exception_raise_t(in_request);
|
| + if (kr != MACH_MSG_SUCCESS) {
|
| + SetReplyError(out_header, kr);
|
| + return true;
|
| + }
|
| +
|
| + typedef __Reply__mach_exception_raise_t Reply;
|
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header);
|
| + out_reply->RetCode =
|
| + interface_->CatchMachExceptionRaise(in_header->msgh_local_port,
|
| + in_request->thread.name,
|
| + in_request->task.name,
|
| + in_request->exception,
|
| + in_request->code,
|
| + in_request->codeCnt,
|
| + destroy_complex_request);
|
| + if (out_reply->RetCode != KERN_SUCCESS) {
|
| + return true;
|
| + }
|
| +
|
| + out_header->msgh_size = sizeof(*out_reply);
|
| + return true;
|
| + }
|
| +
|
| + case kMachMessageIDMachExceptionRaiseState: {
|
| + // mach_exception_raise_state(), catch_mach_exception_raise_state().
|
| + typedef __Request__mach_exception_raise_state_t Request;
|
| + Request* in_request = reinterpret_cast<Request*>(in_header);
|
| +
|
| + // in_request_1 is used for the portion of the request after the codes,
|
| + // which in theory can be variable-length. The check function will set it.
|
| + Request* in_request_1;
|
| + kern_return_t kr = __MIG_check__Request__mach_exception_raise_state_t(
|
| + in_request, &in_request_1);
|
| + if (kr != MACH_MSG_SUCCESS) {
|
| + SetReplyError(out_header, kr);
|
| + return true;
|
| + }
|
| +
|
| + typedef __Reply__mach_exception_raise_state_t Reply;
|
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header);
|
| + out_reply->new_stateCnt = arraysize(out_reply->new_state);
|
| + out_reply->RetCode =
|
| + interface_->CatchMachExceptionRaiseState(in_header->msgh_local_port,
|
| + in_request->exception,
|
| + in_request->code,
|
| + in_request->codeCnt,
|
| + &in_request_1->flavor,
|
| + in_request_1->old_state,
|
| + in_request_1->old_stateCnt,
|
| + out_reply->new_state,
|
| + &out_reply->new_stateCnt);
|
| + if (out_reply->RetCode != KERN_SUCCESS) {
|
| + return true;
|
| + }
|
| +
|
| + out_reply->flavor = in_request_1->flavor;
|
| + out_header->msgh_size =
|
| + sizeof(*out_reply) - sizeof(out_reply->new_state) +
|
| + sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
|
| + return true;
|
| + }
|
| +
|
| + case kMachMessageIDMachExceptionRaiseStateIdentity: {
|
| + // mach_exception_raise_state_identity(),
|
| + // catch_mach_exception_raise_state_identity().
|
| + typedef __Request__mach_exception_raise_state_identity_t Request;
|
| + Request* in_request = reinterpret_cast<Request*>(in_header);
|
| +
|
| + // in_request_1 is used for the portion of the request after the codes,
|
| + // which in theory can be variable-length. The check function will set it.
|
| + Request* in_request_1;
|
| + kern_return_t kr =
|
| + __MIG_check__Request__mach_exception_raise_state_identity_t(
|
| + in_request, &in_request_1);
|
| + if (kr != MACH_MSG_SUCCESS) {
|
| + SetReplyError(out_header, kr);
|
| + return true;
|
| + }
|
| +
|
| + typedef __Reply__mach_exception_raise_state_identity_t Reply;
|
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header);
|
| + out_reply->new_stateCnt = arraysize(out_reply->new_state);
|
| + out_reply->RetCode = interface_->CatchMachExceptionRaiseStateIdentity(
|
| + in_header->msgh_local_port,
|
| + in_request->thread.name,
|
| + in_request->task.name,
|
| + in_request->exception,
|
| + in_request->code,
|
| + in_request->codeCnt,
|
| + &in_request_1->flavor,
|
| + in_request_1->old_state,
|
| + in_request_1->old_stateCnt,
|
| + out_reply->new_state,
|
| + &out_reply->new_stateCnt,
|
| + destroy_complex_request);
|
| + if (out_reply->RetCode != KERN_SUCCESS) {
|
| + return true;
|
| + }
|
| +
|
| + out_reply->flavor = in_request_1->flavor;
|
| + out_header->msgh_size =
|
| + sizeof(*out_reply) - sizeof(out_reply->new_state) +
|
| + sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
|
| + return true;
|
| + }
|
| + }
|
| +
|
| + SetReplyError(out_header, MIG_BAD_ID);
|
| + return false;
|
| +}
|
| +
|
| +mach_msg_size_t MachExcServer::MachMessageServerRequestSize() {
|
| + return sizeof(__RequestUnion__mach_exc_subsystem);
|
| +}
|
| +
|
| +mach_msg_size_t MachExcServer::MachMessageServerReplySize() {
|
| + return sizeof(__ReplyUnion__mach_exc_subsystem);
|
| +}
|
| +
|
| +SimplifiedExcServer::SimplifiedExcServer(
|
| + SimplifiedExcServer::Interface* interface)
|
| + : ExcServer(this),
|
| + ExcServer::Interface(),
|
| + interface_(interface) {
|
| +}
|
| +
|
| +kern_return_t SimplifiedExcServer::CatchExceptionRaise(
|
| + exception_handler_t exception_port,
|
| + thread_t thread,
|
| + task_t task,
|
| + exception_type_t exception,
|
| + const exception_data_type_t* code,
|
| + mach_msg_type_number_t code_count,
|
| + bool* destroy_request) {
|
| + thread_state_flavor_t flavor = THREAD_STATE_NONE;
|
| + mach_msg_type_number_t new_state_count = 0;
|
| + return interface_->CatchException(EXCEPTION_DEFAULT,
|
| + exception_port,
|
| + thread,
|
| + task,
|
| + exception,
|
| + code,
|
| + code_count,
|
| + &flavor,
|
| + NULL,
|
| + 0,
|
| + NULL,
|
| + &new_state_count,
|
| + destroy_request);
|
| +}
|
| +
|
| +kern_return_t SimplifiedExcServer::CatchExceptionRaiseState(
|
| + exception_handler_t exception_port,
|
| + exception_type_t exception,
|
| + const exception_data_type_t* code,
|
| + mach_msg_type_number_t code_count,
|
| + thread_state_flavor_t* flavor,
|
| + const natural_t* old_state,
|
| + mach_msg_type_number_t old_state_count,
|
| + thread_state_t new_state,
|
| + mach_msg_type_number_t* new_state_count) {
|
| + bool destroy_complex_request = false;
|
| + return interface_->CatchException(EXCEPTION_STATE,
|
| + exception_port,
|
| + MACH_PORT_NULL,
|
| + MACH_PORT_NULL,
|
| + exception,
|
| + code,
|
| + code_count,
|
| + flavor,
|
| + old_state,
|
| + old_state_count,
|
| + new_state,
|
| + new_state_count,
|
| + &destroy_complex_request);
|
| +}
|
| +
|
| +kern_return_t SimplifiedExcServer::CatchExceptionRaiseStateIdentity(
|
| + exception_handler_t exception_port,
|
| + thread_t thread,
|
| + task_t task,
|
| + exception_type_t exception,
|
| + const exception_data_type_t* code,
|
| + mach_msg_type_number_t code_count,
|
| + thread_state_flavor_t* flavor,
|
| + const natural_t* old_state,
|
| + mach_msg_type_number_t old_state_count,
|
| + thread_state_t new_state,
|
| + mach_msg_type_number_t* new_state_count,
|
| + bool* destroy_request) {
|
| + return interface_->CatchException(EXCEPTION_STATE_IDENTITY,
|
| + exception_port,
|
| + thread,
|
| + task,
|
| + exception,
|
| + code,
|
| + code_count,
|
| + flavor,
|
| + old_state,
|
| + old_state_count,
|
| + new_state,
|
| + new_state_count,
|
| + destroy_request);
|
| +}
|
| +
|
| +SimplifiedMachExcServer::SimplifiedMachExcServer(
|
| + SimplifiedMachExcServer::Interface* interface)
|
| + : MachExcServer(this),
|
| + MachExcServer::Interface(),
|
| + interface_(interface) {
|
| +}
|
| +
|
| +kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaise(
|
| + exception_handler_t exception_port,
|
| + thread_t thread,
|
| + task_t task,
|
| + exception_type_t exception,
|
| + const mach_exception_data_type_t* code,
|
| + mach_msg_type_number_t code_count,
|
| + bool* destroy_request) {
|
| + thread_state_flavor_t flavor = THREAD_STATE_NONE;
|
| + mach_msg_type_number_t new_state_count = 0;
|
| + return interface_->CatchMachException(
|
| + EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES,
|
| + exception_port,
|
| + thread,
|
| + task,
|
| + exception,
|
| + code,
|
| + code_count,
|
| + &flavor,
|
| + NULL,
|
| + 0,
|
| + NULL,
|
| + &new_state_count,
|
| + destroy_request);
|
| +}
|
| +
|
| +kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseState(
|
| + exception_handler_t exception_port,
|
| + exception_type_t exception,
|
| + const mach_exception_data_type_t* code,
|
| + mach_msg_type_number_t code_count,
|
| + thread_state_flavor_t* flavor,
|
| + const natural_t* old_state,
|
| + mach_msg_type_number_t old_state_count,
|
| + thread_state_t new_state,
|
| + mach_msg_type_number_t* new_state_count) {
|
| + bool destroy_complex_request = false;
|
| + return interface_->CatchMachException(EXCEPTION_STATE | MACH_EXCEPTION_CODES,
|
| + exception_port,
|
| + MACH_PORT_NULL,
|
| + MACH_PORT_NULL,
|
| + exception,
|
| + code,
|
| + code_count,
|
| + flavor,
|
| + old_state,
|
| + old_state_count,
|
| + new_state,
|
| + new_state_count,
|
| + &destroy_complex_request);
|
| +}
|
| +
|
| +kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseStateIdentity(
|
| + exception_handler_t exception_port,
|
| + thread_t thread,
|
| + task_t task,
|
| + exception_type_t exception,
|
| + const mach_exception_data_type_t* code,
|
| + mach_msg_type_number_t code_count,
|
| + thread_state_flavor_t* flavor,
|
| + const natural_t* old_state,
|
| + mach_msg_type_number_t old_state_count,
|
| + thread_state_t new_state,
|
| + mach_msg_type_number_t* new_state_count,
|
| + bool* destroy_request) {
|
| + return interface_->CatchMachException(
|
| + EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
|
| + exception_port,
|
| + thread,
|
| + task,
|
| + exception,
|
| + code,
|
| + code_count,
|
| + flavor,
|
| + old_state,
|
| + old_state_count,
|
| + new_state,
|
| + new_state_count,
|
| + destroy_request);
|
| +}
|
| +
|
| +} // namespace internal
|
| +
|
| +UniversalMachExcServer::UniversalMachExcServer()
|
| + : MachMessageServer::Interface(),
|
| + internal::SimplifiedExcServer::Interface(),
|
| + internal::SimplifiedMachExcServer::Interface(),
|
| + exc_server_(this),
|
| + mach_exc_server_(this) {
|
| +}
|
| +
|
| +bool UniversalMachExcServer::MachMessageServerFunction(
|
| + mach_msg_header_t* in_header,
|
| + mach_msg_header_t* out_header,
|
| + bool* destroy_complex_request) {
|
| + switch (in_header->msgh_id) {
|
| + case kMachMessageIDMachExceptionRaise:
|
| + case kMachMessageIDMachExceptionRaiseState:
|
| + case kMachMessageIDMachExceptionRaiseStateIdentity:
|
| + return mach_exc_server_.MachMessageServerFunction(
|
| + in_header, out_header, destroy_complex_request);
|
| + case kMachMessageIDExceptionRaise:
|
| + case kMachMessageIDExceptionRaiseState:
|
| + case kMachMessageIDExceptionRaiseStateIdentity:
|
| + return exc_server_.MachMessageServerFunction(
|
| + in_header, out_header, destroy_complex_request);
|
| + }
|
| +
|
| + // Do what the MIG-generated server routines do when they can’t dispatch a
|
| + // message.
|
| + PrepareReplyFromRequest(in_header, out_header);
|
| + SetReplyError(out_header, MIG_BAD_ID);
|
| + return false;
|
| +}
|
| +
|
| +mach_msg_size_t UniversalMachExcServer::MachMessageServerRequestSize() {
|
| + return std::max(mach_exc_server_.MachMessageServerRequestSize(),
|
| + exc_server_.MachMessageServerRequestSize());
|
| +}
|
| +
|
| +mach_msg_size_t UniversalMachExcServer::MachMessageServerReplySize() {
|
| + return std::max(mach_exc_server_.MachMessageServerReplySize(),
|
| + exc_server_.MachMessageServerReplySize());
|
| +}
|
| +
|
| +kern_return_t UniversalMachExcServer::CatchException(
|
| + exception_behavior_t behavior,
|
| + exception_handler_t exception_port,
|
| + thread_t thread,
|
| + task_t task,
|
| + exception_type_t exception,
|
| + const exception_data_type_t* code,
|
| + mach_msg_type_number_t code_count,
|
| + thread_state_flavor_t* flavor,
|
| + const natural_t* old_state,
|
| + mach_msg_type_number_t old_state_count,
|
| + thread_state_t new_state,
|
| + mach_msg_type_number_t* new_state_count,
|
| + bool* destroy_complex_request) {
|
| + std::vector<mach_exception_data_type_t> mach_codes;
|
| + mach_codes.reserve(code_count);
|
| + for (size_t index = 0; index < code_count; ++index) {
|
| + mach_codes.push_back(code[index]);
|
| + }
|
| +
|
| + return CatchMachException(behavior,
|
| + exception_port,
|
| + thread,
|
| + task,
|
| + exception,
|
| + code_count ? &mach_codes[0] : NULL,
|
| + code_count,
|
| + flavor,
|
| + old_state,
|
| + old_state_count,
|
| + new_state,
|
| + new_state_count,
|
| + destroy_complex_request);
|
| +}
|
| +
|
| +} // namespace crashpad
|
|
|