xref: /NextBSD/usr.bin/migcom/utils.c (revision 6f00ba6f941cf2478afa8a6e005294d3befd2f63)
1 /*-
2  * Copyright (c) 2014, Matthew Macy <kmacy@FreeBSD.ORG>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice unmodified, this list of conditions, and the following
10  *    disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 /*
28  * Copyright 1991-1998 by Open Software Foundation, Inc.
29  *              All Rights Reserved
30  *
31  * Permission to use, copy, modify, and distribute this software and
32  * its documentation for any purpose and without fee is hereby granted,
33  * provided that the above copyright notice appears in all copies and
34  * that both the copyright notice and this permission notice appear in
35  * supporting documentation.
36  *
37  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
38  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
39  * FOR A PARTICULAR PURPOSE.
40  *
41  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
42  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
43  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
44  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
45  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
46  */
47 /*
48  * cmk1.1
49  */
50 /*
51  * Mach Operating System
52  * Copyright (c) 1991,1990 Carnegie Mellon University
53  * All Rights Reserved.
54  *
55  * Permission to use, copy, modify and distribute this software and its
56  * documentation is hereby granted, provided that both the copyright
57  * notice and this permission notice appear in all copies of the
58  * software, derivative works or modified versions, and any portions
59  * thereof, and that both notices appear in supporting documentation.
60  *
61  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
62  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
63  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
64  *
65  * Carnegie Mellon requests users of this software to return to
66  *
67  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
68  *  School of Computer Science
69  *  Carnegie Mellon University
70  *  Pittsburgh PA 15213-3890
71  *
72  * any improvements or extensions that they make and grant Carnegie Mellon
73  * the rights to redistribute these changes.
74  */
75 /*
76  * 92/03/03  16:25:39  jeffreyh
77  * 	Changes from TRUNK
78  * 	[92/02/26  12:33:02  jeffreyh]
79  *
80  * 92/01/14  16:47:08  rpd
81  * 	Modified WriteTypeDeclIn and WriteTypeDeclOut to disable
82  * 	the deallocate flag on Indefinite arguments.
83  * 	[92/01/09            rpd]
84  *
85  * 92/01/03  20:30:51  dbg
86  * 	Change argByReferenceUser and argByReferenceServer to fields in
87  * 	argument_t.
88  * 	[91/08/29            dbg]
89  *
90  * 91/07/31  18:11:45  dbg
91  * 	Accept new dealloc_t argument type in WriteStaticDecl,
92  * 	WritePackMsgType.
93  *
94  * 	Don't need to zero last character of C string.  Mig_strncpy does
95  * 	the proper work.
96  *
97  * 	Add SkipVFPrintf, so that WriteCopyType doesn't print fields in
98  * 	comments.
99  * 	[91/07/17            dbg]
100  *
101  * 91/06/25  10:32:36  rpd
102  * 	Changed WriteVarDecl to WriteUserVarDecl.
103  * 	Added WriteServerVarDecl.
104  * 	[91/05/23            rpd]
105  *
106  * 91/02/05  17:56:28  mrt
107  * 	Changed to new Mach copyright
108  * 	[91/02/01  17:56:39  mrt]
109  *
110  * 90/06/02  15:06:11  rpd
111  * 	Created for new IPC.
112  * 	[90/03/26  21:14:54  rpd]
113  *
114  * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
115  *	Extensive revamping.  Added polymorphic arguments.
116  *	Allow multiple variable-sized inline arguments in messages.
117  *
118  * 21-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
119  *	Added deallocflag to the WritePackMsg routines.
120  *
121  * 29-Jul-87  Mary Thompson (mrt) at Carnegie-Mellon University
122  *	Changed WriteVarDecl to not automatically write
123  *	semi-colons between items, so that it can be
124  *	used to write C++ argument lists.
125  *
126  * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
127  *	Created.
128  */
129 #include <stdarg.h>
130 #include <stdlib.h>
131 #include <stdio.h>
132 
133 #include "type.h"
134 
135 #include <mach/message.h>
136 #include "routine.h"
137 #include "write.h"
138 #include "global.h"
139 #include "routine.h"
140 #include "utils.h"
141 #include "alloc.h"
142 
143 
144 void
WriteIdentificationString(FILE * file)145 WriteIdentificationString(FILE *file)
146 {
147 
148   fprintf(file, "/*\n");
149   fprintf(file, " * IDENTIFICATION:\n");
150   fprintf(file, " * stub generated %s", GenerationDate);
151     fprintf(file, " * with a MiG generated %s by %s\n", MigGenerationDate, MigMoreData);
152   fprintf(file, " * OPTIONS: \n");
153   if (IsKernelUser)
154     fprintf(file, " *\tKernelUser\n");
155   if (IsKernelServer)
156     fprintf(file, " *\tKernelServer\n");
157   if (!UseMsgRPC)
158     fprintf(file, " *\t-R (no RPC calls)\n");
159   fprintf(file, " */\n");
160 }
161 
162 void
WriteMigExternal(FILE * file)163 WriteMigExternal(FILE *file)
164 {
165   fprintf(file, "#ifdef\tmig_external\n");
166   fprintf(file, "mig_external\n");
167   fprintf(file, "#else\n");
168   fprintf(file, "extern\n");
169   fprintf(file, "#endif\t/* mig_external */\n");
170 }
171 
172 void
WriteMigInternal(FILE * file)173 WriteMigInternal(FILE *file)
174 {
175   fprintf(file, "#ifdef\tmig_internal\n");
176   fprintf(file, "mig_internal\n");
177   fprintf(file, "#else\n");
178   fprintf(file, "static\n");
179   fprintf(file, "#endif\t/* mig_internal */\n");
180 }
181 
182 void
WriteImport(FILE * file,string_t filename)183 WriteImport(FILE *file, string_t filename)
184 {
185   fprintf(file, "#include %s\n", filename);
186 }
187 
188 void
WriteImplImports(FILE * file,statement_t * stats,boolean_t isuser)189 WriteImplImports(FILE *file, statement_t *stats, boolean_t isuser)
190 {
191   register statement_t *stat;
192 
193   for (stat = stats; stat != stNULL; stat = stat->stNext)
194 	switch (stat->stKind)
195 	{
196       case skImport:
197       case skIImport:
198         WriteImport(file, stat->stFileName);
199         break;
200       case skSImport:
201         if (!isuser)
202           WriteImport(file, stat->stFileName);
203         break;
204       case skUImport:
205         if (isuser)
206           WriteImport(file, stat->stFileName);
207         break;
208       case skRoutine:
209       case skDImport:
210         break;
211       default:
212 	    printf("WriteImplImport(): bad statement_kind_t (%d)",
213 			   (int) stat->stKind);
214 		abort();
215     }
216 }
217 
218 void
WriteRCSDecl(FILE * file,identifier_t name,string_t rcs)219 WriteRCSDecl(FILE *file, identifier_t name, string_t rcs)
220 {
221   fprintf(file, "#ifndef\tlint\n");
222   fprintf(file, "#if\tUseExternRCSId\n");
223   fprintf(file, "%s char %s_rcsid[] = %s;\n", (BeAnsiC) ? "const" : "", name, rcs);
224   fprintf(file, "#else\t/* UseExternRCSId */\n");
225   fprintf(file, "static %s char rcsid[] = %s;\n", (BeAnsiC) ? "const" : "", rcs);
226   fprintf(file, "#endif\t/* UseExternRCSId */\n");
227   fprintf(file, "#endif\t/* lint */\n");
228   fprintf(file, "\n");
229 }
230 
231 static void
WriteOneApplDefault(FILE * file,const char * word1,const char * word2,const char * word3)232 WriteOneApplDefault(FILE *file, const char *word1, const char *word2, const char *word3)
233 {
234   char buf[50];
235 
236   sprintf(buf, "__%s%s%s", word1, word2, word3);
237   fprintf(file, "#ifndef\t%s\n", buf);
238   fprintf(file, "#define\t%s(_NUM_, _NAME_)\n", buf);
239   fprintf(file, "#endif\t/* %s */\n", buf);
240   fprintf(file, "\n");
241 }
242 
243 void
WriteApplDefaults(FILE * file,const char * dir)244 WriteApplDefaults(FILE *file, const char *dir)
245 {
246   WriteOneApplDefault(file, "Declare", dir, "Rpc");
247   WriteOneApplDefault(file, "Before", dir, "Rpc");
248   WriteOneApplDefault(file, "After", dir, "Rpc");
249   WriteOneApplDefault(file, "Declare", dir, "Simple");
250   WriteOneApplDefault(file, "Before", dir, "Simple");
251   WriteOneApplDefault(file, "After", dir, "Simple");
252 }
253 
254 void
WriteApplMacro(FILE * file,const char * dir,const char * when,routine_t * rt)255 WriteApplMacro(FILE *file, const char *dir, const char *when, routine_t *rt)
256 {
257     const char *what = (rt->rtOneWay) ? "Simple" : "Rpc";
258 
259     fprintf(file, "\t__%s%s%s(%d, \"%s\")\n",
260 	    when, dir, what, SubsystemBase + rt->rtNumber, rt->rtName);
261 }
262 
263 void
WriteBogusDefines(FILE * file)264 WriteBogusDefines(FILE *file)
265 {
266   fprintf(file, "#ifndef\tmig_internal\n");
267   fprintf(file, "#define\tmig_internal\tstatic __inline__\n");
268   fprintf(file, "#endif\t/* mig_internal */\n");
269   fprintf(file, "\n");
270 
271   fprintf(file, "#ifndef\tmig_external\n");
272   fprintf(file, "#define mig_external\n");
273   fprintf(file, "#endif\t/* mig_external */\n");
274   fprintf(file, "\n");
275 
276   fprintf(file, "#if\t!defined(__MigTypeCheck) && defined(TypeCheck)\n");
277   fprintf(file, "#define\t__MigTypeCheck\t\tTypeCheck\t/* Legacy setting */\n");
278   fprintf(file, "#endif\t/* !defined(__MigTypeCheck) */\n");
279   fprintf(file, "\n");
280 
281   fprintf(file, "#if\t!defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_)\n");
282   fprintf(file, "#define\t__MigKernelSpecificCode\t_MIG_KERNEL_SPECIFIC_CODE_\t/* Legacy setting */\n");
283   fprintf(file, "#endif\t/* !defined(__MigKernelSpecificCode) */\n");
284   fprintf(file, "\n");
285 
286   fprintf(file, "#ifndef\tLimitCheck\n");
287   fprintf(file, "#define\tLimitCheck 0\n");
288   fprintf(file, "#endif\t/* LimitCheck */\n");
289   fprintf(file, "\n");
290 
291   fprintf(file, "#ifndef\tmin\n");
292   fprintf(file, "#define\tmin(a,b)  ( ((a) < (b))? (a): (b) )\n");
293   fprintf(file, "#endif\t/* min */\n");
294   fprintf(file, "\n");
295 
296   fprintf(file, "#if !defined(_WALIGN_)\n");
297   fprintf(file, "#define _WALIGN_(x) (((x) + %d) & ~%d)\n", (int)(itWordAlign - 1), (int)(itWordAlign - 1));
298   fprintf(file, "#endif /* !defined(_WALIGN_) */\n");
299   fprintf(file, "\n");
300 
301   fprintf(file, "#if !defined(_WALIGNSZ_)\n");
302   fprintf(file, "#define _WALIGNSZ_(x) _WALIGN_(sizeof(x))\n");
303   fprintf(file, "#endif /* !defined(_WALIGNSZ_) */\n");
304   fprintf(file, "\n");
305 
306   fprintf(file, "#ifndef\tUseStaticTemplates\n");
307   if (BeAnsiC) {
308         fprintf(file, "#define\tUseStaticTemplates\t1\n");
309     } else {
310     fprintf(file, "#if\t%s\n", NewCDecl);
311         fprintf(file, "#define\tUseStaticTemplates\t1\n");
312     fprintf(file, "#endif\t/* %s */\n", NewCDecl);
313   }
314   fprintf(file, "#endif\t/* UseStaticTemplates */\n");
315   fprintf(file, "\n");
316 
317     fprintf(file, "#define _WALIGN_(x) (((x) + %ld) & ~%ld)\n",
318 	    itWordAlign - 1, itWordAlign - 1);
319     fprintf(file, "#define _WALIGNSZ_(x) _WALIGN_(sizeof(x))\n");
320 }
321 
322 void
WriteList(FILE * file,argument_t * args,void (* func)(),u_int mask,const char * between,const char * after)323 WriteList(FILE *file, argument_t *args, void (*func)(), u_int mask, const char *between, const char *after)
324 {
325 	argument_t *arg;
326 	boolean_t sawone = FALSE;
327 
328 	for (arg = args; arg != argNULL; arg = arg->argNext) {
329 		if (akCheckAll(arg->argKind, mask)) {
330 			if (sawone)
331 				fprintf(file, "%s", between);
332 			sawone = TRUE;
333 
334 			(*func)(file, arg);
335 		}
336 	}
337 	if (sawone)
338 		fprintf(file, "%s", after);
339 }
340 
341 static boolean_t
WriteReverseListPrim(FILE * file,argument_t * arg,void (* func)(),u_int mask,const char * between)342 WriteReverseListPrim(FILE *file, argument_t *arg, void (*func)(), u_int mask, const char *between)
343 {
344   boolean_t sawone = FALSE;
345 
346     if (arg != argNULL)
347     {
348     sawone = WriteReverseListPrim(file, arg->argNext, func, mask, between);
349 
350 	if (akCheckAll(arg->argKind, mask))
351 	{
352       if (sawone)
353         fprintf(file, "%s", between);
354       sawone = TRUE;
355 
356       (*func)(file, arg);
357     }
358   }
359 
360   return sawone;
361 }
362 
363 void
WriteReverseList(FILE * file,argument_t * args,void (* func)(),u_int mask,const char * between,const char * after)364 WriteReverseList(FILE *file, argument_t *args, void (*func)(), u_int mask, const char *between, const char *after)
365 {
366   boolean_t sawone;
367 
368   sawone = WriteReverseListPrim(file, args, func, mask, between);
369 
370   if (sawone)
371     fprintf(file, "%s", after);
372 }
373 
374 void
WriteNameDecl(FILE * file,argument_t * arg)375 WriteNameDecl(FILE *file, argument_t *arg)
376 {
377   fprintf(file, "%s", arg->argVarName);
378 }
379 
380 void
WriteUserVarDecl(FILE * file,argument_t * arg)381 WriteUserVarDecl(FILE *file, argument_t *arg)
382 {
383   boolean_t pointer = (arg->argByReferenceUser ||arg->argType->itNativePointer);
384   const char *ref = (pointer) ? "*" : "";
385   const char *cnst = ((arg->argFlags & flConst) &&
386                 (IS_VARIABLE_SIZED_UNTYPED(arg->argType) ||
387                  arg->argType->itNoOptArray || arg->argType->itString)) ? "const " : "";
388 
389   fprintf(file, "\t%s%s %s%s", cnst, arg->argType->itUserType, ref, arg->argVarName);
390 }
391 
392 void
WriteServerVarDecl(FILE * file,argument_t * arg)393 WriteServerVarDecl(FILE *file, argument_t *arg)
394 {
395     const char *ref = (arg->argByReferenceServer ||
396                arg->argType->itNativePointer) ? "*" : "";
397 	const char *cnst = ((arg->argFlags & flConst) &&
398                 (IS_VARIABLE_SIZED_UNTYPED(arg->argType) ||
399                  arg->argType->itNoOptArray || arg->argType->itString)) ? "const " : "";
400 
401   fprintf(file, "\t%s%s %s%s", cnst, arg->argType->itTransType, ref, arg->argVarName);
402 }
403 
404 const char *
ReturnTypeStr(routine_t * rt)405 ReturnTypeStr(routine_t *rt)
406 {
407   return rt->rtRetCode->argType->itUserType;
408 }
409 
410 const char *
FetchUserType(ipc_type_t * it)411 FetchUserType(ipc_type_t *it)
412 {
413   return it->itUserType;
414 }
415 
416 const char *
FetchServerType(ipc_type_t * it)417 FetchServerType(ipc_type_t *it)
418 {
419   return it->itServerType;
420 }
421 
422 const char *
FetchKPDType(ipc_type_t * it)423 FetchKPDType(ipc_type_t *it)
424 {
425   return it->itKPDType;
426 }
427 
428 static void
WriteTrailerDecl(FILE * file,boolean_t trailer)429 WriteTrailerDecl(FILE *file, boolean_t trailer)
430 {
431   if (trailer)
432     fprintf(file, "\t\tmach_msg_max_trailer_t trailer;\n");
433   else
434     fprintf(file, "\t\tmach_msg_trailer_t trailer;\n");
435 }
436 
437 void
WriteFieldDeclPrim(FILE * file,argument_t * arg,const char * (* tfunc)(ipc_type_t *))438 WriteFieldDeclPrim(FILE *file, argument_t *arg, const char *(*tfunc)(ipc_type_t *))
439 {
440   register ipc_type_t *it = arg->argType;
441 
442   if (IS_VARIABLE_SIZED_UNTYPED(it) || it->itNoOptArray) {
443     register argument_t *count = arg->argCount;
444     register ipc_type_t *btype = it->itElement;
445 
446     /*
447      * Build our own declaration for a varying array:
448      * use the element type and maximum size specified.
449      * Note arg->argCount->argMultiplier == btype->itNumber.
450      */
451     /*
452      * NDR encoded VarStrings requires the offset field.
453      * Since it is not used, it wasn't worthwhile to create an extra
454      * parameter
455      */
456     if (it->itString)
457 		fprintf(file, "\t\t%s %sOffset; /* MiG doesn't use it */\n",
458 				(*tfunc)(count->argType), arg->argName);
459 
460     if (!(arg->argFlags & flSameCount) && !it->itNoOptArray)
461     /* in these cases we would have a count, which we don't want */
462 		fprintf(file, "\t\t%s %s;\n", (*tfunc)(count->argType),
463 		    count->argMsgField);
464 	fprintf(file, "\t\t%s %s[%d];",
465 			(*tfunc)(btype),
466 			arg->argMsgField,
467 			it->itNumber/btype->itNumber);
468   }
469   else if (IS_MULTIPLE_KPD(it))
470 	fprintf(file, "\t\t%s %s[%d];", (*tfunc)(it), arg->argMsgField,
471 			it->itKPD_Number);
472   else if (IS_OPTIONAL_NATIVE(it)) {
473     fprintf(file, "\t\tboolean_t __Present__%s;\n",  arg->argMsgField);
474     fprintf(file, "\t\tunion {\n");
475 	fprintf(file, "\t\t    %s __Real__%s;\n",
476 		(*tfunc)(it), arg->argMsgField);
477 	fprintf(file, "\t\t    char __Phony__%s[_WALIGNSZ_(%s)];\n",
478 		arg->argMsgField, (*tfunc)(it));
479     fprintf(file, "\t\t} %s;", arg->argMsgField);
480   }
481   else  {
482     /* either simple KPD or simple in-line */
483     fprintf(file, "\t\t%s %s;", (*tfunc)(it), arg->argMsgField);
484   }
485 
486   /* Kernel Processed Data has always PadSize = 0 */
487   if (it->itPadSize != 0)
488     fprintf(file, "\n\t\tchar %s[%d];", arg->argPadName, it->itPadSize);
489 }
490 
491 void
WriteKPDFieldDecl(FILE * file,argument_t * arg)492 WriteKPDFieldDecl(FILE *file, argument_t *arg)
493 {
494   if (akCheck(arg->argKind, akbSendKPD) ||
495       akCheck(arg->argKind, akbReturnKPD))
496     WriteFieldDeclPrim(file, arg, FetchKPDType);
497   else
498     WriteFieldDeclPrim(file, arg, FetchServerType);
499 }
500 
501 void
WriteStructDecl(FILE * file,argument_t * args,void (* func)(),u_int mask,const char * name,boolean_t simple,boolean_t trailer,boolean_t trailer_t,boolean_t template_only)502 WriteStructDecl(FILE *file, argument_t *args, void (*func)(), u_int mask,
503 				const char *name, boolean_t simple, boolean_t trailer,
504 				boolean_t trailer_t, boolean_t template_only)
505 {
506   fprintf(file, "\n#ifdef  __MigPackStructs\n#pragma pack(%lu)\n#endif\n",sizeof(natural_t));
507   fprintf(file, "\ttypedef struct {\n");
508   fprintf(file, "\t\tmach_msg_header_t Head;\n");
509   if (simple == FALSE) {
510     fprintf(file, "\t\t/* start of the kernel processed data */\n");
511     fprintf(file, "\t\tmach_msg_body_t msgh_body;\n");
512     if (mask == akbRequest)
513       WriteList(file, args, func, mask | akbSendKPD, "\n", "\n");
514     else
515       WriteList(file, args, func, mask | akbReturnKPD, "\n", "\n");
516     fprintf(file, "\t\t/* end of the kernel processed data */\n");
517   }
518   if (!template_only) {
519     if (mask == akbRequest)
520       WriteList(file, args, func, mask | akbSendBody, "\n", "\n");
521 
522     else
523       WriteList(file, args, func, mask | akbReturnBody, "\n", "\n");
524     if (trailer)
525       WriteTrailerDecl(file, trailer_t);
526   }
527   fprintf(file, "\t} %s;\n", name);
528   fprintf(file, "#ifdef  __MigPackStructs\n#pragma pack()\n#endif\n");
529 }
530 
531 void
WriteTemplateDeclIn(FILE * file,register argument_t * arg)532 WriteTemplateDeclIn(FILE *file, register argument_t *arg)
533 {
534   (*arg->argKPD_Template)(file, arg, TRUE);
535 }
536 
537 void
WriteTemplateDeclOut(FILE * file,register argument_t * arg)538 WriteTemplateDeclOut(FILE *file, register argument_t *arg)
539 {
540   (*arg->argKPD_Template)(file, arg, FALSE);
541 }
542 
543 void
WriteTemplateKPD_port(FILE * file,argument_t * arg,boolean_t in)544 WriteTemplateKPD_port(FILE *file, argument_t *arg, boolean_t in)
545 {
546   register ipc_type_t *it = arg->argType;
547 
548   fprintf(file, "#if\tUseStaticTemplates\n");
549   fprintf(file, "\tconst static %s %s = {\n", it->itKPDType, arg->argTTName);
550 
551   fprintf(file, "\t\t.name = MACH_PORT_NULL,\n");
552   fprintf(file, "\t\t.disposition = %s,\n", in ? it->itInNameStr: it->itOutNameStr);
553   fprintf(file, "\t\t.type = MACH_MSG_PORT_DESCRIPTOR,\n");
554 
555   fprintf(file, "\t};\n");
556   fprintf(file, "#endif\t/* UseStaticTemplates */\n");
557 }
558 
559 void
WriteTemplateKPD_ool(FILE * file,argument_t * arg,boolean_t in __unused)560 WriteTemplateKPD_ool(FILE *file, argument_t *arg, boolean_t in __unused)
561 {
562   register ipc_type_t *it = arg->argType;
563 
564   fprintf(file, "#if\tUseStaticTemplates\n");
565   fprintf(file, "\tconst static %s %s = {\n", it->itKPDType, arg->argTTName);
566 
567   if (IS_MULTIPLE_KPD(it))
568     it = it->itElement;
569 
570   fprintf(file, "\t\t.address = (void *)0,\n");
571   if (it->itVarArray)
572     fprintf(file, "\t\t.size = 0,\n");
573   else
574 	fprintf(file, "\t\t.size = %d,\n",
575 	    (it->itNumber * it->itSize + 7)/8);
576     fprintf(file, "\t\t.deallocate = %s,\n",
577 	(arg->argDeallocate == d_YES) ? "TRUE" : "FALSE");
578   /* the d_MAYBE case will be fixed runtime */
579     fprintf(file, "\t\t.copy = %s,\n",
580 	(arg->argFlags & flPhysicalCopy) ? "MACH_MSG_PHYSICAL_COPY" : "MACH_MSG_VIRTUAL_COPY");
581   /* the PHYSICAL COPY flag has not been established yet */
582   fprintf(file, "\t\t.type = MACH_MSG_OOL_DESCRIPTOR,\n");
583 
584   fprintf(file, "\t};\n");
585   fprintf(file, "#endif\t/* UseStaticTemplates */\n");
586 }
587 
588 void
WriteTemplateKPD_oolport(FILE * file,argument_t * arg,boolean_t in)589 WriteTemplateKPD_oolport(FILE *file, argument_t *arg, boolean_t in)
590 {
591   register ipc_type_t *it = arg->argType;
592 
593   fprintf(file, "#if\tUseStaticTemplates\n");
594   fprintf(file, "\tconst static %s %s = {\n", it->itKPDType, arg->argTTName);
595 
596   if (IS_MULTIPLE_KPD(it))
597     it = it->itElement;
598 
599   fprintf(file, "\t\t.address = (void *)0,\n");
600   if (!it->itVarArray)
601 	fprintf(file, "\t\t.count = %d,\n",
602 	    it->itNumber);
603   else
604     fprintf(file, "\t\t.count = 0,\n");
605     fprintf(file, "\t\t.deallocate = %s,\n",
606         (arg->argDeallocate == d_YES) ? "TRUE" : "FALSE");
607   fprintf(file, "\t\t/* copy is meaningful only in overwrite mode */\n");
608   fprintf(file, "\t\t.copy = MACH_MSG_PHYSICAL_COPY,\n");
609     fprintf(file, "\t\t.disposition = %s,\n",
610 	in ? it->itInNameStr: it->itOutNameStr);
611   fprintf(file, "\t\t.type = MACH_MSG_OOL_PORTS_DESCRIPTOR,\n");
612 
613   fprintf(file, "\t};\n");
614   fprintf(file, "#endif\t/* UseStaticTemplates */\n");
615 }
616 
617 void
WriteReplyTypes(FILE * file,statement_t * stats)618 WriteReplyTypes(FILE *file, statement_t *stats)
619 {
620   register statement_t *stat;
621 
622   fprintf(file, "/* typedefs for all replies */\n\n");
623   fprintf(file, "#ifndef __Reply__%s_subsystem__defined\n", SubsystemName);
624   fprintf(file, "#define __Reply__%s_subsystem__defined\n", SubsystemName);
625   for (stat = stats; stat != stNULL; stat = stat->stNext) {
626     if (stat->stKind == skRoutine) {
627       register routine_t *rt;
628       char str[MAX_STR_LEN];
629 
630       rt = stat->stRoutine;
631       sprintf(str, "__Reply__%s_t", rt->rtName);
632       WriteStructDecl(file, rt->rtArgs, WriteKPDFieldDecl, akbReply, str, rt->rtSimpleReply, FALSE, FALSE, FALSE);
633     }
634   }
635   fprintf(file, "#endif /* !__Reply__%s_subsystem__defined */\n", SubsystemName);
636   fprintf(file, "\n");
637 }
638 
639 void
WriteRequestTypes(FILE * file,statement_t * stats)640 WriteRequestTypes(FILE *file, statement_t *stats)
641 {
642   register statement_t *stat;
643 
644   fprintf(file, "/* typedefs for all requests */\n\n");
645   fprintf(file, "#ifndef __Request__%s_subsystem__defined\n", SubsystemName);
646   fprintf(file, "#define __Request__%s_subsystem__defined\n", SubsystemName);
647   for (stat = stats; stat != stNULL; stat = stat->stNext) {
648     if (stat->stKind == skRoutine) {
649       register routine_t *rt;
650       char str[MAX_STR_LEN];
651 
652       rt = stat->stRoutine;
653       sprintf(str, "__Request__%s_t", rt->rtName);
654       WriteStructDecl(file, rt->rtArgs, WriteKPDFieldDecl, akbRequest, str, rt->rtSimpleRequest, FALSE, FALSE, FALSE);
655     }
656   }
657   fprintf(file, "#endif /* !__Request__%s_subsystem__defined */\n", SubsystemName);
658   fprintf(file, "\n");
659 }
660 
661 void
WriteNDRConvertArgDecl(FILE * file,argument_t * arg,const char * convert,const char * dir)662 WriteNDRConvertArgDecl(FILE *file, argument_t *arg, const char *convert, const char *dir)
663 {
664   argument_t *count = arg->argCount;
665   argument_t *parent = arg->argParent;
666   const char *carg = (count) ? ", c" : "";
667   routine_t *rt = arg->argRoutine;
668   ipc_type_t *ptype = arg->argType;
669   ipc_type_t *btype;
670   int multi, array;
671   char domain[MAX_STR_LEN];
672 
673   fprintf(file, "#ifndef __NDR_convert__%s__%s__%s_t__%s__defined\n#", convert, dir, rt->rtName, arg->argMsgField);
674 
675   for (btype = ptype, multi = (!parent) ? arg->argMultiplier : 1, array = 0;
676        btype;
677        ptype = btype, array += ptype->itVarArray, btype = btype->itElement) {
678 	  const char *bttype;
679 
680     if (btype->itNumber < ptype->itNumber && !ptype->itVarArray && !parent) {
681       multi *= ptype->itNumber / btype->itNumber;
682       if (!btype->itString)
683         continue;
684     }
685     else if (array && ptype->itVarArray)
686       continue;
687     if (btype != ptype)
688       fprintf(file, "#el");
689 
690     bttype = (multi > 1 && btype->itString) ? "string" : FetchServerType(btype);
691     sprintf(domain, "__%s", SubsystemName);
692     do {
693       fprintf(file, "if\tdefined(__NDR_convert__%s%s__%s__defined)\n", convert, domain, bttype);
694       fprintf(file, "#define\t__NDR_convert__%s__%s__%s_t__%s__defined\n", convert, dir, rt->rtName, arg->argMsgField);
695       fprintf(file, "#define\t__NDR_convert__%s__%s__%s_t__%s(a, f%s) \\\n\t", convert, dir, rt->rtName, arg->argMsgField, carg);
696       if (multi > 1) {
697         if (array) {
698           if (btype->itString)
699             fprintf(file, "__NDR_convert__2DARRAY((%s *)(a), f, %d, c, ", bttype, multi);
700           else
701             fprintf(file, "__NDR_convert__ARRAY((%s *)(a), f, %d * (c), ", bttype, multi);
702         }
703         else if (!btype->itString)
704           fprintf(file, "__NDR_convert__ARRAY((%s *)(a), f, %d, ", bttype, multi);
705       }
706       else if (array)
707         fprintf(file, "__NDR_convert__ARRAY((%s *)(a), f, c, ", bttype);
708       fprintf(file, "__NDR_convert__%s%s__%s", convert, domain, bttype);
709       if (multi > 1) {
710         if (!array && btype->itString)
711           fprintf(file, "(a, f, %d", multi);
712       }
713       else if (!array)
714         fprintf(file, "((%s *)(a), f%s", bttype, carg);
715       fprintf(file, ")\n");
716     } while (strcmp(domain, "") && (domain[0] = '\0', fprintf(file, "#el")));
717   }
718   fprintf(file, "#endif /* defined(__NDR_convert__*__defined) */\n");
719   fprintf(file, "#endif /* __NDR_convert__%s__%s__%s_t__%s__defined */\n\n", convert, dir, rt->rtName, arg->argMsgField);
720 }
721 
722 /*
723  * Like vfprintf, but omits a leading comment in the format string
724  * and skips the items that would be printed by it.  Only %s, %d,
725  * and %f are recognized.
726  */
727 static void
SkipVFPrintf(FILE * file,const char * fmt,va_list pvar)728 SkipVFPrintf(FILE *file, const char *fmt, va_list pvar)
729 {
730   if (*fmt == 0)
731     return; /* degenerate case */
732 
733   if (fmt[0] == '/' && fmt[1] == '*') {
734     /* Format string begins with C comment.  Scan format
735        string until end-comment delimiter, skipping the
736        items in pvar that the enclosed format items would
737        print. */
738 
739     register int c;
740 
741     fmt += 2;
742     for (;;) {
743       c = *fmt++;
744       if (c == 0)
745         return; /* nothing to format */
746       if (c == '*') {
747         if (*fmt == '/') {
748           break;
749         }
750       }
751       else if (c == '%') {
752         /* Field to skip */
753         c = *fmt++;
754         switch (c) {
755 
756           case 's':
757             (void) va_arg(pvar, char *);
758             break;
759 
760           case 'd':
761             (void) va_arg(pvar, int);
762             break;
763 
764           case 'f':
765             (void) va_arg(pvar, double);
766             break;
767 
768           case '\0':
769             return; /* error - fmt ends with '%' */
770 
771           default:
772             break;
773         }
774       }
775     }
776     /* End of comment.  To be pretty, skip
777      the space that follows. */
778     fmt++;
779     if (*fmt == ' ')
780       fmt++;
781   }
782 
783   /* Now format the string. */
784   (void) vfprintf(file, fmt, pvar);
785 }
786 
787 static void
vWriteCopyType(FILE * file,ipc_type_t * it,const char * left,const char * right,va_list pvar)788 vWriteCopyType(FILE *file, ipc_type_t *it, const char *left, const char *right, va_list pvar)
789 {
790   va_list pv2;
791   va_copy(pv2,pvar);
792     if (it->itStruct)
793     {
794     fprintf(file, "\t");
795     (void) SkipVFPrintf(file, left, pvar);
796     fprintf(file, " = ");
797 	(void) SkipVFPrintf(file, right, pv2);
798     fprintf(file, ";\n");
799   }
800     else if (it->itString)
801     {
802     fprintf(file, "\t(void) mig_strncpy(");
803     (void) SkipVFPrintf(file, left, pvar);
804     fprintf(file, ", ");
805 	(void) SkipVFPrintf(file, right, pv2);
806     fprintf(file, ", %d);\n", it->itTypeSize);
807   }
808     else
809     {
810 	fprintf(file, "\t{   typedef struct { char data[%d]; } *sp;\n",
811 		it->itTypeSize);
812     fprintf(file, "\t    * (sp) ");
813     (void) SkipVFPrintf(file, left, pvar);
814     fprintf(file, " = * (sp) ");
815 	(void) SkipVFPrintf(file, right, pv2);
816     fprintf(file, ";\n\t}\n");
817   }
818 
819   va_end(pv2);
820 }
821 
822 
823 /*ARGSUSED*/
824 /*VARARGS4*/
825 void
WriteCopyType(FILE * file,ipc_type_t * it,const char * left,const char * right,...)826 WriteCopyType(FILE *file, ipc_type_t *it, const char *left, const char *right, ...)
827 {
828   va_list pvar;
829   va_start(pvar, right);
830 
831   vWriteCopyType(file, it, left, right, pvar);
832 
833   va_end(pvar);
834 }
835 
836 
837 /*ARGSUSED*/
838 /*VARARGS4*/
839 void
WriteCopyArg(FILE * file,argument_t * arg,const char * left,const char * right,...)840 WriteCopyArg(FILE *file, argument_t *arg, const char *left, const char *right, ...)
841 {
842   va_list pvar;
843   va_start(pvar, right);
844 
845   {
846     ipc_type_t *it = arg->argType;
847     if (it->itVarArray && !it->itString) {
848       fprintf(file, "\t    (void)memcpy(");
849       (void) SkipVFPrintf(file, left, pvar);
850 	  va_end(pvar);
851       fprintf(file, ", ");
852 	  va_start(pvar, right);
853 	  (void) SkipVFPrintf(file, right, pvar);
854       fprintf(file, ", %s);\n", arg->argCount->argVarName);
855 	} else
856       vWriteCopyType(file, it, left, right, pvar);
857   }
858 
859   va_end(pvar);
860 }
861 
862 
863 /*
864  * Global KPD disciplines
865  */
866 void
KPD_error(FILE * file __unused,argument_t * arg)867 KPD_error(FILE *file __unused, argument_t *arg)
868 {
869   printf("MiG internal error: argument is %s\n", arg->argVarName);
870   exit(1);
871 }
872 
873 void
KPD_noop(FILE * file __unused,argument_t * arg __unused)874 KPD_noop(FILE *file __unused, argument_t *arg __unused)
875 {
876 }
877 
878 static void
WriteStringDynArgs(args,mask,InPOutP,str_oolports,str_ool)879 WriteStringDynArgs(args, mask, InPOutP, str_oolports, str_ool)
880     argument_t *args;
881     u_int	mask;
882     string_t 	InPOutP;
883     string_t 	*str_oolports, *str_ool;
884 {
885   argument_t *arg;
886   char loc[100], sub[20];
887   string_t tmp_str1 = "";
888   string_t tmp_str2 = "";
889   int cnt, multiplier = 1;
890   boolean_t test, complex = FALSE;
891 
892   for (arg = args; arg != argNULL; arg = arg->argNext) {
893     ipc_type_t *it = arg->argType;
894 
895     if (IS_MULTIPLE_KPD(it)) {
896       test = it->itVarArray || it->itElement->itVarArray;
897       if (test) {
898         multiplier = it->itKPD_Number;
899         it = it->itElement;
900         complex = TRUE;
901       }
902 	} else
903       test = it->itVarArray;
904 
905     cnt = multiplier;
906     while (cnt) {
907       if (complex)
908         sprintf(sub, "[%d]", multiplier - cnt);
909       if (akCheck(arg->argKind, mask) &&
910           it->itPortType && !it->itInLine && test) {
911 		    sprintf(loc, " + %s->%s%s.count", InPOutP, arg->argMsgField,
912 		        complex ? sub : "");
913         tmp_str1 = strconcat(tmp_str1, loc);
914       }
915       if (akCheck(arg->argKind, mask) &&
916           !it->itInLine && !it->itPortType && test) {
917 	 	    sprintf(loc, " + %s->%s%s.size", InPOutP, arg->argMsgField,
918 		        complex ? sub : "");
919         tmp_str2 = strconcat(tmp_str2, loc);
920       }
921       cnt--;
922     }
923   }
924   *str_oolports = tmp_str1;
925   *str_ool = tmp_str2;
926 }
927 
928 /*
929  * Utilities for Logging Events that happen at the stub level
930  */
931 void
WriteLogMsg(FILE * file,routine_t * rt,boolean_t where,boolean_t what)932 WriteLogMsg(FILE *file, routine_t *rt, boolean_t where, boolean_t what)
933 {
934   string_t ptr_str;
935   string_t StringOolPorts = strNULL;
936   string_t StringOOL = strNULL;
937   u_int ports, oolports, ool;
938   string_t event;
939 
940   fprintf(file, "\n#if  MIG_DEBUG\n");
941   if (where == LOG_USER)
942     fprintf(file, "\tLOG_TRACE(MACH_MSG_LOG_USER,\n");
943   else
944     fprintf(file, "\tLOG_TRACE(MACH_MSG_LOG_SERVER,\n");
945   if (where == LOG_USER && what == LOG_REQUEST) {
946     ptr_str = "InP";
947     event = "MACH_MSG_REQUEST_BEING_SENT";
948     } else if (where == LOG_USER && what == LOG_REPLY) {
949     ptr_str = "Out0P";
950     event = "MACH_MSG_REPLY_BEING_RCVD";
951     } else if (where == LOG_SERVER && what == LOG_REQUEST) {
952     ptr_str = "In0P";
953     event = "MACH_MSG_REQUEST_BEING_RCVD";
954     } else {
955     ptr_str = "OutP";
956     event = "MACH_MSG_REPLY_BEING_SENT";
957   }
958     WriteStringDynArgs(rt->rtArgs,
959 	(what == LOG_REQUEST) ? akbSendKPD : akbReturnKPD,
960 	ptr_str, &StringOolPorts, &StringOOL);
961   fprintf(file, "\t\t%s,\n", event);
962   fprintf(file, "\t\t%s->Head.msgh_id,\n", ptr_str);
963   if (where == LOG_USER && what == LOG_REQUEST) {
964     if (rt->rtNumRequestVar)
965       fprintf(file, "\t\tmsgh_size,\n");
966     else
967 	    fprintf(file, "\t\tsizeof(Request),\n");
968     } else
969     fprintf(file, "\t\t%s->Head.msgh_size,\n", ptr_str);
970   if ((what == LOG_REQUEST && rt->rtSimpleRequest == FALSE) ||
971       (what == LOG_REPLY && rt->rtSimpleReply == FALSE))
972     fprintf(file, "\t\t%s->msgh_body.msgh_descriptor_count,\n", ptr_str);
973   else
974     fprintf(file, "\t\t0, /* Kernel Proc. Data entries */\n");
975   if (what == LOG_REQUEST) {
976     fprintf(file, "\t\t0, /* RetCode */\n");
977     ports = rt->rtCountPortsIn;
978     oolports = rt->rtCountOolPortsIn;
979     ool = rt->rtCountOolIn;
980     } else {
981     if (akCheck(rt->rtRetCode->argKind, akbReply))
982       fprintf(file, "\t\t%s->RetCode,\n", ptr_str);
983     else
984       fprintf(file, "\t\t0, /* RetCode */\n");
985     ports = rt->rtCountPortsOut;
986     oolports = rt->rtCountOolPortsOut;
987     ool = rt->rtCountOolOut;
988   }
989   fprintf(file, "\t\t/* Ports */\n");
990   fprintf(file, "\t\t%d,\n", ports);
991   fprintf(file, "\t\t/* Out-of-Line Ports */\n");
992   fprintf(file, "\t\t%d", oolports);
993   if (StringOolPorts != strNULL)
994     fprintf(file, "%s,\n", StringOolPorts);
995   else
996     fprintf(file, ",\n");
997   fprintf(file, "\t\t/* Out-of-Line Bytes */\n");
998   fprintf(file, "\t\t%d", ool);
999   if (StringOOL != strNULL)
1000     fprintf(file, "%s,\n", StringOOL);
1001   else
1002     fprintf(file, ",\n");
1003   fprintf(file, "\t\t__FILE__, __LINE__);\n");
1004   fprintf(file, "#endif /* MIG_DEBUG */\n\n");
1005 }
1006 
1007 void
WriteLogDefines(FILE * file,string_t who)1008 WriteLogDefines(FILE *file, string_t who)
1009 {
1010   fprintf(file, "#if  MIG_DEBUG\n");
1011   fprintf(file, "#define LOG_W_E(X)\tLOG_ERRORS(%s, \\\n", who);
1012   fprintf(file, "\t\t\tMACH_MSG_ERROR_WHILE_PARSING, (void *)(X), __FILE__, __LINE__)\n");
1013   fprintf(file, "#else  /* MIG_DEBUG */\n");
1014   fprintf(file, "#define LOG_W_E(X)\n");
1015   fprintf(file, "#endif /* MIG_DEBUG */\n");
1016   fprintf(file, "\n");
1017 }
1018 
1019 /* common utility to report errors */
1020 void
WriteReturnMsgError(FILE * file,routine_t * rt,boolean_t isuser,argument_t * arg,string_t error)1021 WriteReturnMsgError(FILE *file, routine_t *rt, boolean_t isuser, argument_t *arg, string_t error)
1022 {
1023   char space[MAX_STR_LEN];
1024   char * string = &space[0];
1025 
1026   if (UseEventLogger && arg != argNULL)
1027     sprintf(string, "LOG_W_E(\"%s\"); ", arg->argVarName);
1028   else
1029 	  string = __DECONST(char *, "");
1030 
1031   fprintf(file, "\t\t{ ");
1032 
1033   if (isuser) {
1034     if (! rtMessOnStack(rt))
1035 		fprintf(file, "%s((char *) Mess, sizeof(*Mess)); ", MessFreeRoutine);
1036 
1037     fprintf(file, "%sreturn %s; }\n", string, error);
1038   }
1039   else
1040     fprintf(file, "%sMIG_RETURN_ERROR(OutP, %s); }\n", string, error);
1041 }
1042 
1043 /* executed iff elements are defined */
1044 void
WriteCheckTrailerHead(FILE * file,routine_t * rt __unused,boolean_t isuser)1045 WriteCheckTrailerHead(FILE *file, routine_t *rt __unused, boolean_t isuser)
1046 {
1047   string_t who = (isuser) ? "Out0P" : "In0P";
1048 
1049   fprintf(file, "\tTrailerP = (mach_msg_max_trailer_t *)((vm_offset_t)%s +\n", who);
1050   fprintf(file, "\t\tround_msg(%s->Head.msgh_size));\n", who);
1051   fprintf(file, "\tif (TrailerP->msgh_trailer_type != MACH_MSG_TRAILER_FORMAT_0)\n");
1052   if (isuser)
1053     fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
1054   else
1055     fprintf(file, "\t\t{ MIG_RETURN_ERROR(%s, MIG_TRAILER_ERROR); }\n", who);
1056 
1057   fprintf(file, "#if\t__MigTypeCheck\n");
1058   fprintf(file, "\ttrailer_size = TrailerP->msgh_trailer_size -\n");
1059   fprintf(file, "\t\t(mach_msg_size_t)(sizeof(mach_msg_trailer_type_t) - sizeof(mach_msg_trailer_size_t));\n");
1060   fprintf(file, "#endif\t/* __MigTypeCheck */\n");
1061 }
1062 
1063 /* executed iff elements are defined */
1064 void
WriteCheckTrailerSize(FILE * file,boolean_t isuser,register argument_t * arg)1065 WriteCheckTrailerSize(FILE *file, boolean_t isuser, register argument_t *arg)
1066 {
1067   fprintf(file, "#if\t__MigTypeCheck\n");
1068   if (akIdent(arg->argKind) == akeMsgSeqno) {
1069     fprintf(file, "\tif (trailer_size < (mach_msg_size_t)sizeof(mach_port_seqno_t))\n");
1070     if (isuser)
1071       fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
1072     else
1073       fprintf(file, "\t\t{ MIG_RETURN_ERROR(OutP, MIG_TRAILER_ERROR); }\n");
1074     fprintf(file, "\ttrailer_size -= (mach_msg_size_t)sizeof(mach_port_seqno_t);\n");
1075   }
1076   else if (akIdent(arg->argKind) == akeSecToken) {
1077     fprintf(file, "\tif (trailer_size < (mach_msg_size_t)sizeof(security_token_t))\n");
1078     if (isuser)
1079       fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
1080     else
1081       fprintf(file, "\t\t{ MIG_RETURN_ERROR(OutP, MIG_TRAILER_ERROR); }\n");
1082     fprintf(file, "\ttrailer_size -= (mach_msg_size_t)sizeof(security_token_t);\n");
1083   }
1084   else if (akIdent(arg->argKind) == akeAuditToken) {
1085     fprintf(file, "\tif (trailer_size < (mach_msg_size_t)sizeof(audit_token_t))\n");
1086     if (isuser)
1087       fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
1088     else
1089       fprintf(file, "\t\t{ MIG_RETURN_ERROR(OutP, MIG_TRAILER_ERROR); }\n");
1090     fprintf(file, "\ttrailer_size -= (mach_msg_size_t)sizeof(audit_token_t);\n");
1091   }
1092   else if (akIdent(arg->argKind) == akeContextToken) {
1093     fprintf(file, "\tif (trailer_size < (mach_msg_size_t)sizeof(mach_vm_address_t))\n");
1094     if (isuser)
1095       fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
1096     else
1097       fprintf(file, "\t\t{ MIG_RETURN_ERROR(OutP, MIG_TRAILER_ERROR); }\n");
1098     fprintf(file, "\ttrailer_size -= (mach_msg_size_t)sizeof(mach_vm_address_t);\n");
1099   }
1100   fprintf(file, "#endif\t/* __MigTypeCheck */\n");
1101 }
1102 
1103