mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
Pass Mach message trailers to server handler functions.
TEST=util_test ChildPortServer.*:ExcServerVariants.*:MachMessageUtil.* R=rsesek@chromium.org Review URL: https://codereview.chromium.org/755313004
This commit is contained in:
parent
de5a6cdd6f
commit
0437bc53b6
@ -89,6 +89,7 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) override {
|
||||
*destroy_complex_request = true;
|
||||
|
||||
|
@ -81,6 +81,7 @@ class TestMachOImageAnnotationsReader final : public MachMultiprocess,
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) override {
|
||||
*destroy_complex_request = true;
|
||||
|
||||
|
@ -70,6 +70,7 @@ class ExceptionServer : public UniversalMachExcServer {
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) override {
|
||||
*destroy_complex_request = true;
|
||||
++*exceptions_handled_;
|
||||
|
@ -247,6 +247,7 @@ kern_return_t ChildPortHandshake::HandleChildPortCheckIn(
|
||||
const child_port_token_t token,
|
||||
mach_port_t port,
|
||||
mach_msg_type_name_t right_type,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) {
|
||||
DCHECK_EQ(child_port_, kMachPortNull);
|
||||
|
||||
|
@ -136,6 +136,7 @@ class ChildPortHandshake : public ChildPortServer::Interface {
|
||||
child_port_token_t token,
|
||||
mach_port_t port,
|
||||
mach_msg_type_name_t right_type,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) override;
|
||||
|
||||
//! \brief Runs the client.
|
||||
|
@ -72,6 +72,9 @@ bool ChildPortServer::MachMessageServerFunction(
|
||||
bool* destroy_complex_request) {
|
||||
PrepareMIGReplyFromRequest(in_header, out_header);
|
||||
|
||||
const mach_msg_trailer_t* in_trailer =
|
||||
MachMessageTrailerFromHeader(in_header);
|
||||
|
||||
switch (in_header->msgh_id) {
|
||||
case kMachMessageIDChildPortCheckIn: {
|
||||
// child_port_check_in(), handle_child_port_check_in().
|
||||
@ -90,6 +93,7 @@ bool ChildPortServer::MachMessageServerFunction(
|
||||
in_request->token,
|
||||
in_request->port.name,
|
||||
in_request->port.disposition,
|
||||
in_trailer,
|
||||
destroy_complex_request);
|
||||
return true;
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ class ChildPortServer : public MachMessageServer::Interface {
|
||||
//! This behaves equivalently to a `handle_child_port_check_in()` function
|
||||
//! used with `child_port_server()`.
|
||||
//!
|
||||
//! \param[in] trailer The trailer received with the request message.
|
||||
//! \param[out] destroy_request `true` if the request message is to be
|
||||
//! destroyed even when this method returns success. See
|
||||
//! MachMessageServer::Interface.
|
||||
@ -43,6 +44,7 @@ class ChildPortServer : public MachMessageServer::Interface {
|
||||
const child_port_token_t token,
|
||||
mach_port_t port,
|
||||
mach_msg_type_name_t right_type,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) = 0;
|
||||
|
||||
protected:
|
||||
|
@ -48,7 +48,7 @@ struct __attribute__((packed, aligned(4))) 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_size = sizeof(*this) - sizeof(trailer);
|
||||
Head.msgh_remote_port = MACH_PORT_NULL;
|
||||
Head.msgh_local_port = kServerLocalPort;
|
||||
Head.msgh_id = 10011;
|
||||
@ -65,6 +65,7 @@ struct __attribute__((packed, aligned(4))) ChildPortCheckInRequest {
|
||||
mach_msg_port_descriptor_t port;
|
||||
NDR_record_t NDR;
|
||||
child_port_token_t token;
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
|
||||
struct MIGReply : public mig_reply_error_t {
|
||||
@ -87,11 +88,12 @@ struct MIGReply : public mig_reply_error_t {
|
||||
|
||||
class MockChildPortServerInterface : public ChildPortServer::Interface {
|
||||
public:
|
||||
MOCK_METHOD5(HandleChildPortCheckIn,
|
||||
MOCK_METHOD6(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,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request));
|
||||
};
|
||||
|
||||
@ -100,7 +102,7 @@ TEST(ChildPortServer, MockChildPortCheckIn) {
|
||||
ChildPortServer server(&server_interface);
|
||||
|
||||
ChildPortCheckInRequest request;
|
||||
EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize());
|
||||
EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize());
|
||||
|
||||
MIGReply reply;
|
||||
EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize());
|
||||
@ -110,6 +112,7 @@ TEST(ChildPortServer, MockChildPortCheckIn) {
|
||||
kCheckInToken,
|
||||
kCheckInPort,
|
||||
kCheckInPortRightType,
|
||||
Eq(&request.trailer),
|
||||
Pointee(Eq(false))))
|
||||
.WillOnce(Return(MIG_NO_REPLY))
|
||||
.RetiresOnSaturation();
|
||||
|
@ -60,6 +60,7 @@ class TestExcClientVariants : public UniversalMachExcServer,
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) override {
|
||||
*destroy_complex_request = true;
|
||||
|
||||
|
@ -196,6 +196,9 @@ bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
|
||||
bool* destroy_complex_request) {
|
||||
PrepareMIGReplyFromRequest(in_header, out_header);
|
||||
|
||||
const mach_msg_trailer_t* in_trailer =
|
||||
MachMessageTrailerFromHeader(in_header);
|
||||
|
||||
switch (in_header->msgh_id) {
|
||||
case kMachMessageIDExceptionRaise: {
|
||||
// exception_raise(), catch_exception_raise().
|
||||
@ -216,6 +219,7 @@ bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
|
||||
in_request->exception,
|
||||
in_request->code,
|
||||
in_request->codeCnt,
|
||||
in_trailer,
|
||||
destroy_complex_request);
|
||||
if (out_reply->RetCode != KERN_SUCCESS) {
|
||||
return true;
|
||||
@ -253,7 +257,8 @@ bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
|
||||
in_request_1->old_state,
|
||||
in_request_1->old_stateCnt,
|
||||
out_reply->new_state,
|
||||
&out_reply->new_stateCnt);
|
||||
&out_reply->new_stateCnt,
|
||||
in_trailer);
|
||||
if (out_reply->RetCode != KERN_SUCCESS) {
|
||||
return true;
|
||||
}
|
||||
@ -296,6 +301,7 @@ bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
|
||||
in_request_1->old_stateCnt,
|
||||
out_reply->new_state,
|
||||
&out_reply->new_stateCnt,
|
||||
in_trailer,
|
||||
destroy_complex_request);
|
||||
if (out_reply->RetCode != KERN_SUCCESS) {
|
||||
return true;
|
||||
@ -331,6 +337,9 @@ bool MachExcServer::MachMessageServerFunction(
|
||||
bool* destroy_complex_request) {
|
||||
PrepareMIGReplyFromRequest(in_header, out_header);
|
||||
|
||||
const mach_msg_trailer_t* in_trailer =
|
||||
MachMessageTrailerFromHeader(in_header);
|
||||
|
||||
switch (in_header->msgh_id) {
|
||||
case kMachMessageIDMachExceptionRaise: {
|
||||
// mach_exception_raise(), catch_mach_exception_raise().
|
||||
@ -351,6 +360,7 @@ bool MachExcServer::MachMessageServerFunction(
|
||||
in_request->exception,
|
||||
in_request->code,
|
||||
in_request->codeCnt,
|
||||
in_trailer,
|
||||
destroy_complex_request);
|
||||
if (out_reply->RetCode != KERN_SUCCESS) {
|
||||
return true;
|
||||
@ -388,7 +398,8 @@ bool MachExcServer::MachMessageServerFunction(
|
||||
in_request_1->old_state,
|
||||
in_request_1->old_stateCnt,
|
||||
out_reply->new_state,
|
||||
&out_reply->new_stateCnt);
|
||||
&out_reply->new_stateCnt,
|
||||
in_trailer);
|
||||
if (out_reply->RetCode != KERN_SUCCESS) {
|
||||
return true;
|
||||
}
|
||||
@ -431,6 +442,7 @@ bool MachExcServer::MachMessageServerFunction(
|
||||
in_request_1->old_stateCnt,
|
||||
out_reply->new_state,
|
||||
&out_reply->new_stateCnt,
|
||||
in_trailer,
|
||||
destroy_complex_request);
|
||||
if (out_reply->RetCode != KERN_SUCCESS) {
|
||||
return true;
|
||||
@ -469,6 +481,7 @@ kern_return_t SimplifiedExcServer::CatchExceptionRaise(
|
||||
exception_type_t exception,
|
||||
const exception_data_type_t* code,
|
||||
mach_msg_type_number_t code_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) {
|
||||
thread_state_flavor_t flavor = THREAD_STATE_NONE;
|
||||
mach_msg_type_number_t new_state_count = 0;
|
||||
@ -484,6 +497,7 @@ kern_return_t SimplifiedExcServer::CatchExceptionRaise(
|
||||
0,
|
||||
nullptr,
|
||||
&new_state_count,
|
||||
trailer,
|
||||
destroy_request);
|
||||
}
|
||||
|
||||
@ -496,7 +510,8 @@ kern_return_t SimplifiedExcServer::CatchExceptionRaiseState(
|
||||
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) {
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer) {
|
||||
bool destroy_complex_request = false;
|
||||
return interface_->CatchException(EXCEPTION_STATE,
|
||||
exception_port,
|
||||
@ -510,6 +525,7 @@ kern_return_t SimplifiedExcServer::CatchExceptionRaiseState(
|
||||
old_state_count,
|
||||
new_state,
|
||||
new_state_count,
|
||||
trailer,
|
||||
&destroy_complex_request);
|
||||
}
|
||||
|
||||
@ -525,6 +541,7 @@ kern_return_t SimplifiedExcServer::CatchExceptionRaiseStateIdentity(
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) {
|
||||
return interface_->CatchException(EXCEPTION_STATE_IDENTITY,
|
||||
exception_port,
|
||||
@ -538,6 +555,7 @@ kern_return_t SimplifiedExcServer::CatchExceptionRaiseStateIdentity(
|
||||
old_state_count,
|
||||
new_state,
|
||||
new_state_count,
|
||||
trailer,
|
||||
destroy_request);
|
||||
}
|
||||
|
||||
@ -555,6 +573,7 @@ kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaise(
|
||||
exception_type_t exception,
|
||||
const mach_exception_data_type_t* code,
|
||||
mach_msg_type_number_t code_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) {
|
||||
thread_state_flavor_t flavor = THREAD_STATE_NONE;
|
||||
mach_msg_type_number_t new_state_count = 0;
|
||||
@ -571,6 +590,7 @@ kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaise(
|
||||
0,
|
||||
nullptr,
|
||||
&new_state_count,
|
||||
trailer,
|
||||
destroy_request);
|
||||
}
|
||||
|
||||
@ -583,7 +603,8 @@ kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseState(
|
||||
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) {
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer) {
|
||||
bool destroy_complex_request = false;
|
||||
return interface_->CatchMachException(EXCEPTION_STATE | MACH_EXCEPTION_CODES,
|
||||
exception_port,
|
||||
@ -597,6 +618,7 @@ kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseState(
|
||||
old_state_count,
|
||||
new_state,
|
||||
new_state_count,
|
||||
trailer,
|
||||
&destroy_complex_request);
|
||||
}
|
||||
|
||||
@ -612,6 +634,7 @@ kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseStateIdentity(
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) {
|
||||
return interface_->CatchMachException(
|
||||
EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
|
||||
@ -626,6 +649,7 @@ kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseStateIdentity(
|
||||
old_state_count,
|
||||
new_state,
|
||||
new_state_count,
|
||||
trailer,
|
||||
destroy_request);
|
||||
}
|
||||
|
||||
@ -686,6 +710,7 @@ kern_return_t UniversalMachExcServer::CatchException(
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) {
|
||||
std::vector<mach_exception_data_type_t> mach_codes;
|
||||
mach_codes.reserve(code_count);
|
||||
@ -705,6 +730,7 @@ kern_return_t UniversalMachExcServer::CatchException(
|
||||
old_state_count,
|
||||
new_state,
|
||||
new_state_count,
|
||||
trailer,
|
||||
destroy_complex_request);
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ class ExcServer : public MachMessageServer::Interface {
|
||||
//! This behaves equivalently to a `catch_exception_raise()` function used
|
||||
//! with `exc_server()`.
|
||||
//!
|
||||
//! \param[in] trailer The trailer received with the request message.
|
||||
//! \param[out] destroy_request `true` if the request message is to be
|
||||
//! destroyed even when this method returns success. See
|
||||
//! MachMessageServer::Interface.
|
||||
@ -52,6 +53,7 @@ class ExcServer : public MachMessageServer::Interface {
|
||||
exception_type_t exception,
|
||||
const exception_data_type_t* code,
|
||||
mach_msg_type_number_t code_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) = 0;
|
||||
|
||||
//! \brief Handles exceptions raised by `exception_raise_state()`.
|
||||
@ -63,6 +65,8 @@ class ExcServer : public MachMessageServer::Interface {
|
||||
//! CatchExceptionRaise() and CatchExceptionRaiseStateIdentity(), the
|
||||
//! request message is not complex (it does not carry the \a thread or \a
|
||||
//! task port rights) and thus there is nothing to destroy.
|
||||
//!
|
||||
//! \param[in] trailer The trailer received with the request message.
|
||||
virtual kern_return_t CatchExceptionRaiseState(
|
||||
exception_handler_t exception_port,
|
||||
exception_type_t exception,
|
||||
@ -72,13 +76,15 @@ class ExcServer : public MachMessageServer::Interface {
|
||||
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) = 0;
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer) = 0;
|
||||
|
||||
//! \brief Handles exceptions raised by `exception_raise_state_identity()`.
|
||||
//!
|
||||
//! This behaves equivalently to a `catch_exception_raise_state_identity()`
|
||||
//! function used with `exc_server()`.
|
||||
//!
|
||||
//! \param[in] trailer The trailer received with the request message.
|
||||
//! \param[out] destroy_request `true` if the request message is to be
|
||||
//! destroyed even when this method returns success. See
|
||||
//! MachMessageServer::Interface.
|
||||
@ -94,6 +100,7 @@ class ExcServer : public MachMessageServer::Interface {
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) = 0;
|
||||
|
||||
protected:
|
||||
@ -132,6 +139,7 @@ class MachExcServer : public MachMessageServer::Interface {
|
||||
//! This behaves equivalently to a `catch_mach_exception_raise()` function
|
||||
//! used with `mach_exc_server()`.
|
||||
//!
|
||||
//! \param[in] trailer The trailer received with the request message.
|
||||
//! \param[out] destroy_request `true` if the request message is to be
|
||||
//! destroyed even when this method returns success. See
|
||||
//! MachMessageServer::Interface.
|
||||
@ -142,6 +150,7 @@ class MachExcServer : public MachMessageServer::Interface {
|
||||
exception_type_t exception,
|
||||
const mach_exception_data_type_t* code,
|
||||
mach_msg_type_number_t code_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) = 0;
|
||||
|
||||
//! \brief Handles exceptions raised by `mach_exception_raise_state()`.
|
||||
@ -153,6 +162,8 @@ class MachExcServer : public MachMessageServer::Interface {
|
||||
//! CatchMachExceptionRaise() and CatchMachExceptionRaiseStateIdentity(),
|
||||
//! the request message is not complex (it does not carry the \a thread or
|
||||
//! \a task port rights) and thus there is nothing to destroy.
|
||||
//!
|
||||
//! \param[in] trailer The trailer received with the request message.
|
||||
virtual kern_return_t CatchMachExceptionRaiseState(
|
||||
exception_handler_t exception_port,
|
||||
exception_type_t exception,
|
||||
@ -162,7 +173,8 @@ class MachExcServer : public MachMessageServer::Interface {
|
||||
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) = 0;
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer) = 0;
|
||||
|
||||
//! \brief Handles exceptions raised by
|
||||
//! `mach_exception_raise_state_identity()`.
|
||||
@ -171,6 +183,7 @@ class MachExcServer : public MachMessageServer::Interface {
|
||||
//! `catch_mach_exception_raise_state_identity()` function used with
|
||||
//! `mach_exc_server()`.
|
||||
//!
|
||||
//! \param[in] trailer The trailer received with the request message.
|
||||
//! \param[out] destroy_request `true` if the request message is to be
|
||||
//! destroyed even when this method returns success. See
|
||||
//! MachMessageServer::Interface.
|
||||
@ -186,6 +199,7 @@ class MachExcServer : public MachMessageServer::Interface {
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) = 0;
|
||||
|
||||
protected:
|
||||
@ -248,6 +262,7 @@ class SimplifiedExcServer : public ExcServer, public ExcServer::Interface {
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) = 0;
|
||||
|
||||
protected:
|
||||
@ -267,6 +282,7 @@ class SimplifiedExcServer : public ExcServer, public ExcServer::Interface {
|
||||
exception_type_t exception,
|
||||
const exception_data_type_t* code,
|
||||
mach_msg_type_number_t code_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) override;
|
||||
kern_return_t CatchExceptionRaiseState(
|
||||
exception_handler_t exception_port,
|
||||
@ -277,7 +293,8 @@ class SimplifiedExcServer : public ExcServer, public ExcServer::Interface {
|
||||
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) override;
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer) override;
|
||||
kern_return_t CatchExceptionRaiseStateIdentity(
|
||||
exception_handler_t exception_port,
|
||||
thread_t thread,
|
||||
@ -290,6 +307,7 @@ class SimplifiedExcServer : public ExcServer, public ExcServer::Interface {
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) override;
|
||||
|
||||
private:
|
||||
@ -344,6 +362,7 @@ class SimplifiedMachExcServer : public MachExcServer,
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) = 0;
|
||||
|
||||
protected:
|
||||
@ -363,6 +382,7 @@ class SimplifiedMachExcServer : public MachExcServer,
|
||||
exception_type_t exception,
|
||||
const mach_exception_data_type_t* code,
|
||||
mach_msg_type_number_t code_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) override;
|
||||
kern_return_t CatchMachExceptionRaiseState(
|
||||
exception_handler_t exception_port,
|
||||
@ -373,7 +393,8 @@ class SimplifiedMachExcServer : public MachExcServer,
|
||||
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) override;
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer) override;
|
||||
kern_return_t CatchMachExceptionRaiseStateIdentity(
|
||||
exception_handler_t exception_port,
|
||||
thread_t thread,
|
||||
@ -386,6 +407,7 @@ class SimplifiedMachExcServer : public MachExcServer,
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_request) override;
|
||||
|
||||
private:
|
||||
@ -440,6 +462,7 @@ class UniversalMachExcServer
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) override;
|
||||
|
||||
private:
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "util/mach/exception_behaviors.h"
|
||||
#include "util/mach/mach_extensions.h"
|
||||
#include "util/mach/mach_message_util.h"
|
||||
#include "util/test/mac/mach_errors.h"
|
||||
#include "util/test/mac/mach_multiprocess.h"
|
||||
|
||||
@ -82,7 +83,7 @@ struct __attribute__((packed, aligned(4))) ExceptionRaiseRequest {
|
||||
Head.msgh_bits =
|
||||
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) |
|
||||
MACH_MSGH_BITS_COMPLEX;
|
||||
Head.msgh_size = sizeof(*this);
|
||||
Head.msgh_size = sizeof(*this) - sizeof(trailer);
|
||||
Head.msgh_remote_port = kClientRemotePort;
|
||||
Head.msgh_local_port = kServerLocalPort;
|
||||
Head.msgh_id = 2401;
|
||||
@ -104,6 +105,7 @@ struct __attribute__((packed, aligned(4))) ExceptionRaiseRequest {
|
||||
exception_type_t exception;
|
||||
mach_msg_type_number_t codeCnt;
|
||||
integer_t code[2];
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
|
||||
struct __attribute__((packed, aligned(4))) ExceptionRaiseReply {
|
||||
@ -149,7 +151,7 @@ struct __attribute__((packed, aligned(4))) ExceptionRaiseStateRequest {
|
||||
memset(this, 0xa5, sizeof(*this));
|
||||
Head.msgh_bits =
|
||||
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND);
|
||||
Head.msgh_size = sizeof(*this);
|
||||
Head.msgh_size = sizeof(*this) - sizeof(trailer);
|
||||
Head.msgh_remote_port = kClientRemotePort;
|
||||
Head.msgh_local_port = kServerLocalPort;
|
||||
Head.msgh_id = 2402;
|
||||
@ -166,6 +168,12 @@ struct __attribute__((packed, aligned(4))) ExceptionRaiseStateRequest {
|
||||
Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state);
|
||||
}
|
||||
|
||||
// Because the message size has been adjusted, the trailer may not appear in
|
||||
// its home member variable. This computes the actual address of the trailer.
|
||||
const mach_msg_trailer_t* Trailer() const {
|
||||
return MachMessageTrailerFromHeader(&Head);
|
||||
}
|
||||
|
||||
mach_msg_header_t Head;
|
||||
NDR_record_t NDR;
|
||||
exception_type_t exception;
|
||||
@ -174,6 +182,7 @@ struct __attribute__((packed, aligned(4))) ExceptionRaiseStateRequest {
|
||||
int flavor;
|
||||
mach_msg_type_number_t old_stateCnt;
|
||||
natural_t old_state[THREAD_STATE_MAX];
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
|
||||
struct __attribute__((packed, aligned(4))) ExceptionRaiseStateReply {
|
||||
@ -232,7 +241,7 @@ struct __attribute__((packed, aligned(4))) ExceptionRaiseStateIdentityRequest {
|
||||
Head.msgh_bits =
|
||||
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) |
|
||||
MACH_MSGH_BITS_COMPLEX;
|
||||
Head.msgh_size = sizeof(*this);
|
||||
Head.msgh_size = sizeof(*this) - sizeof(trailer);
|
||||
Head.msgh_remote_port = kClientRemotePort;
|
||||
Head.msgh_local_port = kServerLocalPort;
|
||||
Head.msgh_id = 2403;
|
||||
@ -252,6 +261,12 @@ struct __attribute__((packed, aligned(4))) ExceptionRaiseStateIdentityRequest {
|
||||
Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state);
|
||||
}
|
||||
|
||||
// Because the message size has been adjusted, the trailer may not appear in
|
||||
// its home member variable. This computes the actual address of the trailer.
|
||||
const mach_msg_trailer_t* Trailer() const {
|
||||
return MachMessageTrailerFromHeader(&Head);
|
||||
}
|
||||
|
||||
mach_msg_header_t Head;
|
||||
mach_msg_body_t msgh_body;
|
||||
mach_msg_port_descriptor_t thread;
|
||||
@ -263,6 +278,7 @@ struct __attribute__((packed, aligned(4))) ExceptionRaiseStateIdentityRequest {
|
||||
int flavor;
|
||||
mach_msg_type_number_t old_stateCnt;
|
||||
natural_t old_state[THREAD_STATE_MAX];
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
|
||||
// The reply messages for exception_raise_state and
|
||||
@ -275,7 +291,7 @@ struct __attribute__((packed, aligned(4))) MachExceptionRaiseRequest {
|
||||
Head.msgh_bits =
|
||||
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) |
|
||||
MACH_MSGH_BITS_COMPLEX;
|
||||
Head.msgh_size = sizeof(*this);
|
||||
Head.msgh_size = sizeof(*this) - sizeof(trailer);
|
||||
Head.msgh_remote_port = kClientRemotePort;
|
||||
Head.msgh_local_port = kServerLocalPort;
|
||||
Head.msgh_id = 2405;
|
||||
@ -297,6 +313,7 @@ struct __attribute__((packed, aligned(4))) MachExceptionRaiseRequest {
|
||||
exception_type_t exception;
|
||||
mach_msg_type_number_t codeCnt;
|
||||
int64_t code[2];
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
|
||||
// The reply messages for exception_raise and mach_exception_raise are
|
||||
@ -308,7 +325,7 @@ struct __attribute__((packed, aligned(4))) MachExceptionRaiseStateRequest {
|
||||
memset(this, 0xa5, sizeof(*this));
|
||||
Head.msgh_bits =
|
||||
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND);
|
||||
Head.msgh_size = sizeof(*this);
|
||||
Head.msgh_size = sizeof(*this) - sizeof(trailer);
|
||||
Head.msgh_remote_port = kClientRemotePort;
|
||||
Head.msgh_local_port = kServerLocalPort;
|
||||
Head.msgh_id = 2406;
|
||||
@ -325,6 +342,12 @@ struct __attribute__((packed, aligned(4))) MachExceptionRaiseStateRequest {
|
||||
Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state);
|
||||
}
|
||||
|
||||
// Because the message size has been adjusted, the trailer may not appear in
|
||||
// its home member variable. This computes the actual address of the trailer.
|
||||
const mach_msg_trailer_t* Trailer() const {
|
||||
return MachMessageTrailerFromHeader(&Head);
|
||||
}
|
||||
|
||||
mach_msg_header_t Head;
|
||||
NDR_record_t NDR;
|
||||
exception_type_t exception;
|
||||
@ -333,6 +356,7 @@ struct __attribute__((packed, aligned(4))) MachExceptionRaiseStateRequest {
|
||||
int flavor;
|
||||
mach_msg_type_number_t old_stateCnt;
|
||||
natural_t old_state[THREAD_STATE_MAX];
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
|
||||
// The reply messages for exception_raise_state and mach_exception_raise_state
|
||||
@ -346,7 +370,7 @@ struct __attribute__((packed,
|
||||
Head.msgh_bits =
|
||||
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) |
|
||||
MACH_MSGH_BITS_COMPLEX;
|
||||
Head.msgh_size = sizeof(*this);
|
||||
Head.msgh_size = sizeof(*this) - sizeof(trailer);
|
||||
Head.msgh_remote_port = kClientRemotePort;
|
||||
Head.msgh_local_port = kServerLocalPort;
|
||||
Head.msgh_id = 2407;
|
||||
@ -366,6 +390,12 @@ struct __attribute__((packed,
|
||||
Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state);
|
||||
}
|
||||
|
||||
// Because the message size has been adjusted, the trailer may not appear in
|
||||
// its home member variable. This computes the actual address of the trailer.
|
||||
const mach_msg_trailer_t* Trailer() const {
|
||||
return MachMessageTrailerFromHeader(&Head);
|
||||
}
|
||||
|
||||
mach_msg_header_t Head;
|
||||
mach_msg_body_t msgh_body;
|
||||
mach_msg_port_descriptor_t thread;
|
||||
@ -377,6 +407,7 @@ struct __attribute__((packed,
|
||||
int flavor;
|
||||
mach_msg_type_number_t old_stateCnt;
|
||||
natural_t old_state[THREAD_STATE_MAX];
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
|
||||
// The reply messages for exception_raise_state_identity and
|
||||
@ -449,6 +480,7 @@ class MockUniversalMachExcServer : public UniversalMachExcServer {
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) override {
|
||||
*destroy_complex_request = true;
|
||||
const ConstExceptionCodes exception_codes = {code, code_count};
|
||||
@ -462,19 +494,21 @@ class MockUniversalMachExcServer : public UniversalMachExcServer {
|
||||
&exception_codes,
|
||||
flavor,
|
||||
&old_thread_state,
|
||||
&new_thread_state);
|
||||
&new_thread_state,
|
||||
trailer);
|
||||
}
|
||||
|
||||
MOCK_METHOD9(MockCatchMachException,
|
||||
kern_return_t(exception_behavior_t behavior,
|
||||
exception_handler_t exception_port,
|
||||
thread_t thread,
|
||||
task_t task,
|
||||
exception_type_t exception,
|
||||
const ConstExceptionCodes* exception_codes,
|
||||
thread_state_flavor_t* flavor,
|
||||
const ConstThreadState* old_thread_state,
|
||||
ThreadState* new_thread_state));
|
||||
MOCK_METHOD10(MockCatchMachException,
|
||||
kern_return_t(exception_behavior_t behavior,
|
||||
exception_handler_t exception_port,
|
||||
thread_t thread,
|
||||
task_t task,
|
||||
exception_type_t exception,
|
||||
const ConstExceptionCodes* exception_codes,
|
||||
thread_state_flavor_t* flavor,
|
||||
const ConstThreadState* old_thread_state,
|
||||
ThreadState* new_thread_state,
|
||||
const mach_msg_trailer_t* trailer));
|
||||
};
|
||||
|
||||
// Matcher for ConstExceptionCodes, testing that it carries 2 codes matching
|
||||
@ -548,7 +582,7 @@ TEST(ExcServerVariants, MockExceptionRaise) {
|
||||
MockUniversalMachExcServer server;
|
||||
|
||||
ExceptionRaiseRequest request;
|
||||
EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize());
|
||||
EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize());
|
||||
|
||||
ExceptionRaiseReply reply;
|
||||
EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize());
|
||||
@ -565,7 +599,8 @@ TEST(ExcServerVariants, MockExceptionRaise) {
|
||||
kTestExceptonCodes[1]),
|
||||
Pointee(Eq(THREAD_STATE_NONE)),
|
||||
IsThreadStateCount(0u),
|
||||
IsThreadStateCount(0u)))
|
||||
IsThreadStateCount(0u),
|
||||
Eq(&request.trailer)))
|
||||
.WillOnce(Return(KERN_SUCCESS))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
@ -585,7 +620,7 @@ TEST(ExcServerVariants, MockExceptionRaiseState) {
|
||||
MockUniversalMachExcServer server;
|
||||
|
||||
ExceptionRaiseStateRequest request;
|
||||
EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize());
|
||||
EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize());
|
||||
|
||||
ExceptionRaiseStateReply reply;
|
||||
EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize());
|
||||
@ -603,7 +638,8 @@ TEST(ExcServerVariants, MockExceptionRaiseState) {
|
||||
AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]),
|
||||
Pointee(Eq(kThreadStateFlavor)),
|
||||
IsThreadStateCount(kThreadStateFlavorCount),
|
||||
IsThreadStateCount(arraysize(reply.new_state))))
|
||||
IsThreadStateCount(arraysize(reply.new_state)),
|
||||
Eq(request.Trailer())))
|
||||
.WillOnce(Return(KERN_SUCCESS))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
@ -626,7 +662,7 @@ TEST(ExcServerVariants, MockExceptionRaiseStateIdentity) {
|
||||
MockUniversalMachExcServer server;
|
||||
|
||||
ExceptionRaiseStateIdentityRequest request;
|
||||
EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize());
|
||||
EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize());
|
||||
|
||||
ExceptionRaiseStateIdentityReply reply;
|
||||
EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize());
|
||||
@ -644,7 +680,8 @@ TEST(ExcServerVariants, MockExceptionRaiseStateIdentity) {
|
||||
AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]),
|
||||
Pointee(Eq(kThreadStateFlavor)),
|
||||
IsThreadStateCount(kThreadStateFlavorCount),
|
||||
IsThreadStateCount(arraysize(reply.new_state))))
|
||||
IsThreadStateCount(arraysize(reply.new_state)),
|
||||
Eq(request.Trailer())))
|
||||
.WillOnce(Return(KERN_SUCCESS))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
@ -664,7 +701,7 @@ TEST(ExcServerVariants, MockMachExceptionRaise) {
|
||||
MockUniversalMachExcServer server;
|
||||
|
||||
MachExceptionRaiseRequest request;
|
||||
EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize());
|
||||
EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize());
|
||||
|
||||
MachExceptionRaiseReply reply;
|
||||
EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize());
|
||||
@ -683,7 +720,8 @@ TEST(ExcServerVariants, MockMachExceptionRaise) {
|
||||
kTestMachExceptionCodes[1]),
|
||||
Pointee(Eq(THREAD_STATE_NONE)),
|
||||
IsThreadStateCount(0u),
|
||||
IsThreadStateCount(0u)))
|
||||
IsThreadStateCount(0u),
|
||||
Eq(&request.trailer)))
|
||||
.WillOnce(Return(KERN_SUCCESS))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
@ -703,7 +741,7 @@ TEST(ExcServerVariants, MockMachExceptionRaiseState) {
|
||||
MockUniversalMachExcServer server;
|
||||
|
||||
MachExceptionRaiseStateRequest request;
|
||||
EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize());
|
||||
EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize());
|
||||
|
||||
MachExceptionRaiseStateReply reply;
|
||||
EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize());
|
||||
@ -722,7 +760,8 @@ TEST(ExcServerVariants, MockMachExceptionRaiseState) {
|
||||
kTestMachExceptionCodes[1]),
|
||||
Pointee(Eq(kThreadStateFlavor)),
|
||||
IsThreadStateCount(kThreadStateFlavorCount),
|
||||
IsThreadStateCount(arraysize(reply.new_state))))
|
||||
IsThreadStateCount(arraysize(reply.new_state)),
|
||||
Eq(request.Trailer())))
|
||||
.WillOnce(Return(KERN_SUCCESS))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
@ -745,7 +784,7 @@ TEST(ExcServerVariants, MockMachExceptionRaiseStateIdentity) {
|
||||
MockUniversalMachExcServer server;
|
||||
|
||||
MachExceptionRaiseStateIdentityRequest request;
|
||||
EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize());
|
||||
EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize());
|
||||
|
||||
MachExceptionRaiseStateIdentityReply reply;
|
||||
EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize());
|
||||
@ -764,7 +803,8 @@ TEST(ExcServerVariants, MockMachExceptionRaiseStateIdentity) {
|
||||
kTestMachExceptionCodes[1]),
|
||||
Pointee(Eq(kThreadStateFlavor)),
|
||||
IsThreadStateCount(kThreadStateFlavorCount),
|
||||
IsThreadStateCount(arraysize(reply.new_state))))
|
||||
IsThreadStateCount(arraysize(reply.new_state)),
|
||||
Eq(request.Trailer())))
|
||||
.WillOnce(Return(KERN_SUCCESS))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
@ -871,6 +911,7 @@ class TestExcServerVariants : public UniversalMachExcServer,
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) override {
|
||||
*destroy_complex_request = true;
|
||||
|
||||
@ -917,6 +958,11 @@ class TestExcServerVariants : public UniversalMachExcServer,
|
||||
EXPECT_EQ(nullptr, new_state);
|
||||
}
|
||||
|
||||
EXPECT_EQ(implicit_cast<mach_msg_trailer_type_t>(MACH_MSG_TRAILER_FORMAT_0),
|
||||
trailer->msgh_trailer_type);
|
||||
EXPECT_EQ(REQUESTED_TRAILER_SIZE(kMachMessageOptions),
|
||||
trailer->msgh_trailer_size);
|
||||
|
||||
return ExcServerSuccessfulReturnValue(behavior, false);
|
||||
}
|
||||
|
||||
@ -927,7 +973,7 @@ class TestExcServerVariants : public UniversalMachExcServer,
|
||||
kern_return_t kr =
|
||||
MachMessageServer::Run(this,
|
||||
LocalPort(),
|
||||
MACH_MSG_OPTION_NONE,
|
||||
kMachMessageOptions,
|
||||
MachMessageServer::kOneShot,
|
||||
MachMessageServer::kBlocking,
|
||||
MachMessageServer::kReceiveLargeError,
|
||||
@ -954,6 +1000,9 @@ class TestExcServerVariants : public UniversalMachExcServer,
|
||||
mach_msg_type_number_t state_count_;
|
||||
bool handled_;
|
||||
|
||||
static const mach_msg_option_t kMachMessageOptions =
|
||||
MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TestExcServerVariants);
|
||||
};
|
||||
|
||||
|
@ -154,6 +154,7 @@ class TestExceptionPorts : public UniversalMachExcServer,
|
||||
mach_msg_type_number_t old_state_count,
|
||||
thread_state_t new_state,
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) override {
|
||||
*destroy_complex_request = true;
|
||||
|
||||
|
@ -111,7 +111,8 @@ mach_msg_return_t MachMessageServer::Run(Interface* interface,
|
||||
|
||||
mach_msg_size_t trailer_alloc = REQUESTED_TRAILER_SIZE(options);
|
||||
mach_msg_size_t max_request_size = interface->MachMessageServerRequestSize();
|
||||
mach_msg_size_t request_alloc = round_page(max_request_size + trailer_alloc);
|
||||
mach_msg_size_t request_alloc =
|
||||
round_page(round_msg(max_request_size) + trailer_alloc);
|
||||
|
||||
// mach_msg_server() and mach_msg_server_once() invert this condition, but
|
||||
// their interpretation is incorrect. When it is desirable to retry a receive
|
||||
@ -120,9 +121,10 @@ mach_msg_return_t MachMessageServer::Run(Interface* interface,
|
||||
// the initial receive attempt. On the other hand, when this behavior is not
|
||||
// requested, there is no reason to attempt receiving messages any larger than
|
||||
// expected.
|
||||
mach_msg_size_t request_size = (receive_large == kReceiveLargeResize)
|
||||
? max_request_size + trailer_alloc
|
||||
: request_alloc;
|
||||
mach_msg_size_t request_size =
|
||||
(receive_large == kReceiveLargeResize)
|
||||
? round_msg(max_request_size) + trailer_alloc
|
||||
: request_alloc;
|
||||
|
||||
mach_msg_size_t max_reply_size = interface->MachMessageServerReplySize();
|
||||
|
||||
@ -186,7 +188,7 @@ mach_msg_return_t MachMessageServer::Run(Interface* interface,
|
||||
} else if (kr == MACH_RCV_TOO_LARGE &&
|
||||
receive_large == kReceiveLargeResize) {
|
||||
this_request_size =
|
||||
round_page(request_header->msgh_size + trailer_alloc);
|
||||
round_page(round_msg(request_header->msgh_size) + trailer_alloc);
|
||||
this_request_alloc = this_request_size;
|
||||
} else {
|
||||
return kr;
|
||||
|
@ -34,4 +34,11 @@ void SetMIGReplyError(mach_msg_header_t* out_header, kern_return_t error) {
|
||||
reinterpret_cast<mig_reply_error_t*>(out_header)->RetCode = error;
|
||||
}
|
||||
|
||||
const mach_msg_trailer_t* MachMessageTrailerFromHeader(
|
||||
const mach_msg_header_t* header) {
|
||||
vm_address_t header_address = reinterpret_cast<vm_address_t>(header);
|
||||
vm_address_t trailer_address = header_address + round_msg(header->msgh_size);
|
||||
return reinterpret_cast<const mach_msg_trailer_t*>(trailer_address);
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
||||
|
@ -48,6 +48,20 @@ void PrepareMIGReplyFromRequest(const mach_msg_header_t* in_header,
|
||||
//! \sa PrepareMIGReplyFromRequest()
|
||||
void SetMIGReplyError(mach_msg_header_t* out_header, kern_return_t error);
|
||||
|
||||
//! \brief Returns a Mach message trailer for a message that has been received.
|
||||
//!
|
||||
//! This function must only be called on Mach messages that have been received
|
||||
//! via the Mach messaging interface, such as `mach_msg()`. Messages constructed
|
||||
//! for sending do not contain trailers.
|
||||
//!
|
||||
//! \param[in] header A pointer to a received Mach message.
|
||||
//!
|
||||
//! \return A pointer to the trailer following the received Mach message’s body.
|
||||
//! The contents of the trailer depend on the options provided to
|
||||
//! `mach_msg()` or a similar function when the message was received.
|
||||
const mach_msg_trailer_t* MachMessageTrailerFromHeader(
|
||||
const mach_msg_header_t* header);
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_UTIL_MACH_MACH_MESSAGE_UTIL_H_
|
||||
|
@ -63,6 +63,29 @@ TEST(MachMessageUtil, PrepareMIGReplyFromRequest_SetMIGReplyError) {
|
||||
EXPECT_EQ(MIG_BAD_ID, reply.RetCode);
|
||||
}
|
||||
|
||||
TEST(MachMessageUtil, MachMessageTrailerFromHeader) {
|
||||
mach_msg_empty_t empty;
|
||||
empty.send.header.msgh_size = sizeof(mach_msg_empty_send_t);
|
||||
EXPECT_EQ(&empty.rcv.trailer,
|
||||
MachMessageTrailerFromHeader(&empty.rcv.header));
|
||||
|
||||
struct TestSendMessage : public mach_msg_header_t {
|
||||
uint8_t data[126];
|
||||
};
|
||||
struct TestReceiveMessage : public TestSendMessage {
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
union TestMessage {
|
||||
TestSendMessage send;
|
||||
TestReceiveMessage receive;
|
||||
};
|
||||
|
||||
TestMessage test;
|
||||
test.send.msgh_size = sizeof(TestSendMessage);
|
||||
EXPECT_EQ(&test.receive.trailer,
|
||||
MachMessageTrailerFromHeader(&test.receive));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
Loading…
x
Reference in New Issue
Block a user