summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavio Cruz <flaviocruz@gmail.com>2016-02-07 20:08:58 -0500
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2016-02-09 23:50:11 +0100
commite2e50a2471af7c8708d49323a3f000042a032b59 (patch)
tree05cf4b7abec488d81546ff9f4a9e7dabfd0c6630
parentc01a23d17a84fc42caba4031241c050e4a533d3f (diff)
Cast kernel server port arguments to the correct type.
* server.c: Add cast for ipc_port_t arguments that are handled differently. * type.c: Set itKernelPort when the mach_port_t is treated as a ipc_port_t. * type.h: Add itKernelPort to struct ipc_type.
-rw-r--r--server.c12
-rw-r--r--type.c11
-rw-r--r--type.h5
3 files changed, 24 insertions, 4 deletions
diff --git a/server.c b/server.c
index a08795b..37cb6e0 100644
--- a/server.c
+++ b/server.c
@@ -749,6 +749,18 @@ WriteServerCallArg(FILE *file, const argument_t *arg)
const ipc_type_t *it = arg->argType;
boolean_t NeedClose = FALSE;
+ if (IsKernelServer) {
+ /* If the type (incl. array) is handled differently, then we need to
+ cast it to the real argument type. */
+ if (it->itKernelPort ||
+ it->itInLine && it->itVarArray && it->itElement->itKernelPort) {
+ /* Some arguments are transformed into the correct type already. */
+ if (!akCheckAll(arg->argKind, akbSendRcv|akbVarNeeded))
+ fprintf(file, "(%s%s)", it->itTransType,
+ arg->argByReferenceServer ? "*" : "");
+ }
+ }
+
if (arg->argByReferenceServer)
fprintf(file, "&");
diff --git a/type.c b/type.c
index 7565f34..4450b52 100644
--- a/type.c
+++ b/type.c
@@ -219,16 +219,19 @@ itCalculateNameInfo(ipc_type_t *it)
(((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) &&
(it->itOutName == MACH_MSG_TYPE_POLYMORPHIC)) ||
MACH_MSG_TYPE_PORT_ANY(it->itInName) ||
- MACH_MSG_TYPE_PORT_ANY(it->itOutName)))
+ MACH_MSG_TYPE_PORT_ANY(it->itOutName))) {
it->itServerType = "ipc_port_t";
-
- if (IsKernelUser &&
+ it->itKernelPort = TRUE;
+ } else if (IsKernelUser &&
streql(it->itUserType, "mach_port_t") &&
(((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) &&
(it->itOutName == MACH_MSG_TYPE_POLYMORPHIC)) ||
MACH_MSG_TYPE_PORT_ANY(it->itInName) ||
- MACH_MSG_TYPE_PORT_ANY(it->itOutName)))
+ MACH_MSG_TYPE_PORT_ANY(it->itOutName))) {
it->itUserType = "ipc_port_t";
+ it->itKernelPort = TRUE;
+ } else
+ it->itKernelPort = FALSE;
if (it->itTransType == strNULL)
it->itTransType = it->itServerType;
diff --git a/type.h b/type.h
index 50de063..6cf5d63 100644
--- a/type.h
+++ b/type.h
@@ -129,6 +129,10 @@ typedef enum dealloc {
*
* itElement points to any substructure that the type may have.
* It is only used with variable-sized array types.
+ *
+ * itKernelPort is used only on kernel interfaces and is set to TRUE when
+ * the initial type is mach_port_t, which in turn is actually translated to
+ * internal port pointers (ipc_port_t).
*/
typedef struct ipc_type
@@ -158,6 +162,7 @@ typedef struct ipc_type
boolean_t itString;
boolean_t itVarArray;
boolean_t itIndefinite;
+ boolean_t itKernelPort;
struct ipc_type *itElement; /* may be NULL */