1 | /* |
2 | * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
5 | * |
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. |
14 | * |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. |
17 | * |
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. |
25 | * |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ |
28 | /* |
29 | * @OSF_COPYRIGHT@ |
30 | */ |
31 | /* |
32 | * Mach Operating System |
33 | * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University |
34 | * All Rights Reserved. |
35 | * |
36 | * Permission to use, copy, modify and distribute this software and its |
37 | * documentation is hereby granted, provided that both the copyright |
38 | * notice and this permission notice appear in all copies of the |
39 | * software, derivative works or modified versions, and any portions |
40 | * thereof, and that both notices appear in supporting documentation. |
41 | * |
42 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" |
43 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR |
44 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. |
45 | * |
46 | * Carnegie Mellon requests users of this software to return to |
47 | * |
48 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU |
49 | * School of Computer Science |
50 | * Carnegie Mellon University |
51 | * Pittsburgh PA 15213-3890 |
52 | * |
53 | * any improvements or extensions that they make and grant Carnegie Mellon |
54 | * the rights to redistribute these changes. |
55 | */ |
56 | /* |
57 | * NOTICE: This file was modified by McAfee Research in 2004 to introduce |
58 | * support for mandatory and extensible security protections. This notice |
59 | * is included in support of clause 2.2 (b) of the Apple Public License, |
60 | * Version 2.0. |
61 | * Copyright (c) 2005 SPARTA, Inc. |
62 | */ |
63 | /* |
64 | */ |
65 | /* |
66 | * File: mach/message.h |
67 | * |
68 | * Mach IPC message and primitive function definitions. |
69 | */ |
70 | |
71 | #ifndef _MACH_MESSAGE_H_ |
72 | #define _MACH_MESSAGE_H_ |
73 | |
74 | #include <stdint.h> |
75 | #include <machine/limits.h> |
76 | #include <mach/port.h> |
77 | #include <mach/boolean.h> |
78 | #include <mach/kern_return.h> |
79 | #include <mach/machine/vm_types.h> |
80 | |
81 | #include <sys/cdefs.h> |
82 | #include <sys/appleapiopts.h> |
83 | #include <Availability.h> |
84 | #if !KERNEL && PRIVATE |
85 | #include <TargetConditionals.h> |
86 | #endif |
87 | |
88 | /* |
89 | * The timeout mechanism uses mach_msg_timeout_t values, |
90 | * passed by value. The timeout units are milliseconds. |
91 | * It is controlled with the MACH_SEND_TIMEOUT |
92 | * and MACH_RCV_TIMEOUT options. |
93 | */ |
94 | |
95 | typedef natural_t mach_msg_timeout_t; |
96 | |
97 | /* |
98 | * The value to be used when there is no timeout. |
99 | * (No MACH_SEND_TIMEOUT/MACH_RCV_TIMEOUT option.) |
100 | */ |
101 | |
102 | #define MACH_MSG_TIMEOUT_NONE ((mach_msg_timeout_t) 0) |
103 | |
104 | /* |
105 | * The kernel uses MACH_MSGH_BITS_COMPLEX as a hint. If it isn't on, it |
106 | * assumes the body of the message doesn't contain port rights or OOL |
107 | * data. The field is set in received messages. A user task must |
108 | * use caution in interpreting the body of a message if the bit isn't |
109 | * on, because the mach_msg_type's in the body might "lie" about the |
110 | * contents. If the bit isn't on, but the mach_msg_types |
111 | * in the body specify rights or OOL data, the behavior is undefined. |
112 | * (Ie, an error may or may not be produced.) |
113 | * |
114 | * The value of MACH_MSGH_BITS_REMOTE determines the interpretation |
115 | * of the msgh_remote_port field. It is handled like a msgt_name, |
116 | * but must result in a send or send-once type right. |
117 | * |
118 | * The value of MACH_MSGH_BITS_LOCAL determines the interpretation |
119 | * of the msgh_local_port field. It is handled like a msgt_name, |
120 | * and also must result in a send or send-once type right. |
121 | * |
122 | * The value of MACH_MSGH_BITS_VOUCHER determines the interpretation |
123 | * of the msgh_voucher_port field. It is handled like a msgt_name, |
124 | * but must result in a send right (and the msgh_voucher_port field |
125 | * must be the name of a send right to a Mach voucher kernel object. |
126 | * |
127 | * MACH_MSGH_BITS() combines two MACH_MSG_TYPE_* values, for the remote |
128 | * and local fields, into a single value suitable for msgh_bits. |
129 | * |
130 | * MACH_MSGH_BITS_CIRCULAR should be zero; is is used internally. |
131 | * |
132 | * The unused bits should be zero and are reserved for the kernel |
133 | * or for future interface expansion. |
134 | */ |
135 | |
136 | #define MACH_MSGH_BITS_ZERO 0x00000000 |
137 | |
138 | #define MACH_MSGH_BITS_REMOTE_MASK 0x0000001f |
139 | #define MACH_MSGH_BITS_LOCAL_MASK 0x00001f00 |
140 | #define MACH_MSGH_BITS_VOUCHER_MASK 0x001f0000 |
141 | |
142 | #define MACH_MSGH_BITS_PORTS_MASK \ |
143 | (MACH_MSGH_BITS_REMOTE_MASK | \ |
144 | MACH_MSGH_BITS_LOCAL_MASK | \ |
145 | MACH_MSGH_BITS_VOUCHER_MASK) |
146 | |
147 | #define MACH_MSGH_BITS_COMPLEX 0x80000000U /* message is complex */ |
148 | |
149 | #define MACH_MSGH_BITS_USER 0x801f1f1fU /* allowed bits user->kernel */ |
150 | |
151 | #define MACH_MSGH_BITS_RAISEIMP 0x20000000U /* importance raised due to msg */ |
152 | #define MACH_MSGH_BITS_DENAP MACH_MSGH_BITS_RAISEIMP |
153 | |
154 | #define MACH_MSGH_BITS_IMPHOLDASRT 0x10000000U /* assertion help, userland private */ |
155 | #define MACH_MSGH_BITS_DENAPHOLDASRT MACH_MSGH_BITS_IMPHOLDASRT |
156 | |
157 | #define MACH_MSGH_BITS_CIRCULAR 0x10000000U /* message circular, kernel private */ |
158 | |
159 | #define MACH_MSGH_BITS_USED 0xb01f1f1fU |
160 | |
161 | /* setter macros for the bits */ |
162 | #define MACH_MSGH_BITS(remote, local) /* legacy */ \ |
163 | ((remote) | ((local) << 8)) |
164 | #define MACH_MSGH_BITS_SET_PORTS(remote, local, voucher) \ |
165 | (((remote) & MACH_MSGH_BITS_REMOTE_MASK) | \ |
166 | (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) | \ |
167 | (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK)) |
168 | #define MACH_MSGH_BITS_SET(remote, local, voucher, other) \ |
169 | (MACH_MSGH_BITS_SET_PORTS((remote), (local), (voucher)) \ |
170 | | ((other) &~ MACH_MSGH_BITS_PORTS_MASK)) |
171 | |
172 | /* getter macros for pulling values out of the bits field */ |
173 | #define MACH_MSGH_BITS_REMOTE(bits) \ |
174 | ((bits) & MACH_MSGH_BITS_REMOTE_MASK) |
175 | #define MACH_MSGH_BITS_LOCAL(bits) \ |
176 | (((bits) & MACH_MSGH_BITS_LOCAL_MASK) >> 8) |
177 | #define MACH_MSGH_BITS_VOUCHER(bits) \ |
178 | (((bits) & MACH_MSGH_BITS_VOUCHER_MASK) >> 16) |
179 | #define MACH_MSGH_BITS_PORTS(bits) \ |
180 | ((bits) & MACH_MSGH_BITS_PORTS_MASK) |
181 | #define MACH_MSGH_BITS_OTHER(bits) \ |
182 | ((bits) &~ MACH_MSGH_BITS_PORTS_MASK) |
183 | |
184 | /* checking macros */ |
185 | #define MACH_MSGH_BITS_HAS_REMOTE(bits) \ |
186 | (MACH_MSGH_BITS_REMOTE(bits) != MACH_MSGH_BITS_ZERO) |
187 | #define MACH_MSGH_BITS_HAS_LOCAL(bits) \ |
188 | (MACH_MSGH_BITS_LOCAL(bits) != MACH_MSGH_BITS_ZERO) |
189 | #define MACH_MSGH_BITS_HAS_VOUCHER(bits) \ |
190 | (MACH_MSGH_BITS_VOUCHER(bits) != MACH_MSGH_BITS_ZERO) |
191 | #define MACH_MSGH_BITS_IS_COMPLEX(bits) \ |
192 | (((bits) & MACH_MSGH_BITS_COMPLEX) != MACH_MSGH_BITS_ZERO) |
193 | |
194 | /* importance checking macros */ |
195 | #define MACH_MSGH_BITS_RAISED_IMPORTANCE(bits) \ |
196 | (((bits) & MACH_MSGH_BITS_RAISEIMP) != MACH_MSGH_BITS_ZERO) |
197 | #define MACH_MSGH_BITS_HOLDS_IMPORTANCE_ASSERTION(bits) \ |
198 | (((bits) & MACH_MSGH_BITS_IMPHOLDASRT) != MACH_MSGH_BITS_ZERO) |
199 | |
200 | /* |
201 | * Every message starts with a message header. |
202 | * Following the message header, if the message is complex, are a count |
203 | * of type descriptors and the type descriptors themselves |
204 | * (mach_msg_descriptor_t). The size of the message must be specified in |
205 | * bytes, and includes the message header, descriptor count, descriptors, |
206 | * and inline data. |
207 | * |
208 | * The msgh_remote_port field specifies the destination of the message. |
209 | * It must specify a valid send or send-once right for a port. |
210 | * |
211 | * The msgh_local_port field specifies a "reply port". Normally, |
212 | * This field carries a send-once right that the receiver will use |
213 | * to reply to the message. It may carry the values MACH_PORT_NULL, |
214 | * MACH_PORT_DEAD, a send-once right, or a send right. |
215 | * |
216 | * The msgh_voucher_port field specifies a Mach voucher port. Only |
217 | * send rights to kernel-implemented Mach Voucher kernel objects in |
218 | * addition to MACH_PORT_NULL or MACH_PORT_DEAD may be passed. |
219 | * |
220 | * The msgh_id field is uninterpreted by the message primitives. |
221 | * It normally carries information specifying the format |
222 | * or meaning of the message. |
223 | */ |
224 | |
225 | typedef unsigned int mach_msg_bits_t; |
226 | typedef natural_t mach_msg_size_t; |
227 | typedef integer_t mach_msg_id_t; |
228 | |
229 | #define MACH_MSG_SIZE_NULL (mach_msg_size_t *) 0 |
230 | |
231 | typedef unsigned int mach_msg_priority_t; |
232 | |
233 | #define MACH_MSG_PRIORITY_UNSPECIFIED (mach_msg_priority_t) 0 |
234 | |
235 | #if PRIVATE |
236 | typedef uint8_t mach_msg_qos_t; // same as thread_qos_t |
237 | #define MACH_MSG_QOS_UNSPECIFIED 0 |
238 | #define MACH_MSG_QOS_MAINTENANCE 1 |
239 | #define MACH_MSG_QOS_BACKGROUND 2 |
240 | #define MACH_MSG_QOS_UTILITY 3 |
241 | #define MACH_MSG_QOS_DEFAULT 4 |
242 | #define MACH_MSG_QOS_USER_INITIATED 5 |
243 | #define MACH_MSG_QOS_USER_INTERACTIVE 6 |
244 | #define MACH_MSG_QOS_LAST 6 |
245 | |
246 | extern int mach_msg_priority_is_pthread_priority(mach_msg_priority_t pri); |
247 | extern mach_msg_priority_t mach_msg_priority_encode( |
248 | mach_msg_qos_t override_qos, |
249 | mach_msg_qos_t qos, |
250 | int relpri); |
251 | extern mach_msg_qos_t mach_msg_priority_overide_qos(mach_msg_priority_t pri); |
252 | extern mach_msg_qos_t mach_msg_priority_qos(mach_msg_priority_t pri); |
253 | extern int mach_msg_priority_relpri(mach_msg_priority_t pri); |
254 | |
255 | #if KERNEL || !TARGET_OS_SIMULATOR |
256 | static inline int |
257 | mach_msg_priority_is_pthread_priority_inline(mach_msg_priority_t pri) |
258 | { |
259 | return (pri & 0xff) == 0xff; |
260 | } |
261 | |
262 | #define MACH_MSG_PRIORITY_RELPRI_SHIFT 8 |
263 | #define MACH_MSG_PRIORITY_RELPRI_MASK (0xff << MACH_MSG_PRIORITY_RELPRI_SHIFT) |
264 | #define MACH_MSG_PRIORITY_QOS_SHIFT 16 |
265 | #define MACH_MSG_PRIORITY_QOS_MASK (0xf << MACH_MSG_PRIORITY_QOS_SHIFT) |
266 | #define MACH_MSG_PRIORITY_OVERRIDE_SHIFT 20 |
267 | #define MACH_MSG_PRIORITY_OVERRIDE_MASK (0xf << MACH_MSG_PRIORITY_OVERRIDE_SHIFT) |
268 | |
269 | static inline mach_msg_priority_t |
270 | mach_msg_priority_encode_inline(mach_msg_qos_t override_qos, mach_msg_qos_t qos, int relpri) |
271 | { |
272 | mach_msg_priority_t pri = 0; |
273 | if (qos > 0 && qos <= MACH_MSG_QOS_LAST) { |
274 | pri |= (uint32_t)(qos << MACH_MSG_PRIORITY_QOS_SHIFT); |
275 | pri |= (uint32_t)((uint8_t)(relpri - 1) << MACH_MSG_PRIORITY_RELPRI_SHIFT); |
276 | } |
277 | if (override_qos > 0 && override_qos <= MACH_MSG_QOS_LAST) { |
278 | pri |= (uint32_t)(override_qos << MACH_MSG_PRIORITY_OVERRIDE_SHIFT); |
279 | } |
280 | return pri; |
281 | } |
282 | |
283 | static inline mach_msg_qos_t |
284 | mach_msg_priority_overide_qos_inline(mach_msg_priority_t pri) |
285 | { |
286 | pri &= MACH_MSG_PRIORITY_OVERRIDE_MASK; |
287 | pri >>= MACH_MSG_PRIORITY_OVERRIDE_SHIFT; |
288 | return (mach_msg_qos_t)(pri <= MACH_MSG_QOS_LAST ? pri : 0); |
289 | } |
290 | |
291 | static inline mach_msg_qos_t |
292 | mach_msg_priority_qos_inline(mach_msg_priority_t pri) |
293 | { |
294 | pri &= MACH_MSG_PRIORITY_QOS_MASK; |
295 | pri >>= MACH_MSG_PRIORITY_QOS_SHIFT; |
296 | return (mach_msg_qos_t)(pri <= MACH_MSG_QOS_LAST ? pri : 0); |
297 | } |
298 | |
299 | static inline int |
300 | mach_msg_priority_relpri_inline(mach_msg_priority_t pri) |
301 | { |
302 | if (mach_msg_priority_qos_inline(pri)) { |
303 | return (int8_t)(pri >> MACH_MSG_PRIORITY_RELPRI_SHIFT) + 1; |
304 | } |
305 | return 0; |
306 | } |
307 | |
308 | #define mach_msg_priority_is_pthread_priority(...) \ |
309 | mach_msg_priority_is_pthread_priority_inline(__VA_ARGS__) |
310 | #define mach_msg_priority_encode(...) \ |
311 | mach_msg_priority_encode_inline(__VA_ARGS__) |
312 | #define mach_msg_priority_overide_qos(...) \ |
313 | mach_msg_priority_overide_qos_inline(__VA_ARGS__) |
314 | #define mach_msg_priority_qos(...) \ |
315 | mach_msg_priority_qos_inline(__VA_ARGS__) |
316 | #define mach_msg_priority_relpri(...) \ |
317 | mach_msg_priority_relpri_inline(__VA_ARGS__) |
318 | #endif |
319 | |
320 | #endif // PRIVATE |
321 | |
322 | typedef unsigned int mach_msg_type_name_t; |
323 | |
324 | #define MACH_MSG_TYPE_MOVE_RECEIVE 16 /* Must hold receive right */ |
325 | #define MACH_MSG_TYPE_MOVE_SEND 17 /* Must hold send right(s) */ |
326 | #define MACH_MSG_TYPE_MOVE_SEND_ONCE 18 /* Must hold sendonce right */ |
327 | #define MACH_MSG_TYPE_COPY_SEND 19 /* Must hold send right(s) */ |
328 | #define MACH_MSG_TYPE_MAKE_SEND 20 /* Must hold receive right */ |
329 | #define MACH_MSG_TYPE_MAKE_SEND_ONCE 21 /* Must hold receive right */ |
330 | #define MACH_MSG_TYPE_COPY_RECEIVE 22 /* NOT VALID */ |
331 | #define MACH_MSG_TYPE_DISPOSE_RECEIVE 24 /* must hold receive right */ |
332 | #define MACH_MSG_TYPE_DISPOSE_SEND 25 /* must hold send right(s) */ |
333 | #define MACH_MSG_TYPE_DISPOSE_SEND_ONCE 26 /* must hold sendonce right */ |
334 | |
335 | typedef unsigned int mach_msg_copy_options_t; |
336 | |
337 | #define MACH_MSG_PHYSICAL_COPY 0 |
338 | #define MACH_MSG_VIRTUAL_COPY 1 |
339 | #define MACH_MSG_ALLOCATE 2 |
340 | #define MACH_MSG_OVERWRITE 3 /* deprecated */ |
341 | #ifdef MACH_KERNEL |
342 | #define MACH_MSG_KALLOC_COPY_T 4 |
343 | #endif /* MACH_KERNEL */ |
344 | |
345 | #define MACH_MSG_GUARD_FLAGS_NONE 0x0000 |
346 | #define MACH_MSG_GUARD_FLAGS_IMMOVABLE_RECEIVE 0x0001 /* Move the receive right and mark it as immovable */ |
347 | #define MACH_MSG_GUARD_FLAGS_UNGUARDED_ON_SEND 0x0002 /* Verify that the port is unguarded */ |
348 | #define MACH_MSG_GUARD_FLAGS_MASK 0x0003 /* Valid flag bits */ |
349 | typedef unsigned int mach_msg_guard_flags_t; |
350 | |
351 | /* |
352 | * In a complex mach message, the mach_msg_header_t is followed by |
353 | * a descriptor count, then an array of that number of descriptors |
354 | * (mach_msg_*_descriptor_t). The type field of mach_msg_type_descriptor_t |
355 | * (which any descriptor can be cast to) indicates the flavor of the |
356 | * descriptor. |
357 | * |
358 | * Note that in LP64, the various types of descriptors are no longer all |
359 | * the same size as mach_msg_descriptor_t, so the array cannot be indexed |
360 | * as expected. |
361 | */ |
362 | |
363 | typedef unsigned int mach_msg_descriptor_type_t; |
364 | |
365 | #define MACH_MSG_PORT_DESCRIPTOR 0 |
366 | #define MACH_MSG_OOL_DESCRIPTOR 1 |
367 | #define MACH_MSG_OOL_PORTS_DESCRIPTOR 2 |
368 | #define MACH_MSG_OOL_VOLATILE_DESCRIPTOR 3 |
369 | #define MACH_MSG_GUARDED_PORT_DESCRIPTOR 4 |
370 | |
371 | #define MACH_MSG_DESCRIPTOR_MAX MACH_MSG_GUARDED_PORT_DESCRIPTOR |
372 | |
373 | #pragma pack(push, 4) |
374 | |
375 | typedef struct { |
376 | natural_t pad1; |
377 | mach_msg_size_t pad2; |
378 | unsigned int pad3 : 24; |
379 | mach_msg_descriptor_type_t type : 8; |
380 | } mach_msg_type_descriptor_t; |
381 | |
382 | typedef struct { |
383 | mach_port_t name; |
384 | #if !(defined(KERNEL) && defined(__LP64__)) |
385 | // Pad to 8 bytes everywhere except the K64 kernel where mach_port_t is 8 bytes |
386 | mach_msg_size_t pad1; |
387 | #endif |
388 | unsigned int pad2 : 16; |
389 | mach_msg_type_name_t disposition : 8; |
390 | mach_msg_descriptor_type_t type : 8; |
391 | #if defined(KERNEL) |
392 | uint32_t pad_end; |
393 | #endif |
394 | } mach_msg_port_descriptor_t; |
395 | |
396 | #if MACH_KERNEL_PRIVATE |
397 | typedef struct { |
398 | mach_port_name_t name; |
399 | mach_msg_size_t pad1; |
400 | uint32_t pad2 : 16; |
401 | mach_msg_type_name_t disposition : 8; |
402 | mach_msg_descriptor_type_t type : 8; |
403 | } mach_msg_user_port_descriptor_t; |
404 | #endif /* MACH_KERNEL_PRIVATE */ |
405 | |
406 | typedef struct { |
407 | uint32_t address; |
408 | mach_msg_size_t size; |
409 | boolean_t deallocate: 8; |
410 | mach_msg_copy_options_t copy: 8; |
411 | unsigned int pad1: 8; |
412 | mach_msg_descriptor_type_t type: 8; |
413 | } mach_msg_ool_descriptor32_t; |
414 | |
415 | typedef struct { |
416 | uint64_t address; |
417 | boolean_t deallocate: 8; |
418 | mach_msg_copy_options_t copy: 8; |
419 | unsigned int pad1: 8; |
420 | mach_msg_descriptor_type_t type: 8; |
421 | mach_msg_size_t size; |
422 | } mach_msg_ool_descriptor64_t; |
423 | |
424 | typedef struct { |
425 | void* address; |
426 | #if !defined(__LP64__) |
427 | mach_msg_size_t size; |
428 | #endif |
429 | boolean_t deallocate: 8; |
430 | mach_msg_copy_options_t copy: 8; |
431 | unsigned int pad1: 8; |
432 | mach_msg_descriptor_type_t type: 8; |
433 | #if defined(__LP64__) |
434 | mach_msg_size_t size; |
435 | #endif |
436 | #if defined(KERNEL) && !defined(__LP64__) |
437 | uint32_t pad_end; |
438 | #endif |
439 | } mach_msg_ool_descriptor_t; |
440 | |
441 | typedef struct { |
442 | uint32_t address; |
443 | mach_msg_size_t count; |
444 | boolean_t deallocate: 8; |
445 | mach_msg_copy_options_t copy: 8; |
446 | mach_msg_type_name_t disposition : 8; |
447 | mach_msg_descriptor_type_t type : 8; |
448 | } mach_msg_ool_ports_descriptor32_t; |
449 | |
450 | typedef struct { |
451 | uint64_t address; |
452 | boolean_t deallocate: 8; |
453 | mach_msg_copy_options_t copy: 8; |
454 | mach_msg_type_name_t disposition : 8; |
455 | mach_msg_descriptor_type_t type : 8; |
456 | mach_msg_size_t count; |
457 | } mach_msg_ool_ports_descriptor64_t; |
458 | |
459 | typedef struct { |
460 | void* address; |
461 | #if !defined(__LP64__) |
462 | mach_msg_size_t count; |
463 | #endif |
464 | boolean_t deallocate: 8; |
465 | mach_msg_copy_options_t copy: 8; |
466 | mach_msg_type_name_t disposition : 8; |
467 | mach_msg_descriptor_type_t type : 8; |
468 | #if defined(__LP64__) |
469 | mach_msg_size_t count; |
470 | #endif |
471 | #if defined(KERNEL) && !defined(__LP64__) |
472 | uint32_t pad_end; |
473 | #endif |
474 | } mach_msg_ool_ports_descriptor_t; |
475 | |
476 | typedef struct { |
477 | uint32_t context; |
478 | mach_port_name_t name; |
479 | mach_msg_guard_flags_t flags : 16; |
480 | mach_msg_type_name_t disposition : 8; |
481 | mach_msg_descriptor_type_t type : 8; |
482 | } mach_msg_guarded_port_descriptor32_t; |
483 | |
484 | typedef struct { |
485 | uint64_t context; |
486 | mach_msg_guard_flags_t flags : 16; |
487 | mach_msg_type_name_t disposition : 8; |
488 | mach_msg_descriptor_type_t type : 8; |
489 | mach_port_name_t name; |
490 | } mach_msg_guarded_port_descriptor64_t; |
491 | |
492 | typedef struct { |
493 | #if defined(KERNEL) |
494 | mach_port_t name; |
495 | #if !defined(__LP64__) |
496 | uint32_t pad1; |
497 | #endif |
498 | mach_msg_guard_flags_t flags : 16; |
499 | mach_msg_type_name_t disposition : 8; |
500 | mach_msg_descriptor_type_t type : 8; |
501 | #if defined(__LP64__) |
502 | uint32_t pad_end; |
503 | #endif /* defined(__LP64__) */ |
504 | #else |
505 | mach_port_context_t context; |
506 | #if !defined(__LP64__) |
507 | mach_port_name_t name; |
508 | #endif |
509 | mach_msg_guard_flags_t flags : 16; |
510 | mach_msg_type_name_t disposition : 8; |
511 | mach_msg_descriptor_type_t type : 8; |
512 | #if defined(__LP64__) |
513 | mach_port_name_t name; |
514 | #endif /* defined(__LP64__) */ |
515 | #endif /* defined(KERNEL) */ |
516 | } mach_msg_guarded_port_descriptor_t; |
517 | |
518 | /* |
519 | * LP64support - This union definition is not really |
520 | * appropriate in LP64 mode because not all descriptors |
521 | * are of the same size in that environment. |
522 | */ |
523 | #if defined(__LP64__) && defined(KERNEL) |
524 | typedef union{ |
525 | mach_msg_port_descriptor_t port; |
526 | mach_msg_ool_descriptor32_t out_of_line; |
527 | mach_msg_ool_ports_descriptor32_t ool_ports; |
528 | mach_msg_type_descriptor_t type; |
529 | mach_msg_guarded_port_descriptor32_t guarded_port; |
530 | } mach_msg_descriptor_t; |
531 | #else |
532 | typedef union{ |
533 | mach_msg_port_descriptor_t port; |
534 | mach_msg_ool_descriptor_t out_of_line; |
535 | mach_msg_ool_ports_descriptor_t ool_ports; |
536 | mach_msg_type_descriptor_t type; |
537 | mach_msg_guarded_port_descriptor_t guarded_port; |
538 | } mach_msg_descriptor_t; |
539 | #endif |
540 | |
541 | typedef struct { |
542 | mach_msg_size_t msgh_descriptor_count; |
543 | } mach_msg_body_t; |
544 | |
545 | #define MACH_MSG_BODY_NULL ((mach_msg_body_t *) 0) |
546 | #define MACH_MSG_DESCRIPTOR_NULL ((mach_msg_descriptor_t *) 0) |
547 | |
548 | typedef struct { |
549 | mach_msg_bits_t ; |
550 | mach_msg_size_t ; |
551 | mach_port_t ; |
552 | mach_port_t ; |
553 | mach_port_name_t ; |
554 | mach_msg_id_t ; |
555 | } ; |
556 | |
557 | #if PRIVATE |
558 | |
559 | /* mach msg2 data vectors are positional */ |
560 | __enum_decl(mach_msgv_index_t, uint32_t, { |
561 | MACH_MSGV_IDX_MSG = 0, |
562 | MACH_MSGV_IDX_AUX = 1, |
563 | }); |
564 | |
565 | #define MACH_MSGV_MAX_COUNT (MACH_MSGV_IDX_AUX + 1) |
566 | /* at least DISPATCH_MSGV_AUX_MAX_SIZE in libdispatch */ |
567 | #define LIBSYSCALL_MSGV_AUX_MAX_SIZE 128 |
568 | |
569 | typedef struct { |
570 | /* a mach_msg_header_t* or mach_msg_aux_header_t* */ |
571 | mach_vm_address_t msgv_data; |
572 | /* if msgv_rcv_addr is non-zero, use it as rcv address instead */ |
573 | mach_vm_address_t msgv_rcv_addr; |
574 | mach_msg_size_t msgv_send_size; |
575 | mach_msg_size_t msgv_rcv_size; |
576 | } mach_msg_vector_t; |
577 | |
578 | typedef struct { |
579 | mach_msg_size_t ; |
580 | uint32_t ; /* For future */ |
581 | } ; |
582 | |
583 | #endif /* PRIVATE */ |
584 | |
585 | #define msgh_reserved msgh_voucher_port |
586 | #define MACH_MSG_NULL ((mach_msg_header_t *) 0) |
587 | |
588 | typedef struct { |
589 | mach_msg_header_t ; |
590 | mach_msg_body_t body; |
591 | } mach_msg_base_t; |
592 | |
593 | #if MACH_KERNEL_PRIVATE |
594 | typedef struct { |
595 | /* first two fields must align with mach_msg_header_t */ |
596 | mach_msg_bits_t ; |
597 | mach_msg_size_t ; |
598 | mach_port_name_t ; |
599 | mach_port_name_t ; |
600 | mach_port_name_t ; |
601 | mach_msg_id_t ; |
602 | } ; |
603 | |
604 | typedef struct { |
605 | mach_msg_user_header_t ; |
606 | mach_msg_body_t body; |
607 | } mach_msg_user_base_t; |
608 | #endif /* MACH_KERNEL_PRIVATE */ |
609 | |
610 | typedef unsigned int mach_msg_trailer_type_t; |
611 | |
612 | #define MACH_MSG_TRAILER_FORMAT_0 0 |
613 | |
614 | typedef unsigned int mach_msg_trailer_size_t; |
615 | typedef char *mach_msg_trailer_info_t; |
616 | |
617 | typedef struct { |
618 | mach_msg_trailer_type_t msgh_trailer_type; |
619 | mach_msg_trailer_size_t msgh_trailer_size; |
620 | } mach_msg_trailer_t; |
621 | |
622 | /* |
623 | * The msgh_seqno field carries a sequence number |
624 | * associated with the received-from port. A port's |
625 | * sequence number is incremented every time a message |
626 | * is received from it and included in the received |
627 | * trailer to help put messages back in sequence if |
628 | * multiple threads receive and/or process received |
629 | * messages. |
630 | */ |
631 | typedef struct { |
632 | mach_msg_trailer_type_t msgh_trailer_type; |
633 | mach_msg_trailer_size_t msgh_trailer_size; |
634 | mach_port_seqno_t msgh_seqno; |
635 | } mach_msg_seqno_trailer_t; |
636 | |
637 | typedef struct { |
638 | unsigned int val[2]; |
639 | } security_token_t; |
640 | |
641 | typedef struct { |
642 | mach_msg_trailer_type_t msgh_trailer_type; |
643 | mach_msg_trailer_size_t msgh_trailer_size; |
644 | mach_port_seqno_t msgh_seqno; |
645 | security_token_t msgh_sender; |
646 | } mach_msg_security_trailer_t; |
647 | |
648 | /* |
649 | * The audit token is an opaque token which identifies |
650 | * Mach tasks and senders of Mach messages as subjects |
651 | * to the BSM audit system. Only the appropriate BSM |
652 | * library routines should be used to interpret the |
653 | * contents of the audit token as the representation |
654 | * of the subject identity within the token may change |
655 | * over time. |
656 | */ |
657 | typedef struct { |
658 | unsigned int val[8]; |
659 | } audit_token_t; |
660 | |
661 | /* |
662 | * Safe initializer for audit_token_t. |
663 | * Variables holding unset audit tokens should generally |
664 | * be initialized to INVALID_AUDIT_TOKEN_VALUE, to allow |
665 | * unset audit tokens be distinguished from the kernel's |
666 | * audit token, KERNEL_AUDIT_TOKEN_VALUE. It is `safe' |
667 | * in that it limits potential damage if such an unset |
668 | * audit token, or one of its fields, were ever to be |
669 | * interpreted as valid by mistake. Notably, the pid is |
670 | * outside of range of valid pids, and none of the |
671 | * fields correspond to privileged users or groups. |
672 | */ |
673 | #define INVALID_AUDIT_TOKEN_VALUE {{ \ |
674 | UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX, \ |
675 | UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX }} |
676 | |
677 | typedef struct { |
678 | mach_msg_trailer_type_t msgh_trailer_type; |
679 | mach_msg_trailer_size_t msgh_trailer_size; |
680 | mach_port_seqno_t msgh_seqno; |
681 | security_token_t msgh_sender; |
682 | audit_token_t msgh_audit; |
683 | } mach_msg_audit_trailer_t; |
684 | |
685 | typedef struct { |
686 | mach_msg_trailer_type_t msgh_trailer_type; |
687 | mach_msg_trailer_size_t msgh_trailer_size; |
688 | mach_port_seqno_t msgh_seqno; |
689 | security_token_t msgh_sender; |
690 | audit_token_t msgh_audit; |
691 | mach_port_context_t msgh_context; |
692 | } mach_msg_context_trailer_t; |
693 | |
694 | #if defined(MACH_KERNEL_PRIVATE) && defined(__arm64__) |
695 | typedef struct { |
696 | mach_msg_trailer_type_t msgh_trailer_type; |
697 | mach_msg_trailer_size_t msgh_trailer_size; |
698 | mach_port_seqno_t msgh_seqno; |
699 | security_token_t msgh_sender; |
700 | audit_token_t msgh_audit; |
701 | mach_port_context32_t msgh_context; |
702 | } mach_msg_context_trailer32_t; |
703 | |
704 | typedef struct { |
705 | mach_msg_trailer_type_t msgh_trailer_type; |
706 | mach_msg_trailer_size_t msgh_trailer_size; |
707 | mach_port_seqno_t msgh_seqno; |
708 | security_token_t msgh_sender; |
709 | audit_token_t msgh_audit; |
710 | mach_port_context64_t msgh_context; |
711 | } mach_msg_context_trailer64_t; |
712 | #endif |
713 | |
714 | |
715 | typedef struct { |
716 | mach_port_name_t sender; |
717 | } msg_labels_t; |
718 | |
719 | typedef int mach_msg_filter_id; |
720 | #define MACH_MSG_FILTER_POLICY_ALLOW (mach_msg_filter_id)0 |
721 | |
722 | /* |
723 | * Trailer type to pass MAC policy label info as a mach message trailer. |
724 | * |
725 | */ |
726 | |
727 | typedef struct { |
728 | mach_msg_trailer_type_t msgh_trailer_type; |
729 | mach_msg_trailer_size_t msgh_trailer_size; |
730 | mach_port_seqno_t msgh_seqno; |
731 | security_token_t msgh_sender; |
732 | audit_token_t msgh_audit; |
733 | mach_port_context_t msgh_context; |
734 | mach_msg_filter_id msgh_ad; |
735 | msg_labels_t msgh_labels; |
736 | } mach_msg_mac_trailer_t; |
737 | |
738 | #if defined(MACH_KERNEL_PRIVATE) && defined(__arm64__) |
739 | typedef struct { |
740 | mach_msg_trailer_type_t msgh_trailer_type; |
741 | mach_msg_trailer_size_t msgh_trailer_size; |
742 | mach_port_seqno_t msgh_seqno; |
743 | security_token_t msgh_sender; |
744 | audit_token_t msgh_audit; |
745 | mach_port_context32_t msgh_context; |
746 | mach_msg_filter_id msgh_ad; |
747 | msg_labels_t msgh_labels; |
748 | } mach_msg_mac_trailer32_t; |
749 | |
750 | typedef struct { |
751 | mach_msg_trailer_type_t msgh_trailer_type; |
752 | mach_msg_trailer_size_t msgh_trailer_size; |
753 | mach_port_seqno_t msgh_seqno; |
754 | security_token_t msgh_sender; |
755 | audit_token_t msgh_audit; |
756 | mach_port_context64_t msgh_context; |
757 | mach_msg_filter_id msgh_ad; |
758 | msg_labels_t msgh_labels; |
759 | } mach_msg_mac_trailer64_t; |
760 | |
761 | #endif |
762 | |
763 | #define MACH_MSG_TRAILER_MINIMUM_SIZE sizeof(mach_msg_trailer_t) |
764 | |
765 | /* |
766 | * These values can change from release to release - but clearly |
767 | * code cannot request additional trailer elements one was not |
768 | * compiled to understand. Therefore, it is safe to use this |
769 | * constant when the same module specified the receive options. |
770 | * Otherwise, you run the risk that the options requested by |
771 | * another module may exceed the local modules notion of |
772 | * MAX_TRAILER_SIZE. |
773 | */ |
774 | #if defined(MACH_KERNEL_PRIVATE) && defined(__arm64__) |
775 | typedef mach_msg_mac_trailer64_t mach_msg_max_trailer64_t; |
776 | typedef mach_msg_mac_trailer32_t mach_msg_max_trailer32_t; |
777 | #endif |
778 | |
779 | typedef mach_msg_mac_trailer_t mach_msg_max_trailer_t; |
780 | #define MAX_TRAILER_SIZE ((mach_msg_size_t)sizeof(mach_msg_max_trailer_t)) |
781 | |
782 | /* |
783 | * Legacy requirements keep us from ever updating these defines (even |
784 | * when the format_0 trailers gain new option data fields in the future). |
785 | * Therefore, they shouldn't be used going forward. Instead, the sizes |
786 | * should be compared against the specific element size requested using |
787 | * REQUESTED_TRAILER_SIZE. |
788 | */ |
789 | typedef mach_msg_security_trailer_t mach_msg_format_0_trailer_t; |
790 | |
791 | /*typedef mach_msg_mac_trailer_t mach_msg_format_0_trailer_t; |
792 | */ |
793 | |
794 | #define MACH_MSG_TRAILER_FORMAT_0_SIZE sizeof(mach_msg_format_0_trailer_t) |
795 | |
796 | #define KERNEL_SECURITY_TOKEN_VALUE { {0, 1} } |
797 | extern const security_token_t KERNEL_SECURITY_TOKEN; |
798 | |
799 | #define KERNEL_AUDIT_TOKEN_VALUE { {0, 0, 0, 0, 0, 0, 0, 0} } |
800 | extern const audit_token_t KERNEL_AUDIT_TOKEN; |
801 | |
802 | typedef integer_t mach_msg_options_t; |
803 | |
804 | #define (mach_msg_header_t){ } |
805 | |
806 | typedef struct { |
807 | mach_msg_header_t ; |
808 | } mach_msg_empty_send_t; |
809 | |
810 | typedef struct { |
811 | mach_msg_header_t ; |
812 | mach_msg_trailer_t trailer; |
813 | } mach_msg_empty_rcv_t; |
814 | |
815 | typedef union{ |
816 | mach_msg_empty_send_t send; |
817 | mach_msg_empty_rcv_t rcv; |
818 | } mach_msg_empty_t; |
819 | |
820 | #pragma pack(pop) |
821 | |
822 | /* utility to round the message size - will become machine dependent */ |
823 | #define round_msg(x) (((mach_msg_size_t)(x) + sizeof (natural_t) - 1) & \ |
824 | ~(sizeof (natural_t) - 1)) |
825 | |
826 | #ifdef XNU_KERNEL_PRIVATE |
827 | |
828 | #include <os/base.h> |
829 | #include <os/overflow.h> |
830 | #include <kern/debug.h> |
831 | |
832 | #define round_msg_overflow(in, out) __os_warn_unused(({ \ |
833 | bool __ovr = os_add_overflow(in, (__typeof__(*out))(sizeof(natural_t) - 1), out); \ |
834 | *out &= ~((__typeof__(*out))(sizeof(natural_t) - 1)); \ |
835 | __ovr; \ |
836 | })) |
837 | |
838 | static inline mach_msg_size_t |
839 | mach_round_msg(mach_msg_size_t x) |
840 | { |
841 | if (round_msg_overflow(x, &x)) { |
842 | panic("round msg overflow" ); |
843 | } |
844 | return x; |
845 | } |
846 | #endif /* XNU_KERNEL_PRIVATE */ |
847 | |
848 | /* |
849 | * There is no fixed upper bound to the size of Mach messages. |
850 | */ |
851 | #define MACH_MSG_SIZE_MAX ((mach_msg_size_t) ~0) |
852 | |
853 | #if defined(__APPLE_API_PRIVATE) |
854 | /* |
855 | * But architectural limits of a given implementation, or |
856 | * temporal conditions may cause unpredictable send failures |
857 | * for messages larger than MACH_MSG_SIZE_RELIABLE. |
858 | * |
859 | * In either case, waiting for memory is [currently] outside |
860 | * the scope of send timeout values provided to IPC. |
861 | */ |
862 | #define MACH_MSG_SIZE_RELIABLE ((mach_msg_size_t) 256 * 1024) |
863 | #endif |
864 | /* |
865 | * Compatibility definitions, for code written |
866 | * when there was a msgh_kind instead of msgh_seqno. |
867 | */ |
868 | #define MACH_MSGH_KIND_NORMAL 0x00000000 |
869 | #define MACH_MSGH_KIND_NOTIFICATION 0x00000001 |
870 | #define msgh_kind msgh_seqno |
871 | #define mach_msg_kind_t mach_port_seqno_t |
872 | |
873 | typedef natural_t mach_msg_type_size_t; |
874 | typedef natural_t mach_msg_type_number_t; |
875 | |
876 | /* |
877 | * Values received/carried in messages. Tells the receiver what |
878 | * sort of port right he now has. |
879 | * |
880 | * MACH_MSG_TYPE_PORT_NAME is used to transfer a port name |
881 | * which should remain uninterpreted by the kernel. (Port rights |
882 | * are not transferred, just the port name.) |
883 | */ |
884 | |
885 | #define MACH_MSG_TYPE_PORT_NONE 0 |
886 | |
887 | #define MACH_MSG_TYPE_PORT_NAME 15 |
888 | #define MACH_MSG_TYPE_PORT_RECEIVE MACH_MSG_TYPE_MOVE_RECEIVE |
889 | #define MACH_MSG_TYPE_PORT_SEND MACH_MSG_TYPE_MOVE_SEND |
890 | #define MACH_MSG_TYPE_PORT_SEND_ONCE MACH_MSG_TYPE_MOVE_SEND_ONCE |
891 | |
892 | #define MACH_MSG_TYPE_LAST 22 /* Last assigned */ |
893 | |
894 | /* |
895 | * A dummy value. Mostly used to indicate that the actual value |
896 | * will be filled in later, dynamically. |
897 | */ |
898 | |
899 | #define MACH_MSG_TYPE_POLYMORPHIC ((mach_msg_type_name_t) -1) |
900 | |
901 | /* |
902 | * Is a given item a port type? |
903 | */ |
904 | |
905 | #define MACH_MSG_TYPE_PORT_ANY(x) \ |
906 | (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) && \ |
907 | ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE)) |
908 | |
909 | #define MACH_MSG_TYPE_PORT_ANY_SEND(x) \ |
910 | (((x) >= MACH_MSG_TYPE_MOVE_SEND) && \ |
911 | ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE)) |
912 | |
913 | #define MACH_MSG_TYPE_PORT_ANY_RIGHT(x) \ |
914 | (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) && \ |
915 | ((x) <= MACH_MSG_TYPE_MOVE_SEND_ONCE)) |
916 | |
917 | typedef integer_t mach_msg_option_t; |
918 | |
919 | #define MACH_MSG_OPTION_NONE 0x00000000 |
920 | |
921 | #define MACH_SEND_MSG 0x00000001 |
922 | #define MACH_RCV_MSG 0x00000002 |
923 | |
924 | #define MACH_RCV_LARGE 0x00000004 /* report large message sizes */ |
925 | #define MACH_RCV_LARGE_IDENTITY 0x00000008 /* identify source of large messages */ |
926 | |
927 | #define MACH_SEND_TIMEOUT 0x00000010 /* timeout value applies to send */ |
928 | #define MACH_SEND_OVERRIDE 0x00000020 /* priority override for send */ |
929 | #define MACH_SEND_INTERRUPT 0x00000040 /* don't restart interrupted sends */ |
930 | #define MACH_SEND_NOTIFY 0x00000080 /* arm send-possible notify */ |
931 | #define MACH_SEND_ALWAYS 0x00010000 /* ignore qlimits - kernel only */ |
932 | #define MACH_SEND_FILTER_NONFATAL 0x00010000 /* rejection by message filter should return failure - user only */ |
933 | #define MACH_SEND_TRAILER 0x00020000 /* sender-provided trailer */ |
934 | #define MACH_SEND_NOIMPORTANCE 0x00040000 /* msg won't carry importance */ |
935 | #define MACH_SEND_NODENAP MACH_SEND_NOIMPORTANCE |
936 | #define MACH_SEND_IMPORTANCE 0x00080000 /* msg carries importance - kernel only */ |
937 | #define MACH_SEND_SYNC_OVERRIDE 0x00100000 /* msg should do sync IPC override (on legacy kernels) */ |
938 | #define MACH_SEND_PROPAGATE_QOS 0x00200000 /* IPC should propagate the caller's QoS */ |
939 | #define MACH_SEND_SYNC_USE_THRPRI MACH_SEND_PROPAGATE_QOS /* obsolete name */ |
940 | #define MACH_SEND_KERNEL 0x00400000 /* full send from kernel space - kernel only */ |
941 | #define MACH_SEND_SYNC_BOOTSTRAP_CHECKIN 0x00800000 /* special reply port should boost thread doing sync bootstrap checkin */ |
942 | |
943 | #define MACH_RCV_TIMEOUT 0x00000100 /* timeout value applies to receive */ |
944 | #define MACH_RCV_NOTIFY 0x00000000 /* legacy name (value was: 0x00000200) */ |
945 | #define MACH_RCV_INTERRUPT 0x00000400 /* don't restart interrupted receive */ |
946 | #define MACH_RCV_VOUCHER 0x00000800 /* willing to receive voucher port */ |
947 | #define MACH_RCV_OVERWRITE 0x00000000 /* scatter receive (deprecated) */ |
948 | #define MACH_RCV_GUARDED_DESC 0x00001000 /* Can receive new guarded descriptor */ |
949 | #define MACH_RCV_SYNC_WAIT 0x00004000 /* sync waiter waiting for rcv */ |
950 | #define MACH_RCV_SYNC_PEEK 0x00008000 /* sync waiter waiting to peek */ |
951 | |
952 | #define MACH_MSG_STRICT_REPLY 0x00000200 /* Enforce specific properties about the reply port, and |
953 | * the context in which a thread replies to a message. |
954 | * This flag must be passed on both the SEND and RCV */ |
955 | |
956 | #if PRIVATE |
957 | |
958 | __options_decl(mach_msg_option64_t, uint64_t, { |
959 | MACH64_MSG_OPTION_NONE = 0x0ull, |
960 | /* share lower 32 bits with mach_msg_option_t */ |
961 | MACH64_SEND_MSG = MACH_SEND_MSG, |
962 | MACH64_RCV_MSG = MACH_RCV_MSG, |
963 | |
964 | MACH64_RCV_LARGE = MACH_RCV_LARGE, |
965 | MACH64_RCV_LARGE_IDENTITY = MACH_RCV_LARGE_IDENTITY, |
966 | |
967 | MACH64_SEND_TIMEOUT = MACH_SEND_TIMEOUT, |
968 | MACH64_SEND_OVERRIDE = MACH_SEND_OVERRIDE, |
969 | MACH64_SEND_INTERRUPT = MACH_SEND_INTERRUPT, |
970 | MACH64_SEND_NOTIFY = MACH_SEND_NOTIFY, |
971 | #if KERNEL |
972 | MACH64_SEND_ALWAYS = MACH_SEND_ALWAYS, |
973 | MACH64_SEND_IMPORTANCE = MACH_SEND_IMPORTANCE, |
974 | MACH64_SEND_KERNEL = MACH_SEND_KERNEL, |
975 | #endif |
976 | MACH64_SEND_FILTER_NONFATAL = MACH_SEND_FILTER_NONFATAL, |
977 | MACH64_SEND_TRAILER = MACH_SEND_TRAILER, |
978 | MACH64_SEND_NOIMPORTANCE = MACH_SEND_NOIMPORTANCE, |
979 | MACH64_SEND_NODENAP = MACH_SEND_NODENAP, |
980 | MACH64_SEND_SYNC_OVERRIDE = MACH_SEND_SYNC_OVERRIDE, |
981 | MACH64_SEND_PROPAGATE_QOS = MACH_SEND_PROPAGATE_QOS, |
982 | |
983 | MACH64_SEND_SYNC_BOOTSTRAP_CHECKIN = MACH_SEND_SYNC_BOOTSTRAP_CHECKIN, |
984 | |
985 | MACH64_RCV_TIMEOUT = MACH_RCV_TIMEOUT, |
986 | |
987 | MACH64_RCV_INTERRUPT = MACH_RCV_INTERRUPT, |
988 | MACH64_RCV_VOUCHER = MACH_RCV_VOUCHER, |
989 | |
990 | MACH64_RCV_GUARDED_DESC = MACH_RCV_GUARDED_DESC, |
991 | MACH64_RCV_SYNC_WAIT = MACH_RCV_SYNC_WAIT, |
992 | MACH64_RCV_SYNC_PEEK = MACH_RCV_SYNC_PEEK, |
993 | |
994 | MACH64_MSG_STRICT_REPLY = MACH_MSG_STRICT_REPLY, |
995 | /* following options are 64 only */ |
996 | |
997 | /* Send and receive message as vectors */ |
998 | MACH64_MSG_VECTOR = 0x0000000100000000ull, |
999 | /* The message is a kobject call */ |
1000 | MACH64_SEND_KOBJECT_CALL = 0x0000000200000000ull, |
1001 | /* The message is sent to a message queue */ |
1002 | MACH64_SEND_MQ_CALL = 0x0000000400000000ull, |
1003 | /* This message destination is unknown. Used by old simulators only. */ |
1004 | MACH64_SEND_ANY = 0x0000000800000000ull, |
1005 | /* This message is a DriverKit call (Temporary) */ |
1006 | MACH64_SEND_DK_CALL = 0x0000001000000000ull, |
1007 | |
1008 | #ifdef XNU_KERNEL_PRIVATE |
1009 | /* |
1010 | * If kmsg has auxiliary data, append it immediate after the message |
1011 | * and trailer. |
1012 | * |
1013 | * Must be used in conjunction with MACH64_MSG_VECTOR |
1014 | */ |
1015 | MACH64_RCV_LINEAR_VECTOR = 0x1000000000000000ull, |
1016 | /* Receive into highest addr of buffer */ |
1017 | MACH64_RCV_STACK = 0x2000000000000000ull, |
1018 | #if MACH_FLIPC |
1019 | /* |
1020 | * This internal-only flag is intended for use by a single thread per-port/set! |
1021 | * If more than one thread attempts to MACH64_PEEK_MSG on a port or set, one of |
1022 | * the threads may miss messages (in fact, it may never wake up). |
1023 | */ |
1024 | MACH64_PEEK_MSG = 0x4000000000000000ull, |
1025 | #endif /* MACH_FLIPC */ |
1026 | /* |
1027 | * This is a mach_msg2() send/receive operation. |
1028 | */ |
1029 | MACH64_MACH_MSG2 = 0x8000000000000000ull |
1030 | #endif |
1031 | }); |
1032 | |
1033 | /* old spelling */ |
1034 | #define MACH64_SEND_USER_CALL MACH64_SEND_MQ_CALL |
1035 | #endif /* PRIVATE */ |
1036 | |
1037 | /* |
1038 | * NOTE: a 0x00------ RCV mask implies to ask for |
1039 | * a MACH_MSG_TRAILER_FORMAT_0 with 0 Elements, |
1040 | * which is equivalent to a mach_msg_trailer_t. |
1041 | * |
1042 | * XXXMAC: unlike the rest of the MACH_RCV_* flags, MACH_RCV_TRAILER_LABELS |
1043 | * needs its own private bit since we only calculate its fields when absolutely |
1044 | * required. |
1045 | */ |
1046 | #define MACH_RCV_TRAILER_NULL 0 |
1047 | #define MACH_RCV_TRAILER_SEQNO 1 |
1048 | #define MACH_RCV_TRAILER_SENDER 2 |
1049 | #define MACH_RCV_TRAILER_AUDIT 3 |
1050 | #define MACH_RCV_TRAILER_CTX 4 |
1051 | #define MACH_RCV_TRAILER_AV 7 |
1052 | #define MACH_RCV_TRAILER_LABELS 8 |
1053 | |
1054 | #define MACH_RCV_TRAILER_TYPE(x) (((x) & 0xf) << 28) |
1055 | #define MACH_RCV_TRAILER_ELEMENTS(x) (((x) & 0xf) << 24) |
1056 | #define MACH_RCV_TRAILER_MASK ((0xf << 24)) |
1057 | |
1058 | #define GET_RCV_ELEMENTS(y) (((y) >> 24) & 0xf) |
1059 | |
1060 | #ifdef MACH_KERNEL_PRIVATE |
1061 | /* |
1062 | * The options that the kernel honors when passed from user space, not including |
1063 | * user-only options that alias kernel-only options. |
1064 | */ |
1065 | #define MACH_SEND_USER (MACH_SEND_MSG | MACH_SEND_TIMEOUT | \ |
1066 | MACH_SEND_NOTIFY | MACH_SEND_OVERRIDE | \ |
1067 | MACH_SEND_TRAILER | MACH_SEND_NOIMPORTANCE | \ |
1068 | MACH_SEND_SYNC_OVERRIDE | MACH_SEND_PROPAGATE_QOS | \ |
1069 | MACH_SEND_FILTER_NONFATAL | \ |
1070 | MACH_SEND_SYNC_BOOTSTRAP_CHECKIN | \ |
1071 | MACH_MSG_STRICT_REPLY | MACH_RCV_GUARDED_DESC) |
1072 | |
1073 | #define MACH_RCV_USER (MACH_RCV_MSG | MACH_RCV_TIMEOUT | \ |
1074 | MACH_RCV_LARGE | MACH_RCV_LARGE_IDENTITY | \ |
1075 | MACH_RCV_VOUCHER | MACH_RCV_TRAILER_MASK | \ |
1076 | MACH_RCV_SYNC_WAIT | MACH_RCV_SYNC_PEEK | \ |
1077 | MACH_RCV_GUARDED_DESC | MACH_MSG_STRICT_REPLY) |
1078 | |
1079 | #define MACH64_MSG_OPTION_CFI_MASK (MACH64_SEND_KOBJECT_CALL | MACH64_SEND_MQ_CALL | \ |
1080 | MACH64_SEND_ANY | MACH64_SEND_DK_CALL) |
1081 | |
1082 | #define MACH64_RCV_USER (MACH_RCV_USER | MACH64_MSG_VECTOR) |
1083 | |
1084 | #define MACH_MSG_OPTION_USER (MACH_SEND_USER | MACH_RCV_USER) |
1085 | |
1086 | #define MACH64_MSG_OPTION_USER (MACH64_SEND_USER | MACH64_RCV_USER) |
1087 | |
1088 | #define MACH64_SEND_USER (MACH_SEND_USER | MACH64_MSG_VECTOR | \ |
1089 | MACH64_MSG_OPTION_CFI_MASK) |
1090 | |
1091 | /* The options implemented by the library interface to mach_msg et. al. */ |
1092 | #define MACH_MSG_OPTION_LIB (MACH_SEND_INTERRUPT | MACH_RCV_INTERRUPT) |
1093 | |
1094 | /* |
1095 | * Default options to use when sending from the kernel. |
1096 | * |
1097 | * Until we are sure of its effects, we are disabling |
1098 | * importance donation from the kernel-side of user |
1099 | * threads in importance-donating tasks. |
1100 | * (11938665 & 23925818) |
1101 | */ |
1102 | #define MACH_SEND_KERNEL_DEFAULT (MACH_SEND_MSG | \ |
1103 | MACH_SEND_ALWAYS | MACH_SEND_NOIMPORTANCE) |
1104 | |
1105 | #define MACH_SEND_WITH_STRICT_REPLY(_opts) (((_opts) & (MACH_MSG_STRICT_REPLY | MACH_SEND_MSG)) == \ |
1106 | (MACH_MSG_STRICT_REPLY | MACH_SEND_MSG)) |
1107 | |
1108 | #define MACH_SEND_REPLY_IS_IMMOVABLE(_opts) (((_opts) & (MACH_MSG_STRICT_REPLY | \ |
1109 | MACH_SEND_MSG | MACH_RCV_MSG | \ |
1110 | MACH_RCV_GUARDED_DESC)) == \ |
1111 | (MACH_MSG_STRICT_REPLY | MACH_SEND_MSG | MACH_RCV_GUARDED_DESC)) |
1112 | |
1113 | #define MACH_RCV_WITH_STRICT_REPLY(_opts) (((_opts) & (MACH_MSG_STRICT_REPLY | MACH_RCV_MSG)) == \ |
1114 | (MACH_MSG_STRICT_REPLY | MACH_RCV_MSG)) |
1115 | |
1116 | #define MACH_RCV_WITH_IMMOVABLE_REPLY(_opts) (((_opts) & (MACH_MSG_STRICT_REPLY | \ |
1117 | MACH_RCV_MSG | MACH_RCV_GUARDED_DESC)) == \ |
1118 | (MACH_MSG_STRICT_REPLY | MACH_RCV_MSG | MACH_RCV_GUARDED_DESC)) |
1119 | |
1120 | #endif /* MACH_KERNEL_PRIVATE */ |
1121 | |
1122 | /* |
1123 | * XXXMAC: note that in the case of MACH_RCV_TRAILER_LABELS, |
1124 | * we just fall through to mach_msg_max_trailer_t. |
1125 | * This is correct behavior since mach_msg_max_trailer_t is defined as |
1126 | * mac_msg_mac_trailer_t which is used for the LABELS trailer. |
1127 | * It also makes things work properly if MACH_RCV_TRAILER_LABELS is ORed |
1128 | * with one of the other options. |
1129 | */ |
1130 | |
1131 | #define REQUESTED_TRAILER_SIZE_NATIVE(y) \ |
1132 | ((mach_msg_trailer_size_t) \ |
1133 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_NULL) ? \ |
1134 | sizeof(mach_msg_trailer_t) : \ |
1135 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SEQNO) ? \ |
1136 | sizeof(mach_msg_seqno_trailer_t) : \ |
1137 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SENDER) ? \ |
1138 | sizeof(mach_msg_security_trailer_t) : \ |
1139 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AUDIT) ? \ |
1140 | sizeof(mach_msg_audit_trailer_t) : \ |
1141 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_CTX) ? \ |
1142 | sizeof(mach_msg_context_trailer_t) : \ |
1143 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AV) ? \ |
1144 | sizeof(mach_msg_mac_trailer_t) : \ |
1145 | sizeof(mach_msg_max_trailer_t)))))))) |
1146 | |
1147 | |
1148 | #ifdef XNU_KERNEL_PRIVATE |
1149 | |
1150 | #if defined(__arm64__) |
1151 | #define REQUESTED_TRAILER_SIZE(is64, y) \ |
1152 | ((mach_msg_trailer_size_t) \ |
1153 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_NULL) ? \ |
1154 | sizeof(mach_msg_trailer_t) : \ |
1155 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SEQNO) ? \ |
1156 | sizeof(mach_msg_seqno_trailer_t) : \ |
1157 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SENDER) ? \ |
1158 | sizeof(mach_msg_security_trailer_t) : \ |
1159 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AUDIT) ? \ |
1160 | sizeof(mach_msg_audit_trailer_t) : \ |
1161 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_CTX) ? \ |
1162 | ((is64) ? sizeof(mach_msg_context_trailer64_t) : sizeof(mach_msg_context_trailer32_t)) : \ |
1163 | ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AV) ? \ |
1164 | ((is64) ? sizeof(mach_msg_mac_trailer64_t) : sizeof(mach_msg_mac_trailer32_t)) : \ |
1165 | sizeof(mach_msg_max_trailer_t)))))))) |
1166 | #else |
1167 | #define REQUESTED_TRAILER_SIZE(is64, y) REQUESTED_TRAILER_SIZE_NATIVE(y) |
1168 | #endif |
1169 | |
1170 | #else /* XNU_KERNEL_PRIVATE */ |
1171 | #define REQUESTED_TRAILER_SIZE(y) REQUESTED_TRAILER_SIZE_NATIVE(y) |
1172 | #endif /* XNU_KERNEL_PRIVATE */ |
1173 | |
1174 | /* |
1175 | * Much code assumes that mach_msg_return_t == kern_return_t. |
1176 | * This definition is useful for descriptive purposes. |
1177 | * |
1178 | * See <mach/error.h> for the format of error codes. |
1179 | * IPC errors are system 4. Send errors are subsystem 0; |
1180 | * receive errors are subsystem 1. The code field is always non-zero. |
1181 | * The high bits of the code field communicate extra information |
1182 | * for some error codes. MACH_MSG_MASK masks off these special bits. |
1183 | */ |
1184 | |
1185 | typedef kern_return_t mach_msg_return_t; |
1186 | |
1187 | #define MACH_MSG_SUCCESS 0x00000000 |
1188 | |
1189 | |
1190 | #define MACH_MSG_MASK 0x00003e00 |
1191 | /* All special error code bits defined below. */ |
1192 | #define MACH_MSG_IPC_SPACE 0x00002000 |
1193 | /* No room in IPC name space for another capability name. */ |
1194 | #define MACH_MSG_VM_SPACE 0x00001000 |
1195 | /* No room in VM address space for out-of-line memory. */ |
1196 | #define MACH_MSG_IPC_KERNEL 0x00000800 |
1197 | /* Kernel resource shortage handling an IPC capability. */ |
1198 | #define MACH_MSG_VM_KERNEL 0x00000400 |
1199 | /* Kernel resource shortage handling out-of-line memory. */ |
1200 | |
1201 | #define MACH_SEND_IN_PROGRESS 0x10000001 |
1202 | /* Thread is waiting to send. (Internal use only.) */ |
1203 | #define MACH_SEND_INVALID_DATA 0x10000002 |
1204 | /* Bogus in-line data. */ |
1205 | #define MACH_SEND_INVALID_DEST 0x10000003 |
1206 | /* Bogus destination port. */ |
1207 | #define MACH_SEND_TIMED_OUT 0x10000004 |
1208 | /* Message not sent before timeout expired. */ |
1209 | #define MACH_SEND_INVALID_VOUCHER 0x10000005 |
1210 | /* Bogus voucher port. */ |
1211 | #define MACH_SEND_INTERRUPTED 0x10000007 |
1212 | /* Software interrupt. */ |
1213 | #define MACH_SEND_MSG_TOO_SMALL 0x10000008 |
1214 | /* Data doesn't contain a complete message. */ |
1215 | #define MACH_SEND_INVALID_REPLY 0x10000009 |
1216 | /* Bogus reply port. */ |
1217 | #define MACH_SEND_INVALID_RIGHT 0x1000000a |
1218 | /* Bogus port rights in the message body. */ |
1219 | #define MACH_SEND_INVALID_NOTIFY 0x1000000b |
1220 | /* Bogus notify port argument. */ |
1221 | #define MACH_SEND_INVALID_MEMORY 0x1000000c |
1222 | /* Invalid out-of-line memory pointer. */ |
1223 | #define MACH_SEND_NO_BUFFER 0x1000000d |
1224 | /* No message buffer is available. */ |
1225 | #define MACH_SEND_TOO_LARGE 0x1000000e |
1226 | /* Send is too large for port */ |
1227 | #define MACH_SEND_INVALID_TYPE 0x1000000f |
1228 | /* Invalid msg-type specification. */ |
1229 | #define 0x10000010 |
1230 | /* A field in the header had a bad value. */ |
1231 | #define MACH_SEND_INVALID_TRAILER 0x10000011 |
1232 | /* The trailer to be sent does not match kernel format. */ |
1233 | #define MACH_SEND_INVALID_CONTEXT 0x10000012 |
1234 | /* The sending thread context did not match the context on the dest port */ |
1235 | #define MACH_SEND_INVALID_OPTIONS 0x10000013 |
1236 | /* Send options are invalid. */ |
1237 | #define MACH_SEND_INVALID_RT_OOL_SIZE 0x10000015 |
1238 | /* compatibility: no longer a returned error */ |
1239 | #define MACH_SEND_NO_GRANT_DEST 0x10000016 |
1240 | /* The destination port doesn't accept ports in body */ |
1241 | #define MACH_SEND_MSG_FILTERED 0x10000017 |
1242 | /* Message send was rejected by message filter */ |
1243 | #define MACH_SEND_AUX_TOO_SMALL 0x10000018 |
1244 | /* Message auxiliary data is too small */ |
1245 | #define MACH_SEND_AUX_TOO_LARGE 0x10000019 |
1246 | /* Message auxiliary data is too large */ |
1247 | |
1248 | #define MACH_RCV_IN_PROGRESS 0x10004001 |
1249 | /* Thread is waiting for receive. (Internal use only.) */ |
1250 | #define MACH_RCV_INVALID_NAME 0x10004002 |
1251 | /* Bogus name for receive port/port-set. */ |
1252 | #define MACH_RCV_TIMED_OUT 0x10004003 |
1253 | /* Didn't get a message within the timeout value. */ |
1254 | #define MACH_RCV_TOO_LARGE 0x10004004 |
1255 | /* Message buffer is not large enough for inline data. */ |
1256 | #define MACH_RCV_INTERRUPTED 0x10004005 |
1257 | /* Software interrupt. */ |
1258 | #define MACH_RCV_PORT_CHANGED 0x10004006 |
1259 | /* compatibility: no longer a returned error */ |
1260 | #define MACH_RCV_INVALID_NOTIFY 0x10004007 |
1261 | /* Bogus notify port argument. */ |
1262 | #define MACH_RCV_INVALID_DATA 0x10004008 |
1263 | /* Bogus message buffer for inline data. */ |
1264 | #define MACH_RCV_PORT_DIED 0x10004009 |
1265 | /* Port/set was sent away/died during receive. */ |
1266 | #define MACH_RCV_IN_SET 0x1000400a |
1267 | /* compatibility: no longer a returned error */ |
1268 | #define 0x1000400b |
1269 | /* Error receiving message header. See special bits. */ |
1270 | #define MACH_RCV_BODY_ERROR 0x1000400c |
1271 | /* Error receiving message body. See special bits. */ |
1272 | #define MACH_RCV_INVALID_TYPE 0x1000400d |
1273 | /* Invalid msg-type specification in scatter list. */ |
1274 | #define MACH_RCV_SCATTER_SMALL 0x1000400e |
1275 | /* Out-of-line overwrite region is not large enough */ |
1276 | #define MACH_RCV_INVALID_TRAILER 0x1000400f |
1277 | /* trailer type or number of trailer elements not supported */ |
1278 | #define MACH_RCV_IN_PROGRESS_TIMED 0x10004011 |
1279 | /* Waiting for receive with timeout. (Internal use only.) */ |
1280 | #define MACH_RCV_INVALID_REPLY 0x10004012 |
1281 | /* invalid reply port used in a STRICT_REPLY message */ |
1282 | #define MACH_RCV_INVALID_ARGUMENTS 0x10004013 |
1283 | /* invalid receive arguments, receive has not started */ |
1284 | |
1285 | #ifdef XNU_KERNEL_PRIVATE |
1286 | #if MACH_FLIPC |
1287 | #define MACH_PEEK_IN_PROGRESS 0x10008001 |
1288 | /* Waiting for a peek. (Internal use only.) */ |
1289 | #define MACH_PEEK_READY 0x10008002 |
1290 | /* Waiting for a peek. (Internal use only.) */ |
1291 | #endif /* MACH_FLIPC */ |
1292 | #endif |
1293 | |
1294 | |
1295 | __BEGIN_DECLS |
1296 | |
1297 | /* |
1298 | * Routine: mach_msg_overwrite |
1299 | * Purpose: |
1300 | * Send and/or receive a message. If the message operation |
1301 | * is interrupted, and the user did not request an indication |
1302 | * of that fact, then restart the appropriate parts of the |
1303 | * operation silently (trap version does not restart). |
1304 | * |
1305 | * Distinct send and receive buffers may be specified. If |
1306 | * no separate receive buffer is specified, the msg parameter |
1307 | * will be used for both send and receive operations. |
1308 | * |
1309 | * In addition to a distinct receive buffer, that buffer may |
1310 | * already contain scatter control information to direct the |
1311 | * receiving of the message. |
1312 | */ |
1313 | __WATCHOS_PROHIBITED __TVOS_PROHIBITED |
1314 | extern mach_msg_return_t mach_msg_overwrite( |
1315 | mach_msg_header_t *msg, |
1316 | mach_msg_option_t option, |
1317 | mach_msg_size_t send_size, |
1318 | mach_msg_size_t rcv_size, |
1319 | mach_port_name_t rcv_name, |
1320 | mach_msg_timeout_t timeout, |
1321 | mach_port_name_t notify, |
1322 | mach_msg_header_t *rcv_msg, |
1323 | mach_msg_size_t rcv_limit); |
1324 | |
1325 | #ifndef KERNEL |
1326 | |
1327 | /* |
1328 | * Routine: mach_msg |
1329 | * Purpose: |
1330 | * Send and/or receive a message. If the message operation |
1331 | * is interrupted, and the user did not request an indication |
1332 | * of that fact, then restart the appropriate parts of the |
1333 | * operation silently (trap version does not restart). |
1334 | */ |
1335 | __WATCHOS_PROHIBITED __TVOS_PROHIBITED |
1336 | extern mach_msg_return_t mach_msg( |
1337 | mach_msg_header_t *msg, |
1338 | mach_msg_option_t option, |
1339 | mach_msg_size_t send_size, |
1340 | mach_msg_size_t rcv_size, |
1341 | mach_port_name_t rcv_name, |
1342 | mach_msg_timeout_t timeout, |
1343 | mach_port_name_t notify); |
1344 | |
1345 | #if PRIVATE |
1346 | #if defined(__LP64__) || defined(__arm64__) |
1347 | __API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) |
1348 | __IOS_PROHIBITED __WATCHOS_PROHIBITED __TVOS_PROHIBITED |
1349 | extern mach_msg_return_t mach_msg2_internal( |
1350 | void *data, |
1351 | mach_msg_option64_t option64, |
1352 | uint64_t msgh_bits_and_send_size, |
1353 | uint64_t msgh_remote_and_local_port, |
1354 | uint64_t msgh_voucher_and_id, |
1355 | uint64_t desc_count_and_rcv_name, |
1356 | uint64_t rcv_size_and_priority, |
1357 | uint64_t timeout); |
1358 | |
1359 | __API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) |
1360 | __IOS_PROHIBITED __WATCHOS_PROHIBITED __TVOS_PROHIBITED |
1361 | static inline mach_msg_return_t |
1362 | mach_msg2( |
1363 | void *data, |
1364 | mach_msg_option64_t option64, |
1365 | mach_msg_header_t header, |
1366 | mach_msg_size_t send_size, |
1367 | mach_msg_size_t rcv_size, |
1368 | mach_port_t rcv_name, |
1369 | uint64_t timeout, |
1370 | uint32_t priority) |
1371 | { |
1372 | mach_msg_base_t *base; |
1373 | mach_msg_size_t descriptors; |
1374 | |
1375 | if (option64 & MACH64_MSG_VECTOR) { |
1376 | base = (mach_msg_base_t *)((mach_msg_vector_t *)data)->msgv_data; |
1377 | } else { |
1378 | base = (mach_msg_base_t *)data; |
1379 | } |
1380 | |
1381 | if ((option64 & MACH64_SEND_MSG) && |
1382 | (base->header.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { |
1383 | descriptors = base->body.msgh_descriptor_count; |
1384 | } else { |
1385 | descriptors = 0; |
1386 | } |
1387 | |
1388 | #define MACH_MSG2_SHIFT_ARGS(lo, hi) ((uint64_t)hi << 32 | (uint32_t)lo) |
1389 | return mach_msg2_internal(data, option64, |
1390 | MACH_MSG2_SHIFT_ARGS(header.msgh_bits, send_size), |
1391 | MACH_MSG2_SHIFT_ARGS(header.msgh_remote_port, header.msgh_local_port), |
1392 | MACH_MSG2_SHIFT_ARGS(header.msgh_voucher_port, header.msgh_id), |
1393 | MACH_MSG2_SHIFT_ARGS(descriptors, rcv_name), |
1394 | MACH_MSG2_SHIFT_ARGS(rcv_size, priority), timeout); |
1395 | #undef MACH_MSG2_SHIFT_ARGS |
1396 | } |
1397 | #endif |
1398 | #endif /* PRIVATE */ |
1399 | |
1400 | /* |
1401 | * Routine: mach_voucher_deallocate |
1402 | * Purpose: |
1403 | * Deallocate a mach voucher created or received in a message. Drops |
1404 | * one (send right) reference to the voucher. |
1405 | */ |
1406 | __WATCHOS_PROHIBITED __TVOS_PROHIBITED |
1407 | extern kern_return_t mach_voucher_deallocate( |
1408 | mach_port_name_t voucher); |
1409 | |
1410 | #elif defined(MACH_KERNEL_PRIVATE) |
1411 | |
1412 | extern mach_msg_return_t mach_msg_receive_results_kevent( |
1413 | mach_msg_size_t *size, |
1414 | mach_msg_size_t *aux_size, |
1415 | uint32_t *ppri, |
1416 | mach_msg_qos_t *oqos); |
1417 | |
1418 | extern mach_msg_return_t mach_msg_receive_results(void); |
1419 | #endif /* KERNEL */ |
1420 | |
1421 | __END_DECLS |
1422 | |
1423 | #endif /* _MACH_MESSAGE_H_ */ |
1424 | |