xref: /NextBSD/sys/sys/mach/rpc.h (revision 33da5adc555b3bc29986eeadca03829e4ad06b1e)
1 /*
2  * Copyright 1991-1998 by Open Software Foundation, Inc.
3  *              All Rights Reserved
4  *
5  * Permission to use, copy, modify, and distribute this software and
6  * its documentation for any purpose and without fee is hereby granted,
7  * provided that the above copyright notice appears in all copies and
8  * that both the copyright notice and this permission notice appear in
9  * supporting documentation.
10  *
11  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
12  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13  * FOR A PARTICULAR PURPOSE.
14  *
15  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
16  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
18  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
19  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 /*
22  * MkLinux
23  */
24 
25 /*
26  * Mach RPC Subsystem Interfaces
27  */
28 
29 #ifndef	_MACH_RPC_H_
30 #define _MACH_RPC_H_
31 
32 #include <sys/mach/kern_return.h>
33 #include <sys/mach/port.h>
34 #include <sys/mach/vm_types.h>
35 
36 #include <sys/mach/mig_errors.h>
37 #include <sys/mach/ipc_common.h>
38 
39 #ifdef	MACH_KERNEL
40 #include <ipc/ipc_object.h>
41 #endif	/* MACH_KERNEL */
42 
43 #pragma clang diagnostic ignored "-Wunused-local-typedef"
44 
45 /*
46  *
47  * Definition of RPC "glue code" operations vector -- entry
48  * points needed to accomplish short-circuiting
49  */
50 typedef struct rpc_glue_vector {
51         kern_return_t   (*rpc_simple)(int, int, void *);
52         boolean_t       (*copyin)(mach_port_t, void *);
53         boolean_t       (*copyout)(mach_port_t, void *);
54         boolean_t       (*copyinstr)(mach_port_t, void *);
55         kern_return_t   (*thread_switch)(void *);
56         kern_return_t   (*thread_depress_abort)(mach_port_t);
57 } *rpc_glue_vector_t;
58 
59 /*
60  * Macros used to dereference glue code ops vector -- note
61  * hard-wired references to global defined below.  Also note
62  * that most of the macros assume their caller has stacked
63  * the target args somewhere, so that they can pass just the
64  * address of the first arg to the short-circuited
65  * implementation.
66  */
67 #define CAN_SHCIRCUIT(name)     (_rpc_glue_vector->name != 0)
68 #define RPC_SIMPLE(port, rtn_num, argc, argv) \
69         ((*(_rpc_glue_vector->rpc_simple))(rtn_num, argc, (void *)(&(port))))
70 #define COPYIN(map, from, to, count) \
71         ((*(_rpc_glue_vector->copyin))(map, (void *)(&(from))))
72 #define COPYOUT(map, from, to, count) \
73         ((*(_rpc_glue_vector->copyout))(map, (void *)(&(from))))
74 #define COPYINSTR(map, from, to, max, actual) \
75         ((*(_rpc_glue_vector->copyinstr))(map, (void *)(&(from))))
76 #define THREAD_SWITCH(thread, option, option_time) \
77         ((*(_rpc_glue_vector->thread_switch))((void *)(&(thread))))
78 #define THREAD_DEPRESS_ABORT(act)       \
79         ((*(_rpc_glue_vector->thread_depress_abort))(act))
80 
81 /*
82  * User machine dependent macros for mach rpc
83  */
84 #define MACH_RPC(sig_ptr, sig_size, id, dest, arg_list)                    \
85         mach_rpc_trap(dest, id, (mach_rpc_signature_t) sig_ptr, sig_size)
86 
87 /*
88  * Kernel machine dependent macros for mach rpc
89  *
90  * User args (argv) begin two words above the frame pointer (past saved ebp
91  * and return address) on the user stack. Return code is stored in register
92  * ecx, by convention (must be a caller-saves register, to survive return
93  * from server work function). The user space instruction pointer is eip,
94  * and the user stack pointer is uesp.
95  */
96 #define MACH_RPC_ARGV(act)      ( (char *)(USER_REGS(act)->ebp + 8) )
97 #define MACH_RPC_RET(act)       ( USER_REGS(act)->ecx )
98 #define MACH_RPC_UIP(act)       ( USER_REGS(act)->eip )
99 #define MACH_RPC_USP(act)       ( USER_REGS(act)->uesp )
100 
101 
102 extern boolean_t        klcopyin(
103                                 mach_port_t,
104                                 void *);
105 
106 extern boolean_t        klcopyout(
107                                 mach_port_t,
108                                 void *);
109 
110 extern boolean_t        klcopyinstr(
111                                 mach_port_t,
112                                 void *);
113 
114 extern kern_return_t    klthread_switch(
115                                 void *);
116 
117 /*
118  * The various bits of the type field of the routine_arg_descriptor
119  */
120 
121 /* The basic types */
122 
123 #define TYPE_SHIFT                      0
124 #define MACH_RPC_PORT			(1 << TYPE_SHIFT)
125 #define MACH_RPC_ARRAY                  (1 << (TYPE_SHIFT + 1))
126 #define MACH_RPC_VARIABLE               (1 << (TYPE_SHIFT + 2))
127 #define LAST_TYPE_BIT                   (TYPE_SHIFT+3)
128 
129 /* XXX Port arrays need not be variable arrays, as assumed below. Fixme. */
130 #define MACH_RPC_ARRAY_FIX		(MACH_RPC_ARRAY)
131 #define MACH_RPC_ARRAY_FIXED		(MACH_RPC_ARRAY)
132 #define MACH_RPC_ARRAY_VAR		(MACH_RPC_ARRAY | MACH_RPC_VARIABLE)
133 #define MACH_RPC_ARRAY_VARIABLE		(MACH_RPC_ARRAY | MACH_RPC_VARIABLE)
134 #define MACH_RPC_PORT_ARRAY		(MACH_RPC_PORT  | MACH_RPC_ARRAY_VAR)
135 
136 /* Argument direction bits */
137 
138 #define DIRECT_SHIFT            	LAST_TYPE_BIT
139 #define DIRECTION_SHIFT                 LAST_TYPE_BIT
140 #define MACH_RPC_IN			(1 << DIRECTION_SHIFT)
141 #define MACH_RPC_OUT			(1 << (DIRECTION_SHIFT + 1))
142 #define LAST_DIRECT_BIT         	(DIRECTION_SHIFT + 2)
143 #define LAST_DIRECTION_BIT              (DIRECTION_SHIFT + 2)
144 
145 #define MACH_RPC_INOUT			(MACH_RPC_IN | MACH_RPC_OUT)
146 
147 /* Persist and pointer bit */
148 
149 #define POINTER_SHIFT                   LAST_DIRECTION_BIT
150 #define MACH_RPC_POINTER                (1 << POINTER_SHIFT)
151 #define LAST_POINTER_BIT                (POINTER_SHIFT + 1)
152 
153 /* Port disposition bits */
154 
155 #define NAME_SHIFT                    	LAST_POINTER_BIT
156 #define MACH_RPC_RECEIVE                (1 << NAME_SHIFT)
157 #define MACH_RPC_SEND                   (2 << NAME_SHIFT)
158 #define MACH_RPC_SEND_ONCE              (3 << NAME_SHIFT)
159 #define LAST_NAME_BIT			(NAME_SHIFT + 2)
160 
161 #define ACTION_SHIFT			LAST_NAME_BIT
162 #define MACH_RPC_MOVE                   (1 << ACTION_SHIFT)
163 #define MACH_RPC_COPY                   (2 << ACTION_SHIFT)
164 #define MACH_RPC_MAKE                   (3 << ACTION_SHIFT)
165 #define LAST_ACTION_BIT                 (ACTION_SHIFT + 2)
166 
167 #define MACH_RPC_MOVE_RECEIVE		(MACH_RPC_MOVE | MACH_RPC_RECEIVE)
168 #define MACH_RPC_MOVE_SEND		(MACH_RPC_MOVE | MACH_RPC_SEND)
169 #define MACH_RPC_COPY_SEND		(MACH_RPC_COPY | MACH_RPC_SEND)
170 #define MACH_RPC_MAKE_SEND		(MACH_RPC_MAKE | MACH_RPC_SEND)
171 #define MACH_RPC_MOVE_SEND_ONCE		(MACH_RPC_MOVE | MACH_RPC_SEND_ONCE)
172 #define MACH_RPC_MAKE_SEND_ONCE		(MACH_RPC_MAKE | MACH_RPC_SEND_ONCE)
173 
174 /* Hint for virtual vs. physical copy */
175 
176 #define OPTION_SHIFT                    LAST_ACTION_BIT
177 #define MACH_RPC_PHYSICAL_COPY		(1 << OPTION_SHIFT)
178 #define MACH_RPC_VIRTUAL_COPY		(1 << (OPTION_SHIFT + 1))
179 #define LAST_OPTION_BIT                 (OPTION_SHIFT + 2)
180 
181 /* Deallocate? */
182 
183 #define DEALLOCATE_SHIFT                LAST_OPTION_BIT
184 #define MACH_RPC_DEALLOCATE		(1 << DEALLOCATE_SHIFT)
185 #define LAST_DEALLOCATE_BIT             (DEALLOCATE_SHIFT + 1)
186 
187 /* Argument is already on the stack */
188 
189 #define ONSTACK_SHIFT                   LAST_DEALLOCATE_BIT
190 #define MACH_RPC_ONSTACK		(1 << ONSTACK_SHIFT)
191 #define LAST_ONSTACK_BIT                (ONSTACK_SHIFT + 1)
192 
193 /* Is variable array bounded? Derived from type and arg.size */
194 
195 #define BOUND_SHIFT			LAST_ONSTACK_BIT
196 #define MACH_RPC_BOUND			(1 << BOUND_SHIFT)
197 #define MACH_RPC_UNBOUND		(0)
198 #define BOUND				MACH_RPC_BOUND
199 #define UNBND				MACH_RPC_UNBOUND
200 #define LAST_BOUND_BIT			(BOUND_SHIFT + 1)
201 
202 /*
203  * Temporarily map old MiG names to the new names, until the
204  * new MiG is ready. This allows us to continue developing the
205  * RPC path while MiG is being enhanced. *Temporary*
206  */
207 #define OLD
208 #ifdef OLD
209 #define ROUTINE_ARG_PORT	MACH_RPC_PORT
210 #define ROUTINE_ARG_FIXED_ARRAY	MACH_RPC_ARRAY_FIXED
211 #define	ROUTINE_ARG_VAR_ARRAY	MACH_RPC_ARRAY_VARIABLE
212 
213 #define	ROUTINE_ARG_IN		MACH_RPC_IN
214 #define ROUTINE_ARG_OUT		MACH_RPC_OUT
215 #define ROUTINE_ARG_INOUT	MACH_RPC_INOUT
216 
217 #define direction		type
218 #endif 	/* OLD */
219 
220 
221 /*
222  * Basic mach rpc types.
223  */
224 typedef unsigned int    routine_arg_type;
225 typedef unsigned int	routine_arg_offset;
226 typedef unsigned int	routine_arg_size;
227 
228 /*
229  * Definition for MIG-generated server stub routines.  These routines
230  * unpack the request message, call the server procedure, and pack the
231  * reply message.
232  */
233 typedef void	(*mig_stub_routine_t) (mach_msg_header_t *InHeadP,
234 				       mach_msg_header_t *OutHeadP);
235 
236 typedef mig_stub_routine_t mig_routine_t;
237 
238 /*
239  * Definition for MIG-generated server routine.  This routine takes a
240  * message, and returns the appropriate stub function for handling that
241  * message.
242  */
243 typedef mig_routine_t (*mig_server_routine_t) (mach_msg_header_t *InHeadP);
244 
245 
246 /*
247  * Definition for server implementation routines.  This is the routine
248  * called by the MIG-generated server stub routine.
249  */
250 typedef kern_return_t   (*mig_impl_routine_t)(void);
251 
252 /*
253  * Definitions for a signature's argument and routine descriptor's.
254  */
255 struct routine_arg_descriptor {
256 	routine_arg_type	type;	   /* Port, Array, etc. */
257         routine_arg_size        size;      /* element size in bytes */
258         routine_arg_size        count;     /* number of elements */
259 	routine_arg_offset	offset;	   /* Offset in list of routine args */
260 };
261 typedef struct routine_arg_descriptor *routine_arg_descriptor_t;
262 
263 struct routine_descriptor {
264 	mig_impl_routine_t	impl_routine;	/* Server work func pointer   */
265 	mig_stub_routine_t	stub_routine;	/* Unmarshalling func pointer */
266 	unsigned int		argc;		/* Number of argument words   */
267 	unsigned int		descr_count;	/* Number of complex argument */
268 					        /* descriptors                */
269 	struct routine_arg_descriptor *
270 				arg_descr;	/* Pointer to beginning of    */
271 						/* the arg_descr array        */
272 	unsigned int		max_reply_msg;	/* Max size for reply msg     */
273 };
274 typedef struct routine_descriptor *routine_descriptor_t;
275 
276 struct mach_rpc_signature {
277     struct routine_descriptor rd;
278     struct routine_arg_descriptor rad[1];
279 };
280 typedef struct mach_rpc_signature *mach_rpc_signature_t;
281 
282 /*
283  *	A subsystem describes a set of server routines that can be invoked by
284  *	mach_rpc() on the ports that are registered with the subsystem.  For
285  *	each routine, the routine number is given, along with the
286  *	address of the implementation function in the server and a
287  *	description of the arguments of the routine (it's "signature").
288  *
289  *	This structure definition is only a template for what is really a
290  *	variable-length structure (generated by MIG for each subsystem).
291  *	The actual structures do not always have one entry in the routine
292  *	array, and also have a varying number of entries in the arg_descr
293  *	array.  Each routine has an array of zero or more arg descriptors
294  *	one for each complex arg.  These arrays are all catenated together
295  *	to form the arg_descr field of the subsystem struct.  The
296  *	arg_descr field of each routine entry points to a unique sub-sequence
297  *	within this catenated array.  The goal is to keep everything
298  *	contiguous.
299  */
300 struct rpc_subsystem {
301 	struct subsystem *subsystem;	/* Reserved for system use */
302 
303 	mach_msg_id_t	start;		/* Min routine number */
304 	mach_msg_id_t	end;		/* Max routine number + 1 */
305 	unsigned int	maxsize;	/* Max mach_msg size */
306 	vm_address_t	base_addr;	/* Address of this struct in user */
307 
308 	struct routine_descriptor	/* Array of routine descriptors */
309 			routine[1       /* Actually, (start-end+1) */
310 				 ];
311 
312 	struct routine_arg_descriptor
313 			arg_descriptor[1   /* Actually, the sum of the descr_ */
314 					]; /* count fields for all routines   */
315 };
316 typedef struct rpc_subsystem  *rpc_subsystem_t;
317 
318 #define RPC_SUBSYSTEM_NULL	((rpc_subsystem_t) 0)
319 
320 /*
321  * This structure is user-visible, both to user-mode RPC code
322  * and to kernel-loaded servers.
323  */
324 typedef struct rpc_port {
325 
326 	/*
327 	 * Initial sub-structure in common with ipc_pset and rpc_port
328 	 * First element is an ipc_object
329 	 */
330 	struct ipc_common_data rpc_port_comm;
331 
332 	unsigned int rpc_unused_pad[1];	/* XXX unused */
333 
334 } *rpc_port_t;
335 
336 #define rp_object		rpc_port_comm.icd_object
337 				/* access to rp_object internals not needed */
338 #define rp_kobject		rpc_port_comm.icd_kobject
339 #define rp_subsystem		rpc_port_comm.icd_subsystem
340 #define rp_sobject		rpc_port_comm.icd_sobject
341 #define rp_sbits		rpc_port_comm.icd_sbits
342 #define rp_receiver_name	rpc_port_comm.icd_receiver_name
343 
344 
345 /*
346  * 	New RPC declarations
347  *
348  *	First pass at definitions and types for the new rpc service.
349  *	This is subject to revision.
350  */
351 
352 /*
353  *	RPC macros
354  */
355 
356 #define RPC_MASK(shift,last)                                            \
357         ( ((1 << ((last)-(shift)))-1) << (shift) )
358 
359 #define RPC_FIELD(field,shift,last)                                     \
360         ( (field) & (((1 << ((last)-(shift)))-1) << (shift)) )
361 
362 #define RPC_BOUND(dsc)                                                  \
363         (((RPC_FIELD((dsc).type,TYPE_SHIFT+1,TYPE_SHIFT+3) ==           \
364            MACH_RPC_ARRAY_VARIABLE) && (dsc).count != 0) ? MACH_RPC_BOUND : 0)
365 
366 #define ROUNDUP2(x,n)    ((((unsigned)(x)) + (n) - 1) & ~((n)-1))
367 #define ROUNDWORD(x)    ROUNDUP2(x,sizeof(int))
368 
369 /*
370  *      RPC errors
371  *
372  *      Display and process errors of different severity, from just for
373  *      information only to fatal (panic). Error code colors indicate how
374  *      difficult it is for the subsystem to handle the error correctly.
375  *      The implication is that, for example, early versions of the code may
376  *      not be handling code red errors properly. The code should use this
377  *      facility instead of regular printf's.
378  */
379 
380 #define	MACH_RPC_DEBUG	1
381 
382 #define ERR_INFO        1               /* purely informational */
383 #define ERR_GREEN       2               /* easily handled error */
384 #define ERR_YELLOW      3               /* medium difficult error */
385 #define ERR_RED         4               /* difficult to handle error */
386 #define ERR_FATAL       5               /* unrecoverable error, panic */
387 
388 #if MACH_RPC_DEBUG > 1
389 #define rpc_error(E,S)                                                  \
390         printf("RPC error ");                                           \
391         rpc_error_show_severity(S);                                     \
392         printf("in file \"%s\", line %d: ", __FILE__, __LINE__);        \
393         printf E ;                                                      \
394         printf("\n");                                                   \
395         rpc_error_severity(S)
396 #else
397 #define rpc_error(E,S)                                                  \
398 	if ((S) == ERR_FATAL || (S) == ERR_RED) {			\
399         printf("RPC error ");                                           \
400         rpc_error_show_severity(S);                                     \
401         printf("in file \"%s\", line %d: ", __FILE__, __LINE__);        \
402         printf E ;                                                      \
403         printf("\n");                                                   \
404         rpc_error_severity(S);						\
405 	}
406 #endif	/* MACH_RPC_DEBUG */
407 
408 /*
409  *      RPC buffer size and break points
410  *
411  *      These values define the rpc buffer size on the kernel stack,
412  *      and break point values for switching to virtual copy (cow).
413  *      This should be in a machine dependent include file. All sizes
414  *      are in word (sizeof(int)) units.
415  */
416 
417 #define RPC_KBUF_SIZE   16              /* kernel stack buffer size (ints) */
418 #define RPC_COW_SIZE    1024            /* size where COW is a win (ints) */
419 #define RPC_DESC_COUNT  4               /* default descriptor count */
420 
421 
422 /*
423  *      RPC copy state
424  *
425  *      Record the rpc copy state for arrays, so we can unwind our state
426  *      during error processing. There is one entry per complex (signatured)
427  *      argument. The first entry is marked COPY_TYPE_ALLOC_KRN if this record
428  *      itself was kalloc'd because the number of complex arg descriptors
429  *      exceeded the default value (RPC_DESC_COUNT). This is not a conflict
430  *      since the first argument is always the destination port, never an array.
431  */
432 
433 #define COPY_TYPE_NO_COPY               0       /* nothing special */
434 #define COPY_TYPE_ON_KSTACK             1       /* array is on kernel stack */
435 #define COPY_TYPE_ON_SSTACK             2       /* array is on server stack */
436 #define COPY_TYPE_VIRTUAL_IN            3       /* vm_map_copyin part of cow */
437 #define COPY_TYPE_VIRTUAL_OUT_SVR       4       /* map cpyout svr part of cow */
438 #define COPY_TYPE_VIRTUAL_OUT_CLN       5       /* map cpyout cln part of cow */
439 #define COPY_TYPE_ALLOC_KRN             6       /* kernel kalloc'd for array */
440 #define COPY_TYPE_ALLOC_SVR             7       /* vm_alloc'd in server space */
441 #define COPY_TYPE_ALLOC_CLN             8       /* vm_alloc'd in client space */
442 #define COPY_TYPE_PORT                  9       /* plain port translated */
443 #define COPY_TYPE_PORT_ARRAY            10      /* port array translated */
444 
445 
446 /*
447  * 	RPC types
448  */
449 
450 typedef int 			mach_rpc_id_t;
451 typedef int 			mach_rpc_return_t;
452 typedef unsigned int		mach_rpc_size_t;
453 typedef unsigned int		mach_rpc_offset_t;
454 
455 struct rpc_copy_state {
456         unsigned                copy_type;      /* what kind of copy */
457         vm_offset_t             alloc_addr;     /* address to free */
458 };
459 typedef struct rpc_copy_state *rpc_copy_state_t;
460 typedef struct rpc_copy_state  rpc_copy_state_data_t;
461 
462 typedef boolean_t (*copyfunc_t)(const char *, char *, vm_size_t);
463 
464 
465 /*
466  *	RPC function declarations
467  */
468 
469 #ifdef	MACH_KERNEL
470 
471 extern
472 mach_rpc_return_t	mach_rpc_trap(
473 				mach_port_t		dest_port,
474 				mach_rpc_id_t		routine_num,
475 				mach_rpc_signature_t	signature_ptr,
476 				mach_rpc_size_t 	signature_size );
477 
478 extern
479 mach_rpc_return_t	mach_rpc_return_trap( void );
480 
481 extern
482 mach_rpc_return_t	mach_rpc_return_error( void );
483 
484 void			mach_rpc_return_wrapper( void );
485 
486 void            	rpc_upcall(
487 				vm_offset_t		stack,
488 				vm_offset_t		new_stack,
489 				vm_offset_t		server_func,
490 				int 			return_code );
491 
492 void            	rpc_error_severity( int severity );
493 void            	rpc_error_show_severity( int severity );
494 unsigned int    	name_rpc_to_ipc( unsigned int action );
495 
496 void			clean_port_array(
497 				ipc_object_t *		array,
498 				unsigned		count,
499 				unsigned		cooked,
500 				unsigned		direct );
501 
502 void            	unwind_rpc_state(
503 				routine_descriptor_t	routine,
504 				rpc_copy_state_t	state,
505 				int * 			arg_buf );
506 
507 kern_return_t		unwind_invoke_state(
508 				thread_act_t		thr_act );
509 
510 kern_return_t   	rpc_invke_args_in(
511 				routine_descriptor_t	routine,
512 				rpc_copy_state_t	state,
513 				int *			arg_buf,
514 				copyfunc_t		infunc );
515 
516 kern_return_t   	rpc_invke_args_out(
517 				routine_descriptor_t	routine,
518 				rpc_copy_state_t	state,
519 				int *			arg_buf,
520 				int ** 			new_sp,
521 				copyfunc_t		outfunc );
522 
523 kern_return_t   	rpc_reply_args_in(
524 				routine_descriptor_t	routine,
525 				rpc_copy_state_t	state,
526 				int *			svr_buf,
527 				copyfunc_t		infunc );
528 
529 kern_return_t   	rpc_reply_args_out(
530 				routine_descriptor_t	routine,
531 				rpc_copy_state_t	state,
532 				int *			svr_buf,
533 				int * 			cln_buf,
534 				copyfunc_t		outfunc );
535 
536 #endif	/* MACH_KERNEL */
537 
538 #ifndef __alpha
539 /*
540  * This is machine dependent and doesn't belong here.
541  * jfraser
542  */
543 
544 /*
545  * Glue function extern declarations
546  */
547 extern kern_return_t	machine_rpc_simple(
548 				int,
549 				int,
550 				void *);
551 
552 extern kern_return_t	klthread_depress_abort(
553 				mach_port_t);
554 
555 #endif /* __alpha */
556 /*
557  * An rpc_glue_vector_t defined either by the kernel or by crt0
558  */
559 extern rpc_glue_vector_t _rpc_glue_vector;
560 
561 /*
562  * libmach helper functions:
563  */
564 extern rpc_subsystem_t	mach_subsystem_join(
565 				rpc_subsystem_t,
566 				rpc_subsystem_t,
567 				unsigned int *,
568 				void *(* )(int));
569 
570 
571 /* Allocate memory for out-of-line mig structures */
572 extern void mig_allocate(vm_address_t *, vm_size_t);
573 
574 /* Deallocate memory used for out-of-line mig structures */
575 extern void mig_deallocate(vm_address_t, vm_size_t);
576 
577 
578 
579 
580 #endif	/* _MACH_RPC_H_ */
581 
582 
583