aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS7
-rw-r--r--lexxer.l1
-rw-r--r--parser.h1
-rw-r--r--parser.y17
-rw-r--r--routine.c4
-rw-r--r--server.c39
-rw-r--r--type.c10
-rw-r--r--type.h2
8 files changed, 75 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 9fc6b3d..c4bed78 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,13 @@
2013-XX-XX
Version 1.5
+* Add support for protected payloads. The new `intranpayload' option
+ can be used to specify a translation function translating payloads
+ to values of the translated type. This function will be used
+ instead of the `intran' function to to look up the receiving object
+ of a message in a server. This makes it easy to use the protected
+ payloads introduced in GNU Mach 1.5.
+
* Emit `X_server_routine' functions that can be inlined reducing the
message dispatch overhead.
diff --git a/lexxer.l b/lexxer.l
index 5f2f61e..7ff5677 100644
--- a/lexxer.l
+++ b/lexxer.l
@@ -138,6 +138,7 @@ static void doSharp(const char *body); /* process body of # directives */
<Normal>[Ss][Kk][Ii][Pp] RETURN(sySkip);
<Normal>[Ss][Tt][Rr][Uu][Cc][Tt] RETURN(syStruct);
<Normal>[Ii][Nn][Tt][Rr][Aa][Nn] RETURN(syInTran);
+<Normal>[Ii][Nn][Tt][Rr][Aa][Nn][Pp][Aa][Yy][Ll][Oo][Aa][Dd] RETURN(syInTranPayload);
<Normal>[Oo][Uu][Tt][Tt][Rr][Aa][Nn] RETURN(syOutTran);
<Normal>[Dd][Ee][Ss][Tt][Rr][Uu][Cc][Tt][Oo][Rr] RETURN(syDestructor);
<Normal>[Cc][Tt][Yy][Pp][Ee] RETURN(syCType);
diff --git a/parser.h b/parser.h
index 651b66e..96e9b5d 100644
--- a/parser.h
+++ b/parser.h
@@ -82,6 +82,7 @@ typedef union
#define syQString 319
#define syFileName 320
#define syIPCFlag 321
+#define syInTranPayload 322
extern YYSTYPE yylval;
diff --git a/parser.y b/parser.y
index a916cb3..e88fd22 100644
--- a/parser.y
+++ b/parser.y
@@ -98,6 +98,8 @@
%token <string> syFileName
%token <flag> syIPCFlag
+%token syInTranPayload
+
%left syPlus syMinus
%left syStar syDiv
@@ -365,6 +367,21 @@ TransTypeSpec : TypeSpec
$$->itServerType, $7);
$$->itServerType = $7;
}
+ | TransTypeSpec syInTranPayload syColon
+ syIdentifier syIdentifier
+{
+ $$ = $1;
+
+ if (($$->itTransType != strNULL) && !streql($$->itTransType, $4))
+ warn("conflicting translation types (%s, %s)",
+ $$->itTransType, $4);
+ $$->itTransType = $4;
+
+ if (($$->itInTransPayload != strNULL) && !streql($$->itInTransPayload, $5))
+ warn("conflicting in-translation functions (%s, %s)",
+ $$->itInTransPayload, $5);
+ $$->itInTransPayload = $5;
+}
| TransTypeSpec syOutTran syColon syIdentifier
syIdentifier syLParen syIdentifier syRParen
{
diff --git a/routine.c b/routine.c
index 94e2b4c..ddf5770 100644
--- a/routine.c
+++ b/routine.c
@@ -540,6 +540,7 @@ rtAugmentArgKind(argument_t *arg)
* 6) This is a dealloc arg, being returned. The name can't be
* stored directly into the msg_type, because the msg-type
* field is a bit-field.
+ * 7) There is a payload-aware translate-in function defined.
*/
if (((it->itOutTrans != strNULL) &&
@@ -555,7 +556,8 @@ rtAugmentArgKind(argument_t *arg)
((akIdent(arg->argKind) == akePoly) &&
akCheck(arg->argKind, akbReturnSnd)) ||
((akIdent(arg->argKind) == akeDealloc) &&
- akCheck(arg->argKind, akbReturnSnd)))
+ akCheck(arg->argKind, akbReturnSnd)) ||
+ (it->itInTransPayload != strNULL))
{
arg->argKind = akRemFeature(arg->argKind, akbReplyCopy);
arg->argKind = akAddFeature(arg->argKind, akbVarNeeded);
diff --git a/server.c b/server.c
index a3368f6..ae5977f 100644
--- a/server.c
+++ b/server.c
@@ -587,14 +587,45 @@ static void
WriteExtractArgValue(FILE *file, const argument_t *arg)
{
const ipc_type_t *it = arg->argType;
+ boolean_t have_payload;
if (arg->argMultiplier > 1)
WriteCopyType(file, it, "%s", "/* %s */ %s / %d",
arg->argVarName, InArgMsgField(arg), arg->argMultiplier);
- else if (it->itInTrans != strNULL)
- WriteCopyType(file, it, "%s", "/* %s */ %s(%s)",
- arg->argVarName, it->itInTrans, InArgMsgField(arg));
- else
+ else if ((have_payload = (it->itInTransPayload != strNULL &&
+ strcmp(arg->argMsgField, "Head.msgh_request_port") == 0)) ||
+ it->itInTrans != strNULL) {
+
+ if (have_payload) {
+ argument_t argPayload = *arg;
+ argPayload.argMsgField = "Head.msgh_bits";
+ fprintf(file,
+ "\tif (MACH_MSGH_BITS_LOCAL (%s) == "
+ "MACH_MSG_TYPE_PROTECTED_PAYLOAD)\n"
+ "\t", InArgMsgField(&argPayload));
+
+ argPayload.argMsgField = "Head.msgh_protected_payload";
+ WriteCopyType(file, it, "%s", "/* %s */ %s(%s)",
+ arg->argVarName, it->itInTransPayload,
+ InArgMsgField(&argPayload));
+
+ fprintf(file,
+ "\telse\n"
+ "\t");
+
+ if (it->itInTrans == strNULL)
+ fprintf(file, "\t%s = %s;",
+ arg->argVarName, InArgMsgField(arg));
+ else
+ WriteCopyType(file, it, "%s", "/* %s */ %s(%s)",
+ arg->argVarName, it->itInTrans,
+ InArgMsgField(arg));
+ } else {
+ WriteCopyType(file, it, "%s", "/* %s */ %s(%s)",
+ arg->argVarName, it->itInTrans,
+ InArgMsgField(arg));
+ }
+ } else
WriteCopyType(file, it, "%s", "/* %s */ %s",
arg->argVarName, InArgMsgField(arg));
fprintf(file, "\n");
diff --git a/type.c b/type.c
index 3078dab..7565f34 100644
--- a/type.c
+++ b/type.c
@@ -118,6 +118,7 @@ itAlloc(void)
strNULL, /* identifier_t itServerType */
strNULL, /* identifier_t itTransType */
strNULL, /* identifier_t itInTrans */
+ strNULL, /* identifier_t itInTransPayload */
strNULL, /* identifier_t itOutTrans */
strNULL, /* identifier_t itDestructor */
};
@@ -376,7 +377,9 @@ itCheckDecl(identifier_t name, ipc_type_t *it)
limitations in Mig */
if (it->itVarArray) {
- if ((it->itInTrans != strNULL) || (it->itOutTrans != strNULL))
+ if ((it->itInTrans != strNULL) ||
+ (it->itInTransPayload != strNULL) ||
+ (it->itOutTrans != strNULL))
error("%s: can't translate variable-sized arrays", name);
if (it->itDestructor != strNULL)
@@ -419,6 +422,10 @@ itPrintTrans(const ipc_type_t *it)
printf("\tInTran:\t\t%s %s(%s)\n",
it->itTransType, it->itInTrans, it->itServerType);
+ if (it->itInTransPayload != strNULL)
+ printf("\tInTranPayload:\t\t%s %s\n",
+ it->itTransType, it->itInTransPayload);
+
if (it->itOutTrans != strNULL)
printf("\tOutTran:\t%s %s(%s)\n",
it->itServerType, it->itOutTrans, it->itTransType);
@@ -556,6 +563,7 @@ itResetType(ipc_type_t *old)
/* reset all special translation/destruction/type info */
old->itInTrans = strNULL;
+ old->itInTransPayload = strNULL;
old->itOutTrans = strNULL;
old->itDestructor = strNULL;
old->itUserType = strNULL;
diff --git a/type.h b/type.h
index f199059..50de063 100644
--- a/type.h
+++ b/type.h
@@ -107,6 +107,7 @@ typedef enum dealloc {
* cusertype: itUserType
* cservertype: itServerType
* intran: itTransType itInTrans(itServerType)
+ * intranpayload: itTransType itInTransPayload
* outtran: itServerType itOutTrans(itTransType)
* destructor: itDestructor(itTransType);
*
@@ -165,6 +166,7 @@ typedef struct ipc_type
identifier_t itTransType;
identifier_t itInTrans; /* may be NULL */
+ identifier_t itInTransPayload; /* may be NULL */
identifier_t itOutTrans; /* may be NULL */
identifier_t itDestructor; /* may be NULL */
} ipc_type_t;