summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2013-11-25 13:46:41 +0100
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-10-10 15:11:48 +0200
commit003b3a589a0db5eb1db9376d707f3ca68220dba0 (patch)
treecd3d8b0850751cb6323ec147a9807cb40108cfbd
parent4d0503d0040fd1ba590d3c7cd68b444bfcbbae5a (diff)
Add support for protected payloads
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. An inTransPayload function translates payloads to objects, like an inTrans function translates from port names to objects. Generate code in the server routine to optimize lookups to the receiver of the message. Additionally, if no intran function is provided, but an intranpayload function is, it is expected to translate from payloads to port names. This is used to preserve the semantics in case the server routine expects a port name. * NEWS: Add item. * lexxer.l: Emit syInTranPayload. * parser.h: Define syInTranPayload. * parser.y (TransTypeSpec): Handle syInTranPayload. * type.h (struct ipc_type): Add itInTransPayload. * server.c (WriteExtractArgValue): If a payload-aware intrans function has been specified, use it to get a reference to the receiving object. * routine.c (rtAugmentArgKind): Force the use of a local variable if a payload-aware translate-in function is defined.
-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;