1 /* 2 * Copyright 1991-1998 by Open Software Foundation, Inc. 3 * All Rights Reserved 4 * 5 * Permission to use, copy, modify, and distribute this software and 6 * its documentation for any purpose and without fee is hereby granted, 7 * provided that the above copyright notice appears in all copies and 8 * that both the copyright notice and this permission notice appear in 9 * supporting documentation. 10 * 11 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 12 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 * FOR A PARTICULAR PURPOSE. 14 * 15 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 16 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 18 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 19 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 /* 22 * cmk1.1 23 */ 24 /* 25 * Mach Operating System 26 * Copyright (c) 1991,1990 Carnegie Mellon University 27 * All Rights Reserved. 28 * 29 * Permission to use, copy, modify and distribute this software and its 30 * documentation is hereby granted, provided that both the copyright 31 * notice and this permission notice appear in all copies of the 32 * software, derivative works or modified versions, and any portions 33 * thereof, and that both notices appear in supporting documentation. 34 * 35 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 36 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 37 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 38 * 39 * Carnegie Mellon requests users of this software to return to 40 * 41 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 42 * School of Computer Science 43 * Carnegie Mellon University 44 * Pittsburgh PA 15213-3890 45 * 46 * any improvements or extensions that they make and grant Carnegie Mellon 47 * the rights to redistribute these changes. 48 */ 49 /* 50 * 92/03/03 16:25:12 jeffreyh 51 * Changes from TRUNK 52 * [92/02/26 12:32:23 jeffreyh] 53 * 54 * 92/01/14 16:46:34 rpd 55 * Removed akbWasInOut. Added akeCountInOut, argCInOut. 56 * [92/01/08 rpd] 57 * 58 * 92/01/03 20:29:52 dbg 59 * Add byReferenceUser and byReferenceServer to each argument, so 60 * they can be individually set. Add akbPointer. 61 * [91/09/04 dbg] 62 * 63 * 91/08/28 11:17:17 jsb 64 * Removed Camelot and TrapRoutine support. 65 * Changed MsgKind to MsgSeqno. 66 * [91/08/12 rpd] 67 * 68 * 91/07/31 18:10:37 dbg 69 * Add akbIndefinite, argServerCopy. 70 * [91/04/10 dbg] 71 * 72 * Change argDeallocate to an enumerated type, to allow for 73 * user-specified deallocate flag. 74 * 75 * Add rtCheckMaskFunction. Add rtNoReplyArgs to routine 76 * structure. 77 * [91/04/03 dbg] 78 * 79 * 91/02/05 17:55:28 mrt 80 * Changed to new Mach copyright 81 * [91/02/01 17:55:21 mrt] 82 * 83 * 90/06/02 15:05:23 rpd 84 * Created for new IPC. 85 * [90/03/26 21:12:57 rpd] 86 * 87 * 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University 88 * Extensive revamping. Added polymorphic arguments. 89 * Allow multiple variable-sized inline arguments in messages. 90 * 91 * 20-Dec-87 David Golub (dbg) at Carnegie-Mellon University 92 * Added pointers to last Request and Reply arguments. 93 * Added flag to show that (only) last argument is variable-sized. 94 * Added argMultiplier field for count arguments, where parent 95 * argument is itself a multiple of an IPC type. 96 * 97 * 16-Nov-87 David Golub (dbg) at Carnegie-Mellon University 98 * Don't add akbVarNeeded attribute here - server.c can 99 * better determine whether it is needed. 100 * 101 * 21-Aug-87 Mary Thompson (mrt) at Carnegie-Mellon University 102 * Added argFlag field to argument_t 103 * 104 * 18-Aug-87 Mary Thompson (mrt) at Carnegie-Mellon University 105 * Changed akTid to omit akServerArg 106 * Changed arg_kind_t to u_int to make code more obvious and 107 * to get rid of compiler warnings and to give hc a chance. 108 * Changed flags on akTid, akDummy. 109 * 110 * 10-Aug-87 Mary Thompson (mrt) at Carnegie-Mellon University 111 * Added defines need to make MsgType a legitimate argument type 112 * 113 * 28-May-87 Richard Draves (rpd) at Carnegie-Mellon University 114 * Created. 115 */ 116 117 #ifndef _ROUTINE_H 118 #define _ROUTINE_H 119 120 #include "type.h" 121 #include <mach/message.h> 122 #include <mach/boolean.h> 123 #include <sys/types.h> 124 125 /* base kind arg */ 126 #define akeNone (0) 127 #define akeNormal (1) /* a normal, user-defined argument */ 128 #define akeRequestPort (2) /* pointed at by rtRequestPort */ 129 #define akeWaitTime (3) /* pointed at by rtWaitTime */ 130 #define akeReplyPort (4) /* pointed at by rtReplyPort */ 131 #define akeMsgOption (5) /* pointed at by rtMsgOption */ 132 #define akeMsgSeqno (6) /* pointed at by rtMsgSeqno */ 133 #define akeRetCode (7) /* pointed at by rtRetCode */ 134 #define akeNdrCode (8) /* pointed at by rtNdrCode */ 135 #define akeCount (9) /* a count arg for argParent */ 136 #define akePoly (10) /* a poly arg for argParent */ 137 #define akeDealloc (11) /* a deallocate arg for argParent */ 138 #define akeCountInOut (12) /* a count-in-out arg */ 139 #define akeSameCount (13) /* a samecount case: in fact, a no count! */ 140 #define akeSubCount (14) /* a array of array case: subordinate arrays count */ 141 #define akeImplicit (15) /* an implicit argument, from the trailer */ 142 #define akeSecToken (16) /* an argument from the trailer: the security token */ 143 #define akeAuditToken (17) /* an argument from the trailer: the audit token */ 144 #define akeContextToken (18) /* an argument from the trailer: the context token */ 145 #define akeSendTime (19) /* pointed at by rtWaitTime */ 146 147 148 #define akeBITS (0x0000003f) 149 #define akbRequest (0x00000040) /* has a msg_type in request */ 150 #define akbReply (0x00000080) /* has a msg_type in reply */ 151 #define akbUserArg (0x00000100) /* an arg on user-side */ 152 #define akbServerArg (0x00000200) /* an arg on server-side */ 153 #define akbSend (0x00000400) /* value carried in request */ 154 #define akbSendBody (0x00000800) /* value carried in request body */ 155 #define akbSendSnd (0x00001000) /* value stuffed into request */ 156 #define akbSendRcv (0x00002000) /* value grabbed from request */ 157 #define akbReturn (0x00004000) /* value carried in reply */ 158 #define akbReturnBody (0x00008000) /* value carried in reply body */ 159 #define akbReturnSnd (0x00010000) /* value stuffed into reply */ 160 #define akbReturnRcv (0x00020000) /* value grabbed from reply */ 161 #define akbReturnNdr (0x00040000) /* needs NDR conversion in reply */ 162 #define akbReplyInit (0x00080000) /* reply value doesn't come from target routine */ 163 #define akbReplyCopy (0x00200000) /* copy reply value from request */ 164 #define akbVarNeeded (0x00400000) /* may need local var in server */ 165 #define akbDestroy (0x00800000) /* call destructor function */ 166 #define akbSendNdr (0x04000000) /* needs NDR conversion in request */ 167 #define akbVariable (0x01000000) /* variable size inline data */ 168 #define akbSendKPD (0x08000000) /* the arg is sent in the Kernel Processed Data 169 section of the Request message */ 170 #define akbReturnKPD (0x10000000) /* the arg is sent in the Kernel Processed Data 171 section of the Reply message */ 172 #define akbUserImplicit (0x20000000) /* the arg is Impl */ 173 #define akbServerImplicit (0x40000000) /* the arg is Impl */ 174 #define akbOverwrite (0x80000000) 175 /* be careful, there aren't many bits left */ 176 177 typedef u_int arg_kind_t; 178 179 /* 180 * akbRequest means msg_type/data fields are allocated in the request 181 * msg. akbReply means msg_type/data fields are allocated in the 182 * reply msg. These bits * control msg structure declarations packing, 183 * and checking of mach_msg_type_t fields. 184 * 185 * akbUserArg means this argument is an argument to the user-side stub. 186 * akbServerArg means this argument is an argument to 187 * the server procedure called by the server-side stub. 188 * 189 * The akbSend* and akbReturn* bits control packing/extracting values 190 * in the request and reply messages. 191 * 192 * akbSend means the argument's value is carried in the request msg. 193 * akbSendBody implies akbSend; the value is carried in the msg body. 194 * akbSendKPD is the equivalent of akbSendBody for Kernel Processed Data. 195 * akbSendSnd implies akbSend; the value is stuffed into the request. 196 * akbSendRcv implies akbSend; the value is pulled out of the request. 197 * 198 * akbReturn, akbReturnBody, akbReturnSnd, akbReturnRcv are defined 199 * similarly but apply to the reply message. 200 * 201 * User-side code generation (header.c, user.c) and associated code 202 * should use akbSendSnd and akbReturnRcv, but not akbSendRcv and 203 * akbReturnSnd. Server-side code generation (server.c) is reversed. 204 * Code generation should use the more specific akb{Send,Return}{Snd,Rcv} 205 * bits when possible, instead of akb{Send,Return}. 206 * 207 * Note that akRetCode and akReturn lack any Return bits, although 208 * there is a value in the msg. These guys are packed/unpacked 209 * with special code, unlike other arguments. 210 * 211 * akbReplyInit implies akbReply. It means the server-side stub 212 * should initialize the field, because its value does not come 213 * from the execution of the target routine: the setting of the 214 * NDR record is the sole example (at the moment) of use of this flag. 215 * 216 * akbVariable means the argument has variable-sized inline data. 217 * It isn't currently used for code generation, but routine.c 218 * does use it internally. It is added in rtAugmentArgKind. 219 * 220 * akbReplyCopy and akbVarNeeded help control code generation in the 221 * server-side stub. The preferred method of handling data in the 222 * server-side stub avoids copying into/out-of local variables. In 223 * arguments get passed directly to the server proc from the request msg. 224 * Out arguments get stuffed directly into the reply msg by the server proc. 225 * For InOut arguments, the server proc gets the address of the data in 226 * the request msg, and the resulting data gets copied to the reply msg. 227 * Some arguments need a local variable in the server-side stub. The 228 * code extracts the data from the request msg into the variable, and 229 * stuff the reply msg from the variable. 230 * 231 * akbReplyCopy implies akbReply. It means the data should get copied 232 * from the request msg to the reply msg after the server proc is called. 233 * It is only used by akInOut. akTid doesn't need it because the tid 234 * data in the reply msg is initialized in the server demux function. 235 * 236 * akbVarNeeded means the argument needs a local variable in the 237 * server-side stub. It is added in rtAugmentArgKind and 238 * rtCheckVariable. An argument shouldn't have all three of 239 * akbReturnSnd, akbVarNeeded and akbReplyCopy, because this indicates 240 * the reply msg should be stuffed both ways. 241 * 242 * akbDestroy helps control code generation in the server-side stub. 243 * It means this argument has a destructor function which should be called. 244 * 245 * akbOverwrite is used to identify the arguments that have to put an entry in 246 * the scatter list (the message-template used by the User stub to specify 247 * where the out-of-line data sent by server has to land). 248 * 249 * akbUserImplicit (akbServerImplicit) is used to mark the arguments that 250 * correspond to implicit data (data generated by the kernel and inserted in 251 * the trailer). 252 * 253 * Header file generation (header.c) uses: 254 * akbUserArg 255 * 256 * User stub generation (user.c) uses: 257 * akbUserArg, akbRequest, akbReply, akbSendSnd, 258 * akbSendBody, akbSendKPD, akbReturnRcv, akbOverwrite, akbUserImplicit 259 * 260 * Server stub generation (server.c) uses: 261 * akbServerArg, akbRequest, akbReply, akbSendRcv, akbReturnSnd, 262 * akbReplyCopy, akbVarNeeded, akbSendBody, akbServerImplicit 263 * 264 * 265 * During code generation, the routine, argument, and type data structures 266 * are read-only. The code generation functions' output is their only 267 * side-effect. 268 * 269 * 270 * Style note: 271 * Code can use logical operators (|, &, ~) on akb values. 272 * ak values should be manipulated with the ak functions. 273 */ 274 275 /* various useful combinations */ 276 277 #define akbNone (0) 278 #define akbAll (~akbNone) 279 #define akbAllBits (~akeBITS) 280 281 #define akbSendBits (akbSend|akbSendBody|akbSendSnd|akbSendRcv) 282 #define akbReturnBits (akbReturn|akbReturnBody|akbReturnSnd|akbReturnRcv) 283 #define akbSendReturnBits (akbSendBits|akbReturnBits) 284 285 #define akNone akeNone 286 287 #define akIn akAddFeature(akeNormal, \ 288 akbUserArg|akbServerArg|akbRequest|akbSendBits) 289 290 #define akOut akAddFeature(akeNormal, \ 291 akbUserArg|akbServerArg|akbReply|akbReturnBits) 292 293 #define akServerImpl akAddFeature(akeImplicit, \ 294 akbServerArg|akbServerImplicit|akbSend|akbSendRcv) 295 #define akUserImpl akAddFeature(akeImplicit, \ 296 akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv) 297 298 #define akServerSecToken akAddFeature(akeSecToken, \ 299 akbServerArg|akbServerImplicit|akbSend|akbSendRcv) 300 #define akUserSecToken akAddFeature(akeSecToken, \ 301 akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv) 302 303 #define akSecToken akAddFeature(akeSecToken, \ 304 akbServerArg|akbServerImplicit|akbSend|akbSendRcv| \ 305 akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv) 306 307 #define akServerAuditToken akAddFeature(akeAuditToken, \ 308 akbServerArg|akbServerImplicit|akbSend|akbSendRcv) 309 #define akUserAuditToken akAddFeature(akeAuditToken, \ 310 akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv) 311 #define akAuditToken akAddFeature(akeAuditToken, \ 312 akbServerArg|akbServerImplicit|akbSend|akbSendRcv| \ 313 akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv) 314 315 #define akServerContextToken akAddFeature(akeContextToken, \ 316 akbServerArg|akbServerImplicit|akbSend|akbSendRcv) 317 318 #define akMsgSeqno akAddFeature(akeMsgSeqno, \ 319 akbServerArg|akbServerImplicit|akbSend|akbSendRcv) 320 321 #define akInOut akAddFeature(akeNormal, \ 322 akbUserArg|akbServerArg|akbRequest|akbReply| \ 323 akbSendBits|akbReturnBits|akbReplyCopy) 324 325 #define akRequestPort akAddFeature(akeRequestPort, \ 326 akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv) 327 328 #define akWaitTime akAddFeature(akeWaitTime, akbUserArg) 329 330 #define akSendTime akAddFeature(akeSendTime, akbUserArg) 331 332 #define akMsgOption akAddFeature(akeMsgOption, akbUserArg) 333 334 #define akReplyPort akAddFeature(akeReplyPort, \ 335 akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv) 336 337 #define akUReplyPort akAddFeature(akeReplyPort, \ 338 akbUserArg|akbSend|akbSendSnd|akbSendRcv) 339 340 #define akSReplyPort akAddFeature(akeReplyPort, \ 341 akbServerArg|akbSend|akbSendSnd|akbSendRcv) 342 343 #define akRetCode akAddFeature(akeRetCode, akbReply|akbReturnBody) 344 345 #define akCount akAddFeature(akeCount, \ 346 akbUserArg|akbServerArg) 347 348 #define akPoly akePoly 349 350 #define akDealloc akAddFeature(akeDealloc, akbUserArg) 351 352 #define akCountInOut akAddFeature(akeCountInOut, akbRequest|akbSendBits) 353 354 #define akCheck(ak, bits) ((ak) & (bits)) 355 #define akCheckAll(ak, bits) (akCheck(ak, bits) == (bits)) 356 #define akAddFeature(ak, bits) ((ak)|(bits)) 357 #define akRemFeature(ak, bits) ((ak)&~(bits)) 358 #define akIdent(ak) ((ak) & akeBITS) 359 360 #define argIsIn(arg) (akIdent(arg->argKind) == akeNormal && \ 361 akCheck(arg->argKind, akbRequest)) 362 #define argIsOut(arg) (akIdent(arg->argKind) == akeNormal && \ 363 akCheck(arg->argKind, akbReply)) 364 365 /* 366 * The arguments to a routine/function are linked in left-to-right order. 367 * argName is used for error messages and pretty-printing, 368 * not code generation. Code generation shouldn't make any assumptions 369 * about the order of arguments, esp. count and poly arguments. 370 * (Unfortunately, code generation for inline variable-sized arguments 371 * does make such assumptions.) 372 * 373 * argVarName is the name used in generated code for function arguments 374 * and local variable names. argMsgField is the name used in generated 375 * code for the field in msgs where the argument's value lives. 376 * argTTName is the name used in generated code for msg-type fields and 377 * static variables used to initialize those fields. argPadName is the 378 * name used in generated code for a padding field in msgs. 379 * 380 * argFlags can be used to override the deallocate bits 381 * in the argument's type. rtProcessArgFlags sets argDeallocate 382 * from it and the type. Code generation shouldn't use 383 * argFlags. 384 * 385 * argCount, argPoly, and argDealloc get to the implicit count, poly, 386 * and dealloc arguments associated with the argument; they should be 387 * used instead of argNext. In these implicit arguments, argParent is 388 * a pointer to the "real" arg. 389 * 390 * In count arguments, argMultiplier is a scaling factor applied to 391 * the count arg's value to get msg-type-number. It is equal to 392 * argParent->argType->itElement->itNumber 393 * 394 */ 395 396 typedef struct argument 397 { 398 /* if argKind == akReturn, then argName is name of the function */ 399 identifier_t argName; 400 struct argument *argNext; 401 402 arg_kind_t argKind; 403 ipc_type_t *argType; 404 /* Kernel Processed Data */ 405 mach_msg_descriptor_type_t argKPD_Type; /* KPD type: port, ool, port+ool */ 406 void (* argKPD_Template)(); /* KPD discipline for static templates */ 407 void (* argKPD_Init)(); /* KPD discipline for initializing */ 408 void (* argKPD_Pack)(); /* KPD discipline for packing */ 409 void (* argKPD_Extract)(); /* KPD discipline for extracting */ 410 void (* argKPD_TypeCheck)(); /* KPD discipline for type checking */ 411 412 string_t argVarName; /* local variable and argument names */ 413 string_t argMsgField; /* message field's name */ 414 string_t argTTName; /* name for msg_type fields, static vars */ 415 string_t argPadName; /* name for pad field in msg */ 416 string_t argSuffix; /* name extension for KPDs */ 417 418 ipc_flags_t argFlags; 419 dealloc_t argDeallocate; /* overrides argType->itDeallocate */ 420 boolean_t argCountInOut; 421 422 struct routine *argRoutine; /* routine we are part of */ 423 424 struct argument *argCount; /* our count arg, if present */ 425 struct argument *argSubCount; /* our sub-count arg, if present (variable subordinate arrays) */ 426 struct argument *argCInOut; /* our CountInOut arg, if present */ 427 struct argument *argPoly; /* our poly arg, if present */ 428 struct argument *argDealloc;/* our dealloc arg, if present */ 429 struct argument *argSameCount; /* the arg to take the count from, if present */ 430 struct argument *argParent; /* in a count or poly arg, the base arg */ 431 u_int argMultiplier; /* for Count argument: parent is a multiple 432 of a basic IPC type. Argument must be 433 multiplied by Multiplier to get IPC 434 number-of-elements. */ 435 436 /* how variable/inline args precede this one, in request and reply */ 437 u_int argRequestPos; 438 u_int argReplyPos; 439 /* whether argument is by reference, on user and server side */ 440 boolean_t argByReferenceUser; 441 boolean_t argByReferenceServer; 442 443 boolean_t argTempOnStack; /* A temporary for the short-circuiting 444 * code when -maxonstack is used. 445 */ 446 } argument_t; 447 448 /* 449 * The various routine kinds' peculiarities are abstracted by rtCheckRoutine 450 * into attributes like rtOneWay, etc. These are what 451 * code generation should use. It is Bad Form for code generation to 452 * test rtKind. 453 */ 454 455 typedef enum 456 { 457 rkRoutine, 458 rkSimpleRoutine 459 } routine_kind_t; 460 461 typedef struct routine 462 { 463 identifier_t rtName; 464 routine_kind_t rtKind; 465 argument_t *rtArgs; 466 u_int rtNumber; /* used for making msg ids */ 467 468 identifier_t rtUserName; /* user-visible name (UserPrefix + Name) */ 469 identifier_t rtServerName; /* server-side name (ServerPrefix + Name) */ 470 471 identifier_t rtErrorName; /* error-handler name */ 472 473 boolean_t rtOneWay; /* SimpleRoutine */ 474 475 boolean_t rtSimpleRequest; 476 boolean_t rtSimpleReply; 477 478 u_int rtNumRequestVar; /* number of variable/inline args in request */ 479 u_int rtNumReplyVar; /* number of variable/inline args in reply */ 480 481 u_int rtMaxRequestPos; /* maximum of argRequestPos */ 482 u_int rtMaxReplyPos; /* maximum of argReplyPos */ 483 484 u_int rtRequestKPDs; /* number of Kernel Processed Data entries */ 485 u_int rtReplyKPDs; /* number of Kernel Processed Data entries */ 486 u_int rtOverwrite; /* number of Overwrite entries */ 487 u_int rtOverwriteKPDs; /* number of entries in the Overwrite template */ 488 489 boolean_t rtNoReplyArgs; /* if so, no reply message arguments beyond 490 what the server dispatch routine inserts */ 491 492 boolean_t rtRequestFits; /* Request fits within onstack limit */ 493 boolean_t rtReplyFits; /* Reply fits within onstack limit */ 494 boolean_t rtRequestUsedLimit;/* User type limit used in deciding whether 495 request fits within onstack limit */ 496 boolean_t rtReplyUsedLimit; /* User type limit used in deciding whether 497 reply fits within onstack limit */ 498 u_int rtRequestSizeKnown; /* Max size of known portion of request */ 499 u_int rtReplySizeKnown; /* Max size of known portion of request */ 500 501 u_int rtServerImpl; /* Implicit data requested */ 502 u_int rtUserImpl; /* Implicit data requested */ 503 504 /* distinguished arguments */ 505 argument_t *rtRetCArg; /* the Routine has this argument tagged as RetCode */ 506 argument_t *rtRequestPort; /* always non-NULL, defaults to first arg */ 507 argument_t *rtReplyPort; /* always non-NULL, defaults to Mig-supplied */ 508 argument_t *rtRetCode; /* always non-NULL */ 509 argument_t *rtNdrCode; /* always non-NULL */ 510 argument_t *rtWaitTime; /* if non-NULL, will use MACH_RCV_TIMEOUT */ 511 argument_t *rtMsgOption; /* always non-NULL, defaults to NONE */ 512 513 /* more info's used only when UseEventLogger is turned on */ 514 u_int rtCountPortsIn; /* how many in-line Ports are sent */ 515 u_int rtCountOolPortsIn; /* how many out_of-line Ports are sent */ 516 u_int rtCountOolIn; /* how many bytes out_of-line are sent */ 517 518 u_int rtCountPortsOut; /* how many in-line Ports are rcv'd */ 519 u_int rtCountOolPortsOut; /* how many out_of-line Ports are rcv'd */ 520 u_int rtCountOolOut; /* how many bytes out_of-line are rcv'd */ 521 522 u_int rtTempBytesOnStack; /* A temporary for the short-circuiting 523 * code when -maxonstack is used. 524 */ 525 526 } routine_t; 527 528 #define rtNULL ((routine_t *) 0) 529 #define argNULL ((argument_t *) 0) 530 #define argKPD_NULL ((mach_msg_descriptor_type_t) -1) 531 532 #define rtMessOnStack(rt) ((rt)->rtRequestFits && (rt)->rtReplyFits) 533 534 /* 535 * These are the ways MiG organizes stub parameters 536 */ 537 #define IS_VARIABLE_SIZED_UNTYPED(x) ((x)->itVarArray && \ 538 (x)->itInLine && \ 539 !(x)->itPortType) 540 #define IS_KERN_PROC_DATA(x) (!(x)->itInLine || (x)->itPortType) 541 #define IS_OPTIONAL_NATIVE(x) ((x)->itNative && \ 542 (x)->itNativePointer && \ 543 (x)->itBadValue != NULL) 544 545 /* 546 * I consider the case of fixed/variable bounded arrays of ports or ool or oolport 547 */ 548 #define IS_MULTIPLE_KPD(x) ((x)->itKPD_Number > 1) 549 /* 550 * I consider the case of MiG presenting data as it is inLine, even 551 * if it is sent/rcvd as out-of-line 552 */ 553 #define IS_MIG_INLINE_EMUL(x) ((x)->itMigInLine) 554 555 extern u_int rtNumber; 556 /* rt->rtNumber will be initialized */ 557 extern routine_t *rtAlloc(void); 558 /* skip a number */ 559 extern void rtSkip(void); 560 561 extern argument_t *argAlloc(void); 562 563 extern boolean_t 564 rtCheckMask(argument_t *args, u_int mask); 565 566 extern boolean_t 567 rtCheckMaskFunction(argument_t *args, u_int mask, 568 boolean_t (*func)(argument_t *arg)); 569 570 extern routine_t * 571 rtMakeRoutine( identifier_t name, argument_t *args); 572 extern routine_t * 573 rtMakeSimpleRoutine(identifier_t name, argument_t *args); 574 575 extern void rtPrintRoutine(routine_t *rt); 576 extern void rtCheckRoutine(routine_t *rt); 577 578 extern const char *rtRoutineKindToStr(routine_kind_t rk); 579 580 extern int rtCountArgDescriptors(argument_t *args, int *argcount); 581 582 extern void rtMinRequestSize(FILE *file, routine_t *rt, const char *str); 583 extern void rtMinReplySize(FILE *file, routine_t *rt, const char *str); 584 585 #define RPCUserStruct(arg) (arg->argType->itStruct && arg->argType->itInLine) 586 587 #define RPCString(arg) (arg->argType->itString && arg->argType->itInLine) 588 589 #define RPCOutStruct(arg) (arg->argType->itStruct &&\ 590 argIsOut(arg) && (! arg->argType->itVarArray)) 591 #define RPCOutWord(arg) (RPCUserStruct(arg) &&\ 592 (arg->argType->itSize <= 32) &&\ 593 (arg->argType->itNumber == 1) && argIsOut(arg)) 594 595 #define RPCPort(arg) (arg->argKPD_Type == MACH_MSG_PORT_DESCRIPTOR) 596 597 #define RPCPortArray(arg) (arg->argKPD_Type == MACH_MSG_OOL_PORTS_DESCRIPTOR) 598 599 #define RPCVariableArray(arg) ((arg->argType->itVarArray) &&\ 600 !RPCPort(arg) && !RPCPortArray(arg)) 601 602 #define RPCFixedArray(arg) (((! arg->argType->itVarArray) &&\ 603 !RPCPort(arg) && !RPCPortArray(arg) &&\ 604 (arg->argType->itNumber > 1) &&\ 605 !RPCUserStruct(arg)) ||\ 606 RPCString(arg) ||\ 607 RPCOutWord(arg) ||\ 608 RPCOutStruct(arg)) 609 610 611 #endif /* _ROUTINE_H */ 612 613 614 615