1
jkoenig's work on signals
5
diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
6
index 1c4733a..cc96f21 100644
7
--- a/hurd/hurd/signal.h
8
+++ b/hurd/hurd/signal.h
9
@@ -264,6 +264,11 @@ extern void _hurd_raise_signal (struct hurd_sigstate *ss, int signo,
10
extern void _hurd_exception2signal (struct hurd_signal_detail *detail,
13
+/* Translate a Mach exception into a signal with a legacy sigcode. */
15
+extern void _hurd_exception2signal_legacy (struct hurd_signal_detail *detail,
19
/* Make the thread described by SS take the signal described by SIGNO and
20
DETAIL. If the process is traced, this will in fact stop with a SIGNO
21
diff --git a/hurd/hurdinit.c b/hurd/hurdinit.c
22
index 259f8a3..97d3460 100644
25
@@ -176,7 +176,7 @@ _hurd_new_proc_init (char **argv,
26
/* This process is "traced", meaning it should stop on signals or exec.
27
We are all set up now to handle signals. Stop ourselves, to inform
28
our parent (presumably a debugger) that the exec has completed. */
29
- __msg_sig_post (_hurd_msgport, SIGTRAP, 0, __mach_task_self ());
30
+ __msg_sig_post (_hurd_msgport, SIGTRAP, TRAP_TRACE, __mach_task_self ());
33
#include <shlib-compat.h>
34
diff --git a/sysdeps/mach/hurd/bits/sigaction.h b/sysdeps/mach/hurd/bits/sigaction.h
36
index 0000000..4528b38
38
+++ b/sysdeps/mach/hurd/bits/sigaction.h
40
+/* Copyright (C) 1991,92,96,97,98,2001 Free Software Foundation, Inc.
41
+ This file is part of the GNU C Library.
43
+ The GNU C Library is free software; you can redistribute it and/or
44
+ modify it under the terms of the GNU Lesser General Public
45
+ License as published by the Free Software Foundation; either
46
+ version 2.1 of the License, or (at your option) any later version.
48
+ The GNU C Library is distributed in the hope that it will be useful,
49
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
50
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
51
+ Lesser General Public License for more details.
53
+ You should have received a copy of the GNU Lesser General Public
54
+ License along with the GNU C Library; if not, write to the Free
55
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
59
+# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
62
+/* These definitions match those used by the 4.4 BSD kernel.
63
+ If the operating system has a `sigaction' system call that correctly
64
+ implements the POSIX.1 behavior, there should be a system-dependent
65
+ version of this file that defines `struct sigaction' and the `SA_*'
66
+ constants appropriately. */
68
+/* Structure describing the action to be taken when a signal arrives. */
71
+ /* Signal handler. */
72
+#ifdef __USE_POSIX199309
75
+ /* Used if SA_SIGINFO is not set. */
76
+ __sighandler_t sa_handler;
77
+ /* Used if SA_SIGINFO is set. */
78
+ void (*sa_sigaction) (int, siginfo_t *, void *);
80
+ __sigaction_handler;
81
+# define sa_handler __sigaction_handler.sa_handler
82
+# define sa_sigaction __sigaction_handler.sa_sigaction
84
+ __sighandler_t sa_handler;
87
+ /* Additional set of signals to be blocked. */
90
+ /* Special flags. */
94
+/* Bits in `sa_flags'. */
95
+#if defined __USE_UNIX98 || defined __USE_MISC
96
+# define SA_ONSTACK 0x0001 /* Take signal on signal stack. */
97
+# define SA_RESTART 0x0002 /* Restart syscall on signal return. */
98
+# define SA_NODEFER 0x0010 /* Don't automatically block the signal when
99
+ its handler is being executed. */
100
+# define SA_RESETHAND 0x0004 /* Reset to SIG_DFL on entry to handler. */
101
+# define SA_SIGINFO 0x0040 /* Signal handler with SA_SIGINFO args */
103
+#define SA_NOCLDSTOP 0x0008 /* Don't send SIGCHLD when children stop. */
106
+# define SA_INTERRUPT 0 /* Historical no-op ("not SA_RESTART"). */
108
+/* Some aliases for the SA_ constants. */
109
+# define SA_NOMASK SA_NODEFER
110
+# define SA_ONESHOT SA_RESETHAND
111
+# define SA_STACK SA_ONSTACK
115
+/* Values for the HOW argument to `sigprocmask'. */
116
+#define SIG_BLOCK 1 /* Block signals. */
117
+#define SIG_UNBLOCK 2 /* Unblock signals. */
118
+#define SIG_SETMASK 3 /* Set the set of blocked signals. */
119
diff --git a/sysdeps/mach/hurd/i386/bits/sigcontext.h b/sysdeps/mach/hurd/i386/bits/sigcontext.h
120
index a78dd2f..1956d41 100644
121
--- a/sysdeps/mach/hurd/i386/bits/sigcontext.h
122
+++ b/sysdeps/mach/hurd/i386/bits/sigcontext.h
123
@@ -96,6 +96,10 @@ struct sigcontext
127
+/* The deprecated sigcode values below are passed as an extra, non-portable
128
+ argument to regular signal handlers. You should use SA_SIGINFO handlers
129
+ instead, which use the standard POSIX signal codes. */
131
/* Codes for SIGFPE. */
132
#define FPE_INTOVF_TRAP 0x1 /* integer overflow */
133
#define FPE_INTDIV_FAULT 0x2 /* integer divide by zero */
134
diff --git a/sysdeps/mach/hurd/i386/exc2signal.c b/sysdeps/mach/hurd/i386/exc2signal.c
135
index a6bf750..7ffeb5f 100644
136
--- a/sysdeps/mach/hurd/i386/exc2signal.c
137
+++ b/sysdeps/mach/hurd/i386/exc2signal.c
139
/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
140
into a signal number and signal subcode. */
143
-_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
145
+exception2signal (struct hurd_signal_detail *detail, int *signo, int posix)
149
@@ -37,44 +37,62 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
153
- if (detail->exc_code == KERN_INVALID_ADDRESS
154
- || detail->exc_code == KERN_PROTECTION_FAILURE
155
- || detail->exc_code == KERN_WRITE_PROTECTION_FAILURE)
159
- detail->code = detail->exc_subcode;
160
+ switch (detail->exc_code)
162
+ case KERN_INVALID_ADDRESS:
163
+ case KERN_MEMORY_FAILURE:
165
+ detail->code = posix ? SEGV_MAPERR : detail->exc_subcode;
168
+ case KERN_PROTECTION_FAILURE:
169
+ case KERN_WRITE_PROTECTION_FAILURE:
171
+ detail->code = posix ? SEGV_ACCERR : detail->exc_subcode;
179
detail->error = detail->exc_code;
182
case EXC_BAD_INSTRUCTION:
184
- if (detail->exc_code == EXC_I386_INVOP)
185
- detail->code = ILL_INVOPR_FAULT;
186
- else if (detail->exc_code == EXC_I386_STKFLT)
187
- detail->code = ILL_STACK_FAULT;
190
+ switch (detail->exc_code)
192
+ case EXC_I386_INVOP:
193
+ detail->code = posix ? ILL_ILLOPC : ILL_INVOPR_FAULT;
196
+ case EXC_I386_STKFLT:
197
+ detail->code = posix ? ILL_BADSTK : ILL_STACK_FAULT;
208
switch (detail->exc_code)
210
case EXC_I386_DIV: /* integer divide by zero */
212
- detail->code = FPE_INTDIV_FAULT;
213
+ detail->code = posix ? FPE_INTDIV : FPE_INTDIV_FAULT;
216
case EXC_I386_INTO: /* integer overflow */
218
- detail->code = FPE_INTOVF_TRAP;
219
+ detail->code = posix ? FPE_INTOVF : FPE_INTOVF_TRAP;
222
/* These aren't anywhere documented or used in Mach 3.0. */
224
case EXC_I386_EXTOVR:
230
@@ -83,51 +101,43 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
231
Give an error code corresponding to the first bit set. */
232
if (detail->exc_subcode & FPS_IE)
235
- detail->code = ILL_FPEOPR_FAULT;
236
+ /* NB: We used to send SIGILL here but we can't distinguish
237
+ POSIX vs. legacy with respect to what signal we send. */
238
+ detail->code = posix ? FPE_FLTINV : 0 /*ILL_FPEOPR_FAULT*/;
240
else if (detail->exc_subcode & FPS_DE)
243
- detail->code = FPE_FLTDNR_FAULT;
244
+ detail->code = posix ? FPE_FLTUND : FPE_FLTDNR_FAULT;
246
else if (detail->exc_subcode & FPS_ZE)
249
- detail->code = FPE_FLTDIV_FAULT;
250
+ detail->code = posix ? FPE_FLTDIV : FPE_FLTDIV_FAULT;
252
else if (detail->exc_subcode & FPS_OE)
255
- detail->code = FPE_FLTOVF_FAULT;
256
+ detail->code = posix ? FPE_FLTOVF : FPE_FLTOVF_FAULT;
258
else if (detail->exc_subcode & FPS_UE)
261
- detail->code = FPE_FLTUND_FAULT;
262
+ detail->code = posix ? FPE_FLTUND : FPE_FLTUND_FAULT;
264
else if (detail->exc_subcode & FPS_PE)
267
- detail->code = FPE_FLTINX_FAULT;
268
+ detail->code = posix ? FPE_FLTRES : FPE_FLTINX_FAULT;
277
/* These two can only be arithmetic exceptions if we
278
- are in V86 mode, which sounds like emulation to me.
279
- (See Mach 3.0 i386/trap.c.) */
280
+ are in V86 mode. (See Mach 3.0 i386/trap.c.) */
283
- detail->code = FPE_EMERR_FAULT;
284
+ detail->code = posix ? 0 : FPE_EMERR_FAULT;
288
- detail->code = FPE_EMBND_FAULT;
289
+ detail->code = posix ? FPE_FLTSUB : FPE_EMBND_FAULT;
293
@@ -144,7 +154,7 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
294
if (detail->exc_code == EXC_I386_BOUND)
297
- detail->code = FPE_SUBRNG_FAULT;
298
+ detail->code = posix ? FPE_FLTSUB : FPE_SUBRNG_FAULT;
302
@@ -155,12 +165,33 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
306
- if (detail->exc_code == EXC_I386_SGL)
307
- detail->code = DBG_SINGLE_TRAP;
308
- else if (detail->exc_code == EXC_I386_BPT)
309
- detail->code = DBG_BRKPNT_FAULT;
312
+ switch (detail->exc_code)
315
+ detail->code = posix ? TRAP_BRKPT : DBG_SINGLE_TRAP;
319
+ detail->code = posix ? TRAP_BRKPT : DBG_BRKPNT_FAULT;
331
+_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
333
+ exception2signal (detail, signo, 1);
337
+_hurd_exception2signal_legacy (struct hurd_signal_detail *detail, int *signo)
339
+ exception2signal (detail, signo, 0);
342
diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c
343
index ec52847..5abd33d 100644
344
--- a/sysdeps/mach/hurd/i386/trampoline.c
345
+++ b/sysdeps/mach/hurd/i386/trampoline.c
347
#include <hurd/signal.h>
348
#include <hurd/userlink.h>
349
#include <thread_state.h>
350
+#include <mach/exception.h>
351
#include <mach/machine/eflags.h>
354
#include "hurdfault.h"
355
#include <intr-msg.h>
356
+#include <sys/ucontext.h>
359
+/* Fill in a siginfo_t structure for SA_SIGINFO-enabled handlers. */
360
+static void fill_siginfo (siginfo_t *si, int signo,
361
+ const struct hurd_signal_detail *detail,
362
+ const struct machine_thread_all_state *state)
364
+ si->si_signo = signo;
365
+ si->si_errno = detail->error;
366
+ si->si_code = detail->code;
368
+ /* XXX We would need a protocol change for sig_post to include
369
+ * this information. */
373
+ /* Address of the faulting instruction or memory access. */
374
+ if (detail->exc == EXC_BAD_ACCESS)
375
+ si->si_addr = (void *) detail->exc_subcode;
377
+ si->si_addr = (void *) state->basic.eip;
379
+ /* XXX On SIGCHLD, this should be the exit status of the child
380
+ * process. We would need a protocol change for the proc server
381
+ * to send this information along with the signal. */
384
+ si->si_band = 0; /* SIGPOLL is not supported yet. */
385
+ si->si_value.sival_int = 0; /* sigqueue() is not supported yet. */
388
+/* Fill in a ucontext_t structure SA_SIGINFO-enabled handlers. */
389
+static void fill_ucontext (ucontext_t *uc, const struct sigcontext *sc)
392
+ uc->uc_link = NULL;
393
+ uc->uc_sigmask = sc->sc_mask;
394
+ uc->uc_stack.ss_sp = (__ptr_t) sc->sc_esp;
395
+ uc->uc_stack.ss_size = 0;
396
+ uc->uc_stack.ss_flags = 0;
399
+ memcpy (&uc->uc_mcontext.gregs[REG_GS], &sc->sc_gs,
400
+ (REG_TRAPNO - REG_GS) * sizeof (int));
401
+ uc->uc_mcontext.gregs[REG_TRAPNO] = 0;
402
+ uc->uc_mcontext.gregs[REG_ERR] = 0;
403
+ memcpy (&uc->uc_mcontext.gregs[REG_EIP], &sc->sc_eip,
404
+ (NGREG - REG_EIP) * sizeof (int));
406
+ /* XXX FPU state. */
407
+ memset (&uc->uc_mcontext.fpregs, 0, sizeof (fpregset_t));
411
_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
412
int signo, struct hurd_signal_detail *detail,
413
@@ -40,18 +93,37 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
414
extern const void _hurd_intr_rpc_msg_in_trap;
415
extern const void _hurd_intr_rpc_msg_cx_sp;
416
extern const void _hurd_intr_rpc_msg_sp_restored;
417
+ struct sigaction *action;
418
void *volatile sigsp;
419
struct sigcontext *scp;
424
- struct sigcontext *scp; /* Points to ctx, below. */
427
+ /* Extra arguments for traditional signal handlers */
431
+ struct sigcontext *scp; /* Points to ctx, below. */
434
+ /* Extra arguments for SA_SIGINFO handlers */
437
+ siginfo_t *siginfop; /* Points to siginfo, below. */
438
+ ucontext_t *uctxp; /* Points to uctx, below. */
441
void *sigreturn_addr;
442
void *sigreturn_returns_here;
443
struct sigcontext *return_scp; /* Same; arg to sigreturn. */
445
+ /* NB: sigreturn assumes link is next to ctx. */
446
struct sigcontext ctx;
447
struct hurd_userlink link;
448
+ ucontext_t ucontext;
453
@@ -143,15 +215,9 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
454
= &stackframe->link.thread.next;
455
ss->active_resources = &stackframe->link;
457
- /* Set up the arguments for the signal handler. */
458
- stackframe->signo = signo;
459
- stackframe->sigcode = detail->code;
460
- stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx;
461
- stackframe->sigreturn_addr = &__sigreturn;
462
- stackframe->sigreturn_returns_here = firewall; /* Crash on return. */
464
/* Set up the sigcontext from the current state of the thread. */
466
+ scp = &stackframe->ctx;
467
scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
469
/* struct sigcontext is laid out so that starting at sc_gs mimics a
470
@@ -165,6 +231,35 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
471
&state->fpu, &scp->sc_i386_float_state,
472
sizeof (state->fpu));
474
+ /* Set up the arguments for the signal handler. */
475
+ stackframe->signo = signo;
476
+ if (action->sa_flags & SA_SIGINFO)
478
+ stackframe->posix.siginfop = &stackframe->siginfo;
479
+ stackframe->posix.uctxp = &stackframe->ucontext;
480
+ fill_siginfo (&stackframe->siginfo, signo, detail, state);
481
+ fill_ucontext (&stackframe->ucontext, scp);
488
+ _hurd_exception2signal_legacy (detail, &nsigno);
489
+ assert (nsigno == signo);
494
+ stackframe->legacy.sigcode = detail->code;
495
+ stackframe->legacy.scp = &stackframe->ctx;
498
+ /* Set up the bottom of the stack. */
499
+ stackframe->sigreturn_addr = &__sigreturn;
500
+ stackframe->sigreturn_returns_here = firewall; /* Crash on return. */
501
+ stackframe->return_scp = &stackframe->ctx;
503
_hurdsig_end_catch_fault ();
506
diff --git a/sysdeps/mach/hurd/kill.c b/sysdeps/mach/hurd/kill.c
507
index a9946e0..ac7ffc7 100644
508
--- a/sysdeps/mach/hurd/kill.c
509
+++ b/sysdeps/mach/hurd/kill.c
510
@@ -65,7 +65,7 @@ __kill (pid_t pid, int sig)
512
if (msgport != MACH_PORT_NULL)
513
/* Send a signal message to his message port. */
514
- return __msg_sig_post (msgport, sig, 0, refport);
515
+ return __msg_sig_post (msgport, sig, SI_USER, refport);
517
/* The process has no message port. Perhaps try direct
518
frobnication of the task. */
519
diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c
520
index fec64a8..c82bfcd 100644
521
--- a/sysdeps/mach/hurd/setitimer.c
522
+++ b/sysdeps/mach/hurd/setitimer.c
523
@@ -105,7 +105,7 @@ timer_thread (void)
524
__msg_sig_post_request (_hurd_msgport,
526
MACH_MSG_TYPE_MAKE_SEND_ONCE,
527
- SIGALRM, 0, __mach_task_self ());
528
+ SIGALRM, SI_TIMER, __mach_task_self ());
531
case MACH_RCV_INTERRUPTED: