]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/mach/hurd/i386/exc2signal.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / mach / hurd / i386 / exc2signal.c
1 /* Translate Mach exception codes into signal numbers. i386 version.
2 Copyright (C) 1991-2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include <hurd.h>
20 #include <hurd/signal.h>
21 #include <mach/exception.h>
22
23 /* Translate the Mach exception codes, as received in an `exception_raise' RPC,
24 into a signal number and signal subcode. */
25
26 void
27 _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
28 {
29 detail->error = 0;
30
31 switch (detail->exc)
32 {
33 default:
34 *signo = SIGIOT;
35 detail->code = detail->exc;
36 break;
37
38 case EXC_BAD_ACCESS:
39 if (detail->exc_code == KERN_INVALID_ADDRESS
40 || detail->exc_code == KERN_PROTECTION_FAILURE
41 || detail->exc_code == KERN_WRITE_PROTECTION_FAILURE)
42 *signo = SIGSEGV;
43 else
44 *signo = SIGBUS;
45 detail->code = detail->exc_subcode;
46 detail->error = detail->exc_code;
47 break;
48
49 case EXC_BAD_INSTRUCTION:
50 *signo = SIGILL;
51 if (detail->exc_code == EXC_I386_INVOP)
52 detail->code = ILL_INVOPR_FAULT;
53 else if (detail->exc_code == EXC_I386_STKFLT)
54 detail->code = ILL_STACK_FAULT;
55 else
56 detail->code = 0;
57 break;
58
59 case EXC_ARITHMETIC:
60 switch (detail->exc_code)
61 {
62 case EXC_I386_DIV: /* integer divide by zero */
63 *signo = SIGFPE;
64 detail->code = FPE_INTDIV_FAULT;
65 break;
66
67 case EXC_I386_INTO: /* integer overflow */
68 *signo = SIGFPE;
69 detail->code = FPE_INTOVF_TRAP;
70 break;
71
72 /* These aren't anywhere documented or used in Mach 3.0. */
73 case EXC_I386_NOEXT:
74 case EXC_I386_EXTOVR:
75 default:
76 *signo = SIGFPE;
77 detail->code = 0;
78 break;
79
80 case EXC_I386_EXTERR:
81 /* Subcode is the fp_status word saved by the hardware.
82 Give an error code corresponding to the first bit set. */
83 if (detail->exc_subcode & FPS_IE)
84 {
85 *signo = SIGILL;
86 detail->code = ILL_FPEOPR_FAULT;
87 }
88 else if (detail->exc_subcode & FPS_DE)
89 {
90 *signo = SIGFPE;
91 detail->code = FPE_FLTDNR_FAULT;
92 }
93 else if (detail->exc_subcode & FPS_ZE)
94 {
95 *signo = SIGFPE;
96 detail->code = FPE_FLTDIV_FAULT;
97 }
98 else if (detail->exc_subcode & FPS_OE)
99 {
100 *signo = SIGFPE;
101 detail->code = FPE_FLTOVF_FAULT;
102 }
103 else if (detail->exc_subcode & FPS_UE)
104 {
105 *signo = SIGFPE;
106 detail->code = FPE_FLTUND_FAULT;
107 }
108 else if (detail->exc_subcode & FPS_PE)
109 {
110 *signo = SIGFPE;
111 detail->code = FPE_FLTINX_FAULT;
112 }
113 else
114 {
115 *signo = SIGFPE;
116 detail->code = 0;
117 }
118 break;
119
120 /* These two can only be arithmetic exceptions if we
121 are in V86 mode, which sounds like emulation to me.
122 (See Mach 3.0 i386/trap.c.) */
123 case EXC_I386_EMERR:
124 *signo = SIGFPE;
125 detail->code = FPE_EMERR_FAULT;
126 break;
127 case EXC_I386_BOUND:
128 *signo = SIGFPE;
129 detail->code = FPE_EMBND_FAULT;
130 break;
131 }
132 break;
133
134 case EXC_EMULATION:
135 /* 3.0 doesn't give this one, why, I don't know. */
136 *signo = SIGEMT;
137 detail->code = 0;
138 break;
139
140 case EXC_SOFTWARE:
141 /* The only time we get this in Mach 3.0
142 is for an out of bounds trap. */
143 if (detail->exc_code == EXC_I386_BOUND)
144 {
145 *signo = SIGFPE;
146 detail->code = FPE_SUBRNG_FAULT;
147 }
148 else
149 {
150 *signo = SIGEMT;
151 detail->code = 0;
152 }
153 break;
154
155 case EXC_BREAKPOINT:
156 *signo = SIGTRAP;
157 if (detail->exc_code == EXC_I386_SGL)
158 detail->code = DBG_SINGLE_TRAP;
159 else if (detail->exc_code == EXC_I386_BPT)
160 detail->code = DBG_BRKPNT_FAULT;
161 else
162 detail->code = 0;
163 break;
164 }
165 }