diff options
Diffstat (limited to 'server.c')
-rw-r--r-- | server.c | 155 |
1 files changed, 119 insertions, 36 deletions
@@ -455,10 +455,27 @@ WriteTypeCheck(FILE *file, const argument_t *arg) arg->argRequestPos, arg->argTTName, arg->argLongForm ? "l" : "", it->itNumber); - fprintf(file, "\t (In%dP->%s.msgt%s_size != %d)))\n", - arg->argRequestPos, arg->argTTName, - arg->argLongForm ? "l" : "", - it->itSize); + if (IS_64BIT_ABI && it->itUserlandPort && arg->argLongForm) { + /* 64 bit inlined ports are 8 bytes long but we use mach_port_name_t when passing them out of line. */ + fprintf(file, "\t (In%dP->%s.msgtl_size != %d && In%dP->%s.msgtl_header.msgt_inline == TRUE) || \n", + arg->argRequestPos, + arg->argTTName, + it->itSize, + arg->argRequestPos, + arg->argTTName); + fprintf(file, "\t (In%dP->%s.msgtl_size != %d && In%dP->%s.msgtl_header.msgt_inline == FALSE)", + arg->argRequestPos, + arg->argTTName, + port_name_size_in_bits, + arg->argRequestPos, + arg->argTTName); + } else { + fprintf(file, "\t (In%dP->%s.msgt%s_size != %d)", + arg->argRequestPos, arg->argTTName, + arg->argLongForm ? "l" : "", + it->itSize); + } + fprintf(file, "))\n"); } WriteMsgError(file, "MIG_BAD_ARGUMENTS"); fprintf(file, "#endif\t/* TypeCheck */\n"); @@ -565,6 +582,7 @@ static const char * InArgMsgField(const argument_t *arg) { static char buffer[100]; + const ipc_type_t *it = arg->argType; /* * Inside the kernel, the request and reply port fields @@ -588,6 +606,9 @@ static void WriteExtractArgValue(FILE *file, const argument_t *arg) { const ipc_type_t *it = arg->argType; + const bool is_inlined_port = it->itUserlandPort && it->itInLine && + akIdent(arg->argKind) != akeRequestPort && akIdent(arg->argKind) != akeReplyPort; + const char* arg_suffix = is_inlined_port ? ".name" : ""; bool have_payload; if (arg->argMultiplier > 1) @@ -618,17 +639,18 @@ WriteExtractArgValue(FILE *file, const argument_t *arg) fprintf(file, "\t%s = %s;", arg->argVarName, InArgMsgField(arg)); else - WriteCopyType(file, it, "%s", "/* %s */ %s(%s)", + WriteCopyType(file, it, "%s", "/* %s */ %s(%s%s)", arg->argVarName, it->itInTrans, - InArgMsgField(arg)); + InArgMsgField(arg), arg_suffix); } else { - WriteCopyType(file, it, "%s", "/* %s */ %s(%s)", + WriteCopyType(file, it, "%s", "/* %s */ %s(%s%s)", arg->argVarName, it->itInTrans, - InArgMsgField(arg)); + InArgMsgField(arg), arg_suffix); } - } else - WriteCopyType(file, it, "%s", "/* %s */ %s", - arg->argVarName, InArgMsgField(arg)); + } else { + WriteCopyType(file, it, "%s", "/* %s */ %s%s", + arg->argVarName, InArgMsgField(arg), arg_suffix); + } fprintf(file, "\n"); } @@ -745,12 +767,34 @@ WriteExtractArg(FILE *file, const argument_t *arg) if (akCheckAll(arg->argKind, akbReturnSnd|akbPointer)) WriteInitializePtr(file, arg); + if (akCheckAll(arg->argKind, akbSendRcv|akbPointer)) { + if (akCheck(arg->argKind, akbIndefinite)) { + fprintf(file, "\tif (In%dP->%s%s.msgt_inline) {\n", + arg->argRequestPos, arg->argTTName, arg->argLongForm ? ".msgtl_header" : ""); + fprintf(file, "\t\t%sP = (mach_port_t *)%s;\n", arg->argVarName, InArgMsgField(arg)); + fprintf(file, "\t\tmach_msg_type_number_t i;\n"); + fprintf(file, "\t\t/* Resizes the mach_port_name_inlined_t input array as an array of mach_port_name_t. */\n"); + fprintf(file, "\t\tfor (i = 1; i < In%dP->%s.msgt%s_number; i++) {\n", + arg->argRequestPos, arg->argTTName, arg->argLongForm ? "l" : ""); + fprintf(file, "\t\t\t%sP[i] = %s[i].name;\n", arg->argVarName, InArgMsgField(arg)); + fprintf(file, "\t\t}\n"); + fprintf(file, "\t} else {\n"); + fprintf(file, "\t\t%sP = %s%s;\n", arg->argVarName, InArgMsgField(arg), OOLPostfix); + fprintf(file, "\t}\n"); + } + else + assert(false); + } } static void WriteServerCallArg(FILE *file, const argument_t *arg) { const ipc_type_t *it = arg->argType; + const bool is_inlined_port = it->itUserlandPort && + akIdent(arg->argKind) != akeRequestPort && akIdent(arg->argKind) != akeReplyPort && it->itInLine; + const char* arg_suffix = is_inlined_port ? ".name" : ""; + bool NeedClose = false; if (IsKernelServer) { @@ -792,10 +836,10 @@ WriteServerCallArg(FILE *file, const argument_t *arg) OOLPostfix); } else - fprintf(file, "%s", InArgMsgField(arg)); + fprintf(file, "%s%s", InArgMsgField(arg), arg_suffix); } else - fprintf(file, "OutP->%s", arg->argMsgField); + fprintf(file, "OutP->%s%s", arg->argMsgField, arg_suffix); if (NeedClose) fprintf(file, ")"); @@ -818,7 +862,7 @@ WriteDestroyArg(FILE *file, const argument_t *arg) */ argument_t *count = arg->argCount; ipc_type_t *btype = it->itElement; - int multiplier = btype->itTypeSize / btype->itNumber; + int multiplier = it->itUserlandPort ? port_name_size : btype->itTypeSize / btype->itNumber; fprintf(file, "\tif (OutP->%s == KERN_SUCCESS)\n", arg->argRoutine->rtRetCode->argMsgField); @@ -938,6 +982,8 @@ static void WritePackArgValue(FILE *file, const argument_t *arg) { const ipc_type_t *it = arg->argType; + const bool is_inlined_port = it->itUserlandPort && it->itInLine; + const char* arg_suffix = is_inlined_port ? ".name" : ""; fprintf(file, "\n"); @@ -965,6 +1011,7 @@ WritePackArgValue(FILE *file, const argument_t *arg) else { argument_t *count = arg->argCount; ipc_type_t *btype = it->itElement; + const bool is_64bit_port = IS_64BIT_ABI && btype->itUserlandPort; /* Note btype->itNumber == count->argMultiplier */ @@ -988,26 +1035,41 @@ WritePackArgValue(FILE *file, const argument_t *arg) arg->argTTName, arg->argLongForm ? ".msgtl_header" : "", arg->argDealloc->argVarName); + if (is_64bit_port) { + /* We are passing the ports out of line, so they will always have the same size as a port name. */ + fprintf(file, "\t\tOutP->%s%s.msgt_size = %d;\n", + arg->argTTName, + arg->argLongForm ? ".msgtl_header" : "", + port_name_size_in_bits); + } fprintf(file, "\t\tOutP->%s%s = %sP;\n", - arg->argMsgField, - OOLPostfix, - arg->argVarName); + arg->argMsgField, + OOLPostfix, + arg->argVarName); if (!arg->argRoutine->rtSimpleFixedReply) fprintf(file, "\t\tmsgh_simple = FALSE;\n"); - fprintf(file, "\t}\n\telse {\n\t"); + fprintf(file, "\t}\n\telse {\n"); + } + fprintf(file, "\t\tif (%s) {\n", count->argVarName); + if (it->itIndefinite) { + if (is_64bit_port) { + fprintf(file, "\t\t\t/* Copy array of mach_port_name_t into mach_port_name_inlined_t. */\n"); + fprintf(file, "\t\t\tmach_msg_type_number_t i;\n"); + fprintf(file, "\t\t\tfor(i = 0; i < %s; i++) {\n", count->argVarName); + fprintf(file, "\t\t\t\t/* Clear the whole message with zeros. */\n"); + fprintf(file, "\t\t\t\tOutP->%s[i].kernel_port_do_not_use = 0;\n", arg->argMsgField); + fprintf(file, "\t\t\t\tOutP->%s[i].name = %s[i];\n", arg->argMsgField, arg->argVarName); + fprintf(file, "\t\t\t}\n"); + } else { + fprintf(file, "\t\t\tmemcpy(OutP->%s, %s, ", + arg->argMsgField, arg->argVarName); + if (btype->itTypeSize > 1) + fprintf(file, "%d * ", btype->itTypeSize); + fprintf(file, "%s);\n", count->argVarName); + } } - fprintf(file, "\tif (%s)\n", count->argVarName); - if (it->itIndefinite) - fprintf(file, "\t"); - fprintf(file, "\t\tmemcpy(OutP->%s, %s, ", - arg->argMsgField, arg->argVarName); - if (btype->itTypeSize > 1) - fprintf(file, "%d * ", - btype->itTypeSize); - fprintf(file, "%s);\n", - count->argVarName); - if (it->itIndefinite) - fprintf(file, "\t}\n"); + fprintf(file, "\t\t}\n"); + fprintf(file, "\t}\n"); } } else if (arg->argMultiplier > 1) @@ -1015,12 +1077,12 @@ WritePackArgValue(FILE *file, const argument_t *arg) arg->argMsgField, arg->argMultiplier, arg->argVarName); - else if (it->itOutTrans != strNULL) - WriteCopyType(file, it, "OutP->%s", "/* %s */ %s(%s)", - arg->argMsgField, it->itOutTrans, arg->argVarName); - else - WriteCopyType(file, it, "OutP->%s", "/* %s */ %s", - arg->argMsgField, arg->argVarName); + else if (it->itOutTrans != strNULL) { + WriteCopyType(file, it, "OutP->%s%s", "/* %s%s */ %s(%s)", + arg->argMsgField, arg_suffix, it->itOutTrans, arg->argVarName); + } else + WriteCopyType(file, it, "OutP->%s%s", "/* %s%s */ %s", + arg->argMsgField, arg_suffix, arg->argVarName); } static void @@ -1198,6 +1260,8 @@ WritePackArg(FILE *file, const argument_t *arg) fprintf(file, "\tOutP->%s = strlen(OutP->%s) + 1;\n", arg->argCount->argMsgField, arg->argMsgField); } else if (it->itIndefinite) { + const bool is_64bit_port = IS_64BIT_ABI && it->itUserlandPort; + /* * We know that array is in reply message. */ @@ -1216,12 +1280,31 @@ WritePackArg(FILE *file, const argument_t *arg) arg->argTTName, arg->argLongForm ? ".msgtl_header" : "", arg->argDealloc->argVarName); + if (is_64bit_port) { + /* We are passing the ports out of line, so they will always have the same size as a port name. */ + fprintf(file, "\t\tOutP->%s%s.msgt_size = %d;\n", + arg->argTTName, + arg->argLongForm ? ".msgtl_header" : "", + port_name_size_in_bits); + } fprintf(file, "\t\tOutP->%s%s = %sP;\n", arg->argMsgField, OOLPostfix, arg->argVarName); if (!arg->argRoutine->rtSimpleFixedReply) fprintf(file, "\t\tmsgh_simple = FALSE;\n"); + if (is_64bit_port) { + fprintf(file, "\t} else {\n"); + fprintf(file, "\t\t/* Resize mach_port_name_t array into mach_port_name_inlined_t. */\n"); + fprintf(file, "\t\t/* Work in reverse order to avoid overriding subsequent entries. */\n"); + fprintf(file, "\t\tmach_msg_type_number_t i;\n"); + fprintf(file, "\t\tfor(i = %s; i > 0; i--) {\n", arg->argCount->argVarName); + fprintf(file, "\t\t\tmach_port_name_t tmp_port_name = %sP[i - 1];\n", arg->argVarName); + fprintf(file, "\t\t\t/* Clear the whole message with zeros. */\n"); + fprintf(file, "\t\t\tOutP->%s[i - 1].kernel_port_do_not_use = 0;\n", arg->argMsgField); + fprintf(file, "\t\t\tOutP->%s[i - 1].name = tmp_port_name;\n", arg->argMsgField, arg->argVarName); + fprintf(file, "\t\t}\n"); + } fprintf(file, "\t}\n"); } } |