/* Prepare a wakeup message. */ static error_t create_wakeupmsg (struct __pthread *thread) { kern_return_t err; /* Build wakeup message. */ thread->wakeupmsg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); thread->wakeupmsg.msgh_size = 0; err = __mach_port_allocate (__mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &thread->wakeupmsg.msgh_remote_port); if (err) return EAGAIN; thread->wakeupmsg.msgh_local_port = MACH_PORT_NULL; thread->wakeupmsg.msgh_seqno = 0; thread->wakeupmsg.msgh_id = 0; err = __mach_port_insert_right (__mach_task_self (), thread->wakeupmsg.msgh_remote_port, thread->wakeupmsg.msgh_remote_port, MACH_MSG_TYPE_MAKE_SEND); if (err) { __mach_port_destroy (__mach_task_self (), thread->wakeupmsg.msgh_remote_port); return EAGAIN; } return 0; }
void _hurdsig_fault_init (void) { error_t err; struct machine_thread_state state; mach_port_t sigexc; /* Allocate a port to receive signal thread exceptions. We will move this receive right to the proc server. */ err = __mach_port_allocate (__mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &sigexc); assert_perror (err); err = __mach_port_allocate (__mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &forward_sigexc); assert_perror (err); /* Allocate a port to receive the exception msgs forwarded from the proc server. */ err = __mach_port_insert_right (__mach_task_self (), sigexc, sigexc, MACH_MSG_TYPE_MAKE_SEND); assert_perror (err); /* Set the queue limit for this port to just one. The proc server will notice if we ever get a second exception while one remains queued and unreceived, and decide we are hopelessly buggy. */ #ifdef MACH_PORT_RECEIVE_STATUS_COUNT { const mach_port_limits_t lim = { mpl_qlimit: 1 }; assert (MACH_PORT_RECEIVE_STATUS_COUNT == sizeof lim / sizeof (natural_t)); err = __mach_port_set_attributes (__mach_task_self (), forward_sigexc, MACH_PORT_RECEIVE_STATUS, (mach_port_info_t) &lim, MACH_PORT_RECEIVE_STATUS_COUNT); } #else err = __mach_port_set_qlimit (__mach_task_self (), forward_sigexc, 1); #endif assert_perror (err); /* This state will be restored when we fault. It runs the function above. */ memset (&state, 0, sizeof state); MACHINE_THREAD_STATE_SET_PC (&state, faulted); MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack); err = __USEPORT (PROC, __proc_handle_exceptions (port, sigexc, forward_sigexc, MACH_MSG_TYPE_MAKE_SEND, MACHINE_THREAD_STATE_FLAVOR, (natural_t *) &state, MACHINE_THREAD_STATE_COUNT)); assert_perror (err); /* Direct signal thread exceptions to the proc server. */ #ifdef THREAD_EXCEPTION_PORT err = __thread_set_special_port (_hurd_msgport_thread, THREAD_EXCEPTION_PORT, sigexc); #elif defined (EXC_MASK_ALL) __thread_set_exception_ports (_hurd_msgport_thread, EXC_MASK_ALL & ~(EXC_MASK_SYSCALL | EXC_MASK_MACH_SYSCALL | EXC_MASK_RPC_ALERT), sigexc, EXCEPTION_STATE_IDENTITY, MACHINE_THREAD_STATE); #else # error thread_set_exception_ports? #endif __mach_port_deallocate (__mach_task_self (), sigexc); assert_perror (err); }