summaryrefslogtreecommitdiff
path: root/type.c
diff options
context:
space:
mode:
Diffstat (limited to 'type.c')
-rw-r--r--type.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/type.c b/type.c
index c46f8f8..aaa01f9 100644
--- a/type.c
+++ b/type.c
@@ -121,6 +121,7 @@ itAlloc(void)
false, /* bool itString */
false, /* bool itVarArray */
false, /* bool itIndefinite */
+ false, /* bool itUserlandPort */
false, /* bool itKernelPort */
itNULL, /* ipc_type_t *itElement */
strNULL, /* identifier_t itUserType */
@@ -195,6 +196,15 @@ itCalculateSizeInfo(ipc_type_t *it)
warn("sizeof(%s) == 0", it->itName);
}
+static bool
+itIsPortType(ipc_type_t *it)
+{
+ return ((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);
+}
+
/*
* Fill in default values for some fields used in code generation:
* itInNameStr, itOutNameStr, itUserType, itServerType, itTransType
@@ -213,6 +223,10 @@ itCalculateNameInfo(ipc_type_t *it)
if (it->itServerType == strNULL)
it->itServerType = it->itName;
+ bool isPortType = itIsPortType(it);
+ bool isServerPort = isPortType && streql(it->itServerType, "mach_port_t");
+ bool isUserPort = isPortType && streql(it->itUserType, "mach_port_t");
+
/*
* KernelServer and KernelUser interfaces get special treatment here.
* On the kernel side of the interface, ports are really internal
@@ -226,25 +240,23 @@ itCalculateNameInfo(ipc_type_t *it)
* hand-conditionalizing on KERNEL_SERVER and KERNEL_USER.
*/
- if (IsKernelServer &&
- streql(it->itServerType, "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))) {
+ if (IsKernelServer && isServerPort) {
it->itServerType = "ipc_port_t";
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))) {
+ } else if (IsKernelUser && isUserPort) {
it->itUserType = "ipc_port_t";
it->itKernelPort = true;
} else
it->itKernelPort = false;
+ /*
+ * In 64 bits, ports are inlined as 8 bytes even though mach_port_t or
+ * mach_port_name_t are always 4 bytes. We do this to avoid slow message
+ * resizing inside the gnumach by ensuring inlined port names in messages
+ * are always 8 bytes long.
+ */
+ it->itUserlandPort = isPortType && !IsKernelUser && !IsKernelServer;
+
if (it->itTransType == strNULL)
it->itTransType = it->itServerType;
}