Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: util/mach/exc_server_variants.cc

Issue 754123002: Add ChildPortServer, a MachMessageServer::Interface implementation for the child_port subsystem (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@child_port_defs
Patch Set: Address review feedback Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with 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 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include "util/mach/exc_server_variants.h" 15 #include "util/mach/exc_server_variants.h"
16 16
17 #include <algorithm> 17 #include <algorithm>
18 #include <vector> 18 #include <vector>
19 19
20 #include "base/logging.h" 20 #include "base/logging.h"
21 #include "util/mach/exc.h" 21 #include "util/mach/exc.h"
22 #include "util/mach/exception_behaviors.h" 22 #include "util/mach/exception_behaviors.h"
23 #include "util/mach/excServer.h" 23 #include "util/mach/excServer.h"
24 #include "util/mach/mach_exc.h" 24 #include "util/mach/mach_exc.h"
25 #include "util/mach/mach_excServer.h" 25 #include "util/mach/mach_excServer.h"
26 #include "util/mach/mach_message_util.h"
26 27
27 extern "C" { 28 extern "C" {
28 29
29 // These six functions are not used, and are in fact obsoleted by the other 30 // These six functions are not used, and are in fact obsoleted by the other
30 // functionality implemented in this file. The standard MIG-generated exc_server 31 // functionality implemented in this file. The standard MIG-generated exc_server
31 // (in excServer.c) and mach_exc_server (in mach_excServer.c) server dispatch 32 // (in excServer.c) and mach_exc_server (in mach_excServer.c) server dispatch
32 // routines usable with the standard mach_msg_server() function call out to 33 // routines usable with the standard mach_msg_server() function call out to
33 // these functions. exc_server() and mach_exc_server() are unused and are 34 // these functions. exc_server() and mach_exc_server() are unused and are
34 // replaced by the more flexible ExcServer and MachExcServer, but the linker 35 // replaced by the more flexible ExcServer and MachExcServer, but the linker
35 // still needs to see these six function definitions. 36 // still needs to see these six function definitions.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 thread_state_t new_state, 112 thread_state_t new_state,
112 mach_msg_type_number_t* new_state_count) { 113 mach_msg_type_number_t* new_state_count) {
113 NOTREACHED(); 114 NOTREACHED();
114 return KERN_FAILURE; 115 return KERN_FAILURE;
115 } 116 }
116 117
117 } // extern "C" 118 } // extern "C"
118 119
119 namespace { 120 namespace {
120 121
121 void PrepareReplyFromRequest(const mach_msg_header_t* in_header,
122 mach_msg_header_t* out_header) {
123 out_header->msgh_bits =
124 MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(in_header->msgh_bits), 0);
125 out_header->msgh_remote_port = in_header->msgh_remote_port;
126 out_header->msgh_size = sizeof(mig_reply_error_t);
127 out_header->msgh_local_port = MACH_PORT_NULL;
128 out_header->msgh_id = in_header->msgh_id + 100;
129 reinterpret_cast<mig_reply_error_t*>(out_header)->NDR = NDR_record;
130 }
131
132 void SetReplyError(mach_msg_header_t* out_header, kern_return_t error) {
133 reinterpret_cast<mig_reply_error_t*>(out_header)->RetCode = error;
134 }
135
136 // There are no predefined constants for these. 122 // There are no predefined constants for these.
137 enum MachMessageID : mach_msg_id_t { 123 enum MachMessageID : mach_msg_id_t {
138 kMachMessageIDExceptionRaise = 2401, 124 kMachMessageIDExceptionRaise = 2401,
139 kMachMessageIDExceptionRaiseState = 2402, 125 kMachMessageIDExceptionRaiseState = 2402,
140 kMachMessageIDExceptionRaiseStateIdentity = 2403, 126 kMachMessageIDExceptionRaiseStateIdentity = 2403,
141 kMachMessageIDMachExceptionRaise = 2405, 127 kMachMessageIDMachExceptionRaise = 2405,
142 kMachMessageIDMachExceptionRaiseState = 2406, 128 kMachMessageIDMachExceptionRaiseState = 2406,
143 kMachMessageIDMachExceptionRaiseStateIdentity = 2407, 129 kMachMessageIDMachExceptionRaiseStateIdentity = 2407,
144 }; 130 };
145 131
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 namespace internal { 187 namespace internal {
202 188
203 ExcServer::ExcServer(ExcServer::Interface* interface) 189 ExcServer::ExcServer(ExcServer::Interface* interface)
204 : MachMessageServer::Interface(), 190 : MachMessageServer::Interface(),
205 interface_(interface) { 191 interface_(interface) {
206 } 192 }
207 193
208 bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header, 194 bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header,
209 mach_msg_header_t* out_header, 195 mach_msg_header_t* out_header,
210 bool* destroy_complex_request) { 196 bool* destroy_complex_request) {
211 PrepareReplyFromRequest(in_header, out_header); 197 PrepareMIGReplyFromRequest(in_header, out_header);
212 198
213 switch (in_header->msgh_id) { 199 switch (in_header->msgh_id) {
214 case kMachMessageIDExceptionRaise: { 200 case kMachMessageIDExceptionRaise: {
215 // exception_raise(), catch_exception_raise(). 201 // exception_raise(), catch_exception_raise().
216 using Request = __Request__exception_raise_t; 202 using Request = __Request__exception_raise_t;
217 const Request* in_request = reinterpret_cast<const Request*>(in_header); 203 const Request* in_request = reinterpret_cast<const Request*>(in_header);
218 kern_return_t kr = MIGCheckRequestExceptionRaise(in_request); 204 kern_return_t kr = MIGCheckRequestExceptionRaise(in_request);
219 if (kr != MACH_MSG_SUCCESS) { 205 if (kr != MACH_MSG_SUCCESS) {
220 SetReplyError(out_header, kr); 206 SetMIGReplyError(out_header, kr);
221 return true; 207 return true;
222 } 208 }
223 209
224 using Reply = __Reply__exception_raise_t; 210 using Reply = __Reply__exception_raise_t;
225 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 211 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
226 out_reply->RetCode = 212 out_reply->RetCode =
227 interface_->CatchExceptionRaise(in_header->msgh_local_port, 213 interface_->CatchExceptionRaise(in_header->msgh_local_port,
228 in_request->thread.name, 214 in_request->thread.name,
229 in_request->task.name, 215 in_request->task.name,
230 in_request->exception, 216 in_request->exception,
(...skipping 12 matching lines...) Expand all
243 // exception_raise_state(), catch_exception_raise_state(). 229 // exception_raise_state(), catch_exception_raise_state().
244 using Request = __Request__exception_raise_state_t; 230 using Request = __Request__exception_raise_state_t;
245 const Request* in_request = reinterpret_cast<const Request*>(in_header); 231 const Request* in_request = reinterpret_cast<const Request*>(in_header);
246 232
247 // in_request_1 is used for the portion of the request after the codes, 233 // in_request_1 is used for the portion of the request after the codes,
248 // which in theory can be variable-length. The check function will set it. 234 // which in theory can be variable-length. The check function will set it.
249 const Request* in_request_1; 235 const Request* in_request_1;
250 kern_return_t kr = 236 kern_return_t kr =
251 MIGCheckRequestExceptionRaiseState(in_request, &in_request_1); 237 MIGCheckRequestExceptionRaiseState(in_request, &in_request_1);
252 if (kr != MACH_MSG_SUCCESS) { 238 if (kr != MACH_MSG_SUCCESS) {
253 SetReplyError(out_header, kr); 239 SetMIGReplyError(out_header, kr);
254 return true; 240 return true;
255 } 241 }
256 242
257 using Reply = __Reply__exception_raise_state_t; 243 using Reply = __Reply__exception_raise_state_t;
258 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 244 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
259 out_reply->flavor = in_request_1->flavor; 245 out_reply->flavor = in_request_1->flavor;
260 out_reply->new_stateCnt = arraysize(out_reply->new_state); 246 out_reply->new_stateCnt = arraysize(out_reply->new_state);
261 out_reply->RetCode = 247 out_reply->RetCode =
262 interface_->CatchExceptionRaiseState(in_header->msgh_local_port, 248 interface_->CatchExceptionRaiseState(in_header->msgh_local_port,
263 in_request->exception, 249 in_request->exception,
(...skipping 19 matching lines...) Expand all
283 // catch_exception_raise_state_identity(). 269 // catch_exception_raise_state_identity().
284 using Request = __Request__exception_raise_state_identity_t; 270 using Request = __Request__exception_raise_state_identity_t;
285 const Request* in_request = reinterpret_cast<const Request*>(in_header); 271 const Request* in_request = reinterpret_cast<const Request*>(in_header);
286 272
287 // in_request_1 is used for the portion of the request after the codes, 273 // in_request_1 is used for the portion of the request after the codes,
288 // which in theory can be variable-length. The check function will set it. 274 // which in theory can be variable-length. The check function will set it.
289 const Request* in_request_1; 275 const Request* in_request_1;
290 kern_return_t kr = 276 kern_return_t kr =
291 MIGCheckRequestExceptionRaiseStateIdentity(in_request, &in_request_1); 277 MIGCheckRequestExceptionRaiseStateIdentity(in_request, &in_request_1);
292 if (kr != MACH_MSG_SUCCESS) { 278 if (kr != MACH_MSG_SUCCESS) {
293 SetReplyError(out_header, kr); 279 SetMIGReplyError(out_header, kr);
294 return true; 280 return true;
295 } 281 }
296 282
297 using Reply = __Reply__exception_raise_state_identity_t; 283 using Reply = __Reply__exception_raise_state_identity_t;
298 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 284 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
299 out_reply->flavor = in_request_1->flavor; 285 out_reply->flavor = in_request_1->flavor;
300 out_reply->new_stateCnt = arraysize(out_reply->new_state); 286 out_reply->new_stateCnt = arraysize(out_reply->new_state);
301 out_reply->RetCode = interface_->CatchExceptionRaiseStateIdentity( 287 out_reply->RetCode = interface_->CatchExceptionRaiseStateIdentity(
302 in_header->msgh_local_port, 288 in_header->msgh_local_port,
303 in_request->thread.name, 289 in_request->thread.name,
(...skipping 11 matching lines...) Expand all
315 return true; 301 return true;
316 } 302 }
317 303
318 out_header->msgh_size = 304 out_header->msgh_size =
319 sizeof(*out_reply) - sizeof(out_reply->new_state) + 305 sizeof(*out_reply) - sizeof(out_reply->new_state) +
320 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt; 306 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
321 return true; 307 return true;
322 } 308 }
323 } 309 }
324 310
325 SetReplyError(out_header, MIG_BAD_ID); 311 SetMIGReplyError(out_header, MIG_BAD_ID);
326 return false; 312 return false;
327 } 313 }
328 314
329 mach_msg_size_t ExcServer::MachMessageServerRequestSize() { 315 mach_msg_size_t ExcServer::MachMessageServerRequestSize() {
330 return sizeof(__RequestUnion__exc_subsystem); 316 return sizeof(__RequestUnion__exc_subsystem);
331 } 317 }
332 318
333 mach_msg_size_t ExcServer::MachMessageServerReplySize() { 319 mach_msg_size_t ExcServer::MachMessageServerReplySize() {
334 return sizeof(__ReplyUnion__exc_subsystem); 320 return sizeof(__ReplyUnion__exc_subsystem);
335 } 321 }
336 322
337 MachExcServer::MachExcServer(MachExcServer::Interface* interface) 323 MachExcServer::MachExcServer(MachExcServer::Interface* interface)
338 : MachMessageServer::Interface(), 324 : MachMessageServer::Interface(),
339 interface_(interface) { 325 interface_(interface) {
340 } 326 }
341 327
342 bool MachExcServer::MachMessageServerFunction( 328 bool MachExcServer::MachMessageServerFunction(
343 const mach_msg_header_t* in_header, 329 const mach_msg_header_t* in_header,
344 mach_msg_header_t* out_header, 330 mach_msg_header_t* out_header,
345 bool* destroy_complex_request) { 331 bool* destroy_complex_request) {
346 PrepareReplyFromRequest(in_header, out_header); 332 PrepareMIGReplyFromRequest(in_header, out_header);
347 333
348 switch (in_header->msgh_id) { 334 switch (in_header->msgh_id) {
349 case kMachMessageIDMachExceptionRaise: { 335 case kMachMessageIDMachExceptionRaise: {
350 // mach_exception_raise(), catch_mach_exception_raise(). 336 // mach_exception_raise(), catch_mach_exception_raise().
351 using Request = __Request__mach_exception_raise_t; 337 using Request = __Request__mach_exception_raise_t;
352 const Request* in_request = reinterpret_cast<const Request*>(in_header); 338 const Request* in_request = reinterpret_cast<const Request*>(in_header);
353 kern_return_t kr = MIGCheckRequestMachExceptionRaise(in_request); 339 kern_return_t kr = MIGCheckRequestMachExceptionRaise(in_request);
354 if (kr != MACH_MSG_SUCCESS) { 340 if (kr != MACH_MSG_SUCCESS) {
355 SetReplyError(out_header, kr); 341 SetMIGReplyError(out_header, kr);
356 return true; 342 return true;
357 } 343 }
358 344
359 using Reply = __Reply__mach_exception_raise_t; 345 using Reply = __Reply__mach_exception_raise_t;
360 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 346 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
361 out_reply->RetCode = 347 out_reply->RetCode =
362 interface_->CatchMachExceptionRaise(in_header->msgh_local_port, 348 interface_->CatchMachExceptionRaise(in_header->msgh_local_port,
363 in_request->thread.name, 349 in_request->thread.name,
364 in_request->task.name, 350 in_request->task.name,
365 in_request->exception, 351 in_request->exception,
(...skipping 12 matching lines...) Expand all
378 // mach_exception_raise_state(), catch_mach_exception_raise_state(). 364 // mach_exception_raise_state(), catch_mach_exception_raise_state().
379 using Request = __Request__mach_exception_raise_state_t; 365 using Request = __Request__mach_exception_raise_state_t;
380 const Request* in_request = reinterpret_cast<const Request*>(in_header); 366 const Request* in_request = reinterpret_cast<const Request*>(in_header);
381 367
382 // in_request_1 is used for the portion of the request after the codes, 368 // in_request_1 is used for the portion of the request after the codes,
383 // which in theory can be variable-length. The check function will set it. 369 // which in theory can be variable-length. The check function will set it.
384 const Request* in_request_1; 370 const Request* in_request_1;
385 kern_return_t kr = 371 kern_return_t kr =
386 MIGCheckRequestMachExceptionRaiseState(in_request, &in_request_1); 372 MIGCheckRequestMachExceptionRaiseState(in_request, &in_request_1);
387 if (kr != MACH_MSG_SUCCESS) { 373 if (kr != MACH_MSG_SUCCESS) {
388 SetReplyError(out_header, kr); 374 SetMIGReplyError(out_header, kr);
389 return true; 375 return true;
390 } 376 }
391 377
392 using Reply = __Reply__mach_exception_raise_state_t; 378 using Reply = __Reply__mach_exception_raise_state_t;
393 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 379 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
394 out_reply->flavor = in_request_1->flavor; 380 out_reply->flavor = in_request_1->flavor;
395 out_reply->new_stateCnt = arraysize(out_reply->new_state); 381 out_reply->new_stateCnt = arraysize(out_reply->new_state);
396 out_reply->RetCode = 382 out_reply->RetCode =
397 interface_->CatchMachExceptionRaiseState(in_header->msgh_local_port, 383 interface_->CatchMachExceptionRaiseState(in_header->msgh_local_port,
398 in_request->exception, 384 in_request->exception,
(...skipping 19 matching lines...) Expand all
418 // catch_mach_exception_raise_state_identity(). 404 // catch_mach_exception_raise_state_identity().
419 using Request = __Request__mach_exception_raise_state_identity_t; 405 using Request = __Request__mach_exception_raise_state_identity_t;
420 const Request* in_request = reinterpret_cast<const Request*>(in_header); 406 const Request* in_request = reinterpret_cast<const Request*>(in_header);
421 407
422 // in_request_1 is used for the portion of the request after the codes, 408 // in_request_1 is used for the portion of the request after the codes,
423 // which in theory can be variable-length. The check function will set it. 409 // which in theory can be variable-length. The check function will set it.
424 const Request* in_request_1; 410 const Request* in_request_1;
425 kern_return_t kr = MIGCheckRequestMachExceptionRaiseStateIdentity( 411 kern_return_t kr = MIGCheckRequestMachExceptionRaiseStateIdentity(
426 in_request, &in_request_1); 412 in_request, &in_request_1);
427 if (kr != MACH_MSG_SUCCESS) { 413 if (kr != MACH_MSG_SUCCESS) {
428 SetReplyError(out_header, kr); 414 SetMIGReplyError(out_header, kr);
429 return true; 415 return true;
430 } 416 }
431 417
432 using Reply = __Reply__mach_exception_raise_state_identity_t; 418 using Reply = __Reply__mach_exception_raise_state_identity_t;
433 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 419 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
434 out_reply->flavor = in_request_1->flavor; 420 out_reply->flavor = in_request_1->flavor;
435 out_reply->new_stateCnt = arraysize(out_reply->new_state); 421 out_reply->new_stateCnt = arraysize(out_reply->new_state);
436 out_reply->RetCode = interface_->CatchMachExceptionRaiseStateIdentity( 422 out_reply->RetCode = interface_->CatchMachExceptionRaiseStateIdentity(
437 in_header->msgh_local_port, 423 in_header->msgh_local_port,
438 in_request->thread.name, 424 in_request->thread.name,
(...skipping 11 matching lines...) Expand all
450 return true; 436 return true;
451 } 437 }
452 438
453 out_header->msgh_size = 439 out_header->msgh_size =
454 sizeof(*out_reply) - sizeof(out_reply->new_state) + 440 sizeof(*out_reply) - sizeof(out_reply->new_state) +
455 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt; 441 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
456 return true; 442 return true;
457 } 443 }
458 } 444 }
459 445
460 SetReplyError(out_header, MIG_BAD_ID); 446 SetMIGReplyError(out_header, MIG_BAD_ID);
461 return false; 447 return false;
462 } 448 }
463 449
464 mach_msg_size_t MachExcServer::MachMessageServerRequestSize() { 450 mach_msg_size_t MachExcServer::MachMessageServerRequestSize() {
465 return sizeof(__RequestUnion__mach_exc_subsystem); 451 return sizeof(__RequestUnion__mach_exc_subsystem);
466 } 452 }
467 453
468 mach_msg_size_t MachExcServer::MachMessageServerReplySize() { 454 mach_msg_size_t MachExcServer::MachMessageServerReplySize() {
469 return sizeof(__ReplyUnion__mach_exc_subsystem); 455 return sizeof(__ReplyUnion__mach_exc_subsystem);
470 } 456 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 in_header, out_header, destroy_complex_request); 651 in_header, out_header, destroy_complex_request);
666 case kMachMessageIDExceptionRaise: 652 case kMachMessageIDExceptionRaise:
667 case kMachMessageIDExceptionRaiseState: 653 case kMachMessageIDExceptionRaiseState:
668 case kMachMessageIDExceptionRaiseStateIdentity: 654 case kMachMessageIDExceptionRaiseStateIdentity:
669 return exc_server_.MachMessageServerFunction( 655 return exc_server_.MachMessageServerFunction(
670 in_header, out_header, destroy_complex_request); 656 in_header, out_header, destroy_complex_request);
671 } 657 }
672 658
673 // Do what the MIG-generated server routines do when they can’t dispatch a 659 // Do what the MIG-generated server routines do when they can’t dispatch a
674 // message. 660 // message.
675 PrepareReplyFromRequest(in_header, out_header); 661 PrepareMIGReplyFromRequest(in_header, out_header);
676 SetReplyError(out_header, MIG_BAD_ID); 662 SetMIGReplyError(out_header, MIG_BAD_ID);
677 return false; 663 return false;
678 } 664 }
679 665
680 mach_msg_size_t UniversalMachExcServer::MachMessageServerRequestSize() { 666 mach_msg_size_t UniversalMachExcServer::MachMessageServerRequestSize() {
681 return std::max(mach_exc_server_.MachMessageServerRequestSize(), 667 return std::max(mach_exc_server_.MachMessageServerRequestSize(),
682 exc_server_.MachMessageServerRequestSize()); 668 exc_server_.MachMessageServerRequestSize());
683 } 669 }
684 670
685 mach_msg_size_t UniversalMachExcServer::MachMessageServerReplySize() { 671 mach_msg_size_t UniversalMachExcServer::MachMessageServerReplySize() {
686 return std::max(mach_exc_server_.MachMessageServerReplySize(), 672 return std::max(mach_exc_server_.MachMessageServerReplySize(),
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 kern_return_t ExcServerSuccessfulReturnValue(exception_behavior_t behavior, 738 kern_return_t ExcServerSuccessfulReturnValue(exception_behavior_t behavior,
753 bool set_thread_state) { 739 bool set_thread_state) {
754 if (!set_thread_state && ExceptionBehaviorHasState(behavior)) { 740 if (!set_thread_state && ExceptionBehaviorHasState(behavior)) {
755 return MACH_RCV_PORT_DIED; 741 return MACH_RCV_PORT_DIED;
756 } 742 }
757 743
758 return KERN_SUCCESS; 744 return KERN_SUCCESS;
759 } 745 }
760 746
761 } // namespace crashpad 747 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698