blob: 8057c8884827fb3877e6e79182d99dddbe9a6ddd [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00003/*--- Implementation of POSIX signals. m_signals.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00005
sewardjde4a1d02002-03-22 01:27:54 +00006/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
sewardj4d474d02008-02-11 11:34:59 +000010 Copyright (C) 2000-2008 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
jsgf855d93d2003-10-13 22:26:55 +000031/*
sewardjb5f6f512005-03-10 23:59:00 +000032 Signal handling.
jsgf855d93d2003-10-13 22:26:55 +000033
sewardjb5f6f512005-03-10 23:59:00 +000034 There are 4 distinct classes of signal:
jsgf855d93d2003-10-13 22:26:55 +000035
sewardjb5f6f512005-03-10 23:59:00 +000036 1. Synchronous, instruction-generated (SIGILL, FPE, BUS, SEGV and
37 TRAP): these are signals as a result of an instruction fault. If
38 we get one while running client code, then we just do the
39 appropriate thing. If it happens while running Valgrind code, then
40 it indicates a Valgrind bug. Note that we "manually" implement
41 automatic stack growth, such that if a fault happens near the
42 client process stack, it is extended in the same way the kernel
43 would, and the fault is never reported to the client program.
jsgf855d93d2003-10-13 22:26:55 +000044
sewardjb5f6f512005-03-10 23:59:00 +000045 2. Asynchronous varients of the above signals: If the kernel tries
46 to deliver a sync signal while it is blocked, it just kills the
47 process. Therefore, we can't block those signals if we want to be
48 able to report on bugs in Valgrind. This means that we're also
49 open to receiving those signals from other processes, sent with
50 kill. We could get away with just dropping them, since they aren't
51 really signals that processes send to each other.
jsgf855d93d2003-10-13 22:26:55 +000052
sewardjb5f6f512005-03-10 23:59:00 +000053 3. Synchronous, general signals. If a thread/process sends itself
54 a signal with kill, its expected to be synchronous: ie, the signal
55 will have been delivered by the time the syscall finishes.
56
57 4. Asyncronous, general signals. All other signals, sent by
58 another process with kill. These are generally blocked, except for
59 two special cases: we poll for them each time we're about to run a
60 thread for a time quanta, and while running blocking syscalls.
jsgf855d93d2003-10-13 22:26:55 +000061
jsgf855d93d2003-10-13 22:26:55 +000062
sewardjb5f6f512005-03-10 23:59:00 +000063 In addition, we define two signals for internal use: SIGVGCHLD and
64 SIGVGKILL. SIGVGCHLD is used to indicate thread death to any
65 reaping thread (the master thread). It is always blocked and never
66 delivered as a signal; it is always polled with sigtimedwait.
67
68 SIGVGKILL is used to terminate threads. When one thread wants
69 another to exit, it will set its exitreason and send it SIGVGKILL
70 if it appears to be blocked in a syscall.
71
72
73 We use a kernel thread for each application thread. When the
74 thread allows itself to be open to signals, it sets the thread
75 signal mask to what the client application set it to. This means
76 that we get the kernel to do all signal routing: under Valgrind,
77 signals get delivered in the same way as in the non-Valgrind case
78 (the exception being for the sync signal set, since they're almost
79 always unblocked).
jsgf855d93d2003-10-13 22:26:55 +000080 */
sewardjde4a1d02002-03-22 01:27:54 +000081
njnc7561b92005-06-19 01:24:32 +000082#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000083#include "pub_core_vki.h"
sewardj489bfec2006-10-17 02:00:29 +000084#include "pub_core_vkiscnums.h"
sewardj45f4e7c2005-09-27 19:20:21 +000085#include "pub_core_debuglog.h"
njnc7561b92005-06-19 01:24:32 +000086#include "pub_core_threadstate.h"
sewardj14c7cc52007-02-25 15:08:24 +000087#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +000088#include "pub_core_clientstate.h"
njn2521d322005-05-08 14:45:13 +000089#include "pub_core_aspacemgr.h"
njn634a6522005-07-02 01:59:28 +000090#include "pub_core_debugger.h" // For VG_(start_debugger)
njnd2b17112005-04-19 04:10:25 +000091#include "pub_core_errormgr.h"
njn97405b22005-06-02 03:39:33 +000092#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000093#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000094#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000095#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000096#include "pub_core_libcsignal.h"
njnf536bbb2005-06-13 04:21:38 +000097#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +000098#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000099#include "pub_core_options.h"
njnc7561b92005-06-19 01:24:32 +0000100#include "pub_core_scheduler.h"
njn0c246472005-05-31 01:00:08 +0000101#include "pub_core_signals.h"
njn24a6efb2005-06-20 03:36:51 +0000102#include "pub_core_sigframe.h" // For VG_(sigframe_create)()
njn945ed2e2005-06-24 03:28:30 +0000103#include "pub_core_stacks.h" // For VG_(change_stack)()
njn24a6efb2005-06-20 03:36:51 +0000104#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
njn9abd6082005-06-17 21:31:45 +0000105#include "pub_core_syscall.h"
njnc1b01812005-06-17 22:19:06 +0000106#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +0000107#include "pub_core_tooliface.h"
sewardjcf4ac712005-11-01 00:03:40 +0000108#include "pub_core_coredump.h"
sewardj985fabb2005-04-24 14:18:14 +0000109
njnd2b17112005-04-19 04:10:25 +0000110
sewardj018f7622002-05-15 21:13:39 +0000111/* ---------------------------------------------------------------------
112 Forwards decls.
113 ------------------------------------------------------------------ */
114
njn695c16e2005-03-27 03:40:28 +0000115static void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext * );
116static void async_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext * );
sewardj489bfec2006-10-17 02:00:29 +0000117static void sigvgkill_handler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext * );
sewardj018f7622002-05-15 21:13:39 +0000118
jsgf855d93d2003-10-13 22:26:55 +0000119static const Char *signame(Int sigNo);
sewardj018f7622002-05-15 21:13:39 +0000120
sewardjb5f6f512005-03-10 23:59:00 +0000121/* Maximum usable signal. */
122Int VG_(max_signal) = _VKI_NSIG;
nethercote759dda32004-08-07 18:16:56 +0000123
sewardjb5f6f512005-03-10 23:59:00 +0000124#define N_QUEUED_SIGNALS 8
nethercote759dda32004-08-07 18:16:56 +0000125
sewardjb5f6f512005-03-10 23:59:00 +0000126typedef struct SigQueue {
127 Int next;
128 vki_siginfo_t sigs[N_QUEUED_SIGNALS];
129} SigQueue;
nethercote759dda32004-08-07 18:16:56 +0000130
sewardj489bfec2006-10-17 02:00:29 +0000131/* ------ Macros for pulling stuff out of ucontexts ------ */
132
njn605f4882005-05-29 17:50:40 +0000133#if defined(VGP_x86_linux)
njnaf839f52005-06-23 03:27:57 +0000134# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.eip)
135# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp)
136# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.ebp)
137# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.eax)
sewardjacaec5f2005-08-19 16:02:59 +0000138# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardja8d8e232005-06-07 20:04:56 +0000139 /* Convert the value in uc_mcontext.eax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000140 VG_(mk_SysRes_x86_linux)( (uc)->uc_mcontext.eax )
sewardjacaec5f2005-08-19 16:02:59 +0000141# define VG_UCONTEXT_LINK_REG(uc) 0 /* Dude, where's my LR? */
sewardje7aa4ae2005-06-09 12:43:42 +0000142
njn605f4882005-05-29 17:50:40 +0000143#elif defined(VGP_amd64_linux)
njnaf839f52005-06-23 03:27:57 +0000144# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.rip)
145# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.rsp)
146# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.rbp)
147# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.rax)
sewardjacaec5f2005-08-19 16:02:59 +0000148# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardje7aa4ae2005-06-09 12:43:42 +0000149 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000150 VG_(mk_SysRes_amd64_linux)( (uc)->uc_mcontext.rax )
sewardjacaec5f2005-08-19 16:02:59 +0000151# define VG_UCONTEXT_LINK_REG(uc) 0 /* No LR on amd64 either */
sewardje7aa4ae2005-06-09 12:43:42 +0000152
cerion85665ca2005-06-20 15:51:07 +0000153#elif defined(VGP_ppc32_linux)
sewardja36dcfa2005-11-25 02:16:58 +0000154/* Comments from Paul Mackerras 25 Nov 05:
155
156 > I'm tracking down a problem where V's signal handling doesn't
157 > work properly on a ppc440gx running 2.4.20. The problem is that
158 > the ucontext being presented to V's sighandler seems completely
159 > bogus.
160
161 > V's kernel headers and hence ucontext layout are derived from
162 > 2.6.9. I compared include/asm-ppc/ucontext.h from 2.4.20 and
163 > 2.6.13.
164
165 > Can I just check my interpretation: the 2.4.20 one contains the
166 > uc_mcontext field in line, whereas the 2.6.13 one has a pointer
167 > to said struct? And so if V is using the 2.6.13 struct then a
168 > 2.4.20 one will make no sense to it.
169
170 Not quite... what is inline in the 2.4.20 version is a
171 sigcontext_struct, not an mcontext. The sigcontext looks like
172 this:
173
174 struct sigcontext_struct {
175 unsigned long _unused[4];
176 int signal;
177 unsigned long handler;
178 unsigned long oldmask;
179 struct pt_regs *regs;
180 };
181
182 The regs pointer of that struct ends up at the same offset as the
183 uc_regs of the 2.6 struct ucontext, and a struct pt_regs is the
184 same as the mc_gregs field of the mcontext. In fact the integer
185 regs are followed in memory by the floating point regs on 2.4.20.
186
187 Thus if you are using the 2.6 definitions, it should work on 2.4.20
188 provided that you go via uc->uc_regs rather than looking in
189 uc->uc_mcontext directly.
190
191 There is another subtlety: 2.4.20 doesn't save the vector regs when
192 delivering a signal, and 2.6.x only saves the vector regs if the
193 process has ever used an altivec instructions. If 2.6.x does save
194 the vector regs, it sets the MSR_VEC bit in
195 uc->uc_regs->mc_gregs[PT_MSR], otherwise it clears it. That bit
196 will always be clear under 2.4.20. So you can use that bit to tell
197 whether uc->uc_regs->mc_vregs is valid. */
198# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_NIP])
199# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
200# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
201# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R0])
sewardj39a7c1d2005-11-24 03:54:38 +0000202# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
203 /* Convert the values in uc_mcontext r3,cr into a SysRes. */ \
204 VG_(mk_SysRes_ppc32_linux)( \
sewardja36dcfa2005-11-25 02:16:58 +0000205 (uc)->uc_regs->mc_gregs[VKI_PT_R3], \
206 (((uc)->uc_regs->mc_gregs[VKI_PT_CCR] >> 28) & 1) \
sewardj39a7c1d2005-11-24 03:54:38 +0000207 )
sewardja36dcfa2005-11-25 02:16:58 +0000208# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_LNK])
cerion85665ca2005-06-20 15:51:07 +0000209
sewardj2c48c7b2005-11-29 13:05:56 +0000210#elif defined(VGP_ppc64_linux)
211# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_NIP])
212# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
213# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
214# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R0])
sewardjdcb6ec82006-01-19 03:44:10 +0000215 /* Dubious hack: if there is an error, only consider the lowest 8
216 bits of r3. memcheck/tests/post-syscall shows a case where an
217 interrupted syscall should have produced a ucontext with 0x4
218 (VKI_EINTR) in r3 but is in fact producing 0x204. */
219 /* Awaiting clarification from PaulM. Evidently 0x204 is
220 ERESTART_RESTARTBLOCK, which shouldn't have made it into user
221 space. */
222 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( struct vki_ucontext* uc )
223 {
224 ULong err = (uc->uc_mcontext.gp_regs[VKI_PT_CCR] >> 28) & 1;
225 ULong r3 = uc->uc_mcontext.gp_regs[VKI_PT_R3];
226 if (err) r3 &= 0xFF;
227 return VG_(mk_SysRes_ppc64_linux)( r3, err );
228 }
sewardj2c48c7b2005-11-29 13:05:56 +0000229# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_LNK])
230
sewardj489bfec2006-10-17 02:00:29 +0000231#elif defined(VGP_ppc32_aix5)
232
233 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
234# include <ucontext.h>
235 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
236 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
237 ucontext_t* uc = (ucontext_t*)ucV;
238 struct __jmpbuf* mc = &(uc->uc_mcontext);
239 struct mstsave* jc = &mc->jmp_context;
240 return jc->iar;
241 }
242 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
243 ucontext_t* uc = (ucontext_t*)ucV;
244 struct __jmpbuf* mc = &(uc->uc_mcontext);
245 struct mstsave* jc = &mc->jmp_context;
246 return jc->gpr[1];
247 }
248 static inline Addr VG_UCONTEXT_SYSCALL_NUM( void* ucV ) {
249 ucontext_t* uc = (ucontext_t*)ucV;
250 struct __jmpbuf* mc = &(uc->uc_mcontext);
251 struct mstsave* jc = &mc->jmp_context;
252 return jc->gpr[2];
253 }
254 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV ) {
255 ucontext_t* uc = (ucontext_t*)ucV;
256 struct __jmpbuf* mc = &(uc->uc_mcontext);
257 struct mstsave* jc = &mc->jmp_context;
258 return VG_(mk_SysRes_ppc32_aix5)( jc->gpr[3], jc->gpr[4] );
259 }
260 static inline Addr VG_UCONTEXT_LINK_REG( void* ucV ) {
261 ucontext_t* uc = (ucontext_t*)ucV;
262 struct __jmpbuf* mc = &(uc->uc_mcontext);
263 struct mstsave* jc = &mc->jmp_context;
264 return jc->lr;
265 }
266 static inline Addr VG_UCONTEXT_FRAME_PTR( void* ucV ) {
267 return VG_UCONTEXT_STACK_PTR(ucV);
268 }
269
270#elif defined(VGP_ppc64_aix5)
271
272 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
273# include <ucontext.h>
274 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
275 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
276 ucontext_t* uc = (ucontext_t*)ucV;
277 struct __jmpbuf* mc = &(uc->uc_mcontext);
278 struct __context64* jc = &mc->jmp_context;
279 return jc->iar;
280 }
281 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
282 ucontext_t* uc = (ucontext_t*)ucV;
283 struct __jmpbuf* mc = &(uc->uc_mcontext);
284 struct __context64* jc = &mc->jmp_context;
285 return jc->gpr[1];
286 }
287 static inline Addr VG_UCONTEXT_SYSCALL_NUM( void* ucV ) {
288 ucontext_t* uc = (ucontext_t*)ucV;
289 struct __jmpbuf* mc = &(uc->uc_mcontext);
290 struct __context64* jc = &mc->jmp_context;
291 return jc->gpr[2];
292 }
293 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV ) {
294 ucontext_t* uc = (ucontext_t*)ucV;
295 struct __jmpbuf* mc = &(uc->uc_mcontext);
296 struct __context64* jc = &mc->jmp_context;
297 return VG_(mk_SysRes_ppc32_aix5)( jc->gpr[3], jc->gpr[4] );
298 }
299 static inline Addr VG_UCONTEXT_LINK_REG( void* ucV ) {
300 ucontext_t* uc = (ucontext_t*)ucV;
301 struct __jmpbuf* mc = &(uc->uc_mcontext);
302 struct __context64* jc = &mc->jmp_context;
303 return jc->lr;
304 }
305 static inline Addr VG_UCONTEXT_FRAME_PTR( void* ucV ) {
306 return VG_UCONTEXT_STACK_PTR(ucV);
307 }
308
309#else
njn605f4882005-05-29 17:50:40 +0000310# error Unknown platform
311#endif
312
sewardj489bfec2006-10-17 02:00:29 +0000313
314/* ------ Macros for pulling stuff out of siginfos ------ */
315
316/* These macros allow use of uniform names when working with
317 both the Linux and AIX vki definitions. */
318#if defined(VGO_linux)
319# define VKI_SIGINFO_si_addr _sifields._sigfault._addr
320# define VKI_SIGINFO_si_pid _sifields._kill._pid
321#elif defined(VGO_aix5)
322# define VKI_SIGINFO_si_addr si_addr
323# define VKI_SIGINFO_si_pid si_pid
324#else
325# error Unknown OS
326#endif
327
328
nethercote759dda32004-08-07 18:16:56 +0000329/* ---------------------------------------------------------------------
sewardj018f7622002-05-15 21:13:39 +0000330 HIGH LEVEL STUFF TO DO WITH SIGNALS: POLICY (MOSTLY)
331 ------------------------------------------------------------------ */
332
sewardjde4a1d02002-03-22 01:27:54 +0000333/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000334 Signal state for this process.
335 ------------------------------------------------------------------ */
336
sewardj018f7622002-05-15 21:13:39 +0000337
nethercote73b526f2004-10-31 18:48:21 +0000338/* Base-ment of these arrays[_VKI_NSIG].
sewardjb48e5002002-05-13 00:16:03 +0000339
nethercote73b526f2004-10-31 18:48:21 +0000340 Valid signal numbers are 1 .. _VKI_NSIG inclusive.
sewardjb48e5002002-05-13 00:16:03 +0000341 Rather than subtracting 1 for indexing these arrays, which
342 is tedious and error-prone, they are simply dimensioned 1 larger,
343 and entry [0] is not used.
344 */
345
sewardjb48e5002002-05-13 00:16:03 +0000346
sewardj018f7622002-05-15 21:13:39 +0000347/* -----------------------------------------------------
348 Static client signal state (SCSS). This is the state
349 that the client thinks it has the kernel in.
350 SCSS records verbatim the client's settings. These
351 are mashed around only when SKSS is calculated from it.
352 -------------------------------------------------- */
sewardjb48e5002002-05-13 00:16:03 +0000353
sewardj018f7622002-05-15 21:13:39 +0000354typedef
355 struct {
356 void* scss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN or ptr to
357 client's handler */
358 UInt scss_flags;
nethercote73b526f2004-10-31 18:48:21 +0000359 vki_sigset_t scss_mask;
sewardjb5f6f512005-03-10 23:59:00 +0000360 void* scss_restorer; /* where sigreturn goes */
sewardj018f7622002-05-15 21:13:39 +0000361 }
362 SCSS_Per_Signal;
sewardjb48e5002002-05-13 00:16:03 +0000363
sewardj018f7622002-05-15 21:13:39 +0000364typedef
365 struct {
sewardj2342c972002-05-22 23:34:20 +0000366 /* per-signal info */
nethercote73b526f2004-10-31 18:48:21 +0000367 SCSS_Per_Signal scss_per_sig[1+_VKI_NSIG];
sewardj2342c972002-05-22 23:34:20 +0000368
sewardj018f7622002-05-15 21:13:39 +0000369 /* Additional elements to SCSS not stored here:
370 - for each thread, the thread's blocking mask
371 - for each thread in WaitSIG, the set of waited-on sigs
372 */
373 }
374 SCSS;
sewardjb48e5002002-05-13 00:16:03 +0000375
njn695c16e2005-03-27 03:40:28 +0000376static SCSS scss;
sewardj018f7622002-05-15 21:13:39 +0000377
378
379/* -----------------------------------------------------
380 Static kernel signal state (SKSS). This is the state
381 that we have the kernel in. It is computed from SCSS.
382 -------------------------------------------------- */
383
384/* Let's do:
385 sigprocmask assigns to all thread masks
386 so that at least everything is always consistent
387 Flags:
jsgf855d93d2003-10-13 22:26:55 +0000388 SA_SIGINFO -- we always set it, and honour it for the client
sewardj018f7622002-05-15 21:13:39 +0000389 SA_NOCLDSTOP -- passed to kernel
sewardjb5f6f512005-03-10 23:59:00 +0000390 SA_ONESHOT or SA_RESETHAND -- pass through
jsgf855d93d2003-10-13 22:26:55 +0000391 SA_RESTART -- we observe this but set our handlers to always restart
392 SA_NOMASK or SA_NODEFER -- we observe this, but our handlers block everything
sewardjb5f6f512005-03-10 23:59:00 +0000393 SA_ONSTACK -- pass through
394 SA_NOCLDWAIT -- pass through
sewardjb48e5002002-05-13 00:16:03 +0000395*/
sewardjde4a1d02002-03-22 01:27:54 +0000396
sewardj77e466c2002-04-14 02:29:29 +0000397
sewardj018f7622002-05-15 21:13:39 +0000398typedef
399 struct {
400 void* skss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN
401 or ptr to our handler */
402 UInt skss_flags;
403 /* There is no skss_mask, since we know that we will always ask
jsgf855d93d2003-10-13 22:26:55 +0000404 for all signals to be blocked in our sighandlers. */
sewardj018f7622002-05-15 21:13:39 +0000405 /* Also there is no skss_restorer. */
406 }
407 SKSS_Per_Signal;
sewardjde4a1d02002-03-22 01:27:54 +0000408
sewardj018f7622002-05-15 21:13:39 +0000409typedef
410 struct {
nethercote73b526f2004-10-31 18:48:21 +0000411 SKSS_Per_Signal skss_per_sig[1+_VKI_NSIG];
sewardj018f7622002-05-15 21:13:39 +0000412 }
413 SKSS;
414
njn695c16e2005-03-27 03:40:28 +0000415static SKSS skss;
sewardjde4a1d02002-03-22 01:27:54 +0000416
njn07ef6c02005-05-18 19:43:09 +0000417static Bool is_sig_ign(Int sigNo)
jsgf855d93d2003-10-13 22:26:55 +0000418{
nethercote73b526f2004-10-31 18:48:21 +0000419 vg_assert(sigNo >= 1 && sigNo <= _VKI_NSIG);
sewardj2e93c502002-04-12 11:12:52 +0000420
njn695c16e2005-03-27 03:40:28 +0000421 return scss.scss_per_sig[sigNo].scss_handler == VKI_SIG_IGN;
jsgf855d93d2003-10-13 22:26:55 +0000422}
sewardjb48e5002002-05-13 00:16:03 +0000423
sewardj018f7622002-05-15 21:13:39 +0000424/* ---------------------------------------------------------------------
425 Compute the SKSS required by the current SCSS.
426 ------------------------------------------------------------------ */
427
sewardj4f29ddf2002-05-03 22:29:04 +0000428static
sewardj018f7622002-05-15 21:13:39 +0000429void pp_SKSS ( void )
430{
431 Int sig;
432 VG_(printf)("\n\nSKSS:\n");
nethercote73b526f2004-10-31 18:48:21 +0000433 for (sig = 1; sig <= _VKI_NSIG; sig++) {
dirk61780382007-10-01 10:33:41 +0000434 VG_(printf)("sig %d: handler %p, flags 0x%x\n", sig,
njn695c16e2005-03-27 03:40:28 +0000435 skss.skss_per_sig[sig].skss_handler,
436 skss.skss_per_sig[sig].skss_flags );
sewardj77e466c2002-04-14 02:29:29 +0000437
sewardj018f7622002-05-15 21:13:39 +0000438 }
sewardj018f7622002-05-15 21:13:39 +0000439}
440
sewardj018f7622002-05-15 21:13:39 +0000441/* This is the core, clever bit. Computation is as follows:
442
443 For each signal
444 handler = if client has a handler, then our handler
jsgf855d93d2003-10-13 22:26:55 +0000445 else if client is DFL, then our handler as well
446 else (client must be IGN)
sewardjb5f6f512005-03-10 23:59:00 +0000447 then hander is IGN
sewardj018f7622002-05-15 21:13:39 +0000448*/
449static
450void calculate_SKSS_from_SCSS ( SKSS* dst )
451{
452 Int sig;
sewardj018f7622002-05-15 21:13:39 +0000453 UInt scss_flags;
454 UInt skss_flags;
455
nethercote73b526f2004-10-31 18:48:21 +0000456 for (sig = 1; sig <= _VKI_NSIG; sig++) {
jsgf855d93d2003-10-13 22:26:55 +0000457 void *skss_handler;
458 void *scss_handler;
459
njn695c16e2005-03-27 03:40:28 +0000460 scss_handler = scss.scss_per_sig[sig].scss_handler;
461 scss_flags = scss.scss_per_sig[sig].scss_flags;
sewardj018f7622002-05-15 21:13:39 +0000462
jsgf855d93d2003-10-13 22:26:55 +0000463 switch(sig) {
464 case VKI_SIGSEGV:
465 case VKI_SIGBUS:
466 case VKI_SIGFPE:
467 case VKI_SIGILL:
sewardjb5f6f512005-03-10 23:59:00 +0000468 case VKI_SIGTRAP:
jsgf855d93d2003-10-13 22:26:55 +0000469 /* For these, we always want to catch them and report, even
470 if the client code doesn't. */
njn695c16e2005-03-27 03:40:28 +0000471 skss_handler = sync_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000472 break;
473
sewardjb5f6f512005-03-10 23:59:00 +0000474 case VKI_SIGCONT:
475 /* Let the kernel handle SIGCONT unless the client is actually
476 catching it. */
njna530fc62005-03-13 04:46:36 +0000477 case VKI_SIGCHLD:
478 case VKI_SIGWINCH:
479 case VKI_SIGURG:
480 /* For signals which are have a default action of Ignore,
481 only set a handler if the client has set a signal handler.
482 Otherwise the kernel will interrupt a syscall which
483 wouldn't have otherwise been interrupted. */
njn695c16e2005-03-27 03:40:28 +0000484 if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_DFL)
sewardjb5f6f512005-03-10 23:59:00 +0000485 skss_handler = VKI_SIG_DFL;
njn695c16e2005-03-27 03:40:28 +0000486 else if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_IGN)
jsgf855d93d2003-10-13 22:26:55 +0000487 skss_handler = VKI_SIG_IGN;
sewardjb5f6f512005-03-10 23:59:00 +0000488 else
njn695c16e2005-03-27 03:40:28 +0000489 skss_handler = async_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000490 break;
jsgf855d93d2003-10-13 22:26:55 +0000491
sewardjb5f6f512005-03-10 23:59:00 +0000492 default:
njna530fc62005-03-13 04:46:36 +0000493 // VKI_SIGVG* are runtime variables, so we can't make them
494 // cases in the switch, so we handle them in the 'default' case.
njn351d0062005-06-21 22:23:59 +0000495 if (sig == VG_SIGVGKILL)
sewardjb5f6f512005-03-10 23:59:00 +0000496 skss_handler = sigvgkill_handler;
sewardjb5f6f512005-03-10 23:59:00 +0000497 else {
498 if (scss_handler == VKI_SIG_IGN)
499 skss_handler = VKI_SIG_IGN;
500 else
njn695c16e2005-03-27 03:40:28 +0000501 skss_handler = async_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +0000502 }
503 break;
504 }
sewardj018f7622002-05-15 21:13:39 +0000505
sewardj018f7622002-05-15 21:13:39 +0000506 /* Flags */
507
508 skss_flags = 0;
jsgf855d93d2003-10-13 22:26:55 +0000509
sewardjb5f6f512005-03-10 23:59:00 +0000510 /* SA_NOCLDSTOP, SA_NOCLDWAIT: pass to kernel */
511 skss_flags |= scss_flags & (VKI_SA_NOCLDSTOP | VKI_SA_NOCLDWAIT);
jsgf855d93d2003-10-13 22:26:55 +0000512
sewardj018f7622002-05-15 21:13:39 +0000513 /* SA_ONESHOT: ignore client setting */
sewardjb5f6f512005-03-10 23:59:00 +0000514
sewardja8d8e232005-06-07 20:04:56 +0000515 /* SA_RESTART: ignore client setting and always set it for us.
516 Though we never rely on the kernel to restart a
jsgf855d93d2003-10-13 22:26:55 +0000517 syscall, we observe whether it wanted to restart the syscall
sewardja8d8e232005-06-07 20:04:56 +0000518 or not, which is needed by
519 VG_(fixup_guest_state_after_syscall_interrupted) */
sewardj018f7622002-05-15 21:13:39 +0000520 skss_flags |= VKI_SA_RESTART;
jsgf855d93d2003-10-13 22:26:55 +0000521
522 /* SA_NOMASK: ignore it */
523
sewardj2342c972002-05-22 23:34:20 +0000524 /* SA_ONSTACK: client setting is irrelevant here */
sewardjb5f6f512005-03-10 23:59:00 +0000525 /* We don't set a signal stack, so ignore */
sewardj018f7622002-05-15 21:13:39 +0000526
jsgf855d93d2003-10-13 22:26:55 +0000527 /* always ask for SA_SIGINFO */
528 skss_flags |= VKI_SA_SIGINFO;
sewardj018f7622002-05-15 21:13:39 +0000529
fitzhardinge4f10ada2004-06-03 10:00:42 +0000530 /* use our own restorer */
531 skss_flags |= VKI_SA_RESTORER;
532
jsgf855d93d2003-10-13 22:26:55 +0000533 /* Create SKSS entry for this signal. */
sewardj6a3c26e2002-05-23 17:09:43 +0000534 if (sig != VKI_SIGKILL && sig != VKI_SIGSTOP)
535 dst->skss_per_sig[sig].skss_handler = skss_handler;
536 else
537 dst->skss_per_sig[sig].skss_handler = VKI_SIG_DFL;
538
sewardj018f7622002-05-15 21:13:39 +0000539 dst->skss_per_sig[sig].skss_flags = skss_flags;
540 }
541
542 /* Sanity checks. */
nethercote5fd72bb2004-11-04 19:28:38 +0000543 vg_assert(dst->skss_per_sig[VKI_SIGKILL].skss_handler == VKI_SIG_DFL);
544 vg_assert(dst->skss_per_sig[VKI_SIGSTOP].skss_handler == VKI_SIG_DFL);
sewardj018f7622002-05-15 21:13:39 +0000545
546 if (0)
547 pp_SKSS();
548}
549
550
551/* ---------------------------------------------------------------------
552 After a possible SCSS change, update SKSS and the kernel itself.
553 ------------------------------------------------------------------ */
554
njn9abd6082005-06-17 21:31:45 +0000555// We need two levels of macro-expansion here to convert __NR_rt_sigreturn
556// to a number before converting it to a string... sigh.
sewardj03d8aa82005-10-14 11:25:49 +0000557extern void my_sigreturn(void);
njn9abd6082005-06-17 21:31:45 +0000558
559#if defined(VGP_x86_linux)
560# define _MYSIG(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000561 ".text\n" \
njn9abd6082005-06-17 21:31:45 +0000562 "my_sigreturn:\n" \
563 " movl $" #name ", %eax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000564 " int $0x80\n" \
565 ".previous\n"
njn9abd6082005-06-17 21:31:45 +0000566#elif defined(VGP_amd64_linux)
567# define _MYSIG(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000568 ".text\n" \
njn9abd6082005-06-17 21:31:45 +0000569 "my_sigreturn:\n" \
570 " movq $" #name ", %rax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000571 " syscall\n" \
572 ".previous\n"
cerion85665ca2005-06-20 15:51:07 +0000573#elif defined(VGP_ppc32_linux)
574# define _MYSIG(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000575 ".text\n" \
cerion85665ca2005-06-20 15:51:07 +0000576 "my_sigreturn:\n" \
577 " li 0, " #name "\n" \
sewardj2fedc642005-11-19 02:02:57 +0000578 " sc\n" \
579 ".previous\n"
sewardj2c48c7b2005-11-29 13:05:56 +0000580#elif defined(VGP_ppc64_linux)
581# define _MYSIG(name) \
cerion297c88f2005-12-22 15:53:12 +0000582 ".align 2\n" \
583 ".globl my_sigreturn\n" \
584 ".section \".opd\",\"aw\"\n" \
585 ".align 3\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000586 "my_sigreturn:\n" \
cerion297c88f2005-12-22 15:53:12 +0000587 ".quad .my_sigreturn,.TOC.@tocbase,0\n" \
588 ".previous\n" \
589 ".type .my_sigreturn,@function\n" \
590 ".globl .my_sigreturn\n" \
591 ".my_sigreturn:\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000592 " li 0, " #name "\n" \
cerion297c88f2005-12-22 15:53:12 +0000593 " sc\n"
sewardj489bfec2006-10-17 02:00:29 +0000594#elif defined(VGP_ppc32_aix5)
595# define _MYSIG(name) \
596 ".globl my_sigreturn\n" \
597 "my_sigreturn:\n" \
598 ".long 0\n"
599#elif defined(VGP_ppc64_aix5)
600# define _MYSIG(name) \
601 ".globl my_sigreturn\n" \
602 "my_sigreturn:\n" \
603 ".long 0\n"
njn9abd6082005-06-17 21:31:45 +0000604#else
605# error Unknown platform
606#endif
607
608#define MYSIG(name) _MYSIG(name)
609asm(
610 MYSIG(__NR_rt_sigreturn)
611);
612
613
nethercote9dd11512004-08-04 15:31:30 +0000614static void handle_SCSS_change ( Bool force_update )
sewardj018f7622002-05-15 21:13:39 +0000615{
nethercote73b526f2004-10-31 18:48:21 +0000616 Int res, sig;
617 SKSS skss_old;
618 struct vki_sigaction ksa, ksa_old;
sewardj018f7622002-05-15 21:13:39 +0000619
sewardj018f7622002-05-15 21:13:39 +0000620 /* Remember old SKSS and calculate new one. */
njn695c16e2005-03-27 03:40:28 +0000621 skss_old = skss;
622 calculate_SKSS_from_SCSS ( &skss );
sewardj018f7622002-05-15 21:13:39 +0000623
624 /* Compare the new SKSS entries vs the old ones, and update kernel
625 where they differ. */
sewardjb5f6f512005-03-10 23:59:00 +0000626 for (sig = 1; sig <= VG_(max_signal); sig++) {
sewardj018f7622002-05-15 21:13:39 +0000627
628 /* Trying to do anything with SIGKILL is pointless; just ignore
629 it. */
630 if (sig == VKI_SIGKILL || sig == VKI_SIGSTOP)
631 continue;
632
sewardj018f7622002-05-15 21:13:39 +0000633 if (!force_update) {
634 if ((skss_old.skss_per_sig[sig].skss_handler
njn695c16e2005-03-27 03:40:28 +0000635 == skss.skss_per_sig[sig].skss_handler)
sewardj018f7622002-05-15 21:13:39 +0000636 && (skss_old.skss_per_sig[sig].skss_flags
njn695c16e2005-03-27 03:40:28 +0000637 == skss.skss_per_sig[sig].skss_flags))
sewardj018f7622002-05-15 21:13:39 +0000638 /* no difference */
639 continue;
640 }
641
njn695c16e2005-03-27 03:40:28 +0000642 ksa.ksa_handler = skss.skss_per_sig[sig].skss_handler;
643 ksa.sa_flags = skss.skss_per_sig[sig].skss_flags;
sewardj489bfec2006-10-17 02:00:29 +0000644# if !defined(VGP_ppc32_linux) && !defined(VGP_ppc32_aix5) \
645 && !defined(VGP_ppc64_aix5)
njn9abd6082005-06-17 21:31:45 +0000646 ksa.sa_restorer = my_sigreturn;
sewardjce2a6152005-07-08 18:25:13 +0000647# endif
sewardj162bebd2005-07-09 10:43:45 +0000648 /* Re above ifdef (also the assertion below), PaulM says:
649 The sa_restorer field is not used at all on ppc. Glibc
650 converts the sigaction you give it into a kernel sigaction,
651 but it doesn't put anything in the sa_restorer field.
652 */
fitzhardinge4f10ada2004-06-03 10:00:42 +0000653
sewardjb5f6f512005-03-10 23:59:00 +0000654 /* block all signals in handler */
nethercote73b526f2004-10-31 18:48:21 +0000655 VG_(sigfillset)( &ksa.sa_mask );
656 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGKILL );
657 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGSTOP );
sewardj018f7622002-05-15 21:13:39 +0000658
sewardjb5f6f512005-03-10 23:59:00 +0000659 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj018f7622002-05-15 21:13:39 +0000660 VG_(message)(Vg_DebugMsg,
661 "setting ksig %d to: hdlr 0x%x, flags 0x%x, "
662 "mask(63..0) 0x%x 0x%x",
663 sig, ksa.ksa_handler,
nethercote73b526f2004-10-31 18:48:21 +0000664 ksa.sa_flags,
665 ksa.sa_mask.sig[1],
666 ksa.sa_mask.sig[0]
sewardj018f7622002-05-15 21:13:39 +0000667 );
668
nethercote73b526f2004-10-31 18:48:21 +0000669 res = VG_(sigaction)( sig, &ksa, &ksa_old );
sewardj018f7622002-05-15 21:13:39 +0000670 vg_assert(res == 0);
671
672 /* Since we got the old sigaction more or less for free, might
673 as well extract the maximum sanity-check value from it. */
674 if (!force_update) {
675 vg_assert(ksa_old.ksa_handler
676 == skss_old.skss_per_sig[sig].skss_handler);
nethercote73b526f2004-10-31 18:48:21 +0000677 vg_assert(ksa_old.sa_flags
sewardj018f7622002-05-15 21:13:39 +0000678 == skss_old.skss_per_sig[sig].skss_flags);
sewardj489bfec2006-10-17 02:00:29 +0000679# if !defined(VGP_ppc32_linux) && !defined(VGP_ppc32_aix5) \
680 && !defined(VGP_ppc64_aix5)
nethercote73b526f2004-10-31 18:48:21 +0000681 vg_assert(ksa_old.sa_restorer
njn9abd6082005-06-17 21:31:45 +0000682 == my_sigreturn);
sewardjce2a6152005-07-08 18:25:13 +0000683# endif
nethercote73b526f2004-10-31 18:48:21 +0000684 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGKILL );
685 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGSTOP );
686 vg_assert(VG_(isfullsigset)( &ksa_old.sa_mask ));
sewardj018f7622002-05-15 21:13:39 +0000687 }
688 }
sewardj018f7622002-05-15 21:13:39 +0000689}
690
691
692/* ---------------------------------------------------------------------
693 Update/query SCSS in accordance with client requests.
694 ------------------------------------------------------------------ */
695
sewardj2342c972002-05-22 23:34:20 +0000696/* Logic for this alt-stack stuff copied directly from do_sigaltstack
697 in kernel/signal.[ch] */
698
699/* True if we are on the alternate signal stack. */
sewardjb5f6f512005-03-10 23:59:00 +0000700static Bool on_sig_stack ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000701{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000702 ThreadState *tst = VG_(get_ThreadState)(tid);
703
nethercote511e4062004-09-11 13:34:08 +0000704 return (m_SP - (Addr)tst->altstack.ss_sp < tst->altstack.ss_size);
sewardj2342c972002-05-22 23:34:20 +0000705}
706
nethercote511e4062004-09-11 13:34:08 +0000707static Int sas_ss_flags ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000708{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000709 ThreadState *tst = VG_(get_ThreadState)(tid);
710
711 return (tst->altstack.ss_size == 0
sewardj2342c972002-05-22 23:34:20 +0000712 ? VKI_SS_DISABLE
nethercote511e4062004-09-11 13:34:08 +0000713 : on_sig_stack(tid, m_SP) ? VKI_SS_ONSTACK : 0);
sewardj2342c972002-05-22 23:34:20 +0000714}
715
716
sewardja8d8e232005-06-07 20:04:56 +0000717SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
sewardj2342c972002-05-22 23:34:20 +0000718{
njn502badb2005-05-08 02:04:49 +0000719 Addr m_SP;
sewardj2342c972002-05-22 23:34:20 +0000720
721 vg_assert(VG_(is_valid_tid)(tid));
njnf536bbb2005-06-13 04:21:38 +0000722 m_SP = VG_(get_SP)(tid);
sewardj2342c972002-05-22 23:34:20 +0000723
724 if (VG_(clo_trace_signals))
725 VG_(message)(Vg_DebugExtraMsg,
nethercote04d3a802004-11-16 18:26:11 +0000726 "sys_sigaltstack: tid %d, "
nethercote511e4062004-09-11 13:34:08 +0000727 "ss %p, oss %p (current SP %p)",
728 tid, (void*)ss, (void*)oss, (void*)m_SP );
sewardj2342c972002-05-22 23:34:20 +0000729
730 if (oss != NULL) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000731 oss->ss_sp = VG_(threads)[tid].altstack.ss_sp;
732 oss->ss_size = VG_(threads)[tid].altstack.ss_size;
nethercote511e4062004-09-11 13:34:08 +0000733 oss->ss_flags = VG_(threads)[tid].altstack.ss_flags | sas_ss_flags(tid, m_SP);
sewardj2342c972002-05-22 23:34:20 +0000734 }
735
736 if (ss != NULL) {
njnf536bbb2005-06-13 04:21:38 +0000737 if (on_sig_stack(tid, VG_(get_SP)(tid))) {
sewardja8d8e232005-06-07 20:04:56 +0000738 return VG_(mk_SysRes_Error)( VKI_EPERM );
sewardj2342c972002-05-22 23:34:20 +0000739 }
740 if (ss->ss_flags != VKI_SS_DISABLE
741 && ss->ss_flags != VKI_SS_ONSTACK
742 && ss->ss_flags != 0) {
sewardja8d8e232005-06-07 20:04:56 +0000743 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj2342c972002-05-22 23:34:20 +0000744 }
745 if (ss->ss_flags == VKI_SS_DISABLE) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000746 VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
sewardj2342c972002-05-22 23:34:20 +0000747 } else {
748 if (ss->ss_size < VKI_MINSIGSTKSZ) {
sewardja8d8e232005-06-07 20:04:56 +0000749 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
sewardj2342c972002-05-22 23:34:20 +0000750 }
jsgf855d93d2003-10-13 22:26:55 +0000751
nethercote20283c62004-11-04 19:43:22 +0000752 VG_(threads)[tid].altstack.ss_sp = ss->ss_sp;
753 VG_(threads)[tid].altstack.ss_size = ss->ss_size;
fitzhardinge98c4dc02004-03-16 08:27:29 +0000754 VG_(threads)[tid].altstack.ss_flags = 0;
sewardj2342c972002-05-22 23:34:20 +0000755 }
sewardj2342c972002-05-22 23:34:20 +0000756 }
sewardja8d8e232005-06-07 20:04:56 +0000757 return VG_(mk_SysRes_Success)( 0 );
sewardj2342c972002-05-22 23:34:20 +0000758}
759
760
sewardja8d8e232005-06-07 20:04:56 +0000761SysRes VG_(do_sys_sigaction) ( Int signo,
762 const struct vki_sigaction *new_act,
763 struct vki_sigaction *old_act )
sewardj018f7622002-05-15 21:13:39 +0000764{
sewardj018f7622002-05-15 21:13:39 +0000765 if (VG_(clo_trace_signals))
766 VG_(message)(Vg_DebugExtraMsg,
sewardjb5f6f512005-03-10 23:59:00 +0000767 "sys_sigaction: sigNo %d, "
nethercote93246cf2004-11-04 18:56:47 +0000768 "new %p, old %p, new flags 0x%llx",
sewardjb5f6f512005-03-10 23:59:00 +0000769 signo, (UWord)new_act, (UWord)old_act,
nethercote93246cf2004-11-04 18:56:47 +0000770 (ULong)(new_act ? new_act->sa_flags : 0) );
sewardj018f7622002-05-15 21:13:39 +0000771
772 /* Rule out various error conditions. The aim is to ensure that if
773 when the call is passed to the kernel it will definitely
774 succeed. */
775
776 /* Reject out-of-range signal numbers. */
sewardjb5f6f512005-03-10 23:59:00 +0000777 if (signo < 1 || signo > VG_(max_signal)) goto bad_signo;
sewardj018f7622002-05-15 21:13:39 +0000778
jsgf855d93d2003-10-13 22:26:55 +0000779 /* don't let them use our signals */
njn351d0062005-06-21 22:23:59 +0000780 if ( (signo > VG_SIGVGRTUSERMAX)
jsgf855d93d2003-10-13 22:26:55 +0000781 && new_act
sewardja8d8e232005-06-07 20:04:56 +0000782 && !(new_act->ksa_handler == VKI_SIG_DFL
783 || new_act->ksa_handler == VKI_SIG_IGN) )
nethercote9c42a0f2003-11-17 10:37:19 +0000784 goto bad_signo_reserved;
jsgf855d93d2003-10-13 22:26:55 +0000785
sewardj018f7622002-05-15 21:13:39 +0000786 /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
787 if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP)
788 && new_act
789 && new_act->ksa_handler != VKI_SIG_DFL)
790 goto bad_sigkill_or_sigstop;
791
792 /* If the client supplied non-NULL old_act, copy the relevant SCSS
793 entry into it. */
794 if (old_act) {
njn695c16e2005-03-27 03:40:28 +0000795 old_act->ksa_handler = scss.scss_per_sig[signo].scss_handler;
796 old_act->sa_flags = scss.scss_per_sig[signo].scss_flags;
797 old_act->sa_mask = scss.scss_per_sig[signo].scss_mask;
sewardj489bfec2006-10-17 02:00:29 +0000798# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
njn695c16e2005-03-27 03:40:28 +0000799 old_act->sa_restorer = scss.scss_per_sig[signo].scss_restorer;
sewardj489bfec2006-10-17 02:00:29 +0000800# endif
sewardj018f7622002-05-15 21:13:39 +0000801 }
802
803 /* And now copy new SCSS entry from new_act. */
804 if (new_act) {
njn695c16e2005-03-27 03:40:28 +0000805 scss.scss_per_sig[signo].scss_handler = new_act->ksa_handler;
806 scss.scss_per_sig[signo].scss_flags = new_act->sa_flags;
807 scss.scss_per_sig[signo].scss_mask = new_act->sa_mask;
sewardj489bfec2006-10-17 02:00:29 +0000808
809 scss.scss_per_sig[signo].scss_restorer = 0;
810# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
njn695c16e2005-03-27 03:40:28 +0000811 scss.scss_per_sig[signo].scss_restorer = new_act->sa_restorer;
sewardj489bfec2006-10-17 02:00:29 +0000812# endif
sewardjb5f6f512005-03-10 23:59:00 +0000813
njn695c16e2005-03-27 03:40:28 +0000814 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGKILL);
815 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGSTOP);
sewardj018f7622002-05-15 21:13:39 +0000816 }
817
818 /* All happy bunnies ... */
819 if (new_act) {
nethercote9dd11512004-08-04 15:31:30 +0000820 handle_SCSS_change( False /* lazy update */ );
sewardj018f7622002-05-15 21:13:39 +0000821 }
sewardja8d8e232005-06-07 20:04:56 +0000822 return VG_(mk_SysRes_Success)( 0 );
sewardj018f7622002-05-15 21:13:39 +0000823
824 bad_signo:
sewardjec6e27c2007-11-17 21:31:48 +0000825 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
njn25e49d8e72002-09-23 09:36:25 +0000826 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000827 "Warning: bad signal number %d in sigaction()",
njn25e49d8e72002-09-23 09:36:25 +0000828 signo);
sewardj9a3d8bd2005-05-23 14:47:52 +0000829 }
sewardja8d8e232005-06-07 20:04:56 +0000830 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +0000831
nethercote9c42a0f2003-11-17 10:37:19 +0000832 bad_signo_reserved:
sewardjec6e27c2007-11-17 21:31:48 +0000833 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
nethercote9c42a0f2003-11-17 10:37:19 +0000834 VG_(message)(Vg_UserMsg,
835 "Warning: ignored attempt to set %s handler in sigaction();",
836 signame(signo));
837 VG_(message)(Vg_UserMsg,
838 " the %s signal is used internally by Valgrind",
839 signame(signo));
fitzhardingebf459872003-11-18 16:55:33 +0000840 }
sewardja8d8e232005-06-07 20:04:56 +0000841 return VG_(mk_SysRes_Error)( VKI_EINVAL );
nethercote9c42a0f2003-11-17 10:37:19 +0000842
sewardj018f7622002-05-15 21:13:39 +0000843 bad_sigkill_or_sigstop:
sewardjec6e27c2007-11-17 21:31:48 +0000844 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
njn25e49d8e72002-09-23 09:36:25 +0000845 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000846 "Warning: ignored attempt to set %s handler in sigaction();",
jsgf855d93d2003-10-13 22:26:55 +0000847 signame(signo));
nethercote9c42a0f2003-11-17 10:37:19 +0000848 VG_(message)(Vg_UserMsg,
849 " the %s signal is uncatchable",
850 signame(signo));
sewardj9a3d8bd2005-05-23 14:47:52 +0000851 }
sewardja8d8e232005-06-07 20:04:56 +0000852 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +0000853}
854
855
856static
857void do_sigprocmask_bitops ( Int vki_how,
nethercote73b526f2004-10-31 18:48:21 +0000858 vki_sigset_t* orig_set,
859 vki_sigset_t* modifier )
sewardj018f7622002-05-15 21:13:39 +0000860{
861 switch (vki_how) {
862 case VKI_SIG_BLOCK:
nethercote73b526f2004-10-31 18:48:21 +0000863 VG_(sigaddset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +0000864 break;
865 case VKI_SIG_UNBLOCK:
nethercote73b526f2004-10-31 18:48:21 +0000866 VG_(sigdelset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +0000867 break;
868 case VKI_SIG_SETMASK:
869 *orig_set = *modifier;
870 break;
871 default:
njne427a662002-10-02 11:08:25 +0000872 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +0000873 break;
874 }
875}
876
tomf7781e92005-11-02 15:31:21 +0000877static
878const Char *format_sigset ( const vki_sigset_t* set )
879{
880 static Char buf[128];
881 int w;
882
883 VG_(strcpy)(buf, "");
884
885 for (w = _VKI_NSIG_WORDS - 1; w >= 0; w--)
886 {
887#if _VKI_NSIG_BPW == 32
888 VG_(sprintf)(buf + VG_(strlen)(buf), "%08lx", set ? set->sig[w] : 0);
889#elif _VKI_NSIG_BPW == 64
890 VG_(sprintf)(buf + VG_(strlen)(buf), "%16lx", set ? set->sig[w] : 0);
891#else
892#error "Unsupported value for _VKI_NSIG_BPW"
893#endif
894 }
895
896 return buf;
897}
898
jsgf855d93d2003-10-13 22:26:55 +0000899/*
900 This updates the thread's signal mask. There's no such thing as a
901 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +0000902
903 Note that the thread signal masks are an implicit part of SCSS,
904 which is why this routine is allowed to mess with them.
905*/
906static
907void do_setmask ( ThreadId tid,
908 Int how,
nethercote73b526f2004-10-31 18:48:21 +0000909 vki_sigset_t* newset,
910 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +0000911{
sewardj018f7622002-05-15 21:13:39 +0000912 if (VG_(clo_trace_signals))
sewardja464e5c2002-05-23 17:34:49 +0000913 VG_(message)(Vg_DebugExtraMsg,
tomf7781e92005-11-02 15:31:21 +0000914 "do_setmask: tid = %d how = %d (%s), set = %p %s",
jsgf855d93d2003-10-13 22:26:55 +0000915 tid, how,
916 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
917 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
918 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
tomf7781e92005-11-02 15:31:21 +0000919 newset, format_sigset(newset));
sewardj018f7622002-05-15 21:13:39 +0000920
jsgf855d93d2003-10-13 22:26:55 +0000921 /* Just do this thread. */
922 vg_assert(VG_(is_valid_tid)(tid));
923 if (oldset) {
sewardjb5f6f512005-03-10 23:59:00 +0000924 *oldset = VG_(threads)[tid].sig_mask;
jsgf855d93d2003-10-13 22:26:55 +0000925 if (VG_(clo_trace_signals))
926 VG_(message)(Vg_DebugExtraMsg,
tom1399c742005-11-02 15:32:19 +0000927 "\toldset=%p %s",
tomf7781e92005-11-02 15:31:21 +0000928 oldset, format_sigset(oldset));
sewardj018f7622002-05-15 21:13:39 +0000929 }
sewardj018f7622002-05-15 21:13:39 +0000930 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +0000931 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
nethercote73b526f2004-10-31 18:48:21 +0000932 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
933 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
sewardjb5f6f512005-03-10 23:59:00 +0000934 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
sewardj018f7622002-05-15 21:13:39 +0000935 }
936}
937
938
sewardja8d8e232005-06-07 20:04:56 +0000939SysRes VG_(do_sys_sigprocmask) ( ThreadId tid,
940 Int how,
941 vki_sigset_t* set,
942 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +0000943{
jsgf855d93d2003-10-13 22:26:55 +0000944 switch(how) {
945 case VKI_SIG_BLOCK:
946 case VKI_SIG_UNBLOCK:
947 case VKI_SIG_SETMASK:
sewardj018f7622002-05-15 21:13:39 +0000948 vg_assert(VG_(is_valid_tid)(tid));
jsgf855d93d2003-10-13 22:26:55 +0000949 do_setmask ( tid, how, set, oldset );
sewardja8d8e232005-06-07 20:04:56 +0000950 return VG_(mk_SysRes_Success)( 0 );
jsgf855d93d2003-10-13 22:26:55 +0000951
952 default:
sewardj018f7622002-05-15 21:13:39 +0000953 VG_(message)(Vg_DebugMsg,
njn02bc4b82005-05-15 17:28:26 +0000954 "sigprocmask: unknown 'how' field %d", how);
sewardja8d8e232005-06-07 20:04:56 +0000955 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +0000956 }
957}
958
959
sewardj018f7622002-05-15 21:13:39 +0000960/* ---------------------------------------------------------------------
961 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
962 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +0000963
sewardj2e93c502002-04-12 11:12:52 +0000964/* ---------------------------------------------------------------------
965 Handy utilities to block/restore all host signals.
966 ------------------------------------------------------------------ */
967
968/* Block all host signals, dumping the old mask in *saved_mask. */
njn444eba12005-05-12 03:47:31 +0000969static void block_all_host_signals ( /* OUT */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000970{
971 Int ret;
nethercote73b526f2004-10-31 18:48:21 +0000972 vki_sigset_t block_procmask;
973 VG_(sigfillset)(&block_procmask);
974 ret = VG_(sigprocmask)
sewardj2e93c502002-04-12 11:12:52 +0000975 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
976 vg_assert(ret == 0);
977}
978
979/* Restore the blocking mask using the supplied saved one. */
njn444eba12005-05-12 03:47:31 +0000980static void restore_all_host_signals ( /* IN */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000981{
982 Int ret;
nethercote73b526f2004-10-31 18:48:21 +0000983 ret = VG_(sigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
sewardj2e93c502002-04-12 11:12:52 +0000984 vg_assert(ret == 0);
985}
sewardjde4a1d02002-03-22 01:27:54 +0000986
njn444eba12005-05-12 03:47:31 +0000987void VG_(clear_out_queued_signals)( ThreadId tid, vki_sigset_t* saved_mask )
988{
989 block_all_host_signals(saved_mask);
990 if (VG_(threads)[tid].sig_queue != NULL) {
991 VG_(arena_free)(VG_AR_CORE, VG_(threads)[tid].sig_queue);
992 VG_(threads)[tid].sig_queue = NULL;
993 }
994 restore_all_host_signals(saved_mask);
995}
996
sewardjde4a1d02002-03-22 01:27:54 +0000997/* ---------------------------------------------------------------------
998 The signal simulation proper. A simplified version of what the
999 Linux kernel does.
1000 ------------------------------------------------------------------ */
1001
sewardjde4a1d02002-03-22 01:27:54 +00001002/* Set up a stack frame (VgSigContext) for the client's signal
nethercotefedd8102004-09-13 15:19:34 +00001003 handler. */
sewardj2c5ffbe2005-03-12 13:32:06 +00001004static
tomadacaf92007-12-21 10:24:24 +00001005void push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo, const struct vki_ucontext *uc )
sewardjde4a1d02002-03-22 01:27:54 +00001006{
nethercote6eec4602004-09-13 14:15:36 +00001007 Addr esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +00001008 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +00001009 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +00001010
sewardjb5f6f512005-03-10 23:59:00 +00001011 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardj018f7622002-05-15 21:13:39 +00001012 vg_assert(VG_(is_valid_tid)(tid));
1013 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +00001014
sewardja672ea32006-04-29 18:03:14 +00001015 if (VG_(clo_trace_signals)) {
jsgf855d93d2003-10-13 22:26:55 +00001016 VG_(message)(Vg_DebugMsg,
njn695c16e2005-03-27 03:40:28 +00001017 "push_signal_frame (thread %d): signal %d", tid, sigNo);
sewardja672ea32006-04-29 18:03:14 +00001018 VG_(get_and_pp_StackTrace)(tid, 10);
1019 }
jsgf855d93d2003-10-13 22:26:55 +00001020
sewardj2342c972002-05-22 23:34:20 +00001021 if (/* this signal asked to run on an alt stack */
njn695c16e2005-03-27 03:40:28 +00001022 (scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +00001023 && /* there is a defined and enabled alt stack, which we're not
1024 already using. Logic from get_sigframe in
1025 arch/i386/kernel/signal.c. */
njnf536bbb2005-06-13 04:21:38 +00001026 sas_ss_flags(tid, VG_(get_SP)(tid)) == 0
sewardj2342c972002-05-22 23:34:20 +00001027 ) {
1028 esp_top_of_frame
fitzhardinge98c4dc02004-03-16 08:27:29 +00001029 = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
sewardj2342c972002-05-22 23:34:20 +00001030 if (VG_(clo_trace_signals))
1031 VG_(message)(Vg_DebugMsg,
sewardjb5f6f512005-03-10 23:59:00 +00001032 "delivering signal %d (%s) to thread %d: on ALT STACK (%p-%p; %d bytes)",
1033 sigNo, signame(sigNo), tid,
1034 tst->altstack.ss_sp,
tom151a6392005-11-11 12:30:36 +00001035 (UChar *)tst->altstack.ss_sp + tst->altstack.ss_size,
sewardjb5f6f512005-03-10 23:59:00 +00001036 tst->altstack.ss_size );
njnfdc28af2003-02-24 10:36:48 +00001037
nethercote7cc9c232004-01-21 15:08:04 +00001038 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +00001039 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
njnfdc28af2003-02-24 10:36:48 +00001040
sewardj2342c972002-05-22 23:34:20 +00001041 } else {
njnaf839f52005-06-23 03:27:57 +00001042 esp_top_of_frame = VG_(get_SP)(tid) - VG_STACK_REDZONE_SZB;
njnfdc28af2003-02-24 10:36:48 +00001043
nethercote7cc9c232004-01-21 15:08:04 +00001044 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +00001045 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
sewardj2342c972002-05-22 23:34:20 +00001046 }
sewardjb5f6f512005-03-10 23:59:00 +00001047
njn695c16e2005-03-27 03:40:28 +00001048 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_IGN);
1049 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_DFL);
sewardjb5f6f512005-03-10 23:59:00 +00001050
1051 /* This may fail if the client stack is busted; if that happens,
1052 the whole process will exit rather than simply calling the
1053 signal handler. */
tomadacaf92007-12-21 10:24:24 +00001054 VG_(sigframe_create) (tid, esp_top_of_frame, siginfo, uc,
sewardj985fabb2005-04-24 14:18:14 +00001055 scss.scss_per_sig[sigNo].scss_handler,
1056 scss.scss_per_sig[sigNo].scss_flags,
1057 &tst->sig_mask,
1058 scss.scss_per_sig[sigNo].scss_restorer);
sewardjde4a1d02002-03-22 01:27:54 +00001059}
1060
sewardjde4a1d02002-03-22 01:27:54 +00001061
jsgf855d93d2003-10-13 22:26:55 +00001062static const Char *signame(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +00001063{
jsgf855d93d2003-10-13 22:26:55 +00001064 static Char buf[10];
sewardjb48e5002002-05-13 00:16:03 +00001065
jsgf855d93d2003-10-13 22:26:55 +00001066 switch(sigNo) {
sewardj489bfec2006-10-17 02:00:29 +00001067 case VKI_SIGHUP: return "SIGHUP";
1068 case VKI_SIGINT: return "SIGINT";
1069 case VKI_SIGQUIT: return "SIGQUIT";
1070 case VKI_SIGILL: return "SIGILL";
1071 case VKI_SIGTRAP: return "SIGTRAP";
1072 case VKI_SIGABRT: return "SIGABRT";
1073 case VKI_SIGBUS: return "SIGBUS";
1074 case VKI_SIGFPE: return "SIGFPE";
1075 case VKI_SIGKILL: return "SIGKILL";
1076 case VKI_SIGUSR1: return "SIGUSR1";
1077 case VKI_SIGUSR2: return "SIGUSR2";
1078 case VKI_SIGSEGV: return "SIGSEGV";
1079 case VKI_SIGPIPE: return "SIGPIPE";
1080 case VKI_SIGALRM: return "SIGALRM";
1081 case VKI_SIGTERM: return "SIGTERM";
1082# if defined(VKI_SIGSTKFLT)
1083 case VKI_SIGSTKFLT: return "SIGSTKFLT";
1084# endif
1085 case VKI_SIGCHLD: return "SIGCHLD";
1086 case VKI_SIGCONT: return "SIGCONT";
1087 case VKI_SIGSTOP: return "SIGSTOP";
1088 case VKI_SIGTSTP: return "SIGTSTP";
1089 case VKI_SIGTTIN: return "SIGTTIN";
1090 case VKI_SIGTTOU: return "SIGTTOU";
1091 case VKI_SIGURG: return "SIGURG";
1092 case VKI_SIGXCPU: return "SIGXCPU";
1093 case VKI_SIGXFSZ: return "SIGXFSZ";
1094 case VKI_SIGVTALRM: return "SIGVTALRM";
1095 case VKI_SIGPROF: return "SIGPROF";
1096 case VKI_SIGWINCH: return "SIGWINCH";
1097 case VKI_SIGIO: return "SIGIO";
1098 case VKI_SIGPWR: return "SIGPWR";
1099# if defined(VKI_SIGUNUSED)
1100 case VKI_SIGUNUSED: return "SIGUNUSED";
1101# endif
sewardjde4a1d02002-03-22 01:27:54 +00001102
jsgf855d93d2003-10-13 22:26:55 +00001103 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
sewardjb5f6f512005-03-10 23:59:00 +00001104 VG_(sprintf)(buf, "SIGRT%d", sigNo-VKI_SIGRTMIN);
jsgf855d93d2003-10-13 22:26:55 +00001105 return buf;
sewardjde4a1d02002-03-22 01:27:54 +00001106
jsgf855d93d2003-10-13 22:26:55 +00001107 default:
1108 VG_(sprintf)(buf, "SIG%d", sigNo);
1109 return buf;
1110 }
1111}
sewardjde4a1d02002-03-22 01:27:54 +00001112
jsgf855d93d2003-10-13 22:26:55 +00001113/* Hit ourselves with a signal using the default handler */
1114void VG_(kill_self)(Int sigNo)
1115{
nethercote73b526f2004-10-31 18:48:21 +00001116 vki_sigset_t mask, origmask;
1117 struct vki_sigaction sa, origsa;
sewardj018f7622002-05-15 21:13:39 +00001118
jsgf855d93d2003-10-13 22:26:55 +00001119 sa.ksa_handler = VKI_SIG_DFL;
nethercote73b526f2004-10-31 18:48:21 +00001120 sa.sa_flags = 0;
sewardj489bfec2006-10-17 02:00:29 +00001121# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
nethercote73b526f2004-10-31 18:48:21 +00001122 sa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00001123# endif
nethercote73b526f2004-10-31 18:48:21 +00001124 VG_(sigemptyset)(&sa.sa_mask);
sewardj2e93c502002-04-12 11:12:52 +00001125
nethercote73b526f2004-10-31 18:48:21 +00001126 VG_(sigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +00001127
sewardjb5f6f512005-03-10 23:59:00 +00001128 VG_(sigemptyset)(&mask);
1129 VG_(sigaddset)(&mask, sigNo);
1130 VG_(sigprocmask)(VKI_SIG_UNBLOCK, &mask, &origmask);
jsgf855d93d2003-10-13 22:26:55 +00001131
tomb9b10c72005-07-20 16:05:28 +00001132 VG_(kill)(VG_(getpid)(), sigNo);
jsgf855d93d2003-10-13 22:26:55 +00001133
nethercote73b526f2004-10-31 18:48:21 +00001134 VG_(sigaction)(sigNo, &origsa, NULL);
1135 VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00001136}
1137
1138/*
sewardjb5f6f512005-03-10 23:59:00 +00001139 Perform the default action of a signal. If the signal is fatal, it
1140 marks all threads as needing to exit, but it doesn't actually kill
1141 the process or thread.
jsgf855d93d2003-10-13 22:26:55 +00001142
1143 If we're not being quiet, then print out some more detail about
1144 fatal signals (esp. core dumping signals).
1145 */
njn695c16e2005-03-27 03:40:28 +00001146static void default_action(const vki_siginfo_t *info, ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001147{
1148 Int sigNo = info->si_signo;
sewardjb5f6f512005-03-10 23:59:00 +00001149 Bool terminate = False; /* kills process */
1150 Bool core = False; /* kills process w/ core */
1151 struct vki_rlimit corelim;
1152 Bool could_core;
jsgf855d93d2003-10-13 22:26:55 +00001153
sewardjb5f6f512005-03-10 23:59:00 +00001154 vg_assert(VG_(is_running_thread)(tid));
1155
jsgf855d93d2003-10-13 22:26:55 +00001156 switch(sigNo) {
1157 case VKI_SIGQUIT: /* core */
1158 case VKI_SIGILL: /* core */
1159 case VKI_SIGABRT: /* core */
1160 case VKI_SIGFPE: /* core */
1161 case VKI_SIGSEGV: /* core */
1162 case VKI_SIGBUS: /* core */
1163 case VKI_SIGTRAP: /* core */
1164 case VKI_SIGXCPU: /* core */
1165 case VKI_SIGXFSZ: /* core */
1166 terminate = True;
1167 core = True;
1168 break;
1169
1170 case VKI_SIGHUP: /* term */
1171 case VKI_SIGINT: /* term */
1172 case VKI_SIGKILL: /* term - we won't see this */
1173 case VKI_SIGPIPE: /* term */
1174 case VKI_SIGALRM: /* term */
1175 case VKI_SIGTERM: /* term */
1176 case VKI_SIGUSR1: /* term */
1177 case VKI_SIGUSR2: /* term */
1178 case VKI_SIGIO: /* term */
1179 case VKI_SIGPWR: /* term */
1180 case VKI_SIGSYS: /* term */
1181 case VKI_SIGPROF: /* term */
1182 case VKI_SIGVTALRM: /* term */
1183 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1184 terminate = True;
1185 break;
1186 }
1187
1188 vg_assert(!core || (core && terminate));
1189
fitzhardinge98abfc72003-12-16 02:05:15 +00001190 if (VG_(clo_trace_signals))
sewardjb5f6f512005-03-10 23:59:00 +00001191 VG_(message)(Vg_DebugMsg, "delivering %d (code %d) to default handler; action: %s%s",
1192 sigNo, info->si_code, terminate ? "terminate" : "ignore", core ? "+core" : "");
fitzhardinge98abfc72003-12-16 02:05:15 +00001193
sewardjb5f6f512005-03-10 23:59:00 +00001194 if (!terminate)
1195 return; /* nothing to do */
fitzhardinge4a4d1082004-03-15 23:46:54 +00001196
sewardjb5f6f512005-03-10 23:59:00 +00001197 could_core = core;
1198
1199 if (core) {
1200 /* If they set the core-size limit to zero, don't generate a
1201 core file */
fitzhardinge61a53412004-03-15 23:44:11 +00001202
sewardjb5f6f512005-03-10 23:59:00 +00001203 VG_(getrlimit)(VKI_RLIMIT_CORE, &corelim);
fitzhardinge61a53412004-03-15 23:44:11 +00001204
sewardjb5f6f512005-03-10 23:59:00 +00001205 if (corelim.rlim_cur == 0)
1206 core = False;
1207 }
fitzhardinge61a53412004-03-15 23:44:11 +00001208
sewardjec6e27c2007-11-17 21:31:48 +00001209 if ( (VG_(clo_verbosity) > 1 || (could_core && info->si_code > VKI_SI_USER))
1210 && !VG_(clo_xml) ) {
sewardjb5f6f512005-03-10 23:59:00 +00001211 VG_(message)(Vg_UserMsg, "");
sewardj45f4e7c2005-09-27 19:20:21 +00001212 VG_(message)(Vg_UserMsg,
1213 "Process terminating with default action of signal %d (%s)%s",
sewardjb5f6f512005-03-10 23:59:00 +00001214 sigNo, signame(sigNo), core ? ": dumping core" : "");
jsgf855d93d2003-10-13 22:26:55 +00001215
sewardjb5f6f512005-03-10 23:59:00 +00001216 /* Be helpful - decode some more details about this fault */
1217 if (info->si_code > VKI_SI_USER) {
1218 const Char *event = NULL;
1219 Bool haveaddr = True;
jsgf855d93d2003-10-13 22:26:55 +00001220
sewardjb5f6f512005-03-10 23:59:00 +00001221 switch(sigNo) {
1222 case VKI_SIGSEGV:
1223 switch(info->si_code) {
tom148250b2005-11-12 00:13:20 +00001224 case VKI_SEGV_MAPERR: event = "Access not within mapped region"; break;
1225 case VKI_SEGV_ACCERR: event = "Bad permissions for mapped region"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001226 case 128:
1227 /* General Protection Fault: The CPU/kernel
1228 isn't telling us anything useful, but this
1229 is commonly the result of exceeding a
sewardj74b4cca2005-10-20 01:37:15 +00001230 segment limit. */
1231 event = "General Protection Fault";
sewardjb5f6f512005-03-10 23:59:00 +00001232 haveaddr = False;
jsgf855d93d2003-10-13 22:26:55 +00001233 break;
1234 }
sewardj45f4e7c2005-09-27 19:20:21 +00001235#if 0
1236 {
1237 HChar buf[110];
1238 VG_(am_show_nsegments)(0,"post segfault");
1239 VG_(sprintf)(buf, "/bin/cat /proc/%d/maps", VG_(getpid)());
1240 VG_(system)(buf);
1241 }
1242#endif
sewardjb5f6f512005-03-10 23:59:00 +00001243 break;
jsgf855d93d2003-10-13 22:26:55 +00001244
sewardjb5f6f512005-03-10 23:59:00 +00001245 case VKI_SIGILL:
1246 switch(info->si_code) {
tom148250b2005-11-12 00:13:20 +00001247 case VKI_ILL_ILLOPC: event = "Illegal opcode"; break;
1248 case VKI_ILL_ILLOPN: event = "Illegal operand"; break;
1249 case VKI_ILL_ILLADR: event = "Illegal addressing mode"; break;
1250 case VKI_ILL_ILLTRP: event = "Illegal trap"; break;
1251 case VKI_ILL_PRVOPC: event = "Privileged opcode"; break;
1252 case VKI_ILL_PRVREG: event = "Privileged register"; break;
1253 case VKI_ILL_COPROC: event = "Coprocessor error"; break;
1254 case VKI_ILL_BADSTK: event = "Internal stack error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001255 }
1256 break;
1257
1258 case VKI_SIGFPE:
1259 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001260 case VKI_FPE_INTDIV: event = "Integer divide by zero"; break;
1261 case VKI_FPE_INTOVF: event = "Integer overflow"; break;
1262 case VKI_FPE_FLTDIV: event = "FP divide by zero"; break;
1263 case VKI_FPE_FLTOVF: event = "FP overflow"; break;
1264 case VKI_FPE_FLTUND: event = "FP underflow"; break;
1265 case VKI_FPE_FLTRES: event = "FP inexact"; break;
1266 case VKI_FPE_FLTINV: event = "FP invalid operation"; break;
1267 case VKI_FPE_FLTSUB: event = "FP subscript out of range"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001268 }
1269 break;
1270
1271 case VKI_SIGBUS:
1272 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001273 case VKI_BUS_ADRALN: event = "Invalid address alignment"; break;
1274 case VKI_BUS_ADRERR: event = "Non-existent physical address"; break;
1275 case VKI_BUS_OBJERR: event = "Hardware error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001276 }
1277 break;
sewardj3059d272007-12-21 01:24:59 +00001278 } /* switch (sigNo) */
sewardjb5f6f512005-03-10 23:59:00 +00001279
1280 if (event != NULL) {
1281 if (haveaddr)
nethercote3b390c72003-11-13 17:53:43 +00001282 VG_(message)(Vg_UserMsg, " %s at address %p",
sewardj489bfec2006-10-17 02:00:29 +00001283 event, info->VKI_SIGINFO_si_addr);
sewardjb5f6f512005-03-10 23:59:00 +00001284 else
1285 VG_(message)(Vg_UserMsg, " %s", event);
jsgf855d93d2003-10-13 22:26:55 +00001286 }
1287 }
sewardj3059d272007-12-21 01:24:59 +00001288 /* Print a stack trace. Be cautious if the thread's SP is in an
1289 obviously stupid place (not mapped readable) that would
1290 likely cause a segfault. */
1291 if (VG_(is_valid_tid)(tid)) {
1292 ExeContext* ec = VG_(am_is_valid_for_client)
1293 (VG_(get_SP)(tid), sizeof(Addr), VKI_PROT_READ)
1294 ? VG_(record_ExeContext)( tid, 0/*first_ip_delta*/ )
1295 : VG_(record_depth_1_ExeContext)( tid );
1296 vg_assert(ec);
1297 VG_(pp_ExeContext)( ec );
fitzhardinge126c64f2003-12-08 21:58:37 +00001298 }
sewardj95d86c02007-12-18 01:49:23 +00001299 if (sigNo == VKI_SIGSEGV
1300 && info && info->si_code > VKI_SI_USER
1301 && info->si_code == VKI_SEGV_MAPERR) {
1302 VG_(message)(Vg_UserMsg, " If you believe this happened as a "
1303 "result of a stack overflow in your");
1304 VG_(message)(Vg_UserMsg, " program's main thread (unlikely but"
1305 " possible), you can try to increase");
1306 VG_(message)(Vg_UserMsg, " the size of the main thread stack"
1307 " using the --main-stacksize= flag.");
1308 // FIXME: assumes main ThreadId == 1
1309 if (VG_(is_valid_tid)(1)) {
1310 VG_(message)(Vg_UserMsg,
1311 " The main thread stack size used in this run was %d.",
1312 (Int)VG_(threads)[1].client_stack_szB);
1313 }
1314 }
sewardjb5f6f512005-03-10 23:59:00 +00001315 }
1316
1317 if (VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) {
1318 VG_(start_debugger)( tid );
1319 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001320
sewardjb5f6f512005-03-10 23:59:00 +00001321 if (core) {
1322 const static struct vki_rlimit zero = { 0, 0 };
fitzhardinge4a4d1082004-03-15 23:46:54 +00001323
njn67229832005-08-28 04:38:12 +00001324 VG_(make_coredump)(tid, info, corelim.rlim_cur);
fitzhardinged65dcad2004-03-13 02:06:58 +00001325
sewardjb5f6f512005-03-10 23:59:00 +00001326 /* Make sure we don't get a confusing kernel-generated
1327 coredump when we finally exit */
1328 VG_(setrlimit)(VKI_RLIMIT_CORE, &zero);
1329 }
fitzhardinged65dcad2004-03-13 02:06:58 +00001330
sewardjb5f6f512005-03-10 23:59:00 +00001331 /* stash fatal signal in main thread */
sewardj1d887112005-05-30 21:44:08 +00001332 // what's this for?
1333 //VG_(threads)[VG_(master_tid)].os_state.fatalsig = sigNo;
sewardjde4a1d02002-03-22 01:27:54 +00001334
sewardjb5f6f512005-03-10 23:59:00 +00001335 /* everyone dies */
1336 VG_(nuke_all_threads_except)(tid, VgSrc_FatalSig);
1337 VG_(threads)[tid].exitreason = VgSrc_FatalSig;
1338 VG_(threads)[tid].os_state.fatalsig = sigNo;
sewardjb48e5002002-05-13 00:16:03 +00001339}
1340
sewardjb5f6f512005-03-10 23:59:00 +00001341/*
1342 This does the business of delivering a signal to a thread. It may
1343 be called from either a real signal handler, or from normal code to
1344 cause the thread to enter the signal handler.
sewardj5e2f0012004-12-13 14:10:34 +00001345
sewardjb5f6f512005-03-10 23:59:00 +00001346 This updates the thread state, but it does not set it to be
1347 Runnable.
1348*/
tomadacaf92007-12-21 10:24:24 +00001349static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info, const struct vki_ucontext *uc )
sewardjde4a1d02002-03-22 01:27:54 +00001350{
jsgf855d93d2003-10-13 22:26:55 +00001351 Int sigNo = info->si_signo;
njn695c16e2005-03-27 03:40:28 +00001352 SCSS_Per_Signal *handler = &scss.scss_per_sig[sigNo];
fitzhardinge98abfc72003-12-16 02:05:15 +00001353 void *handler_fn;
jsgf855d93d2003-10-13 22:26:55 +00001354 ThreadState *tst = VG_(get_ThreadState)(tid);
1355
1356 if (VG_(clo_trace_signals))
sewardjb5f6f512005-03-10 23:59:00 +00001357 VG_(message)(Vg_DebugMsg,"delivering signal %d (%s):%d to thread %d",
1358 sigNo, signame(sigNo), info->si_code, tid );
jsgf855d93d2003-10-13 22:26:55 +00001359
njn351d0062005-06-21 22:23:59 +00001360 if (sigNo == VG_SIGVGKILL) {
sewardjb5f6f512005-03-10 23:59:00 +00001361 /* If this is a SIGVGKILL, we're expecting it to interrupt any
1362 blocked syscall. It doesn't matter whether the VCPU state is
1363 set to restart or not, because we don't expect it will
1364 execute any more client instructions. */
1365 vg_assert(VG_(is_exiting)(tid));
jsgf855d93d2003-10-13 22:26:55 +00001366 return;
1367 }
1368
sewardjb5f6f512005-03-10 23:59:00 +00001369 /* If the client specifies SIG_IGN, treat it as SIG_DFL.
jsgf855d93d2003-10-13 22:26:55 +00001370
njn9ec0f3e2005-03-13 06:00:47 +00001371 If deliver_signal() is being called on a thread, we want
sewardjb5f6f512005-03-10 23:59:00 +00001372 the signal to get through no matter what; if they're ignoring
1373 it, then we do this override (this is so we can send it SIGSEGV,
1374 etc). */
fitzhardinge98abfc72003-12-16 02:05:15 +00001375 handler_fn = handler->scss_handler;
sewardjb5f6f512005-03-10 23:59:00 +00001376 if (handler_fn == VKI_SIG_IGN)
fitzhardinge98abfc72003-12-16 02:05:15 +00001377 handler_fn = VKI_SIG_DFL;
1378
1379 vg_assert(handler_fn != VKI_SIG_IGN);
jsgf855d93d2003-10-13 22:26:55 +00001380
fitzhardinge98abfc72003-12-16 02:05:15 +00001381 if (handler_fn == VKI_SIG_DFL) {
njn695c16e2005-03-27 03:40:28 +00001382 default_action(info, tid);
jsgf855d93d2003-10-13 22:26:55 +00001383 } else {
1384 /* Create a signal delivery frame, and set the client's %ESP and
1385 %EIP so that when execution continues, we will enter the
1386 signal handler with the frame on top of the client's stack,
sewardjb5f6f512005-03-10 23:59:00 +00001387 as it expects.
1388
1389 Signal delivery can fail if the client stack is too small or
1390 missing, and we can't push the frame. If that happens,
1391 push_signal_frame will cause the whole process to exit when
1392 we next hit the scheduler.
1393 */
jsgf855d93d2003-10-13 22:26:55 +00001394 vg_assert(VG_(is_valid_tid)(tid));
sewardjb5f6f512005-03-10 23:59:00 +00001395
tomadacaf92007-12-21 10:24:24 +00001396 push_signal_frame ( tid, info, uc );
jsgf855d93d2003-10-13 22:26:55 +00001397
1398 if (handler->scss_flags & VKI_SA_ONESHOT) {
1399 /* Do the ONESHOT thing. */
1400 handler->scss_handler = VKI_SIG_DFL;
1401
nethercote9dd11512004-08-04 15:31:30 +00001402 handle_SCSS_change( False /* lazy update */ );
jsgf855d93d2003-10-13 22:26:55 +00001403 }
sewardjb5f6f512005-03-10 23:59:00 +00001404
1405 /* At this point:
1406 tst->sig_mask is the current signal mask
1407 tst->tmp_sig_mask is the same as sig_mask, unless we're in sigsuspend
1408 handler->scss_mask is the mask set by the handler
1409
1410 Handler gets a mask of tmp_sig_mask|handler_mask|signo
1411 */
1412 tst->sig_mask = tst->tmp_sig_mask;
1413 if (!(handler->scss_flags & VKI_SA_NOMASK)) {
1414 VG_(sigaddset_from_set)(&tst->sig_mask, &handler->scss_mask);
1415 VG_(sigaddset)(&tst->sig_mask, sigNo);
1416
1417 tst->tmp_sig_mask = tst->sig_mask;
1418 }
1419 }
1420
1421 /* Thread state is ready to go - just add Runnable */
1422}
1423
njn06244e72005-06-21 22:27:19 +00001424static void resume_scheduler(ThreadId tid)
1425{
1426 ThreadState *tst = VG_(get_ThreadState)(tid);
1427
1428 vg_assert(tst->os_state.lwpid == VG_(gettid)());
1429
1430 if (tst->sched_jmpbuf_valid) {
1431 /* Can't continue; must longjmp back to the scheduler and thus
1432 enter the sighandler immediately. */
sewardj45f4e7c2005-09-27 19:20:21 +00001433 __builtin_longjmp(tst->sched_jmpbuf, True);
njn06244e72005-06-21 22:27:19 +00001434 }
1435}
1436
njn9ec0f3e2005-03-13 06:00:47 +00001437static void synth_fault_common(ThreadId tid, Addr addr, Int si_code)
1438{
1439 vki_siginfo_t info;
1440
1441 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1442
1443 info.si_signo = VKI_SIGSEGV;
1444 info.si_code = si_code;
sewardj489bfec2006-10-17 02:00:29 +00001445 info.VKI_SIGINFO_si_addr = (void*)addr;
njn9ec0f3e2005-03-13 06:00:47 +00001446
1447 /* If they're trying to block the signal, force it to be delivered */
1448 if (VG_(sigismember)(&VG_(threads)[tid].sig_mask, VKI_SIGSEGV))
1449 VG_(set_default_handler)(VKI_SIGSEGV);
1450
tomadacaf92007-12-21 10:24:24 +00001451 deliver_signal(tid, &info, NULL);
njn9ec0f3e2005-03-13 06:00:47 +00001452}
1453
1454// Synthesize a fault where the address is OK, but the page
1455// permissions are bad.
1456void VG_(synth_fault_perms)(ThreadId tid, Addr addr)
1457{
1458 synth_fault_common(tid, addr, 2);
1459}
1460
1461// Synthesize a fault where the address there's nothing mapped at the address.
1462void VG_(synth_fault_mapping)(ThreadId tid, Addr addr)
1463{
1464 synth_fault_common(tid, addr, 1);
1465}
1466
1467// Synthesize a misc memory fault.
1468void VG_(synth_fault)(ThreadId tid)
1469{
1470 synth_fault_common(tid, 0, 0x80);
1471}
1472
1473// Synthesise a SIGILL.
1474void VG_(synth_sigill)(ThreadId tid, Addr addr)
1475{
1476 vki_siginfo_t info;
1477
1478 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1479
1480 info.si_signo = VKI_SIGILL;
sewardj489bfec2006-10-17 02:00:29 +00001481 info.si_code = VKI_ILL_ILLOPC; /* jrs: no idea what this should be */
1482 info.VKI_SIGINFO_si_addr = (void*)addr;
njn9ec0f3e2005-03-13 06:00:47 +00001483
njn06244e72005-06-21 22:27:19 +00001484 resume_scheduler(tid);
tomadacaf92007-12-21 10:24:24 +00001485 deliver_signal(tid, &info, NULL);
njn9ec0f3e2005-03-13 06:00:47 +00001486}
1487
sewardj86df1552006-02-07 20:56:41 +00001488// Synthesise a SIGTRAP.
1489void VG_(synth_sigtrap)(ThreadId tid)
1490{
1491 vki_siginfo_t info;
tomadacaf92007-12-21 10:24:24 +00001492 struct vki_ucontext uc;
sewardj86df1552006-02-07 20:56:41 +00001493
1494 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1495
1496 info.si_signo = VKI_SIGTRAP;
tomadacaf92007-12-21 10:24:24 +00001497 info.si_code = VKI_TRAP_BRKPT; /* tjh: only ever called for a brkpt ins */
1498#if defined(VGA_x86) || defined(VGA_amd64)
1499 uc.uc_mcontext.trapno = 3; /* tjh: this is the x86 trap number
1500 for a breakpoint trap... */
1501#endif
sewardj86df1552006-02-07 20:56:41 +00001502
1503 resume_scheduler(tid);
tomadacaf92007-12-21 10:24:24 +00001504 deliver_signal(tid, &info, &uc);
sewardj86df1552006-02-07 20:56:41 +00001505}
1506
sewardjb5f6f512005-03-10 23:59:00 +00001507/* Make a signal pending for a thread, for later delivery.
1508 VG_(poll_signals) will arrange for it to be delivered at the right
1509 time.
1510
1511 tid==0 means add it to the process-wide queue, and not sent it to a
1512 specific thread.
1513*/
sewardj2c5ffbe2005-03-12 13:32:06 +00001514static
sewardjb5f6f512005-03-10 23:59:00 +00001515void queue_signal(ThreadId tid, const vki_siginfo_t *si)
1516{
1517 ThreadState *tst;
1518 SigQueue *sq;
1519 vki_sigset_t savedmask;
1520
1521 tst = VG_(get_ThreadState)(tid);
1522
1523 /* Protect the signal queue against async deliveries */
njn444eba12005-05-12 03:47:31 +00001524 block_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001525
1526 if (tst->sig_queue == NULL) {
1527 tst->sig_queue = VG_(arena_malloc)(VG_AR_CORE, sizeof(*tst->sig_queue));
1528 VG_(memset)(tst->sig_queue, 0, sizeof(*tst->sig_queue));
1529 }
1530 sq = tst->sig_queue;
1531
1532 if (VG_(clo_trace_signals))
1533 VG_(message)(Vg_DebugMsg, "Queueing signal %d (idx %d) to thread %d",
1534 si->si_signo, sq->next, tid);
1535
1536 /* Add signal to the queue. If the queue gets overrun, then old
1537 queued signals may get lost.
1538
1539 XXX We should also keep a sigset of pending signals, so that at
1540 least a non-siginfo signal gets deliviered.
1541 */
1542 if (sq->sigs[sq->next].si_signo != 0)
1543 VG_(message)(Vg_UserMsg, "Signal %d being dropped from thread %d's queue",
1544 sq->sigs[sq->next].si_signo, tid);
1545
1546 sq->sigs[sq->next] = *si;
1547 sq->next = (sq->next+1) % N_QUEUED_SIGNALS;
1548
njn444eba12005-05-12 03:47:31 +00001549 restore_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001550}
1551
1552/*
1553 Returns the next queued signal for thread tid which is in "set".
1554 tid==0 means process-wide signal. Set si_signo to 0 when the
1555 signal has been delivered.
1556
1557 Must be called with all signals blocked, to protect against async
1558 deliveries.
1559*/
1560static vki_siginfo_t *next_queued(ThreadId tid, const vki_sigset_t *set)
1561{
1562 ThreadState *tst = VG_(get_ThreadState)(tid);
1563 SigQueue *sq;
1564 Int idx;
1565 vki_siginfo_t *ret = NULL;
1566
1567 sq = tst->sig_queue;
1568 if (sq == NULL)
1569 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001570
sewardjb5f6f512005-03-10 23:59:00 +00001571 idx = sq->next;
1572 do {
1573 if (0)
1574 VG_(printf)("idx=%d si_signo=%d inset=%d\n", idx,
1575 sq->sigs[idx].si_signo, VG_(sigismember)(set, sq->sigs[idx].si_signo));
jsgf855d93d2003-10-13 22:26:55 +00001576
sewardjb5f6f512005-03-10 23:59:00 +00001577 if (sq->sigs[idx].si_signo != 0 && VG_(sigismember)(set, sq->sigs[idx].si_signo)) {
1578 if (VG_(clo_trace_signals))
1579 VG_(message)(Vg_DebugMsg, "Returning queued signal %d (idx %d) for thread %d",
1580 sq->sigs[idx].si_signo, idx, tid);
1581 ret = &sq->sigs[idx];
1582 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001583 }
1584
sewardjb5f6f512005-03-10 23:59:00 +00001585 idx = (idx + 1) % N_QUEUED_SIGNALS;
1586 } while(idx != sq->next);
1587 out:
sewardj489bfec2006-10-17 02:00:29 +00001588 return ret;
jsgf855d93d2003-10-13 22:26:55 +00001589}
1590
1591/*
sewardjb5f6f512005-03-10 23:59:00 +00001592 Receive an async signal from the kernel.
jsgf855d93d2003-10-13 22:26:55 +00001593
sewardjb5f6f512005-03-10 23:59:00 +00001594 This should only happen when the thread is blocked in a syscall,
1595 since that's the only time this set of signals is unblocked.
jsgf855d93d2003-10-13 22:26:55 +00001596*/
1597static
njn695c16e2005-03-27 03:40:28 +00001598void async_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00001599{
sewardj42781722006-12-17 19:36:06 +00001600 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
sewardjb5f6f512005-03-10 23:59:00 +00001601 ThreadState *tst = VG_(get_ThreadState)(tid);
jsgf855d93d2003-10-13 22:26:55 +00001602
tom9f4a7bf2005-11-13 00:01:20 +00001603#ifdef VGO_linux
1604 /* The linux kernel uses the top 16 bits of si_code for it's own
1605 use and only exports the bottom 16 bits to user space - at least
1606 that is the theory, but it turns out that there are some kernels
tomc8cb9d02005-11-14 14:37:02 +00001607 around that forget to mask out the top 16 bits so we do it here.
1608
1609 The kernel treats the bottom 16 bits as signed and (when it does
1610 mask them off) sign extends them when exporting to user space so
1611 we do the same thing here. */
tom95458c62005-11-13 11:52:39 +00001612 info->si_code = (Short)info->si_code;
tom9f4a7bf2005-11-13 00:01:20 +00001613#endif
1614
sewardjb5f6f512005-03-10 23:59:00 +00001615 if (VG_(clo_trace_signals))
1616 VG_(message)(Vg_DebugMsg, "Async handler got signal %d for tid %d info %d",
1617 sigNo, tid, info->si_code);
1618
sewardj489bfec2006-10-17 02:00:29 +00001619 vg_assert(tst->status == VgTs_WaitSys);
1620
1621 /* The thread isn't currently running, make it so before going on */
sewardjad0a3a82006-12-17 18:58:55 +00001622 VG_(acquire_BigLock)(tid, "async_signalhandler");
sewardj489bfec2006-10-17 02:00:29 +00001623
sewardjb5f6f512005-03-10 23:59:00 +00001624 /* Update thread state properly */
sewardja8d8e232005-06-07 20:04:56 +00001625 VG_(fixup_guest_state_after_syscall_interrupted)(
1626 tid,
njnaf839f52005-06-23 03:27:57 +00001627 VG_UCONTEXT_INSTR_PTR(uc),
1628 VG_UCONTEXT_SYSCALL_NUM(uc),
1629 VG_UCONTEXT_SYSCALL_SYSRES(uc),
sewardja8d8e232005-06-07 20:04:56 +00001630 !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
1631 );
sewardjb5f6f512005-03-10 23:59:00 +00001632
1633 /* Set up the thread's state to deliver a signal */
njn07ef6c02005-05-18 19:43:09 +00001634 if (!is_sig_ign(info->si_signo))
tomadacaf92007-12-21 10:24:24 +00001635 deliver_signal(tid, info, uc);
sewardjb5f6f512005-03-10 23:59:00 +00001636
1637 /* longjmp back to the thread's main loop to start executing the
1638 handler. */
njn06244e72005-06-21 22:27:19 +00001639 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001640
njn695c16e2005-03-27 03:40:28 +00001641 VG_(core_panic)("async_signalhandler: got unexpected signal while outside of scheduler");
jsgf855d93d2003-10-13 22:26:55 +00001642}
1643
sewardjb5f6f512005-03-10 23:59:00 +00001644/* Extend the stack to cover addr. maxsize is the limit the stack can grow to.
1645
1646 Returns True on success, False on failure.
1647
1648 Succeeds without doing anything if addr is already within a segment.
1649
1650 Failure could be caused by:
1651 - addr not below a growable segment
1652 - new stack size would exceed maxsize
1653 - mmap failed for some other reason
1654 */
1655Bool VG_(extend_stack)(Addr addr, UInt maxsize)
1656{
sewardj45f4e7c2005-09-27 19:20:21 +00001657 SizeT udelta;
sewardjb5f6f512005-03-10 23:59:00 +00001658
1659 /* Find the next Segment above addr */
sewardj489bfec2006-10-17 02:00:29 +00001660 NSegment const* seg
1661 = VG_(am_find_nsegment)(addr);
1662 NSegment const* seg_next
1663 = seg ? VG_(am_next_nsegment)( (NSegment*)seg, True/*fwds*/ )
1664 : NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00001665
1666 if (seg && seg->kind == SkAnonC)
1667 /* addr is already mapped. Nothing to do. */
sewardjb5f6f512005-03-10 23:59:00 +00001668 return True;
1669
sewardj45f4e7c2005-09-27 19:20:21 +00001670 /* Check that the requested new base is in a shrink-down
1671 reservation section which abuts an anonymous mapping that
1672 belongs to the client. */
1673 if ( ! (seg
1674 && seg->kind == SkResvn
1675 && seg->smode == SmUpper
1676 && seg_next
1677 && seg_next->kind == SkAnonC
1678 && seg->end+1 == seg_next->start))
sewardjb5f6f512005-03-10 23:59:00 +00001679 return False;
1680
sewardj45f4e7c2005-09-27 19:20:21 +00001681 udelta = VG_PGROUNDUP(seg_next->start - addr);
1682 VG_(debugLog)(1, "signals",
1683 "extending a stack base 0x%llx down by %lld\n",
1684 (ULong)seg_next->start, (ULong)udelta);
1685 if (! VG_(am_extend_into_adjacent_reservation_client)
sewardj489bfec2006-10-17 02:00:29 +00001686 ( (NSegment*)seg_next, -(SSizeT)udelta )) {
sewardj45f4e7c2005-09-27 19:20:21 +00001687 VG_(debugLog)(1, "signals", "extending a stack base: FAILED\n");
sewardjb5f6f512005-03-10 23:59:00 +00001688 return False;
sewardj45f4e7c2005-09-27 19:20:21 +00001689 }
sewardjb5f6f512005-03-10 23:59:00 +00001690
rjwalsh0140af52005-06-04 20:42:33 +00001691 /* When we change the main stack, we have to let the stack handling
1692 code know about it. */
sewardj45f4e7c2005-09-27 19:20:21 +00001693 VG_(change_stack)(VG_(clstk_id), addr, VG_(clstk_end));
sewardjb5f6f512005-03-10 23:59:00 +00001694
1695 if (VG_(clo_sanity_level) > 2)
1696 VG_(sanity_check_general)(False);
1697
1698 return True;
1699}
1700
sewardj489bfec2006-10-17 02:00:29 +00001701static void (*fault_catcher)(Int sig, Addr addr) = NULL;
sewardjb5f6f512005-03-10 23:59:00 +00001702
1703void VG_(set_fault_catcher)(void (*catcher)(Int, Addr))
1704{
sewardj489bfec2006-10-17 02:00:29 +00001705 if (0)
1706 VG_(debugLog)(0, "signals", "set fault catcher to %p\n", catcher);
njn50ae1a72005-04-08 23:28:23 +00001707 vg_assert2(NULL == catcher || NULL == fault_catcher,
1708 "Fault catcher is already registered");
sewardjb5f6f512005-03-10 23:59:00 +00001709
1710 fault_catcher = catcher;
1711}
1712
1713
jsgf855d93d2003-10-13 22:26:55 +00001714/*
sewardj2a99cf62004-11-24 10:44:19 +00001715 Receive a sync signal from the host.
jsgf855d93d2003-10-13 22:26:55 +00001716*/
1717static
njn695c16e2005-03-27 03:40:28 +00001718void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00001719{
sewardj42781722006-12-17 19:36:06 +00001720 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
jsgf855d93d2003-10-13 22:26:55 +00001721
1722 vg_assert(info != NULL);
1723 vg_assert(info->si_signo == sigNo);
1724 vg_assert(sigNo == VKI_SIGSEGV ||
1725 sigNo == VKI_SIGBUS ||
1726 sigNo == VKI_SIGFPE ||
sewardjb5f6f512005-03-10 23:59:00 +00001727 sigNo == VKI_SIGILL ||
1728 sigNo == VKI_SIGTRAP);
jsgf855d93d2003-10-13 22:26:55 +00001729
tom9f4a7bf2005-11-13 00:01:20 +00001730#ifdef VGO_linux
1731 /* The linux kernel uses the top 16 bits of si_code for it's own
1732 use and only exports the bottom 16 bits to user space - at least
1733 that is the theory, but it turns out that there are some kernels
tomc8cb9d02005-11-14 14:37:02 +00001734 around that forget to mask out the top 16 bits so we do it here.
1735
1736 The kernel treats the bottom 16 bits as signed and (when it does
1737 mask them off) sign extends them when exporting to user space so
1738 we do the same thing here. */
tom95458c62005-11-13 11:52:39 +00001739 info->si_code = (Short)info->si_code;
tom9f4a7bf2005-11-13 00:01:20 +00001740#endif
1741
sewardjb5f6f512005-03-10 23:59:00 +00001742 if (info->si_code <= VKI_SI_USER) {
1743 /* If some user-process sent us one of these signals (ie,
1744 they're not the result of a faulting instruction), then treat
1745 it as an async signal. This is tricky because we could get
1746 this almost anywhere:
1747 - while generated client code
1748 Action: queue signal and return
1749 - while running Valgrind code
1750 Action: queue signal and return
1751 - while blocked in a syscall
1752 Action: make thread runnable, queue signal, resume scheduler
1753 */
1754 if (VG_(threads)[tid].status == VgTs_WaitSys) {
1755 /* Since this signal interrupted a syscall, it means the
1756 client's signal mask was applied, so we can't get here
1757 unless the client wants this signal right now. This means
1758 we can simply use the async_signalhandler. */
njn695c16e2005-03-27 03:40:28 +00001759 async_signalhandler(sigNo, info, uc);
1760 VG_(core_panic)("async_signalhandler returned!?\n");
sewardjb5f6f512005-03-10 23:59:00 +00001761 }
jsgf855d93d2003-10-13 22:26:55 +00001762
sewardj489bfec2006-10-17 02:00:29 +00001763 if (info->VKI_SIGINFO_si_pid == 0) {
sewardjb5f6f512005-03-10 23:59:00 +00001764 /* There's a per-user limit of pending siginfo signals. If
1765 you exceed this, by having more than that number of
1766 pending signals with siginfo, then new signals are
1767 delivered without siginfo. This condition can be caused
1768 by any unrelated program you're running at the same time
1769 as Valgrind, if it has a large number of pending siginfo
1770 signals which it isn't taking delivery of.
1771
1772 Since we depend on siginfo to work out why we were sent a
1773 signal and what we should do about it, we really can't
1774 continue unless we get it. */
1775 VG_(message)(Vg_UserMsg, "Signal %d (%s) appears to have lost its siginfo; I can't go on.",
1776 sigNo, signame(sigNo));
1777 VG_(message)(Vg_UserMsg, " This may be because one of your programs has consumed your");
1778 VG_(message)(Vg_UserMsg, " ration of siginfo structures.");
njn504b72b2005-08-16 01:39:34 +00001779 VG_(printf)(
1780" For more information, see:\n"
1781" http://kerneltrap.org/mailarchive/1/message/25599/thread\n"
1782" Basically, some program on your system is building up a large queue of\n"
1783" pending signals, and this causes the siginfo data for other signals to\n"
1784" be dropped because it's exceeding a system limit. However, Valgrind\n"
1785" absolutely needs siginfo for SIGSEGV. A workaround is to track down the\n"
1786" offending program and avoid running it while using Valgrind, but there\n"
1787" is no easy way to do this. Apparently the problem was fixed in kernel\n"
1788" 2.6.12.\n");
sewardjb5f6f512005-03-10 23:59:00 +00001789
1790 /* It's a fatal signal, so we force the default handler. */
1791 VG_(set_default_handler)(sigNo);
tomadacaf92007-12-21 10:24:24 +00001792 deliver_signal(tid, info, uc);
njn06244e72005-06-21 22:27:19 +00001793 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001794 VG_(exit)(99); /* If we can't resume, then just exit */
1795 }
1796
1797 if (VG_(clo_trace_signals))
1798 VG_(message)(Vg_DebugMsg, "Routing user-sent sync signal %d via queue",
1799 sigNo);
1800
1801 /* Since every thread has these signals unblocked, we can't rely
1802 on the kernel to route them properly, so we need to queue
1803 them manually. */
1804 if (info->si_code == VKI_SI_TKILL)
1805 queue_signal(tid, info); /* directed to us specifically */
1806 else
1807 queue_signal(0, info); /* shared pending */
1808
jsgf855d93d2003-10-13 22:26:55 +00001809 return;
sewardjb5f6f512005-03-10 23:59:00 +00001810 }
1811
1812 if (VG_(clo_trace_signals)) {
sewardj45f4e7c2005-09-27 19:20:21 +00001813 VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d, "
1814 "EIP=%p, eip=%p",
njnf536bbb2005-06-13 04:21:38 +00001815 sigNo, info->si_code, VG_(get_IP)(tid),
njnaf839f52005-06-23 03:27:57 +00001816 VG_UCONTEXT_INSTR_PTR(uc) );
jsgf855d93d2003-10-13 22:26:55 +00001817 }
sewardjb5f6f512005-03-10 23:59:00 +00001818 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardjde4a1d02002-03-22 01:27:54 +00001819
sewardj489bfec2006-10-17 02:00:29 +00001820 /* Check to see if someone is interested in faults. The fault
1821 catcher should never be set whilst we're in generated code, so
1822 check for that. AFAIK the only use of the catcher right now is
1823 memcheck's leak detector.
1824 */
1825 if (fault_catcher) {
1826 vg_assert(VG_(in_generated_code) == False);
1827
1828 (*fault_catcher)(sigNo, (Addr)info->VKI_SIGINFO_si_addr);
1829 /* If the catcher returns, then it didn't handle the fault,
1830 so carry on panicing. */
1831 }
1832
fitzhardinge98abfc72003-12-16 02:05:15 +00001833 /* Special fault-handling case. We can now get signals which can
1834 act upon and immediately restart the faulting instruction.
1835 */
1836 if (info->si_signo == VKI_SIGSEGV) {
sewardj489bfec2006-10-17 02:00:29 +00001837 Addr fault = (Addr)info->VKI_SIGINFO_si_addr;
njnf536bbb2005-06-13 04:21:38 +00001838 Addr esp = VG_(get_SP)(tid);
sewardj489bfec2006-10-17 02:00:29 +00001839 NSegment const* seg
1840 = VG_(am_find_nsegment)(fault);
1841 NSegment const* seg_next
1842 = seg ? VG_(am_next_nsegment)( (NSegment*)seg, True/*fwds*/ )
1843 : NULL;
sewardj548be6d2005-02-16 01:31:37 +00001844
fitzhardinge98abfc72003-12-16 02:05:15 +00001845 if (VG_(clo_trace_signals)) {
1846 if (seg == NULL)
1847 VG_(message)(Vg_DebugMsg,
sewardj45f4e7c2005-09-27 19:20:21 +00001848 "SIGSEGV: si_code=%d faultaddr=%p tid=%d ESP=%p "
1849 "seg=NULL",
1850 info->si_code, fault, tid, esp);
fitzhardinge98abfc72003-12-16 02:05:15 +00001851 else
1852 VG_(message)(Vg_DebugMsg,
sewardj45f4e7c2005-09-27 19:20:21 +00001853 "SIGSEGV: si_code=%d faultaddr=%p tid=%d ESP=%p "
1854 "seg=%p-%p",
1855 info->si_code, fault, tid, esp, seg->start, seg->end);
fitzhardinge98abfc72003-12-16 02:05:15 +00001856 }
tom148250b2005-11-12 00:13:20 +00001857 if (info->si_code == VKI_SEGV_MAPERR
sewardj45f4e7c2005-09-27 19:20:21 +00001858 && seg
1859 && seg->kind == SkResvn
1860 && seg->smode == SmUpper
1861 && seg_next
1862 && seg_next->kind == SkAnonC
1863 && seg->end+1 == seg_next->start
1864 && fault >= (esp - VG_STACK_REDZONE_SZB)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001865 /* If the fault address is above esp but below the current known
1866 stack segment base, and it was a fault because there was
1867 nothing mapped there (as opposed to a permissions fault),
1868 then extend the stack segment.
1869 */
njnaf839f52005-06-23 03:27:57 +00001870 Addr base = VG_PGROUNDDN(esp - VG_STACK_REDZONE_SZB);
njn50ba34e2005-04-04 02:41:42 +00001871 if (VG_(extend_stack)(base, VG_(threads)[tid].client_stack_szB)) {
sewardjb5f6f512005-03-10 23:59:00 +00001872 if (VG_(clo_trace_signals))
1873 VG_(message)(Vg_DebugMsg,
sewardj45f4e7c2005-09-27 19:20:21 +00001874 " -> extended stack base to %p",
1875 VG_PGROUNDDN(fault));
sewardj0ec07f32006-01-12 12:32:32 +00001876 return; // extension succeeded, restart host (hence guest)
1877 // instruction
sewardjb5f6f512005-03-10 23:59:00 +00001878 } else
sewardj45f4e7c2005-09-27 19:20:21 +00001879 VG_(message)(Vg_UserMsg,
1880 "Stack overflow in thread %d: can't grow stack to %p",
sewardjb5f6f512005-03-10 23:59:00 +00001881 tid, fault);
fitzhardinge98abfc72003-12-16 02:05:15 +00001882 }
njnb69f7c12005-06-24 22:17:38 +00001883 /* Fall into normal signal handling for all other cases */
fitzhardinge98abfc72003-12-16 02:05:15 +00001884 }
1885
sewardjb5f6f512005-03-10 23:59:00 +00001886 /* OK, this is a signal we really have to deal with. If it came
1887 from the client's code, then we can jump back into the scheduler
1888 and have it delivered. Otherwise it's a Valgrind bug. */
1889 {
sewardj42781722006-12-17 19:36:06 +00001890 ThreadState *tst
1891 = VG_(get_ThreadState)(VG_(lwpid_to_vgtid)(VG_(gettid)()));
jsgf855d93d2003-10-13 22:26:55 +00001892
sewardjb5f6f512005-03-10 23:59:00 +00001893 if (VG_(sigismember)(&tst->sig_mask, sigNo)) {
1894 /* signal is blocked, but they're not allowed to block faults */
1895 VG_(set_default_handler)(sigNo);
1896 }
1897
sewardj0ec07f32006-01-12 12:32:32 +00001898 if (VG_(in_generated_code)) {
sewardjb5f6f512005-03-10 23:59:00 +00001899 /* Can't continue; must longjmp back to the scheduler and thus
1900 enter the sighandler immediately. */
tomadacaf92007-12-21 10:24:24 +00001901 deliver_signal(tid, info, uc);
njn06244e72005-06-21 22:27:19 +00001902 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001903 }
1904
sewardjb5f6f512005-03-10 23:59:00 +00001905 /* If resume_scheduler returns or its our fault, it means we
1906 don't have longjmp set up, implying that we weren't running
1907 client code, and therefore it was actually generated by
1908 Valgrind internally.
1909 */
jsgf855d93d2003-10-13 22:26:55 +00001910 VG_(message)(Vg_DebugMsg,
njn038ee9e2005-12-12 15:54:50 +00001911 "VALGRIND INTERNAL ERROR: Valgrind received a signal %d (%s) - exiting",
jsgf855d93d2003-10-13 22:26:55 +00001912 sigNo, signame(sigNo));
fitzhardinge98abfc72003-12-16 02:05:15 +00001913
jsgf855d93d2003-10-13 22:26:55 +00001914 VG_(message)(Vg_DebugMsg,
njnd0073f42005-05-14 17:00:25 +00001915 "si_code=%x; Faulting address: %p; sp: %p",
sewardj489bfec2006-10-17 02:00:29 +00001916 info->si_code, info->VKI_SIGINFO_si_addr,
njnaf839f52005-06-23 03:27:57 +00001917 VG_UCONTEXT_STACK_PTR(uc));
jsgf855d93d2003-10-13 22:26:55 +00001918
1919 if (0)
1920 VG_(kill_self)(sigNo); /* generate a core dump */
sewardjb5f6f512005-03-10 23:59:00 +00001921
sewardj1d887112005-05-30 21:44:08 +00001922 //if (tid == 0) /* could happen after everyone has exited */
1923 // tid = VG_(master_tid);
1924 vg_assert(tid != 0);
1925
njndb13c4f2005-06-01 00:00:46 +00001926 VG_(core_panic_at)("Killed by fatal signal",
njnaf839f52005-06-23 03:27:57 +00001927 VG_UCONTEXT_INSTR_PTR(uc),
1928 VG_UCONTEXT_STACK_PTR(uc),
sewardjacaec5f2005-08-19 16:02:59 +00001929 VG_UCONTEXT_FRAME_PTR(uc),
1930 VG_UCONTEXT_LINK_REG(uc));
jsgf855d93d2003-10-13 22:26:55 +00001931 }
1932}
1933
1934
1935/*
sewardjb5f6f512005-03-10 23:59:00 +00001936 Kill this thread. Makes it leave any syscall it might be currently
1937 blocked in, and return to the scheduler. This doesn't mark the thread
1938 as exiting; that's the caller's job.
jsgf855d93d2003-10-13 22:26:55 +00001939 */
sewardjb5f6f512005-03-10 23:59:00 +00001940static void sigvgkill_handler(int signo, vki_siginfo_t *si, struct vki_ucontext *uc)
jsgf855d93d2003-10-13 22:26:55 +00001941{
sewardj42781722006-12-17 19:36:06 +00001942 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
sewardj489bfec2006-10-17 02:00:29 +00001943 ThreadStatus at_signal = VG_(threads)[tid].status;
sewardjb5f6f512005-03-10 23:59:00 +00001944
1945 if (VG_(clo_trace_signals))
sewardj489bfec2006-10-17 02:00:29 +00001946 VG_(message)(Vg_DebugMsg,
1947 "sigvgkill for lwp %d tid %d", VG_(gettid)(), tid);
1948
sewardjad0a3a82006-12-17 18:58:55 +00001949 VG_(acquire_BigLock)(tid, "sigvgkill_handler");
sewardjb5f6f512005-03-10 23:59:00 +00001950
njn351d0062005-06-21 22:23:59 +00001951 vg_assert(signo == VG_SIGVGKILL);
jsgf855d93d2003-10-13 22:26:55 +00001952 vg_assert(si->si_signo == signo);
1953
sewardj489bfec2006-10-17 02:00:29 +00001954 /* jrs 2006 August 3: the following assertion seems incorrect to
1955 me, and fails on AIX. sigvgkill could be sent to a thread which
1956 is runnable - see VG_(nuke_all_threads_except) in the scheduler.
1957 Hence comment these out ..
1958
1959 vg_assert(VG_(threads)[tid].status == VgTs_WaitSys);
1960 VG_(post_syscall)(tid);
1961
1962 and instead do:
1963 */
1964 if (at_signal == VgTs_WaitSys)
1965 VG_(post_syscall)(tid);
1966 /* jrs 2006 August 3 ends */
sewardjb5f6f512005-03-10 23:59:00 +00001967
njn06244e72005-06-21 22:27:19 +00001968 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001969
1970 VG_(core_panic)("sigvgkill_handler couldn't return to the scheduler\n");
sewardjde4a1d02002-03-22 01:27:54 +00001971}
1972
sewardjde4a1d02002-03-22 01:27:54 +00001973static __attribute((unused))
njn695c16e2005-03-27 03:40:28 +00001974void pp_ksigaction ( struct vki_sigaction* sa )
sewardjde4a1d02002-03-22 01:27:54 +00001975{
1976 Int i;
njn695c16e2005-03-27 03:40:28 +00001977 VG_(printf)("pp_ksigaction: handler %p, flags 0x%x, restorer %p\n",
sewardj489bfec2006-10-17 02:00:29 +00001978 sa->ksa_handler,
1979 (UInt)sa->sa_flags,
1980# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
1981 sa->sa_restorer
1982# else
1983 0
1984# endif
1985 );
njn695c16e2005-03-27 03:40:28 +00001986 VG_(printf)("pp_ksigaction: { ");
sewardjb5f6f512005-03-10 23:59:00 +00001987 for (i = 1; i <= VG_(max_signal); i++)
nethercote73b526f2004-10-31 18:48:21 +00001988 if (VG_(sigismember(&(sa->sa_mask),i)))
sewardjde4a1d02002-03-22 01:27:54 +00001989 VG_(printf)("%d ", i);
1990 VG_(printf)("}\n");
1991}
1992
jsgf855d93d2003-10-13 22:26:55 +00001993/*
sewardjb5f6f512005-03-10 23:59:00 +00001994 Force signal handler to default
jsgf855d93d2003-10-13 22:26:55 +00001995 */
sewardjb5f6f512005-03-10 23:59:00 +00001996void VG_(set_default_handler)(Int signo)
1997{
1998 struct vki_sigaction sa;
1999
2000 sa.ksa_handler = VKI_SIG_DFL;
2001 sa.sa_flags = 0;
sewardj489bfec2006-10-17 02:00:29 +00002002# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
sewardjb5f6f512005-03-10 23:59:00 +00002003 sa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00002004# endif
sewardjb5f6f512005-03-10 23:59:00 +00002005 VG_(sigemptyset)(&sa.sa_mask);
2006
2007 VG_(do_sys_sigaction)(signo, &sa, NULL);
2008}
2009
2010/*
2011 Poll for pending signals, and set the next one up for delivery.
2012 */
2013void VG_(poll_signals)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00002014{
sewardjb5f6f512005-03-10 23:59:00 +00002015 vki_siginfo_t si, *sip;
2016 vki_sigset_t pollset;
2017 ThreadState *tst = VG_(get_ThreadState)(tid);
2018 Int i;
2019 vki_sigset_t saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002020
sewardjb5f6f512005-03-10 23:59:00 +00002021 /* look for all the signals this thread isn't blocking */
2022 for(i = 0; i < _VKI_NSIG_WORDS; i++)
2023 pollset.sig[i] = ~tst->sig_mask.sig[i];
jsgf855d93d2003-10-13 22:26:55 +00002024
sewardjb5f6f512005-03-10 23:59:00 +00002025 //VG_(printf)("tid %d pollset=%08x%08x\n", tid, pollset.sig[1], pollset.sig[0]);
jsgf855d93d2003-10-13 22:26:55 +00002026
njn444eba12005-05-12 03:47:31 +00002027 block_all_host_signals(&saved_mask); // protect signal queue
sewardjb5f6f512005-03-10 23:59:00 +00002028
2029 /* First look for any queued pending signals */
2030 sip = next_queued(tid, &pollset); /* this thread */
2031
2032 if (sip == NULL)
2033 sip = next_queued(0, &pollset); /* process-wide */
2034
2035 /* If there was nothing queued, ask the kernel for a pending signal */
sewardj489bfec2006-10-17 02:00:29 +00002036 if (sip == NULL && VG_(sigtimedwait_zero)(&pollset, &si) > 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002037 if (VG_(clo_trace_signals))
sewardja8d8e232005-06-07 20:04:56 +00002038 VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d "
2039 "for thread %d", si.si_signo, tid);
sewardjb5f6f512005-03-10 23:59:00 +00002040 sip = &si;
thughes8abf3922004-10-16 10:59:49 +00002041 }
fitzhardingee1c06d82003-10-30 07:21:44 +00002042
sewardjb5f6f512005-03-10 23:59:00 +00002043 if (sip != NULL) {
2044 /* OK, something to do; deliver it */
2045 if (VG_(clo_trace_signals))
2046 VG_(message)(Vg_DebugMsg, "Polling found signal %d for tid %d",
2047 sip->si_signo, tid);
njn07ef6c02005-05-18 19:43:09 +00002048 if (!is_sig_ign(sip->si_signo))
tomadacaf92007-12-21 10:24:24 +00002049 deliver_signal(tid, sip, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002050 else if (VG_(clo_trace_signals))
2051 VG_(message)(Vg_DebugMsg, " signal %d ignored", sip->si_signo);
2052
2053 sip->si_signo = 0; /* remove from signal queue, if that's
2054 where it came from */
jsgf855d93d2003-10-13 22:26:55 +00002055 }
2056
njn444eba12005-05-12 03:47:31 +00002057 restore_all_host_signals(&saved_mask);
sewardjb5f6f512005-03-10 23:59:00 +00002058}
2059
sewardj018f7622002-05-15 21:13:39 +00002060/* At startup, copy the process' real signal state to the SCSS.
2061 Whilst doing this, block all real signals. Then calculate SKSS and
2062 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00002063*/
2064void VG_(sigstartup_actions) ( void )
2065{
2066 Int i, ret;
nethercote73b526f2004-10-31 18:48:21 +00002067 vki_sigset_t saved_procmask;
nethercote73b526f2004-10-31 18:48:21 +00002068 struct vki_sigaction sa;
sewardjde4a1d02002-03-22 01:27:54 +00002069
sewardj2e93c502002-04-12 11:12:52 +00002070 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00002071 /* Block all signals. saved_procmask remembers the previous mask,
2072 which the first thread inherits.
2073 */
njn444eba12005-05-12 03:47:31 +00002074 block_all_host_signals( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00002075
sewardj018f7622002-05-15 21:13:39 +00002076 /* Copy per-signal settings to SCSS. */
nethercote73b526f2004-10-31 18:48:21 +00002077 for (i = 1; i <= _VKI_NSIG; i++) {
sewardj018f7622002-05-15 21:13:39 +00002078 /* Get the old host action */
nethercote73b526f2004-10-31 18:48:21 +00002079 ret = VG_(sigaction)(i, NULL, &sa);
sewardj018f7622002-05-15 21:13:39 +00002080
sewardjb5f6f512005-03-10 23:59:00 +00002081 if (ret != 0)
2082 break;
2083
2084 /* Try setting it back to see if this signal is really
2085 available */
2086 if (i >= VKI_SIGRTMIN) {
2087 struct vki_sigaction tsa;
2088
njn695c16e2005-03-27 03:40:28 +00002089 tsa.ksa_handler = (void *)sync_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +00002090 tsa.sa_flags = VKI_SA_SIGINFO;
sewardj489bfec2006-10-17 02:00:29 +00002091# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
sewardjb5f6f512005-03-10 23:59:00 +00002092 tsa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00002093# endif
sewardjb5f6f512005-03-10 23:59:00 +00002094 VG_(sigfillset)(&tsa.sa_mask);
2095
2096 /* try setting it to some arbitrary handler */
2097 if (VG_(sigaction)(i, &tsa, NULL) != 0) {
2098 /* failed - not really usable */
2099 break;
2100 }
2101
2102 ret = VG_(sigaction)(i, &sa, NULL);
2103 vg_assert(ret == 0);
2104 }
2105
2106 VG_(max_signal) = i;
2107
2108 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
njn8a7b41b2007-09-23 00:51:24 +00002109 VG_(printf)("snaffling handler 0x%lx for signal %d\n",
sewardj018f7622002-05-15 21:13:39 +00002110 (Addr)(sa.ksa_handler), i );
2111
njn695c16e2005-03-27 03:40:28 +00002112 scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
2113 scss.scss_per_sig[i].scss_flags = sa.sa_flags;
2114 scss.scss_per_sig[i].scss_mask = sa.sa_mask;
sewardj489bfec2006-10-17 02:00:29 +00002115 scss.scss_per_sig[i].scss_restorer = 0;
2116# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
njn695c16e2005-03-27 03:40:28 +00002117 scss.scss_per_sig[i].scss_restorer = sa.sa_restorer;
sewardj489bfec2006-10-17 02:00:29 +00002118# endif
sewardj018f7622002-05-15 21:13:39 +00002119 }
2120
sewardjb5f6f512005-03-10 23:59:00 +00002121 if (VG_(clo_trace_signals))
2122 VG_(message)(Vg_DebugMsg, "Max kernel-supported signal is %d", VG_(max_signal));
2123
jsgf855d93d2003-10-13 22:26:55 +00002124 /* Our private internal signals are treated as ignored */
njn351d0062005-06-21 22:23:59 +00002125 scss.scss_per_sig[VG_SIGVGKILL].scss_handler = VKI_SIG_IGN;
2126 scss.scss_per_sig[VG_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
2127 VG_(sigfillset)(&scss.scss_per_sig[VG_SIGVGKILL].scss_mask);
jsgf855d93d2003-10-13 22:26:55 +00002128
sewardj018f7622002-05-15 21:13:39 +00002129 /* Copy the process' signal mask into the root thread. */
sewardj1d887112005-05-30 21:44:08 +00002130 vg_assert(VG_(threads)[1].status == VgTs_Init);
2131 for (i = 2; i < VG_N_THREADS; i++)
2132 vg_assert(VG_(threads)[i].status == VgTs_Empty);
2133
2134 VG_(threads)[1].sig_mask = saved_procmask;
2135 VG_(threads)[1].tmp_sig_mask = saved_procmask;
sewardj7a61d912002-04-25 01:27:35 +00002136
sewardj018f7622002-05-15 21:13:39 +00002137 /* Calculate SKSS and apply it. This also sets the initial kernel
2138 mask we need to run with. */
nethercote9dd11512004-08-04 15:31:30 +00002139 handle_SCSS_change( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00002140
sewardjb5f6f512005-03-10 23:59:00 +00002141 /* Leave with all signals still blocked; the thread scheduler loop
2142 will set the appropriate mask at the appropriate time. */
sewardjde4a1d02002-03-22 01:27:54 +00002143}
2144
sewardjde4a1d02002-03-22 01:27:54 +00002145/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00002146/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00002147/*--------------------------------------------------------------------*/