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>
39 mach_port_name_array_t
*names
,
40 mach_msg_type_number_t
*namesCnt
,
41 mach_port_type_array_t
*types
,
42 mach_msg_type_number_t
*typesCnt
)
46 rv
= _kernelrpc_mach_port_names(task
, names
, namesCnt
, types
,
55 mach_port_name_t name
,
56 mach_port_type_t
*ptype
)
60 rv
= _kernelrpc_mach_port_type(task
, name
, ptype
);
68 mach_port_name_t old_name
,
69 mach_port_name_t new_name
)
73 rv
= _kernelrpc_mach_port_rename(task
, old_name
, new_name
);
79 mach_port_allocate_name(
81 mach_port_right_t right
,
82 mach_port_name_t name
)
86 rv
= _kernelrpc_mach_port_allocate_name(task
, right
, name
);
94 mach_port_right_t right
,
95 mach_port_name_t
*name
)
99 rv
= _kernelrpc_mach_port_allocate_trap(task
, right
, name
);
101 if (rv
== MACH_SEND_INVALID_DEST
)
102 rv
= _kernelrpc_mach_port_allocate(task
, right
, name
);
110 mach_port_name_t name
)
114 rv
= _kernelrpc_mach_port_destroy_trap(task
, name
);
116 if (rv
== MACH_SEND_INVALID_DEST
)
117 rv
= _kernelrpc_mach_port_destroy(task
, name
);
123 mach_port_deallocate(
125 mach_port_name_t name
)
129 rv
= _kernelrpc_mach_port_deallocate_trap(task
, name
);
131 if (rv
== MACH_SEND_INVALID_DEST
)
132 rv
= _kernelrpc_mach_port_deallocate(task
,name
);
140 mach_port_name_t name
,
141 mach_port_right_t right
,
142 mach_port_urefs_t
*refs
)
146 rv
= _kernelrpc_mach_port_get_refs(task
, name
, right
, refs
);
154 mach_port_name_t name
,
155 mach_port_right_t right
,
156 mach_port_delta_t delta
)
160 rv
= _kernelrpc_mach_port_mod_refs_trap(task
, name
, right
, delta
);
162 if (rv
== MACH_SEND_INVALID_DEST
)
163 rv
= _kernelrpc_mach_port_mod_refs(task
, name
, right
, delta
);
171 mach_port_name_t name
,
172 mach_msg_trailer_type_t trailer_type
,
173 mach_port_seqno_t
*seqnop
,
174 mach_msg_size_t
*msg_sizep
,
175 mach_msg_id_t
*msg_idp
,
176 mach_msg_trailer_info_t trailer_infop
,
177 mach_msg_type_number_t
*trailer_sizep
)
181 rv
= _kernelrpc_mach_port_peek(task
, name
, trailer_type
,
182 seqnop
, msg_sizep
, msg_idp
,
183 trailer_infop
, trailer_sizep
);
189 mach_port_set_mscount(
191 mach_port_name_t name
,
192 mach_port_mscount_t mscount
)
196 rv
= _kernelrpc_mach_port_set_mscount(task
, name
, mscount
);
202 mach_port_get_set_status(
204 mach_port_name_t name
,
205 mach_port_name_array_t
*members
,
206 mach_msg_type_number_t
*membersCnt
)
210 rv
= _kernelrpc_mach_port_get_set_status(task
, name
, members
,
217 mach_port_move_member(
219 mach_port_name_t member
,
220 mach_port_name_t after
)
224 rv
= _kernelrpc_mach_port_move_member_trap(task
, member
, after
);
226 if (rv
== MACH_SEND_INVALID_DEST
)
227 rv
= _kernelrpc_mach_port_move_member(task
, member
, after
);
233 mach_port_request_notification(
235 mach_port_name_t name
,
237 mach_port_mscount_t sync
,
239 mach_msg_type_name_t notifyPoly
,
240 mach_port_t
*previous
)
244 rv
= _kernelrpc_mach_port_request_notification(task
, name
, msgid
,
245 sync
, notify
, notifyPoly
, previous
);
251 mach_port_insert_right(
253 mach_port_name_t name
,
255 mach_msg_type_name_t polyPoly
)
259 rv
= _kernelrpc_mach_port_insert_right_trap(task
, name
, poly
, polyPoly
);
261 if (rv
== MACH_SEND_INVALID_DEST
)
262 rv
= _kernelrpc_mach_port_insert_right(task
, name
, poly
,
269 mach_port_extract_right(
271 mach_port_name_t name
,
272 mach_msg_type_name_t msgt_name
,
274 mach_msg_type_name_t
*polyPoly
)
278 rv
= _kernelrpc_mach_port_extract_right(task
, name
, msgt_name
,
287 mach_port_name_t name
,
288 mach_port_seqno_t seqno
)
292 rv
= _kernelrpc_mach_port_set_seqno(task
, name
, seqno
);
298 mach_port_get_attributes(
300 mach_port_name_t name
,
301 mach_port_flavor_t flavor
,
302 mach_port_info_t port_info_out
,
303 mach_msg_type_number_t
*port_info_outCnt
)
307 rv
= _kernelrpc_mach_port_get_attributes_trap(task
, name
, flavor
,
308 port_info_out
, port_info_outCnt
);
311 /* REMOVE once XBS kernel has new trap */
312 if (rv
== ((1 << 24) | 40)) /* see mach/i386/syscall_sw.h */
313 rv
= MACH_SEND_INVALID_DEST
;
314 #elif defined(__i386__)
315 /* REMOVE once XBS kernel has new trap */
316 if (rv
== (kern_return_t
)(-40))
317 rv
= MACH_SEND_INVALID_DEST
;
320 if (rv
== MACH_SEND_INVALID_DEST
)
321 rv
= _kernelrpc_mach_port_get_attributes(task
, name
, flavor
,
322 port_info_out
, port_info_outCnt
);
328 mach_port_set_attributes(
330 mach_port_name_t name
,
331 mach_port_flavor_t flavor
,
332 mach_port_info_t port_info
,
333 mach_msg_type_number_t port_infoCnt
)
337 rv
= _kernelrpc_mach_port_set_attributes(task
, name
, flavor
,
338 port_info
, port_infoCnt
);
344 mach_port_allocate_qos(
346 mach_port_right_t right
,
347 mach_port_qos_t
*qos
,
348 mach_port_name_t
*name
)
352 rv
= _kernelrpc_mach_port_allocate_qos(task
, right
, qos
, name
);
358 mach_port_allocate_full(
360 mach_port_right_t right
,
362 mach_port_qos_t
*qos
,
363 mach_port_name_t
*name
)
367 rv
= _kernelrpc_mach_port_allocate_full(task
, right
, proto
, qos
, name
);
379 rv
= _kernelrpc_task_set_port_space(task
, table_entries
);
385 mach_port_get_srights(
387 mach_port_name_t name
,
388 mach_port_rights_t
*srights
)
392 rv
= _kernelrpc_mach_port_get_srights(task
, name
, srights
);
398 mach_port_space_info(
400 ipc_info_space_t
*space_info
,
401 ipc_info_name_array_t
*table_info
,
402 mach_msg_type_number_t
*table_infoCnt
,
403 ipc_info_tree_name_array_t
*tree_info
,
404 mach_msg_type_number_t
*tree_infoCnt
)
408 rv
= _kernelrpc_mach_port_space_info(task
, space_info
, table_info
,
409 table_infoCnt
, tree_info
, tree_infoCnt
);
415 mach_port_space_basic_info(
417 ipc_info_space_basic_t
*space_basic_info
)
421 rv
= _kernelrpc_mach_port_space_basic_info(task
, space_basic_info
);
426 static inline mach_port_t
427 _tsd_get_special_reply_port()
429 return (mach_port_t
)(uintptr_t)_os_tsd_get_direct(__TSD_MACH_SPECIAL_REPLY
);
433 _tsd_set_special_reply_port(mach_port_t port
)
435 _os_tsd_set_direct(__TSD_MACH_SPECIAL_REPLY
, (void *)(uintptr_t)port
);
439 mig_get_special_reply_port(void)
443 srp
= _tsd_get_special_reply_port();
444 if (!MACH_PORT_VALID(srp
)) {
445 srp
= thread_get_special_reply_port();
446 _tsd_set_special_reply_port(srp
);
453 mig_dealloc_special_reply_port(mach_port_t migport
)
455 mach_port_t srp
= _tsd_get_special_reply_port();
456 if (MACH_PORT_VALID(srp
)) {
457 thread_destruct_special_reply_port(srp
, THREAD_SPECIAL_REPLY_PORT_ALL
);
458 if (migport
!= srp
) {
459 mach_port_deallocate(mach_task_self(), migport
);
461 _tsd_set_special_reply_port(MACH_PORT_NULL
);
466 mach_sync_ipc_link_monitoring_start(mach_port_t
*special_reply_port
)
469 boolean_t link_broken
;
472 *special_reply_port
= MACH_PORT_DEAD
;
474 srp
= mig_get_special_reply_port();
476 kr
= mach_port_mod_refs(mach_task_self(), srp
, MACH_PORT_RIGHT_SEND
, 1);
478 if (kr
!= KERN_SUCCESS
) {
482 kr
= _kernelrpc_mach_port_special_reply_port_reset_link(mach_task_self(), srp
, &link_broken
);
483 if (kr
!= KERN_SUCCESS
) {
484 mach_port_deallocate(mach_task_self(), srp
);
488 *special_reply_port
= srp
;
494 mach_sync_ipc_link_monitoring_stop(mach_port_t srp
, boolean_t
* in_effect
)
497 boolean_t link_broken
= TRUE
;
499 kr
= _kernelrpc_mach_port_special_reply_port_reset_link(mach_task_self(), srp
, &link_broken
);
502 * We return if the sync IPC priority inversion avoidance facility took
503 * effect, so if the link was broken it didn't take effect.
506 *in_effect
= !link_broken
;
508 mach_port_deallocate(mach_task_self(), srp
);
514 mach_port_dnrequest_info(
516 mach_port_name_t name
,
522 rv
= _kernelrpc_mach_port_dnrequest_info(task
, name
, dnr_total
,
529 mach_port_kernel_object(
531 mach_port_name_t name
,
532 unsigned *object_type
,
533 unsigned *object_addr
)
537 rv
= _kernelrpc_mach_port_kernel_object(task
, name
,
538 object_type
, object_addr
);
544 mach_port_insert_member(
546 mach_port_name_t name
,
547 mach_port_name_t pset
)
551 rv
= _kernelrpc_mach_port_insert_member_trap(task
, name
, pset
);
553 if (rv
== MACH_SEND_INVALID_DEST
)
554 rv
= _kernelrpc_mach_port_insert_member(task
, name
, pset
);
560 mach_port_extract_member(
562 mach_port_name_t name
,
563 mach_port_name_t pset
)
567 rv
= _kernelrpc_mach_port_extract_member_trap(task
, name
, pset
);
569 if (rv
== MACH_SEND_INVALID_DEST
)
570 rv
= _kernelrpc_mach_port_extract_member(task
, name
, pset
);
576 mach_port_get_context(
578 mach_port_name_t name
,
579 mach_port_context_t
*context
)
582 mach_vm_address_t wide_context
;
584 rv
= _kernelrpc_mach_port_get_context(task
, name
, &wide_context
);
586 if (rv
== KERN_SUCCESS
) {
587 *context
= (mach_port_context_t
)wide_context
;
594 mach_port_set_context(
596 mach_port_name_t name
,
597 mach_port_context_t context
)
601 rv
= _kernelrpc_mach_port_set_context(task
, name
, context
);
609 mach_port_name_t name
,
610 natural_t
*object_type
,
611 mach_vm_address_t
*object_addr
)
615 rv
= _kernelrpc_mach_port_kobject(task
, name
, object_type
, object_addr
);
623 mach_port_options_t
*options
,
624 mach_port_context_t context
,
625 mach_port_name_t
*name
)
629 rv
= _kernelrpc_mach_port_construct_trap(task
, options
, (uint64_t) context
, name
);
631 if (rv
== MACH_SEND_INVALID_DEST
)
632 rv
= _kernelrpc_mach_port_construct(task
, options
, (uint64_t) context
, name
);
640 mach_port_name_t name
,
641 mach_port_delta_t srdelta
,
642 mach_port_context_t guard
)
646 rv
= _kernelrpc_mach_port_destruct_trap(task
, name
, srdelta
, (uint64_t) guard
);
648 if (rv
== MACH_SEND_INVALID_DEST
)
649 rv
= _kernelrpc_mach_port_destruct(task
, name
, srdelta
, (uint64_t) guard
);
658 mach_port_name_t name
,
659 mach_port_context_t guard
,
664 rv
= _kernelrpc_mach_port_guard_trap(task
, name
, (uint64_t) guard
, strict
);
666 if (rv
== MACH_SEND_INVALID_DEST
)
667 rv
= _kernelrpc_mach_port_guard(task
, name
, (uint64_t) guard
, strict
);
676 mach_port_name_t name
,
677 mach_port_context_t guard
)
681 rv
= _kernelrpc_mach_port_unguard_trap(task
, name
, (uint64_t) guard
);
683 if (rv
== MACH_SEND_INVALID_DEST
)
684 rv
= _kernelrpc_mach_port_unguard(task
, name
, (uint64_t) guard
);
691 _kernelrpc_mach_voucher_extract_attr_recipe(
692 mach_port_name_t voucher
,
693 mach_voucher_attr_key_t key
,
694 mach_voucher_attr_raw_recipe_t recipe
,
695 mach_msg_type_number_t
*recipe_size
);
698 mach_voucher_extract_attr_recipe(
699 mach_port_name_t voucher
,
700 mach_voucher_attr_key_t key
,
701 mach_voucher_attr_raw_recipe_t recipe
,
702 mach_msg_type_number_t
*recipe_size
)
706 rv
= mach_voucher_extract_attr_recipe_trap(voucher
, key
, recipe
, recipe_size
);
708 if (rv
== MACH_SEND_INVALID_DEST
)
709 rv
= _kernelrpc_mach_voucher_extract_attr_recipe(voucher
, key
, recipe
, recipe_size
);
716 thread_destruct_special_reply_port(
717 mach_port_name_t port
,
718 thread_destruct_special_reply_port_rights_t rights
)
721 case THREAD_SPECIAL_REPLY_PORT_ALL
:
722 return mach_port_destruct(mach_task_self(), port
, -1, 0);
724 case THREAD_SPECIAL_REPLY_PORT_RECEIVE_ONLY
:
725 return mach_port_destruct(mach_task_self(), port
, 0, 0);
727 case THREAD_SPECIAL_REPLY_PORT_SEND_ONLY
:
728 return mach_port_deallocate(mach_task_self(), port
);
731 return KERN_INVALID_ARGUMENT
;