diff -ur -x 'Makefile*' -x debian -x configure -x config.sub -x config.guess gnumach-1.8+git20171101/include/mach/task_special_ports.h mnt/root/gnumach-1.8+git20171101/include/mach/task_special_ports.h --- gnumach-1.8+git20171101/include/mach/task_special_ports.h 2014-03-17 14:29:32.000000000 -0400 +++ mnt/root/gnumach-1.8+git20171101/include/mach/task_special_ports.h 2018-03-06 22:31:19.000000000 -0500 @@ -40,6 +40,8 @@ #define TASK_EXCEPTION_PORT 3 /* Exception messages for task are sent to this port. */ #define TASK_BOOTSTRAP_PORT 4 /* Bootstrap environment for task. */ +#define TASK_TRACE_PORT 5 /* Trace port that receives a copy + of all messages sent to/from task. */ /* * Definitions for ease of use @@ -63,4 +65,10 @@ #define task_set_bootstrap_port(task, port) \ (task_set_special_port((task), TASK_BOOTSTRAP_PORT, (port))) +#define task_get_trace_port(task, port) \ + (task_get_special_port((task), TASK_TRACE_PORT, (port))) + +#define task_set_trace_port(task, port) \ + (task_set_special_port((task), TASK_TRACE_PORT, (port))) + #endif /* _MACH_TASK_SPECIAL_PORTS_H_ */ diff -ur -x 'Makefile*' -x debian -x configure -x config.sub -x config.guess gnumach-1.8+git20171101/ipc/ipc_kmsg.c mnt/root/gnumach-1.8+git20171101/ipc/ipc_kmsg.c --- gnumach-1.8+git20171101/ipc/ipc_kmsg.c 2016-12-19 09:53:33.000000000 -0500 +++ mnt/root/gnumach-1.8+git20171101/ipc/ipc_kmsg.c 2018-03-07 00:08:16.000000000 -0500 @@ -2627,6 +2627,73 @@ } } +/* + * Routine: ipc_kmsg_trace + * Purpose: + * If the current task has a trace port set, send a duplicate + * copy of the message to the trace port. + * Conditions: + * Nothing locked. + */ + +typedef struct { + mach_msg_header_t header; + mach_msg_type_t retval_type; + mach_msg_return_t retval; + mach_msg_type_long_t trace_message_type; +} mach_trace_message_t; + +static mach_trace_message_t trace_template = { + .header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0), + + .retval_type.msgt_name = MACH_MSG_TYPE_INTEGER_32, + .retval_type.msgt_size = 32, + .retval_type.msgt_number = 1, + .retval_type.msgt_inline = TRUE, + .retval_type.msgt_longform = FALSE, + + .trace_message_type.msgtl_header.msgt_inline = TRUE, + .trace_message_type.msgtl_header.msgt_longform = TRUE, + .trace_message_type.msgtl_name = MACH_MSG_TYPE_BYTE, + .trace_message_type.msgtl_size = 8 +}; + +void +ipc_kmsg_trace( + ipc_kmsg_t kmsg, + mach_msg_size_t size, + mach_msg_return_t retval) +{ + if (current_task()->itk_trace != MACH_PORT_NULL) { + + /* XXX: check to make sure trace port doesn't belong to current_task, or we'll loop endlessly */ + + ipc_kmsg_t trace_kmsg; + + trace_kmsg = ikm_alloc(size + sizeof(mach_trace_message_t)); + + if (trace_kmsg == IKM_NULL) { + printf("dropped trace message (alloc failed)\n"); + return; + } + + mach_trace_message_t * trace_msg = (mach_trace_message_t *) & trace_kmsg->ikm_header; + + memcpy(trace_msg, & trace_template, sizeof(mach_trace_message_t)); + + trace_msg->header.msgh_size = size + sizeof(mach_trace_message_t); + trace_msg->header.msgh_remote_port = (mach_port_t) current_task()->itk_trace; + trace_msg->trace_message_type.msgtl_number = size; + + memcpy(trace_msg + 1, & kmsg->ikm_header, size); + + if (ipc_mqueue_send(trace_kmsg, 0, 0) != MACH_MSG_SUCCESS) { + printf("dropped trace message (send failed)\n"); + ikm_free(trace_kmsg); + } + } +} + #if MACH_KDB char * diff -ur -x 'Makefile*' -x debian -x configure -x config.sub -x config.guess gnumach-1.8+git20171101/kern/ipc_tt.c mnt/root/gnumach-1.8+git20171101/kern/ipc_tt.c --- gnumach-1.8+git20171101/kern/ipc_tt.c 2016-10-02 13:45:20.000000000 -0400 +++ mnt/root/gnumach-1.8+git20171101/kern/ipc_tt.c 2018-03-06 22:29:11.000000000 -0500 @@ -89,6 +89,7 @@ if (parent == TASK_NULL) { task->itk_exception = IP_NULL; task->itk_bootstrap = IP_NULL; + task->itk_trace = IP_NULL; for (i = 0; i < TASK_PORT_REGISTER_MAX; i++) task->itk_registered[i] = IP_NULL; } else { @@ -101,12 +102,14 @@ task->itk_registered[i] = ipc_port_copy_send(parent->itk_registered[i]); - /* inherit exception and bootstrap ports */ + /* inherit exception, bootstrap, and trace ports */ task->itk_exception = ipc_port_copy_send(parent->itk_exception); task->itk_bootstrap = ipc_port_copy_send(parent->itk_bootstrap); + task->itk_trace = + ipc_port_copy_send(parent->itk_trace); itk_unlock(parent); } @@ -190,6 +193,8 @@ ipc_port_release_send(task->itk_exception); if (IP_VALID(task->itk_bootstrap)) ipc_port_release_send(task->itk_bootstrap); + if (IP_VALID(task->itk_trace)) + ipc_port_release_send(task->itk_trace); for (i = 0; i < TASK_PORT_REGISTER_MAX; i++) if (IP_VALID(task->itk_registered[i])) @@ -609,6 +614,10 @@ whichp = &task->itk_bootstrap; break; + case TASK_TRACE_PORT: + whichp = &task->itk_trace; + break; + default: return KERN_INVALID_ARGUMENT; } @@ -666,6 +675,10 @@ whichp = &task->itk_bootstrap; break; + case TASK_TRACE_PORT: + whichp = &task->itk_trace; + break; + default: return KERN_INVALID_ARGUMENT; } diff -ur -x 'Makefile*' -x debian -x configure -x config.sub -x config.guess gnumach-1.8+git20171101/kern/task.h mnt/root/gnumach-1.8+git20171101/kern/task.h --- gnumach-1.8+git20171101/kern/task.h 2017-10-31 14:03:02.000000000 -0400 +++ mnt/root/gnumach-1.8+git20171101/kern/task.h 2018-03-06 22:27:28.000000000 -0500 @@ -94,6 +94,7 @@ struct ipc_port *itk_sself; /* a send right */ struct ipc_port *itk_exception; /* a send right */ struct ipc_port *itk_bootstrap; /* a send right */ + struct ipc_port *itk_trace; /* a send right */ struct ipc_port *itk_registered[TASK_PORT_REGISTER_MAX]; /* all send rights */