summaryrefslogtreecommitdiff
path: root/utils/rpctrace.c
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2013-11-28 12:21:49 +0100
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-12-07 15:38:18 +0100
commit02ae7e436efa33b11227c251eb9bb3a036082fe1 (patch)
tree8622c87d4dea705d0e66a86483eb276442d9b4ba /utils/rpctrace.c
parent2e43e93b78786c42828867057818888c306ded1f (diff)
utils/rpctrace: make `trace_and_forward' payload-aware
As the protected payloads were retrofitted into the Mach message format, the local port type is lost. * utils/rpctrace.c (is_notification): New function (trace_and_forward): Recover the original local port type.
Diffstat (limited to 'utils/rpctrace.c')
-rw-r--r--utils/rpctrace.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index c954e515..62d3c876 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -1195,6 +1195,16 @@ wrap_new_task (mach_msg_header_t *inp, struct req_info *req)
ports_port_deref (task_wrapper1);
}
+/* Returns true if the given message is a Mach notification. */
+static inline int
+is_notification (const mach_msg_header_t *InHeadP)
+{
+ int msgh_id = InHeadP->msgh_id - 64;
+ if ((msgh_id > 8) || (msgh_id < 0))
+ return 0;
+ return 1;
+}
+
int
trace_and_forward (mach_msg_header_t *inp, mach_msg_header_t *outp)
{
@@ -1219,7 +1229,24 @@ trace_and_forward (mach_msg_header_t *inp, mach_msg_header_t *outp)
/* Look up our record for the receiving port. There is no need to check
the class, because our port bucket only ever contains one class of
ports (traced_class). */
- info = ports_lookup_port (traced_bucket, inp->msgh_local_port, 0);
+
+ if (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) == MACH_MSG_TYPE_PROTECTED_PAYLOAD)
+ {
+ info = ports_lookup_payload (traced_bucket, inp->msgh_protected_payload,
+ NULL);
+ if (info)
+ {
+ /* Undo the protected payload optimization. */
+ inp->msgh_bits = MACH_MSGH_BITS (
+ MACH_MSGH_BITS_REMOTE (inp->msgh_bits),
+ is_notification (inp)? MACH_MSG_TYPE_MOVE_SEND_ONCE: info->type)
+ | MACH_MSGH_BITS_OTHER (inp->msgh_bits);
+ inp->msgh_local_port = ports_payload_get_name (info);
+ }
+ }
+ else
+ info = ports_lookup_port (traced_bucket, inp->msgh_local_port, NULL);
+
assert (info);
/* A notification message from the kernel appears to have been sent