+ printf_unfiltered (_(" data:"));
+ ldata = (const unsigned int *)data;
+ for (i = 0; i < size / sizeof (unsigned int); i++)
+ printf_unfiltered (" %08x", ldata[i]);
+ printf_unfiltered (_("\n"));
+ }
+}
+
+static int
+darwin_decode_exception_message (mach_msg_header_t *hdr,
+ struct inferior **pinf,
+ darwin_thread_t **pthread)
+{
+ mach_msg_body_t *bod = (mach_msg_body_t*)(hdr + 1);
+ mach_msg_port_descriptor_t *desc = (mach_msg_port_descriptor_t *)(bod + 1);
+ NDR_record_t *ndr;
+ integer_t *data;
+ struct inferior *inf;
+ darwin_thread_t *thread;
+ task_t task_port;
+ thread_t thread_port;
+ kern_return_t kret;
+ int i;
+
+ /* Check message destination. */
+ if (hdr->msgh_local_port != darwin_ex_port)
+ return -1;
+
+ /* Check message header. */
+ if (!(hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX))
+ return -1;
+
+ /* Check descriptors. */
+ if (hdr->msgh_size < (sizeof (*hdr) + sizeof (*bod) + 2 * sizeof (*desc)
+ + sizeof (*ndr) + 2 * sizeof (integer_t))
+ || bod->msgh_descriptor_count != 2
+ || desc[0].type != MACH_MSG_PORT_DESCRIPTOR
+ || desc[0].disposition != MACH_MSG_TYPE_MOVE_SEND
+ || desc[1].type != MACH_MSG_PORT_DESCRIPTOR
+ || desc[1].disposition != MACH_MSG_TYPE_MOVE_SEND)
+ return -1;
+
+ /* Check data representation. */
+ ndr = (NDR_record_t *)(desc + 2);
+ if (ndr->mig_vers != NDR_PROTOCOL_2_0
+ || ndr->if_vers != NDR_PROTOCOL_2_0
+ || ndr->mig_encoding != NDR_record.mig_encoding
+ || ndr->int_rep != NDR_record.int_rep
+ || ndr->char_rep != NDR_record.char_rep
+ || ndr->float_rep != NDR_record.float_rep)
+ return -1;
+
+ /* Ok, the hard work. */
+ data = (integer_t *)(ndr + 1);
+
+ task_port = desc[1].name;
+ thread_port = desc[0].name;
+
+ /* We got new rights to the task, get rid of it. Do not get rid of thread
+ right, as we will need it to find the thread. */
+ kret = mach_port_deallocate (mach_task_self (), task_port);
+ MACH_CHECK_ERROR (kret);
+
+ /* Find process by port. */
+ inf = darwin_find_inferior_by_task (task_port);
+ *pinf = inf;
+ if (inf == NULL)
+ {
+ /* Not a known inferior. This could happen if the child fork, as
+ the created process will inherit its exception port.
+ FIXME: should the exception port be restored ? */
+ kern_return_t kret;
+ mig_reply_error_t reply;
+
+ /* Free thread port (we don't know it). */
+ kret = mach_port_deallocate (mach_task_self (), thread_port);
+ MACH_CHECK_ERROR (kret);
+
+ darwin_encode_reply (&reply, hdr, KERN_SUCCESS);
+
+ kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
+ reply.Head.msgh_size, 0,