2 * Copyright (c) 1999-2018 Apple Inc. All rights reserved.
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Mach Operating System
25 * Copyright (c) 1991,1990 Carnegie Mellon University
26 * All Rights Reserved.
28 * Permission to use, copy, modify and distribute this software and its
29 * documentation is hereby granted, provided that both the copyright
30 * notice and this permission notice appear in all copies of the
31 * software, derivative works or modified versions, and any portions
32 * thereof, and that both notices appear in supporting documentation.
34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
38 * Carnegie Mellon requests users of this software to return to
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
45 * any improvements or extensions that they make and grant Carnegie Mellon
46 * the rights to redistribute these changes.
50 #include <sys/types.h>
51 #include <mach/message.h>
52 #include <mach/std_types.h>
54 #include "mig_machine.h"
61 #define PortSize (sizeof (mach_port_t) * NBBY)
63 ipc_type_t
*itRetCodeType
; /* used for return codes */
64 ipc_type_t
*itNdrCodeType
; /* used for NDR format labels */
65 ipc_type_t
*itDummyType
; /* used for camelot dummy args */
66 ipc_type_t
*itTidType
; /* used for camelot tids */
67 ipc_type_t
*itRequestPortType
; /* used for default Request port arg */
68 ipc_type_t
*itZeroReplyPortType
;/* used for dummy Reply port arg */
69 ipc_type_t
*itRealReplyPortType
;/* used for default Reply port arg */
70 ipc_type_t
*itWaitTimeType
; /* used for dummy WaitTime args */
71 ipc_type_t
*itMsgOptionType
; /* used for dummy MsgOption args */
73 static ipc_type_t
*list
= itNULL
;
75 static char *machine_integer_name
;
76 static u_int machine_integer_size
;
77 static u_int machine_integer_bits
;
80 * Searches for a named type. We use a simple
81 * self-organizing linked list.
84 itLookUp(identifier_t name
)
86 ipc_type_t
*it
, **last
;
88 for (it
= *(last
= &list
); it
!= itNULL
; it
= *(last
= &it
->itNext
))
89 if (streql(name
, it
->itName
)) {
90 /* move this type to the front of the list */
102 * Enters a new name-type association into
103 * our self-organizing linked list.
106 itInsert(identifier_t name
, ipc_type_t
*it
)
116 static ipc_type_t prototype
=
118 strNULL
, /* identifier_t itName */
119 0, /* ipc_type_t *itNext */
120 0, /* u_int itTypeSize */
121 0, /* u_int itPadSize */
122 0, /* u_int itMinTypeSize */
123 0, /* u_int itInName */
124 0, /* u_int itOutName */
125 0, /* u_int itSize */
126 1, /* u_int itNumber */
127 0, /* u_int itKPD_Number */
128 TRUE
, /* boolean_t itInLine */
129 FALSE
, /* boolean_t itMigInLine */
130 FALSE
, /* boolean_t itPortType */
131 strNULL
, /* string_t itInNameStr */
132 strNULL
, /* string_t itOutNameStr */
133 TRUE
, /* boolean_t itStruct */
134 FALSE
, /* boolean_t itString */
135 FALSE
, /* boolean_t itVarArray */
136 FALSE
, /* boolean_t itNoOptArray */
137 FALSE
, /* boolean_t itNative */
138 FALSE
, /* boolean_t itNativePointer */
139 itNULL
, /* ipc_type_t *itElement */
140 strNULL
, /* identifier_t itUserType */
141 strNULL
, /* identifier_t itServerType */
142 strNULL
, /* identifier_t itTransType */
143 strNULL
, /* identifier_t itUserKPDType */
144 strNULL
, /* identifier_t itServerKPDType */
145 strNULL
, /* identifier_t itInTrans */
146 strNULL
, /* identifier_t itOutTrans */
147 strNULL
, /* identifier_t itDestructor */
151 new = (ipc_type_t
*) malloc(sizeof *new);
153 fatal("itAlloc(): %s", strerror(errno
));
159 * Convert an IPC type-name into a string.
162 itNameToString(u_int name
)
166 (void) sprintf(buffer
, "%u", name
);
167 return strmake(buffer
);
171 * Calculate itTypeSize, itPadSize, itMinTypeSize
172 * Every type needs this info; it is recalculated
173 * when itInLine, itNumber, or itSize changes.
176 itCalculateSizeInfo(ipc_type_t
*it
)
178 if (!IS_KERN_PROC_DATA(it
))
180 u_int bytes
= (it
->itNumber
* it
->itSize
+ 7) / 8;
181 u_int padding
= machine_padding(bytes
);
183 it
->itTypeSize
= bytes
;
184 it
->itPadSize
= padding
;
185 if (IS_VARIABLE_SIZED_UNTYPED(it
)) {
187 * for these arrays, the argCount is not a akbRequest|akbReply,
188 * therefore we need to account here for the space of the count
189 * (itMinTypeSize is used only in rtFindSize)
191 it
->itMinTypeSize
= sizeof (mach_msg_type_number_t
);
193 * NDR encoded VarString carry the extra offset 4-bytes fields
194 * for MIG, it should be always 0;
197 it
->itMinTypeSize
+= sizeof (mach_msg_type_number_t
);
200 it
->itMinTypeSize
= bytes
+ padding
;
204 * 1) ports 2) OOL 3) ports OOL
205 * all have the same size = sizeof(mach_msg_descriptor_t)
208 if (IS_MULTIPLE_KPD(it
))
209 bytes
= it
->itKPD_Number
* 12 /* sizeof(mach_msg_descriptor_t) */;
211 bytes
= 12 /* sizeof(mach_msg_descriptor_t) */;
213 it
->itTypeSize
= bytes
;
215 it
->itMinTypeSize
= bytes
;
218 /* Unfortunately, these warning messages can't give a type name;
219 we haven't seen a name yet (it might stay anonymous.) */
221 if ((it
->itTypeSize
== 0) && !it
->itVarArray
&& !it
->itNative
)
222 warn("sizeof(%s) == 0");
226 * Fill in default values for some fields used in code generation:
227 * itInNameStr, itOutNameStr, itUserType, itServerType, itTransType
228 * Every argument's type should have these values filled in.
231 itCalculateNameInfo(ipc_type_t
*it
)
233 if (it
->itInNameStr
== strNULL
)
234 it
->itInNameStr
= strmake(itNameToString(it
->itInName
));
235 if (it
->itOutNameStr
== strNULL
)
236 it
->itOutNameStr
= strmake(itNameToString(it
->itOutName
));
238 if (it
->itUserType
== strNULL
)
239 it
->itUserType
= it
->itName
;
240 if (it
->itServerType
== strNULL
)
241 it
->itServerType
= it
->itName
;
244 * KernelServer and KernelUser interfaces get special treatment here.
245 * On the kernel side of the interface, ports are really internal
246 * port pointers (ipc_port_t), not port names (mach_port_t).
247 * At this point, we don't know if the argument is in or out,
248 * so we don't know if we should look at itInName or itOutName.
249 * Looking at both should be OK.
251 * This is definitely a hack, but I think it is cleaner than
252 * mucking with type declarations throughout the kernel .def files,
253 * hand-conditionalizing on KERNEL_SERVER and KERNEL_USER.
256 if (IsKernelServer
&&
257 streql(it
->itServerType
, "mach_port_t") &&
258 (((it
->itInName
== MACH_MSG_TYPE_POLYMORPHIC
) &&
259 (it
->itOutName
== MACH_MSG_TYPE_POLYMORPHIC
)) ||
260 MACH_MSG_TYPE_PORT_ANY(it
->itInName
) ||
261 MACH_MSG_TYPE_PORT_ANY(it
->itOutName
)))
262 it
->itServerType
= "ipc_port_t";
265 streql(it
->itUserType
, "mach_port_t") &&
266 (((it
->itInName
== MACH_MSG_TYPE_POLYMORPHIC
) &&
267 (it
->itOutName
== MACH_MSG_TYPE_POLYMORPHIC
)) ||
268 MACH_MSG_TYPE_PORT_ANY(it
->itInName
) ||
269 MACH_MSG_TYPE_PORT_ANY(it
->itOutName
)))
270 it
->itUserType
= "ipc_port_t";
273 if (it
->itTransType
== strNULL
)
274 it
->itTransType
= it
->itServerType
;
277 /******************************************************
278 * Checks for non-implemented types, conflicting type
279 * flags and whether the long or short form of msg type
280 * descriptor is appropriate. Called after each type statement
282 ******************************************************/
284 itCheckDecl(identifier_t name
, ipc_type_t
*it
)
288 itCalculateNameInfo(it
);
290 /* do a bit of error checking, mostly necessary because of
291 limitations in Mig */
293 if (it
->itVarArray
) {
294 if ((it
->itInTrans
!= strNULL
) || (it
->itOutTrans
!= strNULL
))
295 error("%s: can't translate variable-sized arrays", name
);
297 if (it
->itDestructor
!= strNULL
)
298 error("%s: can't destroy variable-sized array", name
);
303 * Pretty-prints translation/destruction/type information.
306 itPrintTrans(ipc_type_t
*it
)
308 if (!streql(it
->itName
, it
->itUserType
))
309 printf("\tCUserType:\t%s\n", it
->itUserType
);
311 if (!streql(it
->itName
, it
->itServerType
))
312 printf("\tCServerType:\t%s\n", it
->itServerType
);
314 if (it
->itInTrans
!= strNULL
)
315 printf("\tInTran:\t\t%s %s(%s)\n", it
->itTransType
, it
->itInTrans
, it
->itServerType
);
317 if (it
->itOutTrans
!= strNULL
)
318 printf("\tOutTran:\t%s %s(%s)\n", it
->itServerType
, it
->itOutTrans
, it
->itTransType
);
320 if (it
->itDestructor
!= strNULL
)
321 printf("\tDestructor:\t%s(%s)\n", it
->itDestructor
, it
->itTransType
);
325 * Pretty-prints type declarations.
328 itPrintDecl(identifier_t name
, ipc_type_t
*it
)
330 printf("Type %s = ", name
);
334 if (it
->itNumber
== 0 || it
->itMigInLine
)
335 printf("array [] of ");
337 printf("array [*:%d] of ", it
->itNumber
);
338 else if (it
->itStruct
&& ((it
->itNumber
!= 1) ||
339 (it
->itInName
== MACH_MSG_TYPE_STRING_C
)))
340 printf("struct [%d] of ", it
->itNumber
);
341 else if (it
->itNumber
!= 1)
342 printf("array [%d] of ", it
->itNumber
);
344 if (streql(it
->itInNameStr
, it
->itOutNameStr
))
345 printf("(%s,", it
->itInNameStr
);
347 printf("(%s|%s", it
->itInNameStr
, it
->itOutNameStr
);
349 printf(" %d)\n", it
->itSize
);
357 * Handles named type-specs, which can occur in type
358 * declarations or in argument lists. For example,
359 * type foo = type-spec; // itInsert will get called later
360 * routine foo(arg : bar = type-spec); // itInsert won't get called
363 itTypeDecl(identifier_t name
, ipc_type_t
*it
)
365 itCheckDecl(name
, it
);
368 itPrintDecl(name
, it
);
372 * Handles declarations like
374 * type new = inname|outname;
377 itShortDecl(u_int inname
, string_t instr
, u_int outname
, string_t outstr
, u_int defsize
)
382 error("must use full IPC type decl");
385 it
->itInName
= inname
;
386 it
->itInNameStr
= instr
;
387 it
->itOutName
= outname
;
388 it
->itOutNameStr
= outstr
;
389 it
->itSize
= defsize
;
390 if (inname
== MACH_MSG_TYPE_STRING_C
)
392 it
->itStruct
= FALSE
;
396 * I check only inname, because outname
397 * has to be a port as well (polymorphic types
398 * are now restricted to port rights)
400 if (MACH_MSG_TYPE_PORT_ANY(inname
) ||
401 inname
== MACH_MSG_TYPE_POLYMORPHIC
) {
402 it
->itPortType
= TRUE
;
403 it
->itKPD_Number
= 1;
406 itCalculateSizeInfo(it
);
411 itCopyType(ipc_type_t
*old
)
413 ipc_type_t
*new = itAlloc();
416 new->itName
= strNULL
;
417 new->itNext
= itNULL
;
418 new->itElement
= old
;
420 /* size info still valid */
425 * A call to itCopyType is almost always followed with itResetType.
426 * The exception is itPrevDecl. Also called before adding any new
427 * translation/destruction/type info (see parser.y).
429 * type new = old; // new doesn't get old's info
430 * type new = array[*:10] of old;
431 * // new doesn't get old's info, but new->itElement does
432 * type new = array[*:10] of struct[3] of old;
433 * // new and new->itElement don't get old's info
437 itResetType(ipc_type_t
*old
)
439 /* reset all special translation/destruction/type info */
441 old
->itInTrans
= strNULL
;
442 old
->itOutTrans
= strNULL
;
443 old
->itDestructor
= strNULL
;
444 old
->itUserType
= strNULL
;
445 old
->itServerType
= strNULL
;
446 old
->itTransType
= strNULL
;
451 * Handles the declaration
455 itPrevDecl(identifier_t name
)
459 old
= itLookUp(name
);
461 error("type '%s' not defined", name
);
465 return itCopyType(old
);
469 * Handles the declarations
470 * type new = array[] of old; // number is oo
471 * type new = array[*] of old; // number is oo
472 * type new = array[*:number] of old;
475 itVarArrayDecl(u_int number
, ipc_type_t
*old
)
477 ipc_type_t
*it
= itResetType(itCopyType(old
));
480 /* already an initialized KPD */
481 if (it
->itKPD_Number
!= 1 || !number
)
482 error("IPC type decl is too complicated for Kernel Processed Data");
483 it
->itKPD_Number
*= number
;
485 it
->itInLine
= FALSE
;
486 it
->itStruct
= FALSE
;
487 it
->itOOL_Number
= number
;
489 else if (it
->itVarArray
)
490 error("IPC type decl is too complicated");
492 it
->itNumber
*= number
;
494 * Bounded [Scalar, Port] VarArray: in-line!
497 it
->itStruct
= FALSE
;
499 it
->itKPD_Number
*= number
;
500 it
->itOOL_Number
= number
;
505 * UnBounded [Scalar, Port] VarArray: always in-line
506 * interface and out-of-line mechanism!
508 it
->itMigInLine
= TRUE
;
509 it
->itInLine
= FALSE
;
511 it
->itKPD_Number
= 1;
512 it
->itOOL_Number
= 0;
515 it
->itVarArray
= TRUE
;
516 it
->itString
= FALSE
;
518 itCalculateSizeInfo(it
);
523 * Handles the declaration
524 * type new = array[number] of old;
527 itArrayDecl(u_int number
, ipc_type_t
*old
)
529 ipc_type_t
*it
= itResetType(itCopyType(old
));
532 /* already an initialized KPD */
533 if (it
->itKPD_Number
!= 1)
534 error("IPC type decl is too complicated for Kernel Processed Data");
535 it
->itKPD_Number
*= number
;
537 it
->itStruct
= FALSE
;
538 it
->itString
= FALSE
;
539 it
->itVarArray
= FALSE
;
541 else if (it
->itVarArray
)
542 error("IPC type decl is too complicated");
544 it
->itNumber
*= number
;
545 it
->itStruct
= FALSE
;
546 it
->itString
= FALSE
;
548 it
->itKPD_Number
*= number
;
551 itCalculateSizeInfo(it
);
556 * Handles the declaration
560 itPtrDecl(ipc_type_t
*it
)
562 if (!it
->itInLine
&& !it
->itMigInLine
)
563 error("IPC type decl is already defined to be Out-Of-Line");
564 it
->itInLine
= FALSE
;
566 it
->itString
= FALSE
;
567 it
->itMigInLine
= FALSE
;
568 it
->itKPD_Number
= 1;
570 itCalculateSizeInfo(it
);
575 * Handles the declaration
576 * type new = struct[number] of old;
579 itStructDecl(u_int number
, ipc_type_t
*old
)
581 ipc_type_t
*it
= itResetType(itCopyType(old
));
583 if (!it
->itInLine
|| it
->itVarArray
)
584 error("IPC type decl is too complicated");
585 it
->itNumber
*= number
;
587 it
->itString
= FALSE
;
589 itCalculateSizeInfo(it
);
594 * Treat 'c_string[n]' as
595 * 'array[n] of (MSG_TYPE_STRING_C, 8)'
598 itCStringDecl(int count
, boolean_t varying
)
601 ipc_type_t
*itElement
;
603 itElement
= itShortDecl(MACH_MSG_TYPE_STRING_C
, "MACH_MSG_TYPE_STRING_C", MACH_MSG_TYPE_STRING_C
, "MACH_MSG_TYPE_STRING_C", 8);
604 itCheckDecl("char", itElement
);
606 it
= itResetType(itCopyType(itElement
));
607 it
->itNumber
= count
;
608 it
->itVarArray
= varying
;
609 it
->itStruct
= FALSE
;
612 itCalculateSizeInfo(it
);
617 itMakeSubCountType(int count
, boolean_t varying
, string_t name
)
620 ipc_type_t
*itElement
;
622 itElement
= itShortDecl(machine_integer_size
, machine_integer_name
, machine_integer_size
, machine_integer_name
, machine_integer_bits
);
623 itCheckDecl("mach_msg_type_number_t", itElement
);
625 it
= itResetType(itCopyType(itElement
));
626 it
->itNumber
= count
;
628 * I cannot consider it as a Fixed array, otherwise MiG will try
629 * to follow the path for efficient copy of arrays
631 it
->itVarArray
= FALSE
;
632 it
->itStruct
= FALSE
;
633 it
->itString
= FALSE
;
635 it
->itName
= "mach_msg_type_number_t *";
637 it
->itVarArray
= TRUE
;
639 /* to skip the optimized copy of fixed array: in fact we need to
640 * reference each element and we also miss a user type for it */
641 it
->itNoOptArray
= TRUE
;
643 itCalculateSizeInfo(it
);
644 itCalculateNameInfo(it
);
649 itMakeCountType(void)
651 ipc_type_t
*it
= itAlloc();
653 it
->itName
= "mach_msg_type_number_t";
654 it
->itInName
= machine_integer_size
;
655 it
->itInNameStr
= machine_integer_name
;
656 it
->itOutName
= machine_integer_size
;
657 it
->itOutNameStr
= machine_integer_name
;
658 it
->itSize
= machine_integer_bits
;
660 itCalculateSizeInfo(it
);
661 itCalculateNameInfo(it
);
668 ipc_type_t
*it
= itAlloc();
670 it
->itName
= "mach_msg_type_name_t";
671 it
->itInName
= machine_integer_size
;
672 it
->itInNameStr
= machine_integer_name
;
673 it
->itOutName
= machine_integer_size
;
674 it
->itOutNameStr
= machine_integer_name
;
675 it
->itSize
= machine_integer_bits
;
677 itCalculateSizeInfo(it
);
678 itCalculateNameInfo(it
);
683 itMakeDeallocType(void)
685 ipc_type_t
*it
= itAlloc();
687 it
->itName
= "boolean_t";
688 it
->itInName
= MACH_MSG_TYPE_BOOLEAN
;
689 it
->itInNameStr
= "MACH_MSG_TYPE_BOOLEAN";
690 it
->itOutName
= MACH_MSG_TYPE_BOOLEAN
;
691 it
->itOutNameStr
= "MACH_MSG_TYPE_BOOLEAN";
692 it
->itSize
= machine_integer_bits
;
694 itCalculateSizeInfo(it
);
695 itCalculateNameInfo(it
);
700 itNativeType(identifier_t id
, boolean_t ptr
, identifier_t badval
)
702 ipc_type_t
*it
= itAlloc();
704 it
->itInName
= MACH_MSG_TYPE_BYTE
;
705 it
->itInNameStr
= "MACH_MSG_TYPE_BYTE";
706 it
->itOutName
= MACH_MSG_TYPE_BYTE
;
707 it
->itOutNameStr
= "MACH_MSG_TYPE_BYTE";
710 it
->itNativePointer
= ptr
;
711 it
->itServerType
= id
;
713 it
->itTransType
= id
;
714 it
->itBadValue
= badval
;
716 itCalculateSizeInfo(it
);
717 itCalculateNameInfo(it
);
722 * Initializes the pre-defined types.
729 size
= NBBY
* sizeof (natural_t
);
731 machine_integer_name
= "MACH_MSG_TYPE_INTEGER_32";
732 machine_integer_size
= MACH_MSG_TYPE_INTEGER_32
;
734 else if (size
== 64) {
735 machine_integer_name
= "MACH_MSG_TYPE_INTEGER_64";
736 machine_integer_size
= MACH_MSG_TYPE_INTEGER_64
;
739 error("init_type unknown size %d", size
);
741 machine_integer_bits
= size
;
743 itRetCodeType
= itAlloc();
744 itRetCodeType
->itName
= "kern_return_t";
745 itRetCodeType
->itInName
= machine_integer_size
;
746 itRetCodeType
->itInNameStr
= machine_integer_name
;
747 itRetCodeType
->itOutName
= machine_integer_size
;
748 itRetCodeType
->itOutNameStr
= machine_integer_name
;
749 itRetCodeType
->itSize
= machine_integer_bits
;
750 itCalculateSizeInfo(itRetCodeType
);
751 itCalculateNameInfo(itRetCodeType
);
753 itNdrCodeType
= itAlloc();
754 itNdrCodeType
->itName
= "NDR_record_t";
755 itNdrCodeType
->itInName
= 0;
756 itNdrCodeType
->itInNameStr
= "NDR_record_t";
757 itNdrCodeType
->itOutName
= 0;
758 itNdrCodeType
->itOutNameStr
= "NDR_record_t";
759 itNdrCodeType
->itSize
= sizeof(NDR_record_t
) * 8;
760 itCalculateSizeInfo(itNdrCodeType
);
761 itCalculateNameInfo(itNdrCodeType
);
763 itDummyType
= itAlloc();
764 itDummyType
->itName
= "char *";
765 itDummyType
->itInName
= MACH_MSG_TYPE_UNSTRUCTURED
;
766 itDummyType
->itInNameStr
= "MACH_MSG_TYPE_UNSTRUCTURED";
767 itDummyType
->itOutName
= MACH_MSG_TYPE_UNSTRUCTURED
;
768 itDummyType
->itOutNameStr
= "MACH_MSG_TYPE_UNSTRUCTURED";
769 itDummyType
->itSize
= PortSize
;
770 itCalculateSizeInfo(itDummyType
);
771 itCalculateNameInfo(itDummyType
);
773 itTidType
= itAlloc();
774 itTidType
->itName
= "tid_t";
775 itTidType
->itInName
= machine_integer_size
;
776 itTidType
->itInNameStr
= machine_integer_name
;
777 itTidType
->itOutName
= machine_integer_size
;
778 itTidType
->itOutNameStr
= machine_integer_name
;
779 itTidType
->itSize
= machine_integer_bits
;
780 itTidType
->itNumber
= 6;
781 itCalculateSizeInfo(itTidType
);
782 itCalculateNameInfo(itTidType
);
784 itRequestPortType
= itAlloc();
785 itRequestPortType
->itName
= "mach_port_t";
786 itRequestPortType
->itInName
= MACH_MSG_TYPE_COPY_SEND
;
787 itRequestPortType
->itInNameStr
= "MACH_MSG_TYPE_COPY_SEND";
788 itRequestPortType
->itOutName
= MACH_MSG_TYPE_PORT_SEND
;
789 itRequestPortType
->itOutNameStr
= "MACH_MSG_TYPE_PORT_SEND";
790 itRequestPortType
->itSize
= PortSize
;
791 itCalculateSizeInfo(itRequestPortType
);
792 itCalculateNameInfo(itRequestPortType
);
794 itZeroReplyPortType
= itAlloc();
795 itZeroReplyPortType
->itName
= "mach_port_t";
796 itZeroReplyPortType
->itInName
= 0;
797 itZeroReplyPortType
->itInNameStr
= "0";
798 itZeroReplyPortType
->itOutName
= 0;
799 itZeroReplyPortType
->itOutNameStr
= "0";
800 itZeroReplyPortType
->itSize
= PortSize
;
801 itCalculateSizeInfo(itZeroReplyPortType
);
802 itCalculateNameInfo(itZeroReplyPortType
);
804 itRealReplyPortType
= itAlloc();
805 itRealReplyPortType
->itName
= "mach_port_t";
806 itRealReplyPortType
->itInName
= MACH_MSG_TYPE_MAKE_SEND_ONCE
;
807 itRealReplyPortType
->itInNameStr
= "MACH_MSG_TYPE_MAKE_SEND_ONCE";
808 itRealReplyPortType
->itOutName
= MACH_MSG_TYPE_PORT_SEND_ONCE
;
809 itRealReplyPortType
->itOutNameStr
= "MACH_MSG_TYPE_PORT_SEND_ONCE";
810 itRealReplyPortType
->itSize
= PortSize
;
811 itCalculateSizeInfo(itRealReplyPortType
);
812 itCalculateNameInfo(itRealReplyPortType
);
814 itWaitTimeType
= itMakeCountType();
815 itMsgOptionType
= itMakeCountType();
818 /******************************************************
819 * Make sure return values of functions are assignable.
820 ******************************************************/
822 itCheckReturnType(identifier_t name
, ipc_type_t
*it
)
825 error("type of %s is too complicated", name
);
826 if ((it
->itInName
== MACH_MSG_TYPE_POLYMORPHIC
) ||
827 (it
->itOutName
== MACH_MSG_TYPE_POLYMORPHIC
))
828 error("type of %s can't be polymorphic", name
);
832 /******************************************************
833 * Called by routine.c to check that request ports are
834 * simple and correct ports with send rights.
835 ******************************************************/
837 itCheckRequestPortType(identifier_t name
, ipc_type_t
*it
)
839 /* error("Port size = %d %d name = %s\n", PortSize, it->itSize, it->itName);
840 error("server = %s user = %x\n",it->itServerType, it->itUserType);
842 if (((it
->itOutName
!= MACH_MSG_TYPE_PORT_SEND
) &&
843 (it
->itOutName
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
844 (it
->itOutName
!= MACH_MSG_TYPE_POLYMORPHIC
)) ||
845 (it
->itNumber
!= 1) ||
846 (it
->itSize
!= PortSize
) ||
850 error("argument %s isn't a proper request port", name
);
854 /******************************************************
855 * Called by routine.c to check that reply ports are
856 * simple and correct ports with send rights.
857 ******************************************************/
859 itCheckReplyPortType(identifier_t name
, ipc_type_t
*it
)
861 if (((it
->itOutName
!= MACH_MSG_TYPE_PORT_SEND
) &&
862 (it
->itOutName
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
863 (it
->itOutName
!= MACH_MSG_TYPE_POLYMORPHIC
) &&
864 (it
->itOutName
!= 0)) ||
865 (it
->itNumber
!= 1) ||
866 (it
->itSize
!= PortSize
) ||
870 error("argument %s isn't a proper reply port", name
);
874 /******************************************************
875 * Used by routine.c to check that WaitTime is a
876 * simple bit machine_integer_bits integer.
877 ******************************************************/
879 itCheckIntType(identifier_t name
, ipc_type_t
*it
)
881 if ((it
->itInName
!= machine_integer_size
) ||
882 (it
->itOutName
!= machine_integer_size
) ||
883 (it
->itNumber
!= 1) ||
884 (it
->itSize
!= machine_integer_bits
) ||
888 error("argument %s isn't a proper integer", name
);
892 itCheckTokenType(identifier_t name
, ipc_type_t
*it
)
894 if (it
->itMigInLine
|| it
->itNoOptArray
|| it
->itString
||
895 it
->itTypeSize
!= 8 || !it
->itInLine
|| !it
->itStruct
||
896 it
->itVarArray
|| it
->itPortType
)
897 error("argument %s isn't a proper Token", name
);