2 * Copyright (c) 2011 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <mach/mach_port_internal.h>
30 #include <mach/mach.h>
31 #include <mach/mach_vm.h>
32 #include <mach/mach_traps.h>
33 #include <mach/mach_sync_ipc.h>
40 mach_port_name_array_t
*names
,
41 mach_msg_type_number_t
*namesCnt
,
42 mach_port_type_array_t
*types
,
43 mach_msg_type_number_t
*typesCnt
)
47 rv
= _kernelrpc_mach_port_names(task
, names
, namesCnt
, types
,
56 mach_port_name_t name
,
57 mach_port_type_t
*ptype
)
61 rv
= _kernelrpc_mach_port_type_trap(task
, name
, ptype
);
63 if (rv
== MACH_SEND_INVALID_DEST
) {
64 rv
= _kernelrpc_mach_port_type(task
, name
, ptype
);
73 mach_port_name_t old_name
,
74 mach_port_name_t new_name
)
78 rv
= _kernelrpc_mach_port_rename(task
, old_name
, new_name
);
84 mach_port_allocate_name(
86 mach_port_right_t right
,
87 mach_port_name_t name
)
91 rv
= _kernelrpc_mach_port_allocate_name(task
, right
, name
);
99 mach_port_right_t right
,
100 mach_port_name_t
*name
)
104 rv
= _kernelrpc_mach_port_allocate_trap(task
, right
, name
);
106 if (rv
== MACH_SEND_INVALID_DEST
) {
107 rv
= _kernelrpc_mach_port_allocate(task
, right
, name
);
116 mach_port_name_t name
)
120 rv
= _kernelrpc_mach_port_destroy(task
, name
);
126 mach_port_deallocate(
128 mach_port_name_t name
)
132 rv
= _kernelrpc_mach_port_deallocate_trap(task
, name
);
134 if (rv
== MACH_SEND_INVALID_DEST
) {
135 rv
= _kernelrpc_mach_port_deallocate(task
, name
);
144 mach_port_name_t name
,
145 mach_port_right_t right
,
146 mach_port_urefs_t
*refs
)
150 rv
= _kernelrpc_mach_port_get_refs(task
, name
, right
, refs
);
158 mach_port_name_t name
,
159 mach_port_right_t right
,
160 mach_port_delta_t delta
)
164 rv
= _kernelrpc_mach_port_mod_refs_trap(task
, name
, right
, delta
);
166 if (rv
== MACH_SEND_INVALID_DEST
) {
167 rv
= _kernelrpc_mach_port_mod_refs(task
, name
, right
, delta
);
176 mach_port_name_t name
,
177 mach_msg_trailer_type_t trailer_type
,
178 mach_port_seqno_t
*seqnop
,
179 mach_msg_size_t
*msg_sizep
,
180 mach_msg_id_t
*msg_idp
,
181 mach_msg_trailer_info_t trailer_infop
,
182 mach_msg_type_number_t
*trailer_sizep
)
186 rv
= _kernelrpc_mach_port_peek(task
, name
, trailer_type
,
187 seqnop
, msg_sizep
, msg_idp
,
188 trailer_infop
, trailer_sizep
);
194 mach_port_set_mscount(
196 mach_port_name_t name
,
197 mach_port_mscount_t mscount
)
201 rv
= _kernelrpc_mach_port_set_mscount(task
, name
, mscount
);
207 mach_port_get_set_status(
209 mach_port_name_t name
,
210 mach_port_name_array_t
*members
,
211 mach_msg_type_number_t
*membersCnt
)
215 rv
= _kernelrpc_mach_port_get_set_status(task
, name
, members
,
222 mach_port_move_member(
224 mach_port_name_t member
,
225 mach_port_name_t after
)
229 rv
= _kernelrpc_mach_port_move_member_trap(task
, member
, after
);
231 if (rv
== MACH_SEND_INVALID_DEST
) {
232 rv
= _kernelrpc_mach_port_move_member(task
, member
, after
);
239 mach_port_request_notification(
241 mach_port_name_t name
,
243 mach_port_mscount_t sync
,
245 mach_msg_type_name_t notifyPoly
,
246 mach_port_t
*previous
)
250 rv
= _kernelrpc_mach_port_request_notification_trap(task
, name
, msgid
,
251 sync
, notify
, notifyPoly
, previous
);
253 if (rv
== MACH_SEND_INVALID_DEST
) {
254 rv
= _kernelrpc_mach_port_request_notification(task
, name
, msgid
,
255 sync
, notify
, notifyPoly
, previous
);
262 mach_port_insert_right(
264 mach_port_name_t name
,
266 mach_msg_type_name_t polyPoly
)
270 rv
= _kernelrpc_mach_port_insert_right_trap(task
, name
, poly
, polyPoly
);
272 if (rv
== MACH_SEND_INVALID_DEST
) {
273 rv
= _kernelrpc_mach_port_insert_right(task
, name
, poly
,
281 mach_port_extract_right(
283 mach_port_name_t name
,
284 mach_msg_type_name_t msgt_name
,
286 mach_msg_type_name_t
*polyPoly
)
290 rv
= _kernelrpc_mach_port_extract_right(task
, name
, msgt_name
,
299 mach_port_name_t name
,
300 mach_port_seqno_t seqno
)
304 rv
= _kernelrpc_mach_port_set_seqno(task
, name
, seqno
);
310 mach_port_get_attributes(
312 mach_port_name_t name
,
313 mach_port_flavor_t flavor
,
314 mach_port_info_t port_info_out
,
315 mach_msg_type_number_t
*port_info_outCnt
)
319 rv
= _kernelrpc_mach_port_get_attributes_trap(task
, name
, flavor
,
320 port_info_out
, port_info_outCnt
);
323 /* REMOVE once XBS kernel has new trap */
324 if (rv
== ((1 << 24) | 40)) { /* see mach/i386/syscall_sw.h */
325 rv
= MACH_SEND_INVALID_DEST
;
327 #elif defined(__i386__)
328 /* REMOVE once XBS kernel has new trap */
329 if (rv
== (kern_return_t
)(-40)) {
330 rv
= MACH_SEND_INVALID_DEST
;
334 if (rv
== MACH_SEND_INVALID_DEST
) {
335 rv
= _kernelrpc_mach_port_get_attributes(task
, name
, flavor
,
336 port_info_out
, port_info_outCnt
);
343 mach_port_set_attributes(
345 mach_port_name_t name
,
346 mach_port_flavor_t flavor
,
347 mach_port_info_t port_info
,
348 mach_msg_type_number_t port_infoCnt
)
352 rv
= _kernelrpc_mach_port_set_attributes(task
, name
, flavor
,
353 port_info
, port_infoCnt
);
359 mach_port_allocate_qos(
361 mach_port_right_t right
,
362 mach_port_qos_t
*qos
,
363 mach_port_name_t
*name
)
367 rv
= _kernelrpc_mach_port_allocate_qos(task
, right
, qos
, name
);
373 mach_port_allocate_full(
375 mach_port_right_t right
,
377 mach_port_qos_t
*qos
,
378 mach_port_name_t
*name
)
382 rv
= _kernelrpc_mach_port_allocate_full(task
, right
, proto
, qos
, name
);
394 rv
= _kernelrpc_task_set_port_space(task
, table_entries
);
400 mach_port_get_srights(
402 mach_port_name_t name
,
403 mach_port_rights_t
*srights
)
407 rv
= _kernelrpc_mach_port_get_srights(task
, name
, srights
);
413 mach_port_space_info(
415 ipc_info_space_t
*space_info
,
416 ipc_info_name_array_t
*table_info
,
417 mach_msg_type_number_t
*table_infoCnt
,
418 ipc_info_tree_name_array_t
*tree_info
,
419 mach_msg_type_number_t
*tree_infoCnt
)
423 rv
= _kernelrpc_mach_port_space_info(task
, space_info
, table_info
,
424 table_infoCnt
, tree_info
, tree_infoCnt
);
430 mach_port_space_basic_info(
432 ipc_info_space_basic_t
*space_basic_info
)
436 rv
= _kernelrpc_mach_port_space_basic_info(task
, space_basic_info
);
441 static inline mach_port_t
442 _tsd_get_special_reply_port()
444 return (mach_port_t
)(uintptr_t)_os_tsd_get_direct(__TSD_MACH_SPECIAL_REPLY
);
448 _tsd_set_special_reply_port(mach_port_t port
)
450 _os_tsd_set_direct(__TSD_MACH_SPECIAL_REPLY
, (void *)(uintptr_t)port
);
454 mig_get_special_reply_port(void)
458 srp
= _tsd_get_special_reply_port();
459 if (!MACH_PORT_VALID(srp
)) {
460 srp
= thread_get_special_reply_port();
461 _tsd_set_special_reply_port(srp
);
468 mig_dealloc_special_reply_port(mach_port_t migport
)
470 mach_port_t srp
= _tsd_get_special_reply_port();
471 if (MACH_PORT_VALID(srp
)) {
472 thread_destruct_special_reply_port(srp
, THREAD_SPECIAL_REPLY_PORT_ALL
);
473 if (migport
!= srp
) {
474 mach_port_deallocate(mach_task_self(), migport
);
476 _tsd_set_special_reply_port(MACH_PORT_NULL
);
481 mach_sync_ipc_link_monitoring_start(mach_port_t
*special_reply_port
)
484 boolean_t link_broken
;
487 *special_reply_port
= MACH_PORT_DEAD
;
489 srp
= mig_get_special_reply_port();
491 kr
= mach_port_mod_refs(mach_task_self(), srp
, MACH_PORT_RIGHT_SEND
, 1);
493 if (kr
!= KERN_SUCCESS
) {
497 kr
= _kernelrpc_mach_port_special_reply_port_reset_link(mach_task_self(), srp
, &link_broken
);
498 if (kr
!= KERN_SUCCESS
) {
499 mach_port_deallocate(mach_task_self(), srp
);
503 *special_reply_port
= srp
;
509 mach_sync_ipc_link_monitoring_stop(mach_port_t srp
, boolean_t
* in_effect
)
512 boolean_t link_broken
= TRUE
;
514 kr
= _kernelrpc_mach_port_special_reply_port_reset_link(mach_task_self(), srp
, &link_broken
);
517 * We return if the sync IPC priority inversion avoidance facility took
518 * effect, so if the link was broken it didn't take effect.
521 *in_effect
= !link_broken
;
523 mach_port_deallocate(mach_task_self(), srp
);
529 mach_port_dnrequest_info(
531 mach_port_name_t name
,
537 rv
= _kernelrpc_mach_port_dnrequest_info(task
, name
, dnr_total
,
544 mach_port_kernel_object(
546 mach_port_name_t name
,
547 unsigned *object_type
,
548 unsigned *object_addr
)
552 rv
= _kernelrpc_mach_port_kernel_object(task
, name
,
553 object_type
, object_addr
);
559 mach_port_insert_member(
561 mach_port_name_t name
,
562 mach_port_name_t pset
)
566 rv
= _kernelrpc_mach_port_insert_member_trap(task
, name
, pset
);
568 if (rv
== MACH_SEND_INVALID_DEST
) {
569 rv
= _kernelrpc_mach_port_insert_member(task
, name
, pset
);
576 mach_port_extract_member(
578 mach_port_name_t name
,
579 mach_port_name_t pset
)
583 rv
= _kernelrpc_mach_port_extract_member_trap(task
, name
, pset
);
585 if (rv
== MACH_SEND_INVALID_DEST
) {
586 rv
= _kernelrpc_mach_port_extract_member(task
, name
, pset
);
593 mach_port_get_context(
595 mach_port_name_t name
,
596 mach_port_context_t
*context
)
599 mach_vm_address_t wide_context
;
601 rv
= _kernelrpc_mach_port_get_context(task
, name
, &wide_context
);
603 if (rv
== KERN_SUCCESS
) {
604 *context
= (mach_port_context_t
)wide_context
;
611 mach_port_set_context(
613 mach_port_name_t name
,
614 mach_port_context_t context
)
618 rv
= _kernelrpc_mach_port_set_context(task
, name
, context
);
626 mach_port_name_t name
,
627 natural_t
*object_type
,
628 mach_vm_address_t
*object_addr
)
632 rv
= _kernelrpc_mach_port_kobject(task
, name
, object_type
, object_addr
);
638 mach_port_kobject_description(
640 mach_port_name_t name
,
641 natural_t
*object_type
,
642 mach_vm_address_t
*object_addr
,
643 kobject_description_t desc
)
647 rv
= _kernelrpc_mach_port_kobject_description(task
, name
, object_type
, object_addr
, desc
);
655 mach_port_options_t
*options
,
656 mach_port_context_t context
,
657 mach_port_name_t
*name
)
661 rv
= _kernelrpc_mach_port_construct_trap(task
, options
, (uint64_t) context
, name
);
663 if (rv
== MACH_SEND_INVALID_DEST
) {
664 rv
= _kernelrpc_mach_port_construct(task
, options
, (uint64_t) context
, name
);
673 mach_port_name_t name
,
674 mach_port_delta_t srdelta
,
675 mach_port_context_t guard
)
679 rv
= _kernelrpc_mach_port_destruct_trap(task
, name
, srdelta
, (uint64_t) guard
);
681 if (rv
== MACH_SEND_INVALID_DEST
) {
682 rv
= _kernelrpc_mach_port_destruct(task
, name
, srdelta
, (uint64_t) guard
);
691 mach_port_name_t name
,
692 mach_port_context_t guard
,
697 rv
= _kernelrpc_mach_port_guard_trap(task
, name
, (uint64_t) guard
, strict
);
699 if (rv
== MACH_SEND_INVALID_DEST
) {
700 rv
= _kernelrpc_mach_port_guard(task
, name
, (uint64_t) guard
, strict
);
709 mach_port_name_t name
,
710 mach_port_context_t guard
)
714 rv
= _kernelrpc_mach_port_unguard_trap(task
, name
, (uint64_t) guard
);
716 if (rv
== MACH_SEND_INVALID_DEST
) {
717 rv
= _kernelrpc_mach_port_unguard(task
, name
, (uint64_t) guard
);
724 _kernelrpc_mach_voucher_extract_attr_recipe(
725 mach_port_name_t voucher
,
726 mach_voucher_attr_key_t key
,
727 mach_voucher_attr_raw_recipe_t recipe
,
728 mach_msg_type_number_t
*recipe_size
);
731 mach_voucher_extract_attr_recipe(
732 mach_port_name_t voucher
,
733 mach_voucher_attr_key_t key
,
734 mach_voucher_attr_raw_recipe_t recipe
,
735 mach_msg_type_number_t
*recipe_size
)
739 rv
= mach_voucher_extract_attr_recipe_trap(voucher
, key
, recipe
, recipe_size
);
741 if (rv
== MACH_SEND_INVALID_DEST
) {
742 rv
= _kernelrpc_mach_voucher_extract_attr_recipe(voucher
, key
, recipe
, recipe_size
);
750 thread_destruct_special_reply_port(
751 mach_port_name_t port
,
752 thread_destruct_special_reply_port_rights_t rights
)
755 case THREAD_SPECIAL_REPLY_PORT_ALL
:
756 return mach_port_destruct(mach_task_self(), port
, -1, 0);
758 case THREAD_SPECIAL_REPLY_PORT_RECEIVE_ONLY
:
759 return mach_port_destruct(mach_task_self(), port
, 0, 0);
761 case THREAD_SPECIAL_REPLY_PORT_SEND_ONLY
:
762 return mach_port_deallocate(mach_task_self(), port
);
765 return KERN_INVALID_ARGUMENT
;
770 mach_port_guard_with_flags(
772 mach_port_name_t name
,
773 mach_port_context_t guard
,
778 rv
= _kernelrpc_mach_port_guard_with_flags(task
, name
, (uint64_t) guard
, flags
);
784 mach_port_swap_guard(
786 mach_port_name_t name
,
787 mach_port_context_t old_guard
,
788 mach_port_context_t new_guard
)
792 rv
= _kernelrpc_mach_port_swap_guard(task
, name
, (uint64_t)old_guard
, (uint64_t)new_guard
);