MIG codegen: server demux
Emits the server-side demultiplexer: decode an incoming request message, dispatch to the handler you implement, and pack the reply message.
WriteKPD_Iterator source
static void WriteKPD_Iterator(FILE *file, boolean_t in, boolean_t varying, argument_t *arg, boolean_t bracket) { ipc_type_t *it = arg->argType; char string[MAX_STR_LEN]; fprintf(file, "\t{\n"); fprintf(file, "\t %s\t*ptr;\n", it->itKPDType); fprintf(file, "\t int\ti"); if (varying && !in) fprintf(file, ", j"); fprintf(file, ";\n\n"); if (in) sprintf(string, "%s", arg->argInSegment); else sprintf(string, "%s", arg->argOutSegment); fprintf(file, "\t ptr = &%s->%s[0];\n", string, arg->argMsgField); if (varying) { argument_t *count = arg->argCount; if (in) fprintf(file, "\t for (i = 0; i < %s->%s; ptr++, i++) %s\n", count->argInSegment, count->argMsgField, (bracket) ? "{" : ""); else { fprintf(file, "\t j = min(%d, ", it->itKPD_Number); if (akCheck(count->argKind, akbVarNeeded)) fprintf(file, "%s);\n", count->argName); else … more in source
WriteMyIncludes source
static void WriteMyIncludes(FILE *file, statement_t *stats) { if (ServerHeaderFileName == strNULL || UseSplitHeaders) WriteIncludes(file, FALSE, FALSE); if (ServerHeaderFileName != strNULL) { char *cp; /* Strip any leading path from ServerHeaderFileName. */ cp = strrchr(ServerHeaderFileName, '/'); if (cp == 0) cp = ServerHeaderFileName; else cp++; /* skip '/' */ fprintf(file, "#include \"%s\"\n", cp); } if (ServerHeaderFileName == strNULL || UseSplitHeaders) WriteImplImports(file, stats, FALSE); if (UseEventLogger) { if (IsKernelServer) { fprintf(file, "#if\t__MigKernelSpecificCode\n"); fprintf(file, "#include <mig_debug.h>\n"); fprintf(file, "#endif\t/* __MigKernelSpecificCode */\n"); } fprintf(file, "#if MIG_DEBUG\n"); fprintf(file, "#include <mach/mig_log.h>\n"); fprintf(file, "#endif /* MIG_DEBUG */\n"); } … more in source
WriteGlobalDecls source
static void WriteGlobalDecls(FILE *file) { if (BeAnsiC) { fprintf(file, "#define novalue void\n"); } else { fprintf(file, "#if\t%s\n", NewCDecl); fprintf(file, "#define novalue void\n"); fprintf(file, "#else\n"); fprintf(file, "#define novalue int\n"); fprintf(file, "#endif\t/* %s */\n", NewCDecl); } fprintf(file, "\n"); if (RCSId != strNULL) WriteRCSDecl(file, strconcat(SubsystemName, "_server"), RCSId); /* Used for locations in the request message, *not* reply message. Reply message locations aren't dependent on IsKernelServer. */ if (IsKernelServer) { fprintf(file, "#if\t__MigKernelSpecificCode\n"); fprintf(file, "#define msgh_request_port\tmsgh_remote_port\n"); fprintf(file, "#define MACH_MSGH_BITS_REQUEST(bits)"); fprintf(file, "\tMACH_MSGH_BITS_REMOTE(bits)\n"); fprintf(file, "#define msgh_reply_port\t\tmsgh_local_port\n"); fprintf(file, "#define MACH_MSGH_BITS_REPLY(bits)"); fprintf(file, "\tMACH_MSGH_BITS_LOCAL(bits)\n"); fprintf(file, "#else\n"); … more in source
WriteForwardDeclarations source
static void WriteForwardDeclarations(FILE *file, statement_t *stats) { statement_t *stat; fprintf(file, "/* Forward Declarations */\n\n"); for (stat = stats; stat != stNULL; stat = stat->stNext) if (stat->stKind == skRoutine) { fprintf(file, "\nmig_internal novalue _X%s\n", stat->stRoutine->rtName); if (!UseMachMsg2) { fprintf(file, "\t(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);\n"); } else { fprintf(file, "\t(mach_msg_header_t *InHeadP, void *InDataP, mach_msg_max_trailer_t *InTrailerP, " "mach_msg_header_t *OutHeadP, void *OutDataP);\n"); } } fprintf(file, "\n"); }
WriteMIGCheckDefines source
static void WriteMIGCheckDefines(FILE *file) { fprintf(file, "#define\t__MIG_check__Request__%s_subsystem__ 1\n", SubsystemName); fprintf(file, "\n"); }
WriteNDRDefines source
static void WriteNDRDefines(FILE *file) { fprintf(file, "#define\t__NDR_convert__Request__%s_subsystem__ 1\n", SubsystemName); fprintf(file, "\n"); }
WriteProlog source
static void WriteProlog(FILE *file, statement_t *stats) { WriteIdentificationString(file); fprintf(file, "\n"); fprintf(file, "/* Module %s */\n", SubsystemName); fprintf(file, "\n"); WriteMIGCheckDefines(file); if (CheckNDR) WriteNDRDefines(file); WriteMyIncludes(file, stats); WriteBogusDefines(file); WriteApplDefaults(file, "Rcv"); WriteGlobalDecls(file); if (ServerHeaderFileName == strNULL) { WriteRequestTypes(file, stats); WriteReplyTypes(file, stats); WriteServerReplyUnion(file, stats); } }
WriteSymTabEntries source
static void WriteSymTabEntries(FILE *file, statement_t *stats) { statement_t *stat; u_int current = 0; for (stat = stats; stat != stNULL; stat = stat->stNext) if (stat->stKind == skRoutine) { int num = stat->stRoutine->rtNumber; char *name = stat->stRoutine->rtName; while (++current <= num) fprintf(file,"\t\t\t{ \"\", 0, 0 },\n"); fprintf(file, "\t{ \"%s\", %d, _X%s },\n", name, SubsystemBase + current - 1, name); } while (++current <= rtNumber) fprintf(file,"\t{ \"\", 0, 0 },\n"); }
WriteRoutineEntries source
static void WriteRoutineEntries(FILE *file, statement_t *stats) { u_int current = 0; statement_t *stat; char *sig_array, *rt_name; int arg_count, descr_count; int offset = 0; size_t serverSubsysNameLen = strlen(ServerSubsys); char *kern_ = UseMachMsg2 ? "kern_" : ""; fprintf(file, "\t{\n"); for (stat = stats; stat != stNULL; stat = stat->stNext) if (stat->stKind == skRoutine) { routine_t *rt = stat->stRoutine; size_t rtNameLen = strlen(rt->rtName); if (MaxServerReplyDescrs >= 0 && rt->rtReplyKPDs > MaxServerReplyDescrs) { fatal("WriteRoutine(): method %s uses %d reply descriptors (larger than %d)", rt->rtName, rt->rtReplyKPDs, MaxServerReplyDescrs); } if (MaxServerDescrs >= 0 && rt->rtRequestKPDs > MaxServerDescrs) { fatal("WriteRoutine(): method %s uses %d descriptors (larger than %d)", rt->rtName, rt->rtRequestKPDs, MaxServerDescrs); } // Include length of rt->rtName in calculation of necessary buffer size, since that string // is actually written into the buffer along with the Server Subsystem name. sig_array = (char *) malloc(serverSubsysNameLen + rtNameLen + 80); rt_name = (char *) malloc(rtNameLen + 5); … more in source
WriteArgDescriptorEntries source
static void WriteArgDescriptorEntries(FILE *file, statement_t *stats) { statement_t *stat; fprintf(file, ",\n\n\t{\n"); for (stat = stats; stat != stNULL; stat = stat->stNext) if (stat->stKind == skRoutine) { routine_t *rt = stat->stRoutine; /* For each arg of the routine, write an arg descriptor: */ WriteRPCRoutineArgDescriptor(file, rt); } fprintf(file, "\t},\n\n"); }
WriteSubsystem source
Write out the description of this subsystem, for use in direct RPC
static void WriteSubsystem(FILE *file, statement_t *stats) { statement_t *stat; int descr_count = 0; char *kern_ = ""; char *k = ""; char *kernel = ""; if (UseMachMsg2) { kern_ = "kern_"; k = "k"; kernel = "kernel "; } for (stat = stats; stat != stNULL; stat = stat->stNext) if (stat->stKind == skRoutine) { routine_t *rt = stat->stRoutine; descr_count += rtCountArgDescriptors(rt->rtArgs, (int *) 0); } fprintf(file, "\n"); if (ServerHeaderFileName == strNULL) { WriteMigExternal(file); fprintf(file, "boolean_t %s(", ServerDemux); if (BeAnsiC) { fprintf(file, "\n\t\tmach_msg_header_t *InHeadP,"); if (!UseMachMsg2) { fprintf(file, "\n\t\tmach_msg_header_t *OutHeadP"); } else { fprintf(file, "\n\t\tvoid *InDataP,"); … more in source
WriteArraySizes source
static void WriteArraySizes(FILE *file, statement_t *stats) { u_int current = 0; statement_t *stat; for (stat = stats; stat != stNULL; stat = stat->stNext) if (stat->stKind == skRoutine) { routine_t *rt = stat->stRoutine; while (current++ < rt->rtNumber) fprintf(file, "\t\t0,\n"); fprintf(file, "\t\t(mach_msg_size_t)sizeof(__Reply__%s_t),\n", rt->rtName); } while (current++ < rtNumber) fprintf(file, "\t\t\t0,\n"); }
WriteServerRequestUnion source
NOT_CURRENTLY_USED
void WriteServerRequestUnion(FILE *file, statement_t *stats) { statement_t *stat; fprintf(file, "\n"); fprintf(file, "/* union of all requests */\n\n"); fprintf(file, "#ifndef __RequestUnion__%s__defined\n", ServerSubsys); fprintf(file, "#define __RequestUnion__%s__defined\n", ServerSubsys); fprintf(file, "union __RequestUnion__%s {\n", ServerSubsys); for (stat = stats; stat != stNULL; stat = stat->stNext) { if (stat->stKind == skRoutine) { routine_t *rt; rt = stat->stRoutine; fprintf(file, "\t__Request__%s_t Request_%s;\n", rt->rtName, rt->rtName); } } fprintf(file, "};\n"); fprintf(file, "#endif /* __RequestUnion__%s__defined */\n", ServerSubsys); }
WriteServerReplyUnion source
void WriteServerReplyUnion(FILE *file, statement_t *stats) { statement_t *stat; fprintf(file, "\n"); fprintf(file, "/* union of all replies */\n\n"); fprintf(file, "#ifndef __ReplyUnion__%s__defined\n", ServerSubsys); fprintf(file, "#define __ReplyUnion__%s__defined\n", ServerSubsys); fprintf(file, "union __ReplyUnion__%s {\n", ServerSubsys); for (stat = stats; stat != stNULL; stat = stat->stNext) { if (stat->stKind == skRoutine) { routine_t *rt; rt = stat->stRoutine; fprintf(file, "\t__Reply__%s_t Reply_%s;\n", rt->rtName, rt->rtName); } } fprintf(file, "};\n"); fprintf(file, "#endif /* __ReplyUnion__%s__defined */\n", ServerSubsys); }
WriteDispatcher source
static void WriteDispatcher(FILE *file, statement_t *stats) { char *k = ""; char *kern_ = ""; if (UseMachMsg2) { k = "k"; kern_ = "kern_"; } /* * Write the subsystem stuff. */ fprintf(file, "\n"); WriteSubsystem(file, stats); /* * Then, the server routine */ fprintf(file, "mig_external boolean_t %s\n", ServerDemux); if (BeAnsiC) { if (!UseMachMsg2) { fprintf(file, "\t(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)\n"); } else { fprintf(file, "\t(mach_msg_header_t *InHeadP, void *InDataP, mach_msg_max_trailer_t *InTrailerP," " mach_msg_header_t *OutHeadP, void *OutDataP)\n"); } } else { … more in source
ServerSideType source
Returns the return type of the server-side work function.
Suitable for "extern %s serverfunc()".
static char * ServerSideType(routine_t *rt) { return rt->rtRetCode->argType->itTransType; }
WriteRetCode source
NOT_CURRENTLY_USED
static void WriteRetCode(FILE *file, argument_t *ret) { ipc_type_t *it = ret->argType; if (akCheck(ret->argKind, akbVarNeeded)) { fprintf(file, "\t%s %s;\n", it->itTransType, ret->argVarName); } }
WriteLocalVarDecl source
static void WriteLocalVarDecl(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; ipc_type_t *btype = it->itElement; if (IS_VARIABLE_SIZED_UNTYPED(it)) fprintf(file, "\t%s %s[%d]", btype->itTransType, arg->argVarName, btype->itNumber ? it->itNumber/btype->itNumber : 0); else if (IS_MULTIPLE_KPD(it)) { if (btype->itTransType != strNULL) fprintf(file, "\t%s %s[%d]", btype->itTransType, arg->argVarName, it->itKPD_Number); else /* arrays of ool or oolport */ fprintf(file, "\tvoid *%s[%d]", arg->argVarName, it->itKPD_Number); } else fprintf(file, "\t%s %s", it->itTransType, arg->argVarName); }
WriteServerArgDecl source
static void WriteServerArgDecl(FILE *file, argument_t *arg) { fprintf(file, "%s %s%s", arg->argType->itTransType, arg->argByReferenceServer ? "*" : "", arg->argVarName); }
WriteVarDecls source
Writes the local variable declarations which are always
present: InP, OutP, the server-side work function.
static void WriteVarDecls(FILE *file, routine_t *rt) { int i; if (!UseMachMsg2) { fprintf(file, "\tRequest *In0P = (Request *) InHeadP;\n"); for (i = 1; i <= rt->rtMaxRequestPos; i++) fprintf(file, "\tRequest *In%dP;\n", i); fprintf(file, "\tReply *OutP = (Reply *) OutHeadP;\n"); } else { fprintf(file, "\tRequestK *InKP = (RequestK *) InHeadP;\n"); fprintf(file, "\tRequestU *In0UP = (RequestU *) InDataP;\n"); for (i = 1; i <= rt->rtMaxRequestPos; i++) fprintf(file, "\tRequestU *In%dUP;\n", i); fprintf(file, "\tReplyK *OutKP = (ReplyK *) OutHeadP;\n"); fprintf(file, "\tReplyU *OutUP = (ReplyU *) OutDataP;\n"); fprintf(file, "\t(void)OutUP;\n"); } /* if reply is variable, we may need msgh_size_delta and msgh_size */ if (rt->rtNumReplyVar > 1) fprintf(file, "\tunsigned int msgh_size;\n"); if (rt->rtMaxReplyPos > 0) fprintf(file, "\tunsigned int msgh_size_delta;\n"); if (rt->rtNumReplyVar > 1 || rt->rtMaxReplyPos > 0) fprintf(file, "\n"); if (rt->rtServerImpl) { fprintf(file, "\tmach_msg_max_trailer_t *TrailerP;\n"); … more in source
WriteReplyInit source
static void WriteReplyInit(FILE *file, routine_t *rt) { fprintf(file, "\n"); if (!UseMachMsg2 && (rt->rtNumReplyVar > 1 || rt->rtMaxReplyPos)) /* WritheAdjustMsgSize() has been executed at least once! */ fprintf(file, "\tOutP = (Reply *) OutHeadP;\n"); if (!rt->rtSimpleReply) /* complex reply message */ fprintf(file, "\t%s->Head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;\n", OutHeadSeg); if (rt->rtNumReplyVar == 0) { fprintf(file, "\t%s->Head.msgh_size = ", OutHeadSeg); rtMinReplySize(file, rt, "Reply"); fprintf(file, ";\n"); } else if (rt->rtNumReplyVar > 1) fprintf(file, "\t%s->Head.msgh_size = msgh_size;\n", OutHeadSeg); /* the case rt->rtNumReplyVar = 1 is taken care of in WriteAdjustMsgSize() */ }
WriteRetCArgCheckError source
static void WriteRetCArgCheckError(FILE *file, routine_t *rt) { fprintf(file, "\tif (!(%s->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) &&\n", InHeadSeg); fprintf(file, "\t (%s->Head.msgh_size == (mach_msg_size_t)sizeof(mig_reply_error_t)))\n", InHeadSeg); fprintf(file, "\t{\n"); } static void WriteRetCArgFinishError(FILE *file, routine_t *rt) { argument_t *retcode = rt->rtRetCArg; fprintf(file, "\treturn;\n"); fprintf(file, "\t}\n"); retcode->argMsgField = "KERN_SUCCESS"; }
WriteRetCArgFinishError source
static void WriteRetCArgFinishError(FILE *file, routine_t *rt) { argument_t *retcode = rt->rtRetCArg; fprintf(file, "\treturn;\n"); fprintf(file, "\t}
WriteCheckHead source
static void WriteCheckHead(FILE *file, routine_t *rt) { fprintf(file, "#if\t__MigTypeCheck\n"); if (rt->rtNumRequestVar > 0) fprintf(file, "\tmsgh_size = %s->Head.msgh_size;\n", InHeadSeg); if (rt->rtSimpleRequest) { /* Expecting a simple message. */ fprintf(file, "\tif ((%s->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||\n", InHeadSeg); if (rt->rtNumRequestVar > 0) { fprintf(file, "\t (msgh_size < "); rtMinRequestSize(file, rt, "__Request"); fprintf(file, ") || (msgh_size > (mach_msg_size_t)sizeof(__Request)))\n"); } else fprintf(file, "\t (%s->Head.msgh_size != (mach_msg_size_t)sizeof(__Request)))\n", InHeadSeg); } else { /* Expecting a complex message. */ fprintf(file, "\tif ("); if (rt->rtRetCArg != argNULL) fprintf(file, "("); fprintf(file, "!(%s->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||\n", InHeadSeg); fprintf(file, "\t (%s->msgh_body.msgh_descriptor_count != %d) ||\n", InHeadSeg, rt->rtRequestKPDs); if (rt->rtNumRequestVar > 0) { fprintf(file, "\t (msgh_size < "); rtMinRequestSize(file, rt, "__Request"); fprintf(file, ") || (msgh_size > (mach_msg_size_t)sizeof(__Request))"); … more in source
WriteRequestNDRConvertIntRepArgCond source
void WriteRequestNDRConvertIntRepArgCond(FILE *file, argument_t *arg) { routine_t *rt = arg->argRoutine; fprintf(file, "defined(__NDR_convert__int_rep__Request__%s_t__%s__defined)", rt->rtName, arg->argMsgField); }
WriteRequestNDRConvertCharRepArgCond source
void WriteRequestNDRConvertCharRepArgCond(FILE *file, argument_t *arg) { routine_t *rt = arg->argRoutine; if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut) fprintf(file, "defined(__NDR_convert__char_rep__Request__%s_t__%s__defined)", rt->rtName, arg->argMsgField); else fprintf(file, "0"); }
WriteRequestNDRConvertFloatRepArgCond source
void WriteRequestNDRConvertFloatRepArgCond(FILE *file, argument_t *arg) { routine_t *rt = arg->argRoutine; if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut) fprintf(file, "defined(__NDR_convert__float_rep__Request__%s_t__%s__defined)", rt->rtName, arg->argMsgField); else fprintf(file, "0"); }
WriteRequestNDRConvertIntRepArgDecl source
void WriteRequestNDRConvertIntRepArgDecl(FILE *file, argument_t *arg) { WriteNDRConvertArgDecl(file, arg, "int_rep", "Request"); }
WriteRequestNDRConvertCharRepArgDecl source
void WriteRequestNDRConvertCharRepArgDecl(FILE *file, argument_t *arg) { if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut) WriteNDRConvertArgDecl(file, arg, "char_rep", "Request"); }
WriteRequestNDRConvertFloatRepArgDecl source
void WriteRequestNDRConvertFloatRepArgDecl(FILE *file, argument_t *arg) { if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut) WriteNDRConvertArgDecl(file, arg, "float_rep", "Request"); }
WriteRequestNDRConvertArgUse source
void WriteRequestNDRConvertArgUse(FILE *file, argument_t *arg, char *convert) { routine_t *rt = arg->argRoutine; argument_t *count = arg->argCount; char argname[MAX_STR_LEN]; if ((akIdent(arg->argKind) == akeCount || akIdent(arg->argKind) == akeCountInOut) && (arg->argParent && akCheck(arg->argParent->argKind, akbSendNdr))) return; if (arg->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR) { if (count && !arg->argSameCount && !strcmp(convert, "int_rep")) { fprintf(file, "#if defined(__NDR_convert__int_rep__Request__%s_t__%s__defined)\n", rt->rtName, count->argMsgField); fprintf(file, "\t\t__NDR_convert__int_rep__Request__%s_t__%s(&In%dP->%s, In%dP->NDR.int_rep);\n", rt->rtName, count->argMsgField, count->argRequestPos, count->argMsgField, count->argRequestPos); fprintf(file, "#endif\t/* __NDR_convert__int_rep__Request__%s_t__%s__defined */\n", rt->rtName, count->argMsgField); } sprintf(argname, "(%s)(In%dP->%s.address)", FetchServerType(arg->argType), arg->argRequestPos, arg->argMsgField); } else { sprintf(argname, "&In%dP->%s", arg->argRequestPos, arg->argMsgField); } fprintf(file, "#if defined(__NDR_convert__%s__Request__%s_t__%s__defined)\n", convert, rt->rtName, arg->argMsgField); fprintf(file, "\t\t__NDR_convert__%s__Request__%s_t__%s(%s, In0P->NDR.%s", convert, rt->rtName, arg->argMsgField, argname, convert); if (count) fprintf(file, ", In%dP->%s", count->argRequestPos, count->argMsgField); fprintf(file, ");\n"); fprintf(file, "#endif\t/* __NDR_convert__%s__Request__%s_t__%s__defined */\n", convert, rt->rtName, arg->argMsgField); … more in source
WriteRequestNDRConvertIntRepOneArgUse source
void WriteRequestNDRConvertIntRepOneArgUse(FILE *file, argument_t *arg) { routine_t *rt = arg->argRoutine; char *where = UseMachMsg2 ? "UP" : "P"; fprintf(file, "#if defined(__NDR_convert__int_rep__Request__%s_t__%s__defined)\n", rt->rtName, arg->argMsgField); fprintf(file, "\tif (In0%s->NDR.int_rep != NDR_record.int_rep)\n", where); fprintf(file, "\t\t__NDR_convert__int_rep__Request__%s_t__%s(&%s->%s, %s->NDR.int_rep);\n", rt->rtName, arg->argMsgField, arg->argInSegment, arg->argMsgField, arg->argInSegment); fprintf(file, "#endif\t/* __NDR_convert__int_rep__Request__%s_t__%s__defined */\n", rt->rtName, arg->argMsgField); }
WriteRequestNDRConvertIntRepArgUse source
void WriteRequestNDRConvertIntRepArgUse(FILE *file, argument_t *arg) { WriteRequestNDRConvertArgUse(file, arg, "int_rep"); }
WriteRequestNDRConvertCharRepArgUse source
void WriteRequestNDRConvertCharRepArgUse(FILE *file, argument_t *arg) { if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut) WriteRequestNDRConvertArgUse(file, arg, "char_rep"); }
WriteRequestNDRConvertFloatRepArgUse source
void WriteRequestNDRConvertFloatRepArgUse(FILE *file, argument_t *arg) { if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut) WriteRequestNDRConvertArgUse(file, arg, "float_rep"); }
WriteCalcArgSize source
static void WriteCalcArgSize(FILE *file, argument_t *arg) { ipc_type_t *ptype = arg->argType; if (PackMsg == FALSE) { fprintf(file, "%d", ptype->itTypeSize + ptype->itPadSize); return; } if (IS_OPTIONAL_NATIVE(ptype)) fprintf(file, "(%s->__Present__%s ? _WALIGNSZ_(%s) : 0)" , arg->argInSegment, arg->argMsgField, ptype->itServerType); else { ipc_type_t *btype = ptype->itElement; argument_t *count = arg->argCount; int multiplier = btype->itTypeSize; if (btype->itTypeSize % itWordAlign != 0) fprintf(file, "_WALIGN_"); fprintf(file, "("); if (multiplier > 1) fprintf(file, "%d * ", multiplier); fprintf(file, "%s->%s", count->argInSegment, count->argMsgField); fprintf(file, ")"); } }
WriteCheckArgSize source
static void WriteCheckArgSize(FILE *file, routine_t *rt, argument_t *arg, const char *comparator) { ipc_type_t *ptype = arg->argType; fprintf(file, "\tif (((msgh_size - "); rtMinRequestSize(file, rt, "__Request"); fprintf(file, ") "); if (PackMsg == FALSE) { fprintf(file, "%s %d)", comparator, ptype->itTypeSize + ptype->itPadSize); } else if (IS_OPTIONAL_NATIVE(ptype)) { fprintf(file, "%s (%s->__Present__%s ? _WALIGNSZ_(%s) : 0))" , comparator, arg->argInSegment, arg->argMsgField, ptype->itServerType); } else { ipc_type_t *btype = ptype->itElement; argument_t *count = arg->argCount; int multiplier = btype->itTypeSize; if (multiplier > 1) fprintf(file, "/ %d ", multiplier); fprintf(file, "< %s->%s) ||\n", count->argInSegment, count->argMsgField); fprintf(file, "\t (msgh_size %s ", comparator); rtMinRequestSize(file, rt, "__Request"); fprintf(file, " + "); WriteCalcArgSize(file, arg); fprintf(file, ")"); } fprintf(file, ")\n\t\treturn MIG_BAD_ARGUMENTS;\n"); }
WriteCheckMsgSize source
static void WriteCheckMsgSize(FILE *file, argument_t *arg) { routine_t *rt = arg->argRoutine; ipc_type_t *it = arg->argType; ipc_type_t *btype = it->itElement; if (arg->argCount && !arg->argSameCount) WriteRequestNDRConvertIntRepOneArgUse(file, arg->argCount); if (arg->argRequestPos == rt->rtMaxRequestPos) { fprintf(file, "#if\t__MigTypeCheck\n"); /* verify that the user-code-provided count does not exceed the maximum count allowed by the type. */ fprintf(file, "\t" "if (%s->%s > %d)\n", arg->argCount->argInSegment, arg->argCount->argMsgField, it->itNumber/btype->itNumber); fputs("\t\t" "return MIG_BAD_ARGUMENTS;\n", file); /* ...end... */ WriteCheckArgSize(file, rt, arg, "!="); fprintf(file, "#endif\t/* __MigTypeCheck */\n"); } else { /* If there aren't any more variable-sized arguments after this, then we must check for exact msg-size and we don't need to update msgh_size. */ boolean_t LastVarArg = arg->argRequestPos+1 == rt->rtNumRequestVar; /* calculate the actual size in bytes of the data field. note … more in source
InArgMsgField source
static char * InArgMsgField(argument_t *arg, char *str) { static char buffer[MAX_STR_LEN]; char who[20] = {0}; /* * Inside the kernel, the request and reply port fields * really hold ipc_port_t values, not mach_port_t values. * Hence we must cast the values. */ if (!(arg->argFlags & flRetCode)) { if (akCheck(arg->argKind, akbServerImplicit)) sprintf(who, "TrailerP->"); else sprintf(who, "%s->", arg->argInSegment); } #ifdef MIG_KERNEL_PORT_CONVERSION if (IsKernelServer && ((akIdent(arg->argKind) == akeRequestPort) || (akIdent(arg->argKind) == akeReplyPort))) sprintf(buffer, "(ipc_port_t) %s%s%s", who, str, (arg->argSuffix != strNULL) ? arg->argSuffix : arg->argMsgField); else #endif sprintf(buffer, "%s%s%s", who, str, (arg->argSuffix != strNULL) ? arg->argSuffix : arg->argMsgField); return buffer; }
WriteExtractArgValue source
static void WriteExtractArgValue(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; string_t recast; #ifdef MIG_KERNEL_PORT_CONVERSION if (IsKernelServer && it->itPortType && streql(it->itServerType, "ipc_port_t") && akIdent(arg->argKind) != akeRequestPort && akIdent(arg->argKind) != akeReplyPort) recast = "(mach_port_t)"; else #endif recast = ""; if (it->itInTrans != strNULL) WriteCopyType(file, it, FALSE, "%s", "/* %s */ %s(%s%s)", arg->argVarName, it->itInTrans, recast, InArgMsgField(arg, "")); else WriteCopyType(file, it, FALSE, "%s", "/* %s */ %s%s", arg->argVarName, recast, InArgMsgField(arg, "")); fprintf(file, "\n"); }
WriteExtractKPD_port source
argKPD_Extract discipline for Port types.
static void WriteExtractKPD_port(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; char *recast = ""; WriteKPD_Iterator(file, TRUE, it->itVarArray, arg, FALSE); /* translation function do not apply to complex types */ #ifdef MIG_KERNEL_PORT_CONVERSION if (IsKernelServer) recast = "(mach_port_t)"; #endif fprintf(file, "\t\t%s[i] = %sptr->name;\n", arg->argVarName, recast); fprintf(file, "\t}
WriteExtractKPD_ool source
argKPD_Extract discipline for out-of-line types.
static void WriteExtractKPD_ool(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; WriteKPD_Iterator(file, TRUE, it->itVarArray, arg, FALSE); fprintf(file, "\t\t%s[i] = ptr->address;\n", arg->argVarName); fprintf(file, "\t}
WriteExtractKPD_oolport source
argKPD_Extract discipline for out-of-line Port types.
static void WriteExtractKPD_oolport(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; WriteKPD_Iterator(file, TRUE, it->itVarArray, arg, FALSE); fprintf(file, "\t\t%s[i] = ptr->address;\n", arg->argVarName); fprintf(file, "\t}
WriteInitializeCount source
static void WriteInitializeCount(FILE *file, argument_t *arg) { ipc_type_t *ptype = arg->argParent->argType; ipc_type_t *btype = ptype->itElement; char newstr[MAX_STR_LEN]; /* * Initialize 'count' argument for variable-length inline OUT parameter * with maximum allowed number of elements. */ if (akCheck(arg->argKind, akbVarNeeded)) sprintf(newstr, "%s", arg->argMsgField); else sprintf(newstr, "%s->%s", arg->argOutSegment, arg->argMsgField); fprintf(file, "\t%s = ", newstr); if (IS_MULTIPLE_KPD(ptype)) fprintf(file, "%d;\n", ptype->itKPD_Number); else fprintf(file, "%d;\n", btype->itNumber? ptype->itNumber/btype->itNumber : 0); /* * If the user passed in a count, then we use the minimum. * We can't let the user completely override our maximum, * or the user might convince the server to overwrite the buffer. */ if (arg->argCInOut != argNULL) { … more in source
WriteAdjustRequestMsgPtr source
static void WriteAdjustRequestMsgPtr(FILE *file, argument_t *arg) { ipc_type_t *ptype = arg->argType; char *where = UseMachMsg2 ? "UP" : "P"; char *castType = UseMachMsg2 ? "__RequestU" : "__Request"; if (PackMsg == FALSE) { fprintf(file, "\t*In%d%sP = In%d%s = (%s *) ((pointer_t) %s);\n\n", arg->argRequestPos+1, where, arg->argRequestPos+1, where, castType, arg->argInSegment); return; } fprintf(file, "\t*In%d%sP = In%d%s = (%s *) ((pointer_t) %s + msgh_size_delta - ", arg->argRequestPos+1, where, arg->argRequestPos+1, where, castType, arg->argInSegment); if (IS_OPTIONAL_NATIVE(ptype)) fprintf(file, "_WALIGNSZ_(%s)", ptype->itUserType); else fprintf(file, "%d", ptype->itTypeSize + ptype->itPadSize); fprintf(file, ");\n\n"); }
WriteCheckRequestTrailerArgs source
static void WriteCheckRequestTrailerArgs(FILE *file, routine_t *rt) { argument_t *arg; if (rt->rtServerImpl) WriteCheckTrailerHead(file, rt, FALSE); for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) { if (akCheck(arg->argKind, akbServerImplicit)) WriteCheckTrailerSize(file, FALSE, arg); } }
WriteExtractArg source
static void WriteExtractArg(FILE *file, argument_t *arg) { if (akCheckAll(arg->argKind, akbSendRcv|akbVarNeeded)) { if (akCheck(arg->argKind, akbSendKPD)) (*arg->argKPD_Extract)(file, arg); else WriteExtractArgValue(file, arg); } if ((akIdent(arg->argKind) == akeCount) && akCheck(arg->argKind, akbReturnSnd)) { ipc_type_t *ptype = arg->argParent->argType; /* * the count will be initialized to 0 in the case of * unbounded arrays (MigInLine = TRUE): this is because * the old interface used to pass to the target procedure * the maximum in-line size (it was 2048 bytes) */ if (IS_VARIABLE_SIZED_UNTYPED(ptype) || IS_MIG_INLINE_EMUL(ptype) || (IS_MULTIPLE_KPD(ptype) && ptype->itVarArray)) WriteInitializeCount(file, arg); } }
WriteServerCallArg source
static void WriteServerCallArg(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; boolean_t NeedClose = FALSE; u_int elemsize = 0; string_t at = (arg->argByReferenceServer || it->itNativePointer) ? "&" : ""; string_t star = (arg->argByReferenceServer) ? " *" : ""; string_t msgfield = (arg->argSuffix != strNULL) ? arg->argSuffix : arg->argMsgField; if ((it->itInTrans != strNULL) && akCheck(arg->argKind, akbSendRcv) && !akCheck(arg->argKind, akbVarNeeded)) { fprintf(file, "%s%s(", at, it->itInTrans); NeedClose = TRUE; } if (akCheckAll(arg->argKind, akbVarNeeded|akbServerArg)) fprintf(file, "%s%s", at, arg->argVarName); else if (akCheckAll(arg->argKind, akbSendRcv|akbSendKPD)) { if (!it->itInLine) /* recast the void *, although it is not necessary */ fprintf(file, "(%s%s)%s(%s)", it->itTransType, star, at, InArgMsgField(arg, "")); else #ifdef MIG_KERNEL_PORT_CONVERSION if (IsKernelServer && streql(it->itServerType, "ipc_port_t")) /* recast the port to the kernel internal form value */ fprintf(file, "(ipc_port_t%s)%s(%s)", star, at, InArgMsgField(arg, "")); … more in source
WriteConditionalCallArg source
Shrunk version of WriteServerCallArg, to implement the RetCode functionality:
we have received a mig_reply_error_t, therefore we want to call the target
routine with all 0s except for the error code (and the implicit data).
We know that we are a SimpleRoutine.
static void WriteConditionalCallArg(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; boolean_t NeedClose = FALSE; if ((it->itInTrans != strNULL) && akCheck(arg->argKind, akbSendRcv) && !akCheck(arg->argKind, akbVarNeeded)) { fprintf(file, "%s(", it->itInTrans); NeedClose = TRUE; } if (akCheck(arg->argKind, akbSendRcv)) { if (akIdent(arg->argKind) == akeRequestPort || akCheck(arg->argKind, akbServerImplicit)) fprintf(file, "%s", InArgMsgField(arg, "")); else if (akIdent(arg->argKind) == akeRetCode) { assert(arg->argRequestPos == 0); fprintf(file, "((mig_reply_error_t *)%s)->RetCode", arg->argInSegment); } else fprintf(file, "(%s)(0)", it->itTransType); } if (NeedClose) fprintf(file, ")"); }
WriteDestroyArg source
static void WriteDestroyArg(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; /* * Deallocate IN/INOUT out-of-line args if specified by "auto" flag. * * We also have to deallocate in the cases where the target routine * is given a itInLine semantic whereas the underlying transmission * was out-of-line */ if ((argIsIn(arg) && akCheck(arg->argKind, akbSendKPD|akbReturnKPD) && arg->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR && (arg->argFlags & flAuto)) || IS_MIG_INLINE_EMUL(it) ) { /* * Deallocate only if out-of-line. */ argument_t *count = arg->argCount; ipc_type_t *btype = it->itElement; int multiplier = btype->itNumber ? btype->itSize / (8 * btype->itNumber) : 0; if (IsKernelServer) { fprintf(file, "#if __MigKernelSpecificCode\n"); fprintf(file, "\tvm_map_copy_discard(%s);\n", InArgMsgField(arg, "")); fprintf(file, "#else\n"); } … more in source
WriteDestroyPortArg source
static void WriteDestroyPortArg(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; /* * If a translated port argument occurs in the body of a request * message, and the message is successfully processed, then the * port right should be deallocated. However, the called function * didn't see the port right; it saw the translation. So we have * to release the port right for it. * * The test over it->itInTrans will exclude any complex type * made out of ports */ if ((it->itInTrans != strNULL) && (it->itOutName == MACH_MSG_TYPE_PORT_SEND)) { fprintf(file, "\tipc_port_release_send((ipc_port_t)%s);\n", InArgMsgField(arg, "")); } }
CheckDestroyPortArg source
Check whether WriteDestroyPortArg would generate any code for arg.
boolean_t CheckDestroyPortArg(argument_t *arg) { ipc_type_t *it = arg->argType; if ((it->itInTrans != strNULL) && (it->itOutName == MACH_MSG_TYPE_PORT_SEND)) { return TRUE; } return FALSE; }
WriteServerCall source
static void WriteServerCall(FILE *file, routine_t *rt, void (*func)(FILE *, argument_t *)) { argument_t *arg = rt->rtRetCode; ipc_type_t *it = arg->argType; boolean_t NeedClose = FALSE; fprintf(file, "\t"); if (akCheck(arg->argKind, akbVarNeeded)) fprintf(file, "%s = ", arg->argMsgField); else fprintf(file, "%s->%s = ", arg->argOutSegment, arg->argMsgField); if (it->itOutTrans != strNULL) { fprintf(file, "%s(", it->itOutTrans); NeedClose = TRUE; } fprintf(file, "%s(", rt->rtServerName); WriteList(file, rt->rtArgs, func, akbServerArg, ", ", ""); if (NeedClose) fprintf(file, ")"); fprintf(file, ");\n"); }
WriteCheckReturnValue source
static void WriteCheckReturnValue(FILE *file, routine_t *rt) { argument_t *arg = rt->rtRetCode; char string[MAX_STR_LEN]; if (akCheck(arg->argKind, akbVarNeeded)) sprintf(string, "%s", arg->argMsgField); else sprintf(string, "%s->%s", arg->argOutSegment, arg->argMsgField); fprintf(file, "\tif (%s != KERN_SUCCESS) {\n", string); fprintf(file, "\t\tMIG_RETURN_ERROR(%s, %s);\n", OutHeadSeg, string); fprintf(file, "\t}\n"); }
WriteInitKPD_port source
argKPD_Init discipline for Port types.
static void WriteInitKPD_port(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; char *subindex = ""; boolean_t close = FALSE; char firststring[MAX_STR_LEN]; char string[MAX_STR_LEN]; if (IS_MULTIPLE_KPD(it)) { WriteKPD_Iterator(file, FALSE, FALSE, arg, TRUE); (void)sprintf(firststring, "\t*ptr"); (void)sprintf(string, "\tptr->"); subindex = "[i]"; close = TRUE; } else { (void)sprintf(firststring, "%s->%s", arg->argOutSegment, arg->argMsgField); (void)sprintf(string, "%s->%s.", arg->argOutSegment, arg->argMsgField); } fprintf(file, "#if\tUseStaticTemplates\n"); fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName); fprintf(file, "#else\t/* UseStaticTemplates */\n"); if (IS_MULTIPLE_KPD(it) && it->itVarArray) fprintf(file, "\t%sname = MACH_PORT_NULL;\n", string); if (arg->argPoly == argNULL) { if (IsKernelServer) { fprintf(file, "#if __MigKernelSpecificCode\n"); fprintf(file, "\t%sdisposition = %s;\n", string, it->itOutNameStr); … more in source
WriteInitKPD_ool source
argKPD_Init discipline for out-of-line types.
static void WriteInitKPD_ool(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; char firststring[MAX_STR_LEN]; char string[MAX_STR_LEN]; boolean_t VarArray; u_int howmany, howbig; if (IS_MULTIPLE_KPD(it)) { WriteKPD_Iterator(file, FALSE, FALSE, arg, TRUE); (void)sprintf(firststring, "\t*ptr"); (void)sprintf(string, "\tptr->"); VarArray = it->itElement->itVarArray; howmany = it->itElement->itNumber; howbig = it->itElement->itSize; } else { (void)sprintf(firststring, "%s->%s", arg->argOutSegment, arg->argMsgField); (void)sprintf(string, "%s->%s.", arg->argOutSegment, arg->argMsgField); VarArray = it->itVarArray; howmany = it->itNumber; howbig = it->itSize; } fprintf(file, "#if\tUseStaticTemplates\n"); fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName); fprintf(file, "#else\t/* UseStaticTemplates */\n"); if (!VarArray) fprintf(file, "\t%ssize = %d;\n", string, (howmany * howbig + 7)/8); … more in source
WriteInitKPD_oolport source
argKPD_Init discipline for out-of-line Port types.
static void WriteInitKPD_oolport(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; boolean_t VarArray; ipc_type_t *howit; u_int howmany; char firststring[MAX_STR_LEN]; char string[MAX_STR_LEN]; if (IS_MULTIPLE_KPD(it)) { WriteKPD_Iterator(file, FALSE, FALSE, arg, TRUE); (void)sprintf(firststring, "\t*ptr"); (void)sprintf(string, "\tptr->"); VarArray = it->itElement->itVarArray; howmany = it->itElement->itNumber; howit = it->itElement; } else { (void)sprintf(firststring, "%s->%s", arg->argOutSegment, arg->argMsgField); (void)sprintf(string, "%s->%s.", arg->argOutSegment, arg->argMsgField); VarArray = it->itVarArray; howmany = it->itNumber; howit = it; } fprintf(file, "#if\tUseStaticTemplates\n"); fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName); fprintf(file, "#else\t/* UseStaticTemplates */\n"); … more in source
WriteInitKPDValue source
static void WriteInitKPDValue(FILE *file, argument_t *arg) { (*arg->argKPD_Init)(file, arg); }
WriteAdjustMsgCircular source
static void WriteAdjustMsgCircular(FILE *file, argument_t *arg) { fprintf(file, "\n"); fprintf(file,"#if\t__MigKernelSpecificCode\n"); if (arg->argType->itOutName == MACH_MSG_TYPE_POLYMORPHIC) fprintf(file, "\tif (%s == MACH_MSG_TYPE_PORT_RECEIVE)\n", arg->argPoly->argVarName); /* * The carried port right can be accessed in OutP->XXXX. Normally * the server function stuffs it directly there. If it is InOut, * then it has already been copied into the reply message. * If the server function deposited it into a variable (perhaps * because the reply message is variable-sized) then it has already * been copied into the reply message. * * The old MiG does not check for circularity in the case of * array of ports. So do I ... */ fprintf(file, "\t if (IP_VALID((ipc_port_t) %s->Head.msgh_reply_port) &&\n", InHeadSeg); fprintf(file, "\t IP_VALID((ipc_port_t) %s->%s.name) &&\n", arg->argOutSegment, arg->argMsgField); fprintf(file, "\t ipc_port_check_circularity((ipc_port_t) %s->%s.name, (ipc_port_t) %s->Head.msgh_reply_port))\n", arg->argOutSegment, arg->argMsgField, InHeadSeg); fprintf(file, "\t\t%s->Head.msgh_bits |= MACH_MSGH_BITS_CIRCULAR;\n", OutHeadSeg); fprintf(file, "#endif /* __MigKernelSpecificCode */\n"); }
WriteKPD_port source
argKPD_Pack discipline for Port types.
static void WriteKPD_port(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; char *subindex = ""; char *recast = ""; boolean_t close = FALSE; char string[MAX_STR_LEN]; ipc_type_t *real_it; if (akCheck(arg->argKind, akbVarNeeded)) { if (IS_MULTIPLE_KPD(it)) { WriteKPD_Iterator(file, FALSE, it->itVarArray, arg, TRUE); (void)sprintf(string, "\tptr->"); subindex = "[i]"; close = TRUE; real_it = it->itElement; } else { (void)sprintf(string, "%s->%s.", arg->argOutSegment, arg->argMsgField); real_it = it; } #ifdef MIG_KERNEL_PORT_CONVERSIONS if (IsKernelServer && streql(real_it->itTransType, "ipc_port_t")) recast = "(mach_port_t)"; #endif if (it->itOutTrans != strNULL && !close) fprintf(file, "\t%sname = (mach_port_t)%s(%s);\n", string, it->itOutTrans, arg->argVarName); else … more in source
WriteKPD_ool source
argKPD_Pack discipline for out-of-line types.
static void WriteKPD_ool(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; char string[MAX_STR_LEN]; boolean_t VarArray; argument_t *count; u_int howbig; char *subindex; if (IS_MULTIPLE_KPD(it)) { WriteKPD_Iterator(file, FALSE, it->itVarArray, arg, TRUE); (void)sprintf(string, "\tptr->"); VarArray = it->itElement->itVarArray; count = arg->argSubCount; howbig = it->itElement->itSize; subindex = "[i]"; } else { (void)sprintf(string, "%s->%s.", arg->argOutSegment, arg->argMsgField); VarArray = it->itVarArray; count = arg->argCount; howbig = it->itSize; subindex = ""; } if (akCheck(arg->argKind, akbVarNeeded)) fprintf(file, "\t%saddress = (void *)%s%s;\n", string, arg->argMsgField, subindex); if (arg->argDealloc != argNULL) if (akCheck(arg->argDealloc->argKind, akbVarNeeded) || IS_MULTIPLE_KPD(it)) … more in source
WriteKPD_oolport source
argKPD_Pack discipline for out-of-line Port types.
static void WriteKPD_oolport(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; boolean_t VarArray; argument_t *count; char *subindex, string[MAX_STR_LEN]; if (IS_MULTIPLE_KPD(it)) { WriteKPD_Iterator(file, FALSE, it->itVarArray, arg, TRUE); (void)sprintf(string, "\tptr->"); VarArray = it->itElement->itVarArray; count = arg->argSubCount; subindex = "[i]"; } else { (void)sprintf(string, "%s->%s.", arg->argOutSegment, arg->argMsgField); VarArray = it->itVarArray; count = arg->argCount; subindex = ""; } if (akCheck(arg->argKind, akbVarNeeded)) fprintf(file, "\t%saddress = (void *)%s%s;\n", string, arg->argMsgField, subindex); if (arg->argDealloc != argNULL) if (akCheck(arg->argDealloc->argKind, akbVarNeeded) || IS_MULTIPLE_KPD(it)) fprintf(file, "\t%sdeallocate = %s;\n", string, arg->argDealloc->argVarName); if (VarArray) { fprintf(file, "\t%scount = ", string); if (akCheck(count->argKind, akbVarNeeded)) … more in source
WriteTCheckKPD_port source
argKPD_TypeCheck discipline for Port types.
static void WriteTCheckKPD_port(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; char *tab = ""; char string[MAX_STR_LEN]; boolean_t close = FALSE; if (IS_MULTIPLE_KPD(it)) { WriteKPD_Iterator(file, TRUE, FALSE, arg, TRUE); (void)sprintf(string, "ptr->"); tab = "\t"; close = TRUE; } else (void)sprintf(string, "%s->%s.", arg->argInSegment, arg->argMsgField); fprintf(file, "\t%sif (%stype != MACH_MSG_PORT_DESCRIPTOR", tab, string); /* * We can't check disposition on varArray * (because some of the entries could be empty). */ if (!it->itVarArray) { if (arg->argPoly != argNULL) { switch (it->itOutName) { case MACH_MSG_TYPE_MOVE_RECEIVE: fprintf(file, " || \n\t%s %sdisposition != MACH_MSG_TYPE_MOVE_RECEIVE", tab, string); break; … more in source
WriteTCheckKPD_ool source
argKPD_TypeCheck discipline for out-of-line types.
static void WriteTCheckKPD_ool(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; char *tab, string[MAX_STR_LEN]; boolean_t test; u_int howmany, howbig; if (IS_MULTIPLE_KPD(it)) { WriteKPD_Iterator(file, TRUE, FALSE, arg, TRUE); tab = "\t\t\t"; sprintf(string, "ptr->"); howmany = it->itElement->itNumber; howbig = it->itElement->itSize; test = !it->itVarArray && !it->itElement->itVarArray; } else { tab = ""; sprintf(string, "%s->%s.", arg->argInSegment, arg->argMsgField); howmany = it->itNumber; howbig = it->itSize; test = !it->itVarArray; } fprintf(file, "\t%sif (%stype != MACH_MSG_OOL_DESCRIPTOR", tab, string); if (test) { /* if VarArray we may use no-op; if itElement->itVarArray size might change */ fprintf(file, " ||\n\t%s %ssize != %d", tab, string, (howmany * howbig + 7)/8); } … more in source
WriteTCheckKPD_oolport source
argKPD_TypeCheck discipline for out-of-line Port types.
static void WriteTCheckKPD_oolport(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; char *tab, string[MAX_STR_LEN]; boolean_t test; u_int howmany; char *howstr; if (IS_MULTIPLE_KPD(it)) { WriteKPD_Iterator(file, TRUE, FALSE, arg, TRUE); tab = "\t"; sprintf(string, "ptr->"); howmany = it->itElement->itNumber; test = !it->itVarArray && !it->itElement->itVarArray; howstr = it->itElement->itOutNameStr; } else { tab = ""; sprintf(string, "%s->%s.", arg->argInSegment, arg->argMsgField); howmany = it->itNumber; test = !it->itVarArray; howstr = it->itOutNameStr; } fprintf(file, "\t%sif (%stype != MACH_MSG_OOL_PORTS_DESCRIPTOR", tab, string); if (test) /* if VarArray we may use no-op; if itElement->itVarArray size might change */ fprintf(file, " ||\n\t%s %scount != %d", tab, string, howmany); if (arg->argPoly == argNULL) … more in source
WriteTypeCheck source
***********************************************************
Writes code to check that the type of each of the arguments
in the reply message is what is expected. Called by
WriteRoutine for each in && typed argument in the request message.
***********************************************************
static void WriteTypeCheck(FILE *file, argument_t *arg) { fprintf(file, "#if\t__MigTypeCheck\n"); (*arg->argKPD_TypeCheck)(file, arg); fprintf(file, "#endif\t/* __MigTypeCheck */\n"); }
WritePackArgValueNormal source
static void WritePackArgValueNormal(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; if (IS_VARIABLE_SIZED_UNTYPED(it) || it->itNoOptArray) { if (it->itString) { /* * Copy variable-size C string with mig_strncpy. * Save the string length (+ 1 for trailing 0) * in the argument`s count field. */ fprintf(file, "#ifdef USING_MIG_STRNCPY_ZEROFILL\n"); fprintf(file, "\tif (mig_strncpy_zerofill != NULL) {\n"); fprintf(file, "\t\t%s->%s = (%s) mig_strncpy_zerofill(%s->%s, %s, %d);\n", arg->argCount->argOutSegment, arg->argCount->argMsgField, arg->argCount->argType->itTransType, arg->argOutSegment, arg->argMsgField, arg->argVarName, it->itNumber); fprintf(file, "\t} else {\n"); fprintf(file, "#endif /* USING_MIG_STRNCPY_ZEROFILL */\n"); fprintf(file, "\t\t%s->%s = (%s) mig_strncpy(%s->%s, %s, %d);\n", arg->argCount->argOutSegment, arg->argCount->argMsgField, arg->argCount->argType->itTransType, arg->argOutSegment, arg->argMsgField, arg->argVarName, it->itNumber); fprintf(file, "#ifdef USING_MIG_STRNCPY_ZEROFILL\n"); fprintf(file, "\t}\n"); fprintf(file, "#endif /* USING_MIG_STRNCPY_ZEROFILL */\n"); fprintf(file, "\t%s->%sOffset = 0;\n", arg->argOutSegment, arg->argMsgField); } … more in source
WritePackArgValueVariable source
static void WritePackArgValueVariable(FILE *file, argument_t *arg) { ipc_type_t *it = arg->argType; /* * only itString are treated here so far */ if (it->itString) { /* * Emit logic to call strlen to calculate the size of the argument, and ensure that it fits within the 32-bit result field * in the Reply, when targeting a 64-bit architecture. If a 32-bit architecture is the target, we emit code to just call * strlen() directly (since it'll return a 32-bit value that is guaranteed to fit). */ fputs("#ifdef __LP64__\n", file); fprintf(file, "\t{\n" "\t\t" "size_t strLength = strlen(%s->%s) + 1;\n", arg->argOutSegment, arg->argMsgField); fprintf(file, "\t\t" "if (strLength > 0xffffffff)\n" "\t\t\t" "MIG_RETURN_ERROR(%s, MIG_BAD_ARGUMENTS);\n", OutHeadSeg); fprintf(file, "\t\t" "%s->%s = (mach_msg_type_number_t) strLength;\n" "\t}\n", arg->argCount->argOutSegment, arg->argCount->argMsgField); fputs("#else\n", file); fprintf(file, "\t%s->%s = (mach_msg_type_number_t) strlen(%s->%s) + 1;\n", arg->argCount->argOutSegment, arg->argCount->argMsgField, arg->argOutSegment, arg->argMsgField); fputs("#endif /* __LP64__ */\n", file); fprintf(file, "\t%s->%sOffset = 0;\n", arg->argCount->argOutSegment, arg->argMsgField); } }
WriteCopyArgValue source
static void WriteCopyArgValue(FILE *file, argument_t *arg) { fprintf(file, "\n"); char *field = (arg->argSuffix != strNULL) ? arg->argSuffix : arg->argMsgField; WriteCopyType(file, arg->argType, TRUE, "%s->%s", "/* %s %s */ %s->%s",arg->argOutSegment, field, arg->argInSegment, field); }
WriteInitArgValue source
static void WriteInitArgValue(FILE *file, argument_t *arg) { fprintf(file, "\n"); fprintf(file, "\t%s->%s = %s;\n\n", arg->argOutSegment, arg->argMsgField, arg->argVarName); }
WriteArgSize source
Calculate the size of a variable-length message field.
static void WriteArgSize(FILE *file, argument_t *arg) { ipc_type_t *ptype = arg->argType; int bsize = ptype->itElement->itTypeSize; argument_t *count = arg->argCount; /* If the base type size of the data field isn`t a multiple of 4, we have to round up. */ if (bsize % itWordAlign != 0) fprintf(file, "_WALIGN_"); /* Here, we generate ((value + %d) & ~%d). We have to put two (( at the * the beginning. */ fprintf(file, "(("); if (bsize > 1) fprintf(file, "%d * ", bsize); if (ptype->itString || !akCheck(count->argKind, akbVarNeeded)) /* get count from descriptor in message */ fprintf(file, "%s->%s", count->argOutSegment, count->argMsgField); else /* get count from argument */ fprintf(file, "%s", count->argVarName); /* * If the base type size is not a multiple of sizeof(natural_t), * we have to round up. */ if (bsize % sizeof(natural_t) != 0) … more in source
WriteAdjustMsgSize source
Adjust message size and advance reply pointer.
Called after packing a variable-length argument that
has more arguments following.
static void WriteAdjustMsgSize(FILE *file, argument_t *arg) { routine_t *rt = arg->argRoutine; ipc_type_t *ptype = arg->argType; /* There are more Out arguments. We need to adjust msgh_size and advance OutP, so we save the size of the current field in msgh_size_delta. */ fprintf(file, "\tmsgh_size_delta = "); WriteArgSize(file, arg); fprintf(file, ";\n"); if (rt->rtNumReplyVar == 1) { /* We can still address the message header directly. Fill in the size field. */ fprintf(file, "\t%s->Head.msgh_size = ", OutHeadSeg); rtMinReplySize(file, rt, "Reply"); fprintf(file, " + msgh_size_delta;\n"); } else if (arg->argReplyPos == 0) { /* First variable-length argument. The previous msgh_size value is the minimum reply size. */ fprintf(file, "\tmsgh_size = "); rtMinReplySize(file, rt, "Reply"); fprintf(file, " + msgh_size_delta;\n"); } … more in source
WriteFinishMsgSize source
Calculate the size of the message. Called after the
last argument has been packed.
static void WriteFinishMsgSize(FILE *file, argument_t *arg) { /* No more Out arguments. If this is the only variable Out argument, we can assign to msgh_size directly. */ if (arg->argReplyPos == 0) { fprintf(file, "\t%s->Head.msgh_size = ", OutHeadSeg); rtMinReplySize(file, arg->argRoutine, "Reply"); fprintf(file, " + ("); WriteArgSize(file, arg); fprintf(file, ");\n"); } else { fprintf(file, "\tmsgh_size += "); WriteArgSize(file, arg); fprintf(file, ";\n"); } }
WriteReplyArgs source
Handle reply arguments - fill in message types and copy arguments
that need to be copied.
static void WriteReplyArgs(FILE *file, routine_t *rt) { argument_t *arg; argument_t *lastVarArg; /* * 1. The Kernel Processed Data */ for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) if (akCheckAll(arg->argKind, akbReturnSnd|akbReturnKPD)) (*arg->argKPD_Pack)(file, arg); /* * 2. The Data Stream */ lastVarArg = argNULL; for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) { /* * Adjust message size and advance message pointer if * the last request argument was variable-length and the * request position will change. */ if (lastVarArg != argNULL && lastVarArg->argReplyPos < arg->argReplyPos) { WriteAdjustMsgSize(file, lastVarArg); lastVarArg = argNULL; } if (akCheckAll(arg->argKind, akbReturnSnd|akbReturnBody|akbVarNeeded)) WritePackArgValueNormal(file, arg); … more in source
WriteFieldDecl source
static void WriteFieldDecl(FILE *file, argument_t *arg) { if (akCheck(arg->argKind, akbSendKPD) || akCheck(arg->argKind, akbReturnKPD)) WriteFieldDeclPrim(file, arg, FetchKPDType); else WriteFieldDeclPrim(file, arg, FetchServerType); }
InitKPD_Disciplines source
static void InitKPD_Disciplines(argument_t *args) { argument_t *arg; extern void KPD_noop(FILE *file, argument_t *arg); extern void KPD_error(FILE *file, argument_t *arg); extern void WriteTemplateKPD_port(FILE *file, argument_t *arg, boolean_t in); extern void WriteTemplateKPD_ool(FILE *file, argument_t *arg, boolean_t in); extern void WriteTemplateKPD_oolport(FILE *file, argument_t *arg, boolean_t in); /* * WriteInitKPD_port, WriteKPD_port, WriteExtractKPD_port, * WriteInitKPD_ool, WriteKPD_ool, WriteExtractKPD_ool, * WriteInitKPD_oolport, WriteKPD_oolport, WriteExtractKPD_oolport * are local to this module (which is the reason why this initialization * takes place here rather than in utils.c). * Common routines for user and server will be established SOON, and * all of them (including the initialization) will be transfert to * utils.c * All the KPD disciplines are defaulted to be KPD_error(). * Note that akbSendKPD and akbReturnKPd are not exclusive, * because of inout type of parameters. */ for (arg = args; arg != argNULL; arg = arg->argNext) if (akCheck(arg->argKind, akbSendKPD|akbReturnKPD)) switch (arg->argKPD_Type) { case MACH_MSG_PORT_DESCRIPTOR: if akCheck(arg->argKind, akbSendKPD) { arg->argKPD_Extract = … more in source
WriteOOLSizeCheck source
static void WriteOOLSizeCheck(FILE *file, routine_t *rt) { /* Emit code to validate the actual size of ool data vs. the reported size */ argument_t *argPtr; boolean_t openedTypeCheckConditional = FALSE; // scan through arguments to see if there are any ool data blocks for (argPtr = rt->rtArgs; argPtr != NULL; argPtr = argPtr->argNext) { if (akCheck(argPtr->argKind, akbSendKPD)) { ipc_type_t *it = argPtr->argType; boolean_t multiple_kpd = IS_MULTIPLE_KPD(it); char string[MAX_STR_LEN]; boolean_t test; argument_t *argCountPtr; char *tab; if (argPtr->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR) { if (multiple_kpd) { if ( !openedTypeCheckConditional ) { openedTypeCheckConditional = TRUE; fputs("#if __MigTypeCheck\n", file); } WriteKPD_Iterator(file, TRUE, FALSE, argPtr, TRUE); tab = "\t"; sprintf(string, "ptr->"); test = !it->itVarArray && !it->itElement->itVarArray; it = it->itElement; // point to element descriptor, so size calculation is correct … more in source
WriteCheckRequest source
void WriteCheckRequest(FILE *file, routine_t *rt) { int i; /* initialize the disciplines for the handling of KPDs */ InitKPD_Disciplines(rt->rtArgs); fprintf(file, "\n"); fprintf(file, "#if ( __MigTypeCheck "); if (CheckNDR) fprintf(file, "|| __NDR_convert__ "); fprintf(file, ")\n"); fprintf(file, "#if __MIG_check__Request__%s_subsystem__\n", SubsystemName); fprintf(file, "#if !defined(__MIG_check__Request__%s_t__defined)\n", rt->rtName); fprintf(file, "#define __MIG_check__Request__%s_t__defined\n", rt->rtName); if (CheckNDR && akCheck(rt->rtNdrCode->argKind, akbRequest)) { __KernelServer_unreachable(); WriteList(file, rt->rtArgs, WriteRequestNDRConvertIntRepArgDecl, akbSendNdr, "", ""); WriteList(file, rt->rtArgs, WriteRequestNDRConvertCharRepArgDecl, akbSendNdr, "", ""); WriteList(file, rt->rtArgs, WriteRequestNDRConvertFloatRepArgDecl, akbSendNdr, "", ""); } fprintf(file, "\n"); if (!UseMachMsg2) { fprintf(file, "mig_internal kern_return_t __MIG_check__Request__%s_t(__attribute__((__unused__)) __Request__%s_t *In0P", rt->rtName, rt->rtName); for (i = 1; i <= rt->rtMaxRequestPos; i++) fprintf(file, ", __attribute__((__unused__)) __Request__%s_t **In%dPP", rt->rtName, i); } else { fprintf(file, "mig_internal kern_return_t __MIG_check__Request__%s_t(\n" … more in source
WriteCheckRequestCall source
void WriteCheckRequestCall(FILE *file, routine_t *rt) { int i; fprintf(file, "\n"); fprintf(file, "#if\tdefined(__MIG_check__Request__%s_t__defined)\n", rt->rtName); if (!UseMachMsg2) { fprintf(file, "\tcheck_result = __MIG_check__Request__%s_t((__Request *)In0P", rt->rtName); for (i = 1; i <= rt->rtMaxRequestPos; i++) fprintf(file, ", (__Request **)&In%dP", i); } else { fprintf(file, "\tcheck_result = __MIG_check__Request__%s_t((RequestK *)InKP, (__RequestU *)In0UP, InTrailerP", rt->rtName); for (i = 1; i <= rt->rtMaxRequestPos; i++) fprintf(file, ", (__RequestU **)&In%dUP", i); } fprintf(file, ");\n"); fprintf(file, "\tif (check_result != MACH_MSG_SUCCESS)\n"); fprintf(file, "\t\t{ MIG_RETURN_ERROR(%s, check_result); }\n", OutHeadSeg); fprintf(file, "#endif\t/* defined(__MIG_check__Request__%s_t__defined) */\n", rt->rtName); fprintf(file, "\n"); }
WriteCheckRequests source
void WriteCheckRequests(FILE *file, statement_t *stats) { statement_t *stat; for (stat = stats; stat != stNULL; stat = stat->stNext) if (stat->stKind == skRoutine) WriteCheckRequest(file, stat->stRoutine); }
WriteRoutine source
static void WriteRoutine(FILE *file, routine_t *rt) { /* Declare the server work function: */ if (ServerHeaderFileName == strNULL) WriteServerRoutine(file, rt); fprintf(file, "\n"); fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName); fprintf(file, "mig_internal novalue _X%s\n", rt->rtName); if (BeAnsiC) { if (!UseMachMsg2) { fprintf(file, "\t(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)\n"); } else { fprintf(file, "\t(mach_msg_header_t *InHeadP, __attribute__((__unused__)) void *InDataP,\n" "\t__attribute__((__unused__)) mach_msg_max_trailer_t *InTrailerP,\n" "\tmach_msg_header_t *OutHeadP, __attribute__((__unused__)) void *OutDataP)\n"); } } else { __KernelServer_unreachable(); fprintf(file, "#if\t%s\n", NewCDecl); fprintf(file, "\t(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)\n"); fprintf(file, "#else\n"); fprintf(file, "\t(InHeadP, OutHeadP)\n"); fprintf(file, "\tmach_msg_header_t *InHeadP, *OutHeadP;\n"); fprintf(file, "#endif\t/* %s */\n", NewCDecl); } … more in source
WriteServer source
void WriteServer(FILE *file, statement_t *stats) { statement_t *stat; WriteProlog(file, stats); if (BeAnsiC) WriteForwardDeclarations(file, stats); for (stat = stats; stat != stNULL; stat = stat->stNext) switch (stat->stKind) { case skRoutine: WriteCheckRequest(file, stat->stRoutine); WriteRoutine(file, stat->stRoutine); break; case skIImport: case skImport: case skSImport: case skDImport: case skUImport: break; default: fatal("WriteServer(): bad statement_kind_t (%d)", (int) stat->stKind); } WriteDispatcher(file, stats); }