1 /* Handle faults in the signal thread.
2 Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
21 #include <hurd/signal.h>
22 #include "hurdfault.h"
27 #include "thread_state.h"
28 #include "faultexc_server.h" /* mig-generated header for our exc server. */
31 jmp_buf _hurdsig_fault_env
;
32 struct hurd_signal_preemptor _hurdsig_fault_preemptor
= {0};
34 /* XXX temporary to deal with spelling fix */
35 weak_alias (_hurdsig_fault_preemptor
, _hurdsig_fault_preempter
)
37 static mach_port_t forward_sigexc
;
40 _hurdsig_fault_catch_exception_raise (mach_port_t port
,
48 struct hurd_signal_detail d
;
50 if (port
!= forward_sigexc
||
51 thread
!= _hurd_msgport_thread
|| task
!= __mach_task_self ())
52 return EPERM
; /* Strange bogosity. */
56 d
.exc_subcode
= subcode
;
58 /* Call the machine-dependent function to translate the Mach exception
59 codes into a signal number and subcode. */
60 _hurd_exception2signal (&d
, &signo
);
62 return HURD_PREEMPT_SIGNAL_P (&_hurdsig_fault_preemptor
, signo
, d
.code
)
71 mach_msg_header_t head
;
76 mach_msg_header_t head
;
80 extern int _hurdsig_fault_exc_server (mach_msg_header_t
*,
83 /* Wait for the exception_raise message forwarded by the proc server. */
85 if (__mach_msg (&request
.head
, MACH_RCV_MSG
, 0,
86 sizeof request
, forward_sigexc
,
87 MACH_MSG_TIMEOUT_NONE
, MACH_PORT_NULL
)
89 __libc_fatal ("msg receive failed on signal thread exc\n");
91 /* Run the exc demuxer which should call the server function above.
92 That function returns 0 if the exception was expected. */
93 _hurdsig_fault_exc_server (&request
.head
, &reply
.head
);
94 if (reply
.head
.msgh_remote_port
!= MACH_PORT_NULL
)
95 __mach_msg (&reply
.head
, MACH_SEND_MSG
, reply
.head
.msgh_size
,
96 0, MACH_PORT_NULL
, MACH_MSG_TIMEOUT_NONE
, MACH_PORT_NULL
);
97 if (reply
.result
== MIG_BAD_ID
)
98 __mach_msg_destroy (&request
.head
);
101 __libc_fatal ("BUG: unexpected fault in signal thread\n");
103 _hurdsig_fault_preemptor
.signals
= 0;
104 longjmp (_hurdsig_fault_env
, 1);
107 static char faultstack
[1024];
109 /* Send exceptions for the signal thread to the proc server.
110 It will forward the message on to our message port,
111 and then restore the thread's state to code which
112 does `longjmp (_hurd_sigthread_fault_env, 1)'. */
115 _hurdsig_fault_init (void)
118 struct machine_thread_state state
;
121 /* Allocate a port to receive signal thread exceptions.
122 We will move this receive right to the proc server. */
123 err
= __mach_port_allocate (__mach_task_self (),
124 MACH_PORT_RIGHT_RECEIVE
, &sigexc
);
126 err
= __mach_port_allocate (__mach_task_self (),
127 MACH_PORT_RIGHT_RECEIVE
, &forward_sigexc
);
130 /* Allocate a port to receive the exception msgs forwarded
131 from the proc server. */
132 err
= __mach_port_insert_right (__mach_task_self (), sigexc
,
133 sigexc
, MACH_MSG_TYPE_MAKE_SEND
);
136 /* Set the queue limit for this port to just one. The proc server will
137 notice if we ever get a second exception while one remains queued and
138 unreceived, and decide we are hopelessly buggy. */
139 err
= __mach_port_set_qlimit (__mach_task_self (), forward_sigexc
, 1);
142 /* This state will be restored when we fault.
143 It runs the function above. */
144 memset (&state
, 0, sizeof state
);
145 MACHINE_THREAD_STATE_SET_PC (&state
, faulted
);
146 MACHINE_THREAD_STATE_SET_SP (&state
, faultstack
, sizeof faultstack
);
150 __proc_handle_exceptions (port
,
152 forward_sigexc
, MACH_MSG_TYPE_MAKE_SEND
,
153 MACHINE_THREAD_STATE_FLAVOR
,
154 (natural_t
*) &state
,
155 MACHINE_THREAD_STATE_COUNT
));
158 /* Direct signal thread exceptions to the proc server. */
159 err
= __thread_set_special_port (_hurd_msgport_thread
,
160 THREAD_EXCEPTION_PORT
, sigexc
);
161 __mach_port_deallocate (__mach_task_self (), sigexc
);