Add ChildPortServer, a MachMessageServer::Interface implementation for

the child_port subsystem.

Common routines shared with the ExcServer family of classes have been
moved to a new file, where they can be shared between different
MachMessageServer::Interface implementations.

TEST=util_test ChildPortServer.*:MachMessageUtil.*
R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/754123002
This commit is contained in:
Mark Mentovai 2014-11-25 14:29:46 -05:00
parent af1c7eb098
commit 04aaa36026
9 changed files with 507 additions and 27 deletions

View File

@ -0,0 +1,110 @@
// 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/child_port_server.h"
#include "base/logging.h"
#include "util/mach/child_portServer.h"
#include "util/mach/mach_message_util.h"
extern "C" {
// This function is not used, and is in fact obsoleted by the other
// functionality implemented in this file. The standard MIG-generated
// child_port_server() (in child_portServer.c) server dispatch routine usable
// with the standard mach_msg_server() function calls out to this function.
// child_port_server() is unused and is replaced by the more flexible
// ChildPortServer, but the linker still needs to see this function definition.
kern_return_t handle_child_port_check_in(child_port_server_t server,
child_port_token_t token,
mach_port_t port,
mach_msg_type_name_t right_type) {
NOTREACHED();
return KERN_FAILURE;
}
} // extern "C"
namespace {
// There is no predefined constant for this.
enum MachMessageID : mach_msg_id_t {
kMachMessageIDChildPortCheckIn = 10011,
};
// The MIG-generated __MIG_check__Request__*() functions are not declared as
// accepting const data, but they could have been because they in fact do not
// modify the data. This wrapper function is provided to bridge the const gap
// between the code in this file, which is const-correct and treats request
// message data as const, and the generated function.
kern_return_t MIGCheckRequestChildPortCheckIn(
const __Request__child_port_check_in_t* in_request) {
using Request = __Request__child_port_check_in_t;
return __MIG_check__Request__child_port_check_in_t(
const_cast<Request*>(in_request));
}
} // namespace
namespace crashpad {
ChildPortServer::ChildPortServer(ChildPortServer::Interface* interface)
: MachMessageServer::Interface(),
interface_(interface) {
}
bool ChildPortServer::MachMessageServerFunction(
const mach_msg_header_t* in_header,
mach_msg_header_t* out_header,
bool* destroy_complex_request) {
PrepareMIGReplyFromRequest(in_header, out_header);
switch (in_header->msgh_id) {
case kMachMessageIDChildPortCheckIn: {
// child_port_check_in(), handle_child_port_check_in().
using Request = __Request__child_port_check_in_t;
const Request* in_request = reinterpret_cast<const Request*>(in_header);
kern_return_t kr = MIGCheckRequestChildPortCheckIn(in_request);
if (kr != MACH_MSG_SUCCESS) {
SetMIGReplyError(out_header, kr);
return true;
}
using Reply = __Reply__child_port_check_in_t;
Reply* out_reply = reinterpret_cast<Reply*>(out_header);
out_reply->RetCode =
interface_->HandleChildPortCheckIn(in_header->msgh_local_port,
in_request->token,
in_request->port.name,
in_request->port.disposition,
destroy_complex_request);
return true;
}
}
SetMIGReplyError(out_header, MIG_BAD_ID);
return false;
}
mach_msg_size_t ChildPortServer::MachMessageServerRequestSize() {
return sizeof(__RequestUnion__handle_child_port_subsystem);
}
mach_msg_size_t ChildPortServer::MachMessageServerReplySize() {
return sizeof(__ReplyUnion__handle_child_port_subsystem);
}
} // namespace crashpad

View File

@ -0,0 +1,74 @@
// 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.
#ifndef CRASHPAD_UTIL_MACH_CHILD_PORT_SERVER_H_
#define CRASHPAD_UTIL_MACH_CHILD_PORT_SERVER_H_
#include <mach/mach.h>
#include "base/basictypes.h"
#include "util/mach/child_port_types.h"
#include "util/mach/mach_message_server.h"
namespace crashpad {
//! \brief A server interface for the `child_port` Mach subsystem.
class ChildPortServer : public MachMessageServer::Interface {
public:
//! \brief An interface that the request message that is a part of the
//! `child_port` Mach subsystem can be dispatched to.
class Interface {
public:
//! \brief Handles check-ins sent by `child_port_check_in()`.
//!
//! This behaves equivalently to a `handle_child_port_check_in()` function
//! used with `child_port_server()`.
//!
//! \param[out] destroy_request `true` if the request message is to be
//! destroyed even when this method returns success. See
//! MachMessageServer::Interface.
virtual kern_return_t HandleChildPortCheckIn(
child_port_server_t server,
const child_port_token_t token,
mach_port_t port,
mach_msg_type_name_t right_type,
bool* destroy_complex_request) = 0;
protected:
~Interface() {}
};
//! \brief Constructs an object of this class.
//!
//! \param[in] interface The interface to dispatch requests to. Weak.
explicit ChildPortServer(Interface* interface);
// MachMessageServer::Interface:
bool MachMessageServerFunction(const mach_msg_header_t* in_header,
mach_msg_header_t* out_header,
bool* destroy_complex_request) override;
mach_msg_size_t MachMessageServerRequestSize() override;
mach_msg_size_t MachMessageServerReplySize() override;
private:
Interface* interface_; // weak
DISALLOW_COPY_AND_ASSIGN(ChildPortServer);
};
} // namespace crashpad
#endif // CRASHPAD_UTIL_MACH_CHILD_PORT_SERVER_H_

View File

@ -0,0 +1,133 @@
// 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/child_port_server.h"
#include <string.h>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "util/mach/mach_extensions.h"
namespace crashpad {
namespace test {
namespace {
using testing::Eq;
using testing::Pointee;
using testing::Return;
// Fake Mach ports. These arent used as ports in these tests, theyre just used
// as cookies to make sure that the correct values get passed to the correct
// places.
const mach_port_t kServerLocalPort = 0x05050505;
const mach_port_t kCheckInPort = 0x06060606;
// Other fake values.
const mach_msg_type_name_t kCheckInPortRightType = MACH_MSG_TYPE_PORT_SEND;
const child_port_token_t kCheckInToken = 0xfedcba9876543210;
// The definition of the request structure from child_port.h isnt available
// here. It needs custom initialization code, so duplicate the expected
// definition of the structure from child_port.h here in this file, and provide
// the initialization code as a method in true object-oriented fashion.
struct __attribute__((packed, aligned(4))) ChildPortCheckInRequest {
ChildPortCheckInRequest() {
memset(this, 0xa5, sizeof(*this));
Head.msgh_bits =
MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND) | MACH_MSGH_BITS_COMPLEX;
Head.msgh_size = sizeof(*this);
Head.msgh_remote_port = MACH_PORT_NULL;
Head.msgh_local_port = kServerLocalPort;
Head.msgh_id = 10011;
msgh_body.msgh_descriptor_count = 1;
port.name = kCheckInPort;
port.disposition = kCheckInPortRightType;
port.type = MACH_MSG_PORT_DESCRIPTOR;
NDR = NDR_record;
token = kCheckInToken;
}
mach_msg_header_t Head;
mach_msg_body_t msgh_body;
mach_msg_port_descriptor_t port;
NDR_record_t NDR;
child_port_token_t token;
};
struct __attribute__((packed, aligned(4))) MIGReply {
MIGReply() {
memset(this, 0x5a, sizeof(*this));
RetCode = KERN_FAILURE;
}
mach_msg_header_t Head;
NDR_record_t NDR;
kern_return_t RetCode;
void Verify() {
EXPECT_EQ(implicit_cast<mach_msg_bits_t>(MACH_MSGH_BITS(0, 0)),
Head.msgh_bits);
EXPECT_EQ(sizeof(*this), Head.msgh_size);
EXPECT_EQ(kMachPortNull, Head.msgh_remote_port);
EXPECT_EQ(kMachPortNull, Head.msgh_local_port);
EXPECT_EQ(10111, Head.msgh_id);
EXPECT_EQ(0, memcmp(&NDR, &NDR_record, sizeof(NDR)));
EXPECT_EQ(MIG_NO_REPLY, RetCode);
}
};
class MockChildPortServerInterface : public ChildPortServer::Interface {
public:
MOCK_METHOD5(HandleChildPortCheckIn,
kern_return_t(child_port_server_t server,
const child_port_token_t token,
mach_port_t port,
mach_msg_type_name_t right_type,
bool* destroy_complex_request));
};
TEST(ChildPortServer, MockChildPortCheckIn) {
MockChildPortServerInterface server_interface;
ChildPortServer server(&server_interface);
ChildPortCheckInRequest request;
EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize());
MIGReply reply;
EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize());
EXPECT_CALL(server_interface,
HandleChildPortCheckIn(kServerLocalPort,
kCheckInToken,
kCheckInPort,
kCheckInPortRightType,
Pointee(Eq(false))))
.WillOnce(Return(MIG_NO_REPLY))
.RetiresOnSaturation();
bool destroy_complex_request = false;
EXPECT_TRUE(server.MachMessageServerFunction(
reinterpret_cast<mach_msg_header_t*>(&request),
reinterpret_cast<mach_msg_header_t*>(&reply),
&destroy_complex_request));
EXPECT_FALSE(destroy_complex_request);
reply.Verify();
}
} // namespace
} // namespace test
} // namespace crashpad

View File

@ -23,6 +23,7 @@
#include "util/mach/excServer.h"
#include "util/mach/mach_exc.h"
#include "util/mach/mach_excServer.h"
#include "util/mach/mach_message_util.h"
extern "C" {
@ -118,21 +119,6 @@ kern_return_t catch_mach_exception_raise_state_identity(
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,
@ -208,7 +194,7 @@ ExcServer::ExcServer(ExcServer::Interface* interface)
bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
mach_msg_header_t* out_header,
bool* destroy_complex_request) {
PrepareReplyFromRequest(in_header, out_header);
PrepareMIGReplyFromRequest(in_header, out_header);
switch (in_header->msgh_id) {
case kMachMessageIDExceptionRaise: {
@ -217,7 +203,7 @@ bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
const Request* in_request = reinterpret_cast<const Request*>(in_header);
kern_return_t kr = MIGCheckRequestExceptionRaise(in_request);
if (kr != MACH_MSG_SUCCESS) {
SetReplyError(out_header, kr);
SetMIGReplyError(out_header, kr);
return true;
}
@ -250,7 +236,7 @@ bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
kern_return_t kr =
MIGCheckRequestExceptionRaiseState(in_request, &in_request_1);
if (kr != MACH_MSG_SUCCESS) {
SetReplyError(out_header, kr);
SetMIGReplyError(out_header, kr);
return true;
}
@ -290,7 +276,7 @@ bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
kern_return_t kr =
MIGCheckRequestExceptionRaiseStateIdentity(in_request, &in_request_1);
if (kr != MACH_MSG_SUCCESS) {
SetReplyError(out_header, kr);
SetMIGReplyError(out_header, kr);
return true;
}
@ -322,7 +308,7 @@ bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
}
}
SetReplyError(out_header, MIG_BAD_ID);
SetMIGReplyError(out_header, MIG_BAD_ID);
return false;
}
@ -343,7 +329,7 @@ bool MachExcServer::MachMessageServerFunction(
const mach_msg_header_t* in_header,
mach_msg_header_t* out_header,
bool* destroy_complex_request) {
PrepareReplyFromRequest(in_header, out_header);
PrepareMIGReplyFromRequest(in_header, out_header);
switch (in_header->msgh_id) {
case kMachMessageIDMachExceptionRaise: {
@ -352,7 +338,7 @@ bool MachExcServer::MachMessageServerFunction(
const Request* in_request = reinterpret_cast<const Request*>(in_header);
kern_return_t kr = MIGCheckRequestMachExceptionRaise(in_request);
if (kr != MACH_MSG_SUCCESS) {
SetReplyError(out_header, kr);
SetMIGReplyError(out_header, kr);
return true;
}
@ -385,7 +371,7 @@ bool MachExcServer::MachMessageServerFunction(
kern_return_t kr =
MIGCheckRequestMachExceptionRaiseState(in_request, &in_request_1);
if (kr != MACH_MSG_SUCCESS) {
SetReplyError(out_header, kr);
SetMIGReplyError(out_header, kr);
return true;
}
@ -425,7 +411,7 @@ bool MachExcServer::MachMessageServerFunction(
kern_return_t kr = MIGCheckRequestMachExceptionRaiseStateIdentity(
in_request, &in_request_1);
if (kr != MACH_MSG_SUCCESS) {
SetReplyError(out_header, kr);
SetMIGReplyError(out_header, kr);
return true;
}
@ -457,7 +443,7 @@ bool MachExcServer::MachMessageServerFunction(
}
}
SetReplyError(out_header, MIG_BAD_ID);
SetMIGReplyError(out_header, MIG_BAD_ID);
return false;
}
@ -672,8 +658,8 @@ bool UniversalMachExcServer::MachMessageServerFunction(
// Do what the MIG-generated server routines do when they cant dispatch a
// message.
PrepareReplyFromRequest(in_header, out_header);
SetReplyError(out_header, MIG_BAD_ID);
PrepareMIGReplyFromRequest(in_header, out_header);
SetMIGReplyError(out_header, MIG_BAD_ID);
return false;
}

View File

@ -100,6 +100,9 @@ class ExcServer : public MachMessageServer::Interface {
~Interface() {}
};
//! \brief Constructs an object of this class.
//!
//! \param[in] interface The interface to dispatch requests to. Weak.
explicit ExcServer(Interface* interface);
// MachMessageServer::Interface:
@ -189,6 +192,9 @@ class MachExcServer : public MachMessageServer::Interface {
~Interface() {}
};
//! \brief Constructs an object of this class.
//!
//! \param[in] interface The interface to dispatch requests to. Weak.
explicit MachExcServer(Interface* interface);
// MachMessageServer::Interface:
@ -248,6 +254,9 @@ class SimplifiedExcServer : public ExcServer, public ExcServer::Interface {
~Interface() {}
};
//! \brief Constructs an object of this class.
//!
//! \param[in] interface The interface to dispatch requests to. Weak.
explicit SimplifiedExcServer(Interface* interface);
// ExcServer::Interface:
@ -341,6 +350,9 @@ class SimplifiedMachExcServer : public MachExcServer,
~Interface() {}
};
//! \brief Constructs an object of this class.
//!
//! \param[in] interface The interface to dispatch requests to. Weak.
explicit SimplifiedMachExcServer(Interface* interface);
// MachExcServer::Interface:
@ -402,6 +414,7 @@ class UniversalMachExcServer
public internal::SimplifiedExcServer::Interface,
public internal::SimplifiedMachExcServer::Interface {
public:
//! \brief Constructs an object of this class.
UniversalMachExcServer();
// MachMessageServer::Interface:

View File

@ -0,0 +1,37 @@
// 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/mach_message_util.h"
namespace crashpad {
void PrepareMIGReplyFromRequest(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;
// MIG-generated dispatch routines dont do this, but they should.
out_header->msgh_reserved = 0;
}
void SetMIGReplyError(mach_msg_header_t* out_header, kern_return_t error) {
reinterpret_cast<mig_reply_error_t*>(out_header)->RetCode = error;
}
} // namespace crashpad

View File

@ -0,0 +1,53 @@
// 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.
#ifndef CRASHPAD_UTIL_MACH_MACH_MESSAGE_UTIL_H_
#define CRASHPAD_UTIL_MACH_MACH_MESSAGE_UTIL_H_
#include <mach/mach.h>
namespace crashpad {
//! \brief Initializes a reply message for a MIG server routine based on its
//! corresponding request.
//!
//! If a request is handled by a server routine, it may be necessary to revise
//! some of the fields set by this function, such as `msgh_size` and any fields
//! defined in a routines reply structure type.
//!
//! \param[in] in_header The request message to base the reply on.
//! \param[out] out_header The reply message to initialize. \a out_header will
//! be treated as a `mig_reply_error_t*` and all of its fields will be set
//! except for `RetCode`, which must be set by SetMIGReplyError(). This
//! argument is accepted as a `mach_msg_header_t*` instead of a
//! `mig_reply_error_t*` because that is the type that callers are expected
//! to possess in the C API.
void PrepareMIGReplyFromRequest(const mach_msg_header_t* in_header,
mach_msg_header_t* out_header);
//! \brief Sets the error code in a reply message for a MIG server routine.
//!
//! \param[inout] out_header The reply message to operate on. \a out_header will
//! be treated as a `mig_reply_error_t*` and its `RetCode` field will be
//! set. This argument is accepted as a `mach_msg_header_t*` instead of a
//! `mig_reply_error_t*` because that is the type that callers are expected
//! to possess in the C API.
//! \param[in] error The error code to store in \a out_header.
//!
//! \sa PrepareMIGReplyFromRequest()
void SetMIGReplyError(mach_msg_header_t* out_header, kern_return_t error);
} // namespace crashpad
#endif // CRASHPAD_UTIL_MACH_MACH_MESSAGE_UTIL_H_

View File

@ -0,0 +1,68 @@
// 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/mach_message_util.h"
#include "base/basictypes.h"
#include "gtest/gtest.h"
#include "util/mach/mach_extensions.h"
namespace crashpad {
namespace test {
namespace {
TEST(MachMessageUtil, PrepareMIGReplyFromRequest_SetMIGReplyError) {
mach_msg_header_t request;
request.msgh_bits =
MACH_MSGH_BITS_COMPLEX |
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND);
request.msgh_size = 64;
request.msgh_remote_port = 0x01234567;
request.msgh_local_port = 0x89abcdef;
request.msgh_reserved = 0xa5a5a5a5;
request.msgh_id = 1011;
mig_reply_error_t reply;
// PrepareMIGReplyFromRequest() doesnt touch this field.
reply.RetCode = MIG_TYPE_ERROR;
PrepareMIGReplyFromRequest(&request, &reply.Head);
EXPECT_EQ(implicit_cast<mach_msg_bits_t>(
MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0)),
reply.Head.msgh_bits);
EXPECT_EQ(sizeof(reply), reply.Head.msgh_size);
EXPECT_EQ(request.msgh_remote_port, reply.Head.msgh_remote_port);
EXPECT_EQ(kMachPortNull, reply.Head.msgh_local_port);
EXPECT_EQ(0u, reply.Head.msgh_reserved);
EXPECT_EQ(1111, reply.Head.msgh_id);
EXPECT_EQ(NDR_record.mig_vers, reply.NDR.mig_vers);
EXPECT_EQ(NDR_record.if_vers, reply.NDR.if_vers);
EXPECT_EQ(NDR_record.reserved1, reply.NDR.reserved1);
EXPECT_EQ(NDR_record.mig_encoding, reply.NDR.mig_encoding);
EXPECT_EQ(NDR_record.int_rep, reply.NDR.int_rep);
EXPECT_EQ(NDR_record.char_rep, reply.NDR.char_rep);
EXPECT_EQ(NDR_record.float_rep, reply.NDR.float_rep);
EXPECT_EQ(NDR_record.reserved2, reply.NDR.reserved2);
EXPECT_EQ(MIG_TYPE_ERROR, reply.RetCode);
SetMIGReplyError(&reply.Head, MIG_BAD_ID);
EXPECT_EQ(MIG_BAD_ID, reply.RetCode);
}
} // namespace
} // namespace test
} // namespace crashpad

View File

@ -40,6 +40,8 @@
'mac/mac_util.h',
'mac/service_management.cc',
'mac/service_management.h',
'mach/child_port_server.cc',
'mach/child_port_server.h',
'mach/child_port_types.h',
'mach/exc_client_variants.cc',
'mach/exc_client_variants.h',
@ -53,6 +55,8 @@
'mach/mach_extensions.h',
'mach/mach_message_server.cc',
'mach/mach_message_server.h',
'mach/mach_message_util.cc',
'mach/mach_message_util.h',
'mach/scoped_task_suspend.cc',
'mach/scoped_task_suspend.h',
'mach/symbolic_constants_mach.cc',
@ -232,12 +236,14 @@
'mac/launchd_test.mm',
'mac/mac_util_test.mm',
'mac/service_management_test.mm',
'mach/child_port_server_test.cc',
'mach/exc_client_variants_test.cc',
'mach/exc_server_variants_test.cc',
'mach/exception_behaviors_test.cc',
'mach/exception_ports_test.cc',
'mach/mach_extensions_test.cc',
'mach/mach_message_server_test.cc',
'mach/mach_message_util_test.cc',
'mach/scoped_task_suspend_test.cc',
'mach/symbolic_constants_mach_test.cc',
'mach/task_memory_test.cc',