]> git.cameronkatri.com Git - apple_cmds.git/blob - bootstrap_cmds/migcom.tproj/type.c
text_cmds: All done
[apple_cmds.git] / bootstrap_cmds / migcom.tproj / type.c
1 /*
2 * Copyright (c) 1999-2018 Apple Inc. All rights reserved.
3 *
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * Mach Operating System
25 * Copyright (c) 1991,1990 Carnegie Mellon University
26 * All Rights Reserved.
27 *
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.
33 *
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.
37 *
38 * Carnegie Mellon requests users of this software to return to
39 *
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
44 *
45 * any improvements or extensions that they make and grant Carnegie Mellon
46 * the rights to redistribute these changes.
47 */
48
49 #include "type.h"
50 #include <sys/types.h>
51 #include <mach/message.h>
52 #include <mach/std_types.h>
53 #include <mach/ndr.h>
54 #include "mig_machine.h"
55 #include "routine.h"
56 #include "error.h"
57 #include "alloc.h"
58 #include "global.h"
59 #include <stdio.h>
60
61 #define PortSize (sizeof (mach_port_t) * NBBY)
62
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 */
72
73 static ipc_type_t *list = itNULL;
74
75 static char *machine_integer_name;
76 static u_int machine_integer_size;
77 static u_int machine_integer_bits;
78
79 /*
80 * Searches for a named type. We use a simple
81 * self-organizing linked list.
82 */
83 ipc_type_t *
84 itLookUp(identifier_t name)
85 {
86 ipc_type_t *it, **last;
87
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 */
91 *last = it->itNext;
92 it->itNext = list;
93 list = it;
94
95 return it;
96 }
97
98 return itNULL;
99 }
100
101 /*
102 * Enters a new name-type association into
103 * our self-organizing linked list.
104 */
105 void
106 itInsert(identifier_t name, ipc_type_t *it)
107 {
108 it->itName = name;
109 it->itNext = list;
110 list = it;
111 }
112
113 static ipc_type_t *
114 itAlloc(void)
115 {
116 static ipc_type_t prototype =
117 {
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 */
148 };
149 ipc_type_t *new;
150
151 new = (ipc_type_t *) malloc(sizeof *new);
152 if (new == itNULL)
153 fatal("itAlloc(): %s", strerror(errno));
154 *new = prototype;
155 return new;
156 }
157
158 /*
159 * Convert an IPC type-name into a string.
160 */
161 static char *
162 itNameToString(u_int name)
163 {
164 char buffer[100];
165
166 (void) sprintf(buffer, "%u", name);
167 return strmake(buffer);
168 }
169
170 /*
171 * Calculate itTypeSize, itPadSize, itMinTypeSize
172 * Every type needs this info; it is recalculated
173 * when itInLine, itNumber, or itSize changes.
174 */
175 static void
176 itCalculateSizeInfo(ipc_type_t *it)
177 {
178 if (!IS_KERN_PROC_DATA(it))
179 {
180 u_int bytes = (it->itNumber * it->itSize + 7) / 8;
181 u_int padding = machine_padding(bytes);
182
183 it->itTypeSize = bytes;
184 it->itPadSize = padding;
185 if (IS_VARIABLE_SIZED_UNTYPED(it)) {
186 /*
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)
190 */
191 it->itMinTypeSize = sizeof (mach_msg_type_number_t);
192 /*
193 * NDR encoded VarString carry the extra offset 4-bytes fields
194 * for MIG, it should be always 0;
195 */
196 if (it->itString)
197 it->itMinTypeSize += sizeof (mach_msg_type_number_t);
198 }
199 else
200 it->itMinTypeSize = bytes + padding;
201 }
202 else {
203 /*
204 * 1) ports 2) OOL 3) ports OOL
205 * all have the same size = sizeof(mach_msg_descriptor_t)
206 */
207 u_int bytes;
208 if (IS_MULTIPLE_KPD(it))
209 bytes = it->itKPD_Number * 12 /* sizeof(mach_msg_descriptor_t) */;
210 else
211 bytes = 12 /* sizeof(mach_msg_descriptor_t) */;
212
213 it->itTypeSize = bytes;
214 it->itPadSize = 0;
215 it->itMinTypeSize = bytes;
216 }
217
218 /* Unfortunately, these warning messages can't give a type name;
219 we haven't seen a name yet (it might stay anonymous.) */
220
221 if ((it->itTypeSize == 0) && !it->itVarArray && !it->itNative)
222 warn("sizeof(%s) == 0");
223 }
224
225 /*
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.
229 */
230 static void
231 itCalculateNameInfo(ipc_type_t *it)
232 {
233 if (it->itInNameStr == strNULL)
234 it->itInNameStr = strmake(itNameToString(it->itInName));
235 if (it->itOutNameStr == strNULL)
236 it->itOutNameStr = strmake(itNameToString(it->itOutName));
237
238 if (it->itUserType == strNULL)
239 it->itUserType = it->itName;
240 if (it->itServerType == strNULL)
241 it->itServerType = it->itName;
242 #if 0
243 /*
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.
250 *
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.
254 */
255
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";
263
264 if (IsKernelUser &&
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";
271 #endif /* 0 */
272
273 if (it->itTransType == strNULL)
274 it->itTransType = it->itServerType;
275 }
276
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
281 * is parsed.
282 ******************************************************/
283 static void
284 itCheckDecl(identifier_t name, ipc_type_t *it)
285 {
286 it->itName = name;
287
288 itCalculateNameInfo(it);
289
290 /* do a bit of error checking, mostly necessary because of
291 limitations in Mig */
292
293 if (it->itVarArray) {
294 if ((it->itInTrans != strNULL) || (it->itOutTrans != strNULL))
295 error("%s: can't translate variable-sized arrays", name);
296
297 if (it->itDestructor != strNULL)
298 error("%s: can't destroy variable-sized array", name);
299 }
300 }
301
302 /*
303 * Pretty-prints translation/destruction/type information.
304 */
305 static void
306 itPrintTrans(ipc_type_t *it)
307 {
308 if (!streql(it->itName, it->itUserType))
309 printf("\tCUserType:\t%s\n", it->itUserType);
310
311 if (!streql(it->itName, it->itServerType))
312 printf("\tCServerType:\t%s\n", it->itServerType);
313
314 if (it->itInTrans != strNULL)
315 printf("\tInTran:\t\t%s %s(%s)\n", it->itTransType, it->itInTrans, it->itServerType);
316
317 if (it->itOutTrans != strNULL)
318 printf("\tOutTran:\t%s %s(%s)\n", it->itServerType, it->itOutTrans, it->itTransType);
319
320 if (it->itDestructor != strNULL)
321 printf("\tDestructor:\t%s(%s)\n", it->itDestructor, it->itTransType);
322 }
323
324 /*
325 * Pretty-prints type declarations.
326 */
327 static void
328 itPrintDecl(identifier_t name, ipc_type_t *it)
329 {
330 printf("Type %s = ", name);
331 if (!it->itInLine)
332 printf("^ ");
333 if (it->itVarArray)
334 if (it->itNumber == 0 || it->itMigInLine)
335 printf("array [] of ");
336 else
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);
343
344 if (streql(it->itInNameStr, it->itOutNameStr))
345 printf("(%s,", it->itInNameStr);
346 else
347 printf("(%s|%s", it->itInNameStr, it->itOutNameStr);
348
349 printf(" %d)\n", it->itSize);
350
351 itPrintTrans(it);
352
353 printf("\n");
354 }
355
356 /*
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
361 */
362 void
363 itTypeDecl(identifier_t name, ipc_type_t *it)
364 {
365 itCheckDecl(name, it);
366
367 if (BeVerbose)
368 itPrintDecl(name, it);
369 }
370
371 /*
372 * Handles declarations like
373 * type new = name;
374 * type new = inname|outname;
375 */
376 ipc_type_t *
377 itShortDecl(u_int inname, string_t instr, u_int outname, string_t outstr, u_int defsize)
378 {
379 ipc_type_t *it;
380
381 if (defsize == 0)
382 error("must use full IPC type decl");
383
384 it = itAlloc();
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)
391 {
392 it->itStruct = FALSE;
393 it->itString = TRUE;
394 }
395 /*
396 * I check only inname, because outname
397 * has to be a port as well (polymorphic types
398 * are now restricted to port rights)
399 */
400 if (MACH_MSG_TYPE_PORT_ANY(inname) ||
401 inname == MACH_MSG_TYPE_POLYMORPHIC) {
402 it->itPortType = TRUE;
403 it->itKPD_Number = 1;
404 }
405
406 itCalculateSizeInfo(it);
407 return it;
408 }
409
410 static ipc_type_t *
411 itCopyType(ipc_type_t *old)
412 {
413 ipc_type_t *new = itAlloc();
414
415 *new = *old;
416 new->itName = strNULL;
417 new->itNext = itNULL;
418 new->itElement = old;
419
420 /* size info still valid */
421 return new;
422 }
423
424 /*
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).
428 *
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
434 */
435
436 ipc_type_t *
437 itResetType(ipc_type_t *old)
438 {
439 /* reset all special translation/destruction/type info */
440
441 old->itInTrans = strNULL;
442 old->itOutTrans = strNULL;
443 old->itDestructor = strNULL;
444 old->itUserType = strNULL;
445 old->itServerType = strNULL;
446 old->itTransType = strNULL;
447 return old;
448 }
449
450 /*
451 * Handles the declaration
452 * type new = old;
453 */
454 ipc_type_t *
455 itPrevDecl(identifier_t name)
456 {
457 ipc_type_t *old;
458
459 old = itLookUp(name);
460 if (old == itNULL) {
461 error("type '%s' not defined", name);
462 return itAlloc();
463 }
464 else
465 return itCopyType(old);
466 }
467
468 /*
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;
473 */
474 ipc_type_t *
475 itVarArrayDecl(u_int number, ipc_type_t *old)
476 {
477 ipc_type_t *it = itResetType(itCopyType(old));
478
479 if (!it->itInLine) {
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;
484 it->itNumber = 1;
485 it->itInLine = FALSE;
486 it->itStruct = FALSE;
487 it->itOOL_Number = number;
488 }
489 else if (it->itVarArray)
490 error("IPC type decl is too complicated");
491 else if (number) {
492 it->itNumber *= number;
493 /*
494 * Bounded [Scalar, Port] VarArray: in-line!
495 */
496 it->itInLine = TRUE;
497 it->itStruct = FALSE;
498 if (it->itPortType)
499 it->itKPD_Number *= number;
500 it->itOOL_Number = number;
501 }
502 else {
503 it->itNumber = 0;
504 /*
505 * UnBounded [Scalar, Port] VarArray: always in-line
506 * interface and out-of-line mechanism!
507 */
508 it->itMigInLine = TRUE;
509 it->itInLine = FALSE;
510 it->itStruct = TRUE;
511 it->itKPD_Number = 1;
512 it->itOOL_Number = 0;
513 }
514
515 it->itVarArray = TRUE;
516 it->itString = FALSE;
517
518 itCalculateSizeInfo(it);
519 return it;
520 }
521
522 /*
523 * Handles the declaration
524 * type new = array[number] of old;
525 */
526 ipc_type_t *
527 itArrayDecl(u_int number, ipc_type_t *old)
528 {
529 ipc_type_t *it = itResetType(itCopyType(old));
530
531 if (!it->itInLine) {
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;
536 it->itNumber = 1;
537 it->itStruct = FALSE;
538 it->itString = FALSE;
539 it->itVarArray = FALSE;
540 }
541 else if (it->itVarArray)
542 error("IPC type decl is too complicated");
543 else {
544 it->itNumber *= number;
545 it->itStruct = FALSE;
546 it->itString = FALSE;
547 if (it->itPortType)
548 it->itKPD_Number *= number;
549 }
550
551 itCalculateSizeInfo(it);
552 return it;
553 }
554
555 /*
556 * Handles the declaration
557 * type new = ^ old;
558 */
559 ipc_type_t *
560 itPtrDecl(ipc_type_t *it)
561 {
562 if (!it->itInLine && !it->itMigInLine)
563 error("IPC type decl is already defined to be Out-Of-Line");
564 it->itInLine = FALSE;
565 it->itStruct = TRUE;
566 it->itString = FALSE;
567 it->itMigInLine = FALSE;
568 it->itKPD_Number = 1;
569
570 itCalculateSizeInfo(it);
571 return it;
572 }
573
574 /*
575 * Handles the declaration
576 * type new = struct[number] of old;
577 */
578 ipc_type_t *
579 itStructDecl(u_int number, ipc_type_t *old)
580 {
581 ipc_type_t *it = itResetType(itCopyType(old));
582
583 if (!it->itInLine || it->itVarArray)
584 error("IPC type decl is too complicated");
585 it->itNumber *= number;
586 it->itStruct = TRUE;
587 it->itString = FALSE;
588
589 itCalculateSizeInfo(it);
590 return it;
591 }
592
593 /*
594 * Treat 'c_string[n]' as
595 * 'array[n] of (MSG_TYPE_STRING_C, 8)'
596 */
597 ipc_type_t *
598 itCStringDecl(int count, boolean_t varying)
599 {
600 ipc_type_t *it;
601 ipc_type_t *itElement;
602
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);
605
606 it = itResetType(itCopyType(itElement));
607 it->itNumber = count;
608 it->itVarArray = varying;
609 it->itStruct = FALSE;
610 it->itString = TRUE;
611
612 itCalculateSizeInfo(it);
613 return it;
614 }
615
616 extern ipc_type_t *
617 itMakeSubCountType(int count, boolean_t varying, string_t name)
618 {
619 ipc_type_t *it;
620 ipc_type_t *itElement;
621
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);
624
625 it = itResetType(itCopyType(itElement));
626 it->itNumber = count;
627 /*
628 * I cannot consider it as a Fixed array, otherwise MiG will try
629 * to follow the path for efficient copy of arrays
630 */
631 it->itVarArray = FALSE;
632 it->itStruct = FALSE;
633 it->itString = FALSE;
634 it->itInLine = TRUE;
635 it->itName = "mach_msg_type_number_t *";
636 if (varying)
637 it->itVarArray = TRUE;
638 else
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;
642
643 itCalculateSizeInfo(it);
644 itCalculateNameInfo(it);
645 return it;
646 }
647
648 extern ipc_type_t *
649 itMakeCountType(void)
650 {
651 ipc_type_t *it = itAlloc();
652
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;
659
660 itCalculateSizeInfo(it);
661 itCalculateNameInfo(it);
662 return it;
663 }
664
665 extern ipc_type_t *
666 itMakePolyType(void)
667 {
668 ipc_type_t *it = itAlloc();
669
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;
676
677 itCalculateSizeInfo(it);
678 itCalculateNameInfo(it);
679 return it;
680 }
681
682 extern ipc_type_t *
683 itMakeDeallocType(void)
684 {
685 ipc_type_t *it = itAlloc();
686
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;
693
694 itCalculateSizeInfo(it);
695 itCalculateNameInfo(it);
696 return it;
697 }
698
699 extern ipc_type_t *
700 itNativeType(identifier_t id, boolean_t ptr, identifier_t badval)
701 {
702 ipc_type_t *it = itAlloc();
703
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";
708 it->itInLine = TRUE;
709 it->itNative = TRUE;
710 it->itNativePointer = ptr;
711 it->itServerType = id;
712 it->itUserType = id;
713 it->itTransType = id;
714 it->itBadValue = badval;
715
716 itCalculateSizeInfo(it);
717 itCalculateNameInfo(it);
718 return it;
719 }
720
721 /*
722 * Initializes the pre-defined types.
723 */
724 void
725 init_type(void)
726 {
727 u_int size;
728
729 size = NBBY * sizeof (natural_t);
730 if (size == 32) {
731 machine_integer_name = "MACH_MSG_TYPE_INTEGER_32";
732 machine_integer_size = MACH_MSG_TYPE_INTEGER_32;
733 }
734 else if (size == 64) {
735 machine_integer_name = "MACH_MSG_TYPE_INTEGER_64";
736 machine_integer_size = MACH_MSG_TYPE_INTEGER_64;
737 }
738 else
739 error("init_type unknown size %d", size);
740
741 machine_integer_bits = size;
742
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);
752
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);
762
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);
772
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);
783
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);
793
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);
803
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);
813
814 itWaitTimeType = itMakeCountType();
815 itMsgOptionType = itMakeCountType();
816 }
817
818 /******************************************************
819 * Make sure return values of functions are assignable.
820 ******************************************************/
821 void
822 itCheckReturnType(identifier_t name, ipc_type_t *it)
823 {
824 if (!it->itStruct)
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);
829 }
830
831
832 /******************************************************
833 * Called by routine.c to check that request ports are
834 * simple and correct ports with send rights.
835 ******************************************************/
836 void
837 itCheckRequestPortType(identifier_t name, ipc_type_t *it)
838 {
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);
841 */
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) ||
847 !it->itInLine ||
848 !it->itStruct ||
849 it->itVarArray)
850 error("argument %s isn't a proper request port", name);
851 }
852
853
854 /******************************************************
855 * Called by routine.c to check that reply ports are
856 * simple and correct ports with send rights.
857 ******************************************************/
858 void
859 itCheckReplyPortType(identifier_t name, ipc_type_t *it)
860 {
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) ||
867 !it->itInLine ||
868 !it->itStruct ||
869 it->itVarArray)
870 error("argument %s isn't a proper reply port", name);
871 }
872
873
874 /******************************************************
875 * Used by routine.c to check that WaitTime is a
876 * simple bit machine_integer_bits integer.
877 ******************************************************/
878 void
879 itCheckIntType(identifier_t name, ipc_type_t *it)
880 {
881 if ((it->itInName != machine_integer_size) ||
882 (it->itOutName != machine_integer_size) ||
883 (it->itNumber != 1) ||
884 (it->itSize != machine_integer_bits) ||
885 !it->itInLine ||
886 !it->itStruct ||
887 it->itVarArray)
888 error("argument %s isn't a proper integer", name);
889 }
890
891 void
892 itCheckTokenType(identifier_t name, ipc_type_t *it)
893 {
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);
898
899 }