blob: a3b7690a58d7e57df3f3e5cf9638e766930e9cb0 [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
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2000-2010 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
njn1ee02e32009-05-04 06:54:04 +000045 2. Asynchronous variants of the above signals: If the kernel tries
sewardjb5f6f512005-03-10 23:59:00 +000046 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
sewardj67b38c32010-01-01 12:44:12 +000057 4. Asynchronous, general signals. All other signals, sent by
sewardjb5f6f512005-03-10 23:59:00 +000058 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
sewardjebf58442010-03-01 16:42:56 +000063 In addition, we reserve one signal for internal use: SIGVGKILL.
sewardjb5f6f512005-03-10 23:59:00 +000064 SIGVGKILL is used to terminate threads. When one thread wants
65 another to exit, it will set its exitreason and send it SIGVGKILL
66 if it appears to be blocked in a syscall.
67
68
69 We use a kernel thread for each application thread. When the
70 thread allows itself to be open to signals, it sets the thread
71 signal mask to what the client application set it to. This means
72 that we get the kernel to do all signal routing: under Valgrind,
73 signals get delivered in the same way as in the non-Valgrind case
74 (the exception being for the sync signal set, since they're almost
75 always unblocked).
jsgf855d93d2003-10-13 22:26:55 +000076 */
sewardjde4a1d02002-03-22 01:27:54 +000077
njn1ee02e32009-05-04 06:54:04 +000078/*
79 Some more details...
80
81 First off, we take note of the client's requests (via sys_sigaction
82 and sys_sigprocmask) to set the signal state (handlers for each
83 signal, which are process-wide, + a mask for each signal, which is
84 per-thread). This info is duly recorded in the SCSS (static Client
85 signal state) in m_signals.c, and if the client later queries what
86 the state is, we merely fish the relevant info out of SCSS and give
87 it back.
88
89 However, we set the real signal state in the kernel to something
90 entirely different. This is recorded in SKSS, the static Kernel
91 signal state. What's nice (to the extent that anything is nice w.r.t
92 signals) is that there's a pure function to calculate SKSS from SCSS,
93 calculate_SKSS_from_SCSS. So when the client changes SCSS then we
94 recompute the associated SKSS and apply any changes from the previous
95 SKSS through to the kernel.
96
97 Now, that said, the general scheme we have now is, that regardless of
98 what the client puts into the SCSS (viz, asks for), what we would
99 like to do is as follows:
100
101 (1) run code on the virtual CPU with all signals blocked
102
103 (2) at convenient moments for us (that is, when the VCPU stops, and
104 control is back with the scheduler), ask the kernel "do you have
105 any signals for me?" and if it does, collect up the info, and
106 deliver them to the client (by building sigframes).
107
108 And that's almost what we do. The signal polling is done by
109 VG_(poll_signals), which calls through to VG_(sigtimedwait_zero) to
110 do the dirty work. (of which more later).
111
112 By polling signals, rather than catching them, we get to deal with
113 them only at convenient moments, rather than having to recover from
114 taking a signal while generated code is running.
115
116 Now unfortunately .. the above scheme only works for so-called async
117 signals. An async signal is one which isn't associated with any
118 particular instruction, eg Control-C (SIGINT). For those, it doesn't
119 matter if we don't deliver the signal to the client immediately; it
120 only matters that we deliver it eventually. Hence polling is OK.
121
122 But the other group -- sync signals -- are all related by the fact
123 that they are various ways for the host CPU to fail to execute an
124 instruction: SIGILL, SIGSEGV, SIGFPU. And they can't be deferred,
125 because obviously if a host instruction can't execute, well then we
126 have to immediately do Plan B, whatever that is.
127
128 So the next approximation of what happens is:
129
130 (1) run code on vcpu with all async signals blocked
131
132 (2) at convenient moments (when NOT running the vcpu), poll for async
133 signals.
134
135 (1) and (2) together imply that if the host does deliver a signal to
136 async_signalhandler while the VCPU is running, something's
137 seriously wrong.
138
139 (3) when running code on vcpu, don't block sync signals. Instead
140 register sync_signalhandler and catch any such via that. Of
141 course, that means an ugly recovery path if we do -- the
142 sync_signalhandler has to longjump, exiting out of the generated
143 code, and the assembly-dispatcher thingy that runs it, and gets
144 caught in m_scheduler, which then tells m_signals to deliver the
145 signal.
146
147 Now naturally (ha ha) even that might be tolerable, but there's
148 something worse: dealing with signals delivered to threads in
149 syscalls.
150
151 Obviously from the above, SKSS's signal mask (viz, what we really run
152 with) is way different from SCSS's signal mask (viz, what the client
153 thread thought it asked for). (eg) It may well be that the client
154 did not block control-C, so that it just expects to drop dead if it
155 receives ^C whilst blocked in a syscall, but by default we are
156 running with all async signals blocked, and so that signal could be
157 arbitrarily delayed, or perhaps even lost (not sure).
158
159 So what we have to do, when doing any syscall which SfMayBlock, is to
160 quickly switch in the SCSS-specified signal mask just before the
161 syscall, and switch it back just afterwards, and hope that we don't
162 get caught up in some wierd race condition. This is the primary
163 purpose of the ultra-magical pieces of assembly code in
164 coregrind/m_syswrap/syscall-<plat>.S
165
166 -----------
167
168 The ways in which V can come to hear of signals that need to be
169 forwarded to the client as are follows:
170
171 sync signals: can arrive at any time whatsoever. These are caught
172 by sync_signalhandler
173
174 async signals:
175
176 if running generated code
177 then these are blocked, so we don't expect to catch them in
178 async_signalhandler
179
180 else
181 if thread is blocked in a syscall marked SfMayBlock
182 then signals may be delivered to async_sighandler, since we
183 temporarily unblocked them for the duration of the syscall,
184 by using the real (SCSS) mask for this thread
185
186 else we're doing misc housekeeping activities (eg, making a translation,
187 washing our hair, etc). As in the normal case, these signals are
188 blocked, but we can and do poll for them using VG_(poll_signals).
189
190 Now, re VG_(poll_signals), it polls the kernel by doing
191 VG_(sigtimedwait_zero). This is trivial on Linux, since it's just a
192 syscall. But on Darwin and AIX, we have to cobble together the
193 functionality in a tedious, longwinded and probably error-prone way.
194 */
195
njnc7561b92005-06-19 01:24:32 +0000196#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +0000197#include "pub_core_vki.h"
sewardj489bfec2006-10-17 02:00:29 +0000198#include "pub_core_vkiscnums.h"
sewardj45f4e7c2005-09-27 19:20:21 +0000199#include "pub_core_debuglog.h"
njnc7561b92005-06-19 01:24:32 +0000200#include "pub_core_threadstate.h"
sewardj14c7cc52007-02-25 15:08:24 +0000201#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +0000202#include "pub_core_clientstate.h"
njn2521d322005-05-08 14:45:13 +0000203#include "pub_core_aspacemgr.h"
njn634a6522005-07-02 01:59:28 +0000204#include "pub_core_debugger.h" // For VG_(start_debugger)
njnd2b17112005-04-19 04:10:25 +0000205#include "pub_core_errormgr.h"
njn97405b22005-06-02 03:39:33 +0000206#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +0000207#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +0000208#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +0000209#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +0000210#include "pub_core_libcsignal.h"
njnf536bbb2005-06-13 04:21:38 +0000211#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +0000212#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +0000213#include "pub_core_options.h"
njnc7561b92005-06-19 01:24:32 +0000214#include "pub_core_scheduler.h"
njn0c246472005-05-31 01:00:08 +0000215#include "pub_core_signals.h"
njn24a6efb2005-06-20 03:36:51 +0000216#include "pub_core_sigframe.h" // For VG_(sigframe_create)()
njn945ed2e2005-06-24 03:28:30 +0000217#include "pub_core_stacks.h" // For VG_(change_stack)()
njn24a6efb2005-06-20 03:36:51 +0000218#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
njn9abd6082005-06-17 21:31:45 +0000219#include "pub_core_syscall.h"
njnc1b01812005-06-17 22:19:06 +0000220#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +0000221#include "pub_core_tooliface.h"
sewardjcf4ac712005-11-01 00:03:40 +0000222#include "pub_core_coredump.h"
sewardj985fabb2005-04-24 14:18:14 +0000223
njnd2b17112005-04-19 04:10:25 +0000224
sewardj018f7622002-05-15 21:13:39 +0000225/* ---------------------------------------------------------------------
226 Forwards decls.
227 ------------------------------------------------------------------ */
228
njn5a350be2009-04-30 03:05:05 +0000229static void sync_signalhandler ( Int sigNo, vki_siginfo_t *info,
230 struct vki_ucontext * );
231static void async_signalhandler ( Int sigNo, vki_siginfo_t *info,
232 struct vki_ucontext * );
233static void sigvgkill_handler ( Int sigNo, vki_siginfo_t *info,
234 struct vki_ucontext * );
sewardj018f7622002-05-15 21:13:39 +0000235
jsgf855d93d2003-10-13 22:26:55 +0000236static const Char *signame(Int sigNo);
sewardj018f7622002-05-15 21:13:39 +0000237
sewardjb5f6f512005-03-10 23:59:00 +0000238/* Maximum usable signal. */
239Int VG_(max_signal) = _VKI_NSIG;
nethercote759dda32004-08-07 18:16:56 +0000240
sewardjb5f6f512005-03-10 23:59:00 +0000241#define N_QUEUED_SIGNALS 8
nethercote759dda32004-08-07 18:16:56 +0000242
sewardjb5f6f512005-03-10 23:59:00 +0000243typedef struct SigQueue {
244 Int next;
245 vki_siginfo_t sigs[N_QUEUED_SIGNALS];
246} SigQueue;
nethercote759dda32004-08-07 18:16:56 +0000247
sewardj489bfec2006-10-17 02:00:29 +0000248/* ------ Macros for pulling stuff out of ucontexts ------ */
249
njncda2f0f2009-05-18 02:12:08 +0000250/* Q: what does VG_UCONTEXT_SYSCALL_SYSRES do? A: let's suppose the
njn5a350be2009-04-30 03:05:05 +0000251 machine context (uc) reflects the situation that a syscall had just
252 completed, quite literally -- that is, that the program counter was
253 now at the instruction following the syscall. (or we're slightly
254 downstream, but we're sure no relevant register has yet changed
njncda2f0f2009-05-18 02:12:08 +0000255 value.) Then VG_UCONTEXT_SYSCALL_SYSRES returns a SysRes reflecting
njn5a350be2009-04-30 03:05:05 +0000256 the result of the syscall; it does this by fishing relevant bits of
257 the machine state out of the uc. Of course if the program counter
258 was somewhere else entirely then the result is likely to be
njncda2f0f2009-05-18 02:12:08 +0000259 meaningless, so the caller of VG_UCONTEXT_SYSCALL_SYSRES has to be
njn5a350be2009-04-30 03:05:05 +0000260 very careful to pay attention to the results only when it is sure
261 that the said constraint on the program counter is indeed valid. */
sewardjf5f1e122010-01-02 13:24:58 +0000262
njn605f4882005-05-29 17:50:40 +0000263#if defined(VGP_x86_linux)
njnaf839f52005-06-23 03:27:57 +0000264# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.eip)
265# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp)
sewardjacaec5f2005-08-19 16:02:59 +0000266# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardja8d8e232005-06-07 20:04:56 +0000267 /* Convert the value in uc_mcontext.eax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000268 VG_(mk_SysRes_x86_linux)( (uc)->uc_mcontext.eax )
sewardj59570ff2010-01-01 11:59:33 +0000269# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
270 { (srP)->r_pc = (ULong)((uc)->uc_mcontext.eip); \
271 (srP)->r_sp = (ULong)((uc)->uc_mcontext.esp); \
272 (srP)->misc.X86.r_ebp = (uc)->uc_mcontext.ebp; \
273 }
sewardje7aa4ae2005-06-09 12:43:42 +0000274
njn605f4882005-05-29 17:50:40 +0000275#elif defined(VGP_amd64_linux)
njnaf839f52005-06-23 03:27:57 +0000276# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.rip)
277# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.rsp)
sewardjacaec5f2005-08-19 16:02:59 +0000278# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardje7aa4ae2005-06-09 12:43:42 +0000279 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000280 VG_(mk_SysRes_amd64_linux)( (uc)->uc_mcontext.rax )
sewardj59570ff2010-01-01 11:59:33 +0000281# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
282 { (srP)->r_pc = (uc)->uc_mcontext.rip; \
283 (srP)->r_sp = (uc)->uc_mcontext.rsp; \
284 (srP)->misc.AMD64.r_rbp = (uc)->uc_mcontext.rbp; \
285 }
sewardje7aa4ae2005-06-09 12:43:42 +0000286
cerion85665ca2005-06-20 15:51:07 +0000287#elif defined(VGP_ppc32_linux)
sewardja36dcfa2005-11-25 02:16:58 +0000288/* Comments from Paul Mackerras 25 Nov 05:
289
290 > I'm tracking down a problem where V's signal handling doesn't
291 > work properly on a ppc440gx running 2.4.20. The problem is that
292 > the ucontext being presented to V's sighandler seems completely
293 > bogus.
294
295 > V's kernel headers and hence ucontext layout are derived from
296 > 2.6.9. I compared include/asm-ppc/ucontext.h from 2.4.20 and
297 > 2.6.13.
298
299 > Can I just check my interpretation: the 2.4.20 one contains the
300 > uc_mcontext field in line, whereas the 2.6.13 one has a pointer
301 > to said struct? And so if V is using the 2.6.13 struct then a
302 > 2.4.20 one will make no sense to it.
303
304 Not quite... what is inline in the 2.4.20 version is a
305 sigcontext_struct, not an mcontext. The sigcontext looks like
306 this:
307
308 struct sigcontext_struct {
309 unsigned long _unused[4];
310 int signal;
311 unsigned long handler;
312 unsigned long oldmask;
313 struct pt_regs *regs;
314 };
315
316 The regs pointer of that struct ends up at the same offset as the
317 uc_regs of the 2.6 struct ucontext, and a struct pt_regs is the
318 same as the mc_gregs field of the mcontext. In fact the integer
319 regs are followed in memory by the floating point regs on 2.4.20.
320
321 Thus if you are using the 2.6 definitions, it should work on 2.4.20
322 provided that you go via uc->uc_regs rather than looking in
323 uc->uc_mcontext directly.
324
325 There is another subtlety: 2.4.20 doesn't save the vector regs when
326 delivering a signal, and 2.6.x only saves the vector regs if the
327 process has ever used an altivec instructions. If 2.6.x does save
328 the vector regs, it sets the MSR_VEC bit in
329 uc->uc_regs->mc_gregs[PT_MSR], otherwise it clears it. That bit
330 will always be clear under 2.4.20. So you can use that bit to tell
331 whether uc->uc_regs->mc_vregs is valid. */
sewardjf5f1e122010-01-02 13:24:58 +0000332# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_NIP])
333# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
sewardj39a7c1d2005-11-24 03:54:38 +0000334# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
335 /* Convert the values in uc_mcontext r3,cr into a SysRes. */ \
336 VG_(mk_SysRes_ppc32_linux)( \
sewardja36dcfa2005-11-25 02:16:58 +0000337 (uc)->uc_regs->mc_gregs[VKI_PT_R3], \
338 (((uc)->uc_regs->mc_gregs[VKI_PT_CCR] >> 28) & 1) \
sewardj39a7c1d2005-11-24 03:54:38 +0000339 )
sewardjf5f1e122010-01-02 13:24:58 +0000340# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
341 { (srP)->r_pc = (ULong)((uc)->uc_regs->mc_gregs[VKI_PT_NIP]); \
342 (srP)->r_sp = (ULong)((uc)->uc_regs->mc_gregs[VKI_PT_R1]); \
343 (srP)->misc.PPC32.r_lr = (uc)->uc_regs->mc_gregs[VKI_PT_LNK]; \
344 }
cerion85665ca2005-06-20 15:51:07 +0000345
sewardj2c48c7b2005-11-29 13:05:56 +0000346#elif defined(VGP_ppc64_linux)
sewardjf5f1e122010-01-02 13:24:58 +0000347# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_NIP])
348# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
sewardjdcb6ec82006-01-19 03:44:10 +0000349 /* Dubious hack: if there is an error, only consider the lowest 8
350 bits of r3. memcheck/tests/post-syscall shows a case where an
351 interrupted syscall should have produced a ucontext with 0x4
352 (VKI_EINTR) in r3 but is in fact producing 0x204. */
353 /* Awaiting clarification from PaulM. Evidently 0x204 is
354 ERESTART_RESTARTBLOCK, which shouldn't have made it into user
355 space. */
356 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( struct vki_ucontext* uc )
357 {
358 ULong err = (uc->uc_mcontext.gp_regs[VKI_PT_CCR] >> 28) & 1;
359 ULong r3 = uc->uc_mcontext.gp_regs[VKI_PT_R3];
360 if (err) r3 &= 0xFF;
361 return VG_(mk_SysRes_ppc64_linux)( r3, err );
362 }
sewardjf5f1e122010-01-02 13:24:58 +0000363# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
364 { (srP)->r_pc = (uc)->uc_mcontext.gp_regs[VKI_PT_NIP]; \
365 (srP)->r_sp = (uc)->uc_mcontext.gp_regs[VKI_PT_R1]; \
366 (srP)->misc.PPC64.r_lr = (uc)->uc_mcontext.gp_regs[VKI_PT_LNK]; \
367 }
sewardj2c48c7b2005-11-29 13:05:56 +0000368
sewardj59570ff2010-01-01 11:59:33 +0000369#elif defined(VGP_arm_linux)
370# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.arm_pc)
371# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.arm_sp)
372# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
373 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
374 VG_(mk_SysRes_arm_linux)( (uc)->uc_mcontext.arm_r0 )
375# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
376 { (srP)->r_pc = (uc)->uc_mcontext.arm_pc; \
377 (srP)->r_sp = (uc)->uc_mcontext.arm_sp; \
378 (srP)->misc.ARM.r14 = (uc)->uc_mcontext.arm_lr; \
379 (srP)->misc.ARM.r12 = (uc)->uc_mcontext.arm_ip; \
380 (srP)->misc.ARM.r11 = (uc)->uc_mcontext.arm_fp; \
sewardjfa5ce562010-09-23 22:05:59 +0000381 (srP)->misc.ARM.r7 = (uc)->uc_mcontext.arm_r7; \
sewardj59570ff2010-01-01 11:59:33 +0000382 }
383
sewardj489bfec2006-10-17 02:00:29 +0000384#elif defined(VGP_ppc32_aix5)
385
386 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
387# include <ucontext.h>
388 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
389 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
390 ucontext_t* uc = (ucontext_t*)ucV;
391 struct __jmpbuf* mc = &(uc->uc_mcontext);
392 struct mstsave* jc = &mc->jmp_context;
393 return jc->iar;
394 }
395 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
396 ucontext_t* uc = (ucontext_t*)ucV;
397 struct __jmpbuf* mc = &(uc->uc_mcontext);
398 struct mstsave* jc = &mc->jmp_context;
399 return jc->gpr[1];
400 }
sewardj489bfec2006-10-17 02:00:29 +0000401 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV ) {
402 ucontext_t* uc = (ucontext_t*)ucV;
403 struct __jmpbuf* mc = &(uc->uc_mcontext);
404 struct mstsave* jc = &mc->jmp_context;
405 return VG_(mk_SysRes_ppc32_aix5)( jc->gpr[3], jc->gpr[4] );
406 }
407 static inline Addr VG_UCONTEXT_LINK_REG( void* ucV ) {
408 ucontext_t* uc = (ucontext_t*)ucV;
409 struct __jmpbuf* mc = &(uc->uc_mcontext);
410 struct mstsave* jc = &mc->jmp_context;
411 return jc->lr;
412 }
413 static inline Addr VG_UCONTEXT_FRAME_PTR( void* ucV ) {
414 return VG_UCONTEXT_STACK_PTR(ucV);
415 }
416
417#elif defined(VGP_ppc64_aix5)
418
419 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
420# include <ucontext.h>
421 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
422 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
423 ucontext_t* uc = (ucontext_t*)ucV;
424 struct __jmpbuf* mc = &(uc->uc_mcontext);
425 struct __context64* jc = &mc->jmp_context;
426 return jc->iar;
427 }
428 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
429 ucontext_t* uc = (ucontext_t*)ucV;
430 struct __jmpbuf* mc = &(uc->uc_mcontext);
431 struct __context64* jc = &mc->jmp_context;
432 return jc->gpr[1];
433 }
sewardj489bfec2006-10-17 02:00:29 +0000434 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV ) {
435 ucontext_t* uc = (ucontext_t*)ucV;
436 struct __jmpbuf* mc = &(uc->uc_mcontext);
437 struct __context64* jc = &mc->jmp_context;
438 return VG_(mk_SysRes_ppc32_aix5)( jc->gpr[3], jc->gpr[4] );
439 }
440 static inline Addr VG_UCONTEXT_LINK_REG( void* ucV ) {
441 ucontext_t* uc = (ucontext_t*)ucV;
442 struct __jmpbuf* mc = &(uc->uc_mcontext);
443 struct __context64* jc = &mc->jmp_context;
444 return jc->lr;
445 }
446 static inline Addr VG_UCONTEXT_FRAME_PTR( void* ucV ) {
447 return VG_UCONTEXT_STACK_PTR(ucV);
448 }
449
njnf76d27a2009-05-28 01:53:07 +0000450#elif defined(VGP_x86_darwin)
451
452 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
453 ucontext_t* uc = (ucontext_t*)ucV;
454 struct __darwin_mcontext32* mc = uc->uc_mcontext;
455 struct __darwin_i386_thread_state* ss = &mc->__ss;
456 return ss->__eip;
457 }
458 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
459 ucontext_t* uc = (ucontext_t*)ucV;
460 struct __darwin_mcontext32* mc = uc->uc_mcontext;
461 struct __darwin_i386_thread_state* ss = &mc->__ss;
462 return ss->__esp;
463 }
464 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV,
465 UWord scclass ) {
466 /* this is complicated by the problem that there are 3 different
467 kinds of syscalls, each with its own return convention.
468 NB: scclass is a host word, hence UWord is good for both
469 amd64-darwin and x86-darwin */
470 ucontext_t* uc = (ucontext_t*)ucV;
471 struct __darwin_mcontext32* mc = uc->uc_mcontext;
472 struct __darwin_i386_thread_state* ss = &mc->__ss;
473 /* duplicates logic in m_syswrap.getSyscallStatusFromGuestState */
474 UInt carry = 1 & ss->__eflags;
475 UInt err = 0;
476 UInt wLO = 0;
477 UInt wHI = 0;
478 switch (scclass) {
479 case VG_DARWIN_SYSCALL_CLASS_UNIX:
480 err = carry;
481 wLO = ss->__eax;
482 wHI = ss->__edx;
483 break;
484 case VG_DARWIN_SYSCALL_CLASS_MACH:
485 wLO = ss->__eax;
486 break;
487 case VG_DARWIN_SYSCALL_CLASS_MDEP:
488 wLO = ss->__eax;
489 break;
490 default:
491 vg_assert(0);
492 break;
493 }
494 return VG_(mk_SysRes_x86_darwin)( scclass, err ? True : False,
495 wHI, wLO );
496 }
sewardj67b38c32010-01-01 12:44:12 +0000497 static inline
498 void VG_UCONTEXT_TO_UnwindStartRegs( UnwindStartRegs* srP,
499 void* ucV ) {
500 ucontext_t* uc = (ucontext_t*)(ucV);
njnf76d27a2009-05-28 01:53:07 +0000501 struct __darwin_mcontext32* mc = uc->uc_mcontext;
502 struct __darwin_i386_thread_state* ss = &mc->__ss;
sewardj67b38c32010-01-01 12:44:12 +0000503 srP->r_pc = (ULong)(ss->__eip);
504 srP->r_sp = (ULong)(ss->__esp);
505 srP->misc.X86.r_ebp = (UInt)(ss->__ebp);
njnf76d27a2009-05-28 01:53:07 +0000506 }
507
508#elif defined(VGP_amd64_darwin)
509
510 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
511 I_die_here;
512 }
513 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
514 I_die_here;
515 }
516 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV,
517 UWord scclass ) {
518 I_die_here;
519 }
njnea2d6fd2010-07-01 00:20:20 +0000520 static inline
521 void VG_UCONTEXT_TO_UnwindStartRegs( UnwindStartRegs* srP,
522 void* ucV ) {
njnf76d27a2009-05-28 01:53:07 +0000523 I_die_here;
524 }
525
sewardj489bfec2006-10-17 02:00:29 +0000526#else
njn605f4882005-05-29 17:50:40 +0000527# error Unknown platform
528#endif
529
sewardj489bfec2006-10-17 02:00:29 +0000530
531/* ------ Macros for pulling stuff out of siginfos ------ */
532
533/* These macros allow use of uniform names when working with
534 both the Linux and AIX vki definitions. */
535#if defined(VGO_linux)
536# define VKI_SIGINFO_si_addr _sifields._sigfault._addr
537# define VKI_SIGINFO_si_pid _sifields._kill._pid
538#elif defined(VGO_aix5)
539# define VKI_SIGINFO_si_addr si_addr
540# define VKI_SIGINFO_si_pid si_pid
njnf76d27a2009-05-28 01:53:07 +0000541#elif defined(VGO_darwin)
542# define VKI_SIGINFO_si_addr si_addr
543# define VKI_SIGINFO_si_pid si_pid
sewardj489bfec2006-10-17 02:00:29 +0000544#else
545# error Unknown OS
546#endif
547
548
nethercote759dda32004-08-07 18:16:56 +0000549/* ---------------------------------------------------------------------
sewardj018f7622002-05-15 21:13:39 +0000550 HIGH LEVEL STUFF TO DO WITH SIGNALS: POLICY (MOSTLY)
551 ------------------------------------------------------------------ */
552
sewardjde4a1d02002-03-22 01:27:54 +0000553/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000554 Signal state for this process.
555 ------------------------------------------------------------------ */
556
sewardj018f7622002-05-15 21:13:39 +0000557
nethercote73b526f2004-10-31 18:48:21 +0000558/* Base-ment of these arrays[_VKI_NSIG].
sewardjb48e5002002-05-13 00:16:03 +0000559
nethercote73b526f2004-10-31 18:48:21 +0000560 Valid signal numbers are 1 .. _VKI_NSIG inclusive.
sewardjb48e5002002-05-13 00:16:03 +0000561 Rather than subtracting 1 for indexing these arrays, which
562 is tedious and error-prone, they are simply dimensioned 1 larger,
563 and entry [0] is not used.
564 */
565
sewardjb48e5002002-05-13 00:16:03 +0000566
sewardj018f7622002-05-15 21:13:39 +0000567/* -----------------------------------------------------
568 Static client signal state (SCSS). This is the state
569 that the client thinks it has the kernel in.
570 SCSS records verbatim the client's settings. These
571 are mashed around only when SKSS is calculated from it.
572 -------------------------------------------------- */
sewardjb48e5002002-05-13 00:16:03 +0000573
sewardj018f7622002-05-15 21:13:39 +0000574typedef
575 struct {
576 void* scss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN or ptr to
577 client's handler */
578 UInt scss_flags;
nethercote73b526f2004-10-31 18:48:21 +0000579 vki_sigset_t scss_mask;
sewardjb5f6f512005-03-10 23:59:00 +0000580 void* scss_restorer; /* where sigreturn goes */
njncda2f0f2009-05-18 02:12:08 +0000581 void* scss_sa_tramp; /* sa_tramp setting, Darwin only */
582 /* re _restorer and _sa_tramp, we merely record the values
583 supplied when the client does 'sigaction' and give them back
584 when requested. Otherwise they are simply ignored. */
sewardj018f7622002-05-15 21:13:39 +0000585 }
586 SCSS_Per_Signal;
sewardjb48e5002002-05-13 00:16:03 +0000587
sewardj018f7622002-05-15 21:13:39 +0000588typedef
589 struct {
sewardj2342c972002-05-22 23:34:20 +0000590 /* per-signal info */
nethercote73b526f2004-10-31 18:48:21 +0000591 SCSS_Per_Signal scss_per_sig[1+_VKI_NSIG];
sewardj2342c972002-05-22 23:34:20 +0000592
sewardj018f7622002-05-15 21:13:39 +0000593 /* Additional elements to SCSS not stored here:
594 - for each thread, the thread's blocking mask
595 - for each thread in WaitSIG, the set of waited-on sigs
596 */
597 }
598 SCSS;
sewardjb48e5002002-05-13 00:16:03 +0000599
njn695c16e2005-03-27 03:40:28 +0000600static SCSS scss;
sewardj018f7622002-05-15 21:13:39 +0000601
602
603/* -----------------------------------------------------
604 Static kernel signal state (SKSS). This is the state
605 that we have the kernel in. It is computed from SCSS.
606 -------------------------------------------------- */
607
608/* Let's do:
609 sigprocmask assigns to all thread masks
610 so that at least everything is always consistent
611 Flags:
jsgf855d93d2003-10-13 22:26:55 +0000612 SA_SIGINFO -- we always set it, and honour it for the client
sewardj018f7622002-05-15 21:13:39 +0000613 SA_NOCLDSTOP -- passed to kernel
sewardjb5f6f512005-03-10 23:59:00 +0000614 SA_ONESHOT or SA_RESETHAND -- pass through
jsgf855d93d2003-10-13 22:26:55 +0000615 SA_RESTART -- we observe this but set our handlers to always restart
616 SA_NOMASK or SA_NODEFER -- we observe this, but our handlers block everything
sewardjb5f6f512005-03-10 23:59:00 +0000617 SA_ONSTACK -- pass through
618 SA_NOCLDWAIT -- pass through
sewardjb48e5002002-05-13 00:16:03 +0000619*/
sewardjde4a1d02002-03-22 01:27:54 +0000620
sewardj77e466c2002-04-14 02:29:29 +0000621
sewardj018f7622002-05-15 21:13:39 +0000622typedef
623 struct {
624 void* skss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN
625 or ptr to our handler */
626 UInt skss_flags;
627 /* There is no skss_mask, since we know that we will always ask
jsgf855d93d2003-10-13 22:26:55 +0000628 for all signals to be blocked in our sighandlers. */
sewardj018f7622002-05-15 21:13:39 +0000629 /* Also there is no skss_restorer. */
630 }
631 SKSS_Per_Signal;
sewardjde4a1d02002-03-22 01:27:54 +0000632
sewardj018f7622002-05-15 21:13:39 +0000633typedef
634 struct {
nethercote73b526f2004-10-31 18:48:21 +0000635 SKSS_Per_Signal skss_per_sig[1+_VKI_NSIG];
sewardj018f7622002-05-15 21:13:39 +0000636 }
637 SKSS;
638
njn695c16e2005-03-27 03:40:28 +0000639static SKSS skss;
sewardjde4a1d02002-03-22 01:27:54 +0000640
njn07ef6c02005-05-18 19:43:09 +0000641static Bool is_sig_ign(Int sigNo)
jsgf855d93d2003-10-13 22:26:55 +0000642{
nethercote73b526f2004-10-31 18:48:21 +0000643 vg_assert(sigNo >= 1 && sigNo <= _VKI_NSIG);
sewardj2e93c502002-04-12 11:12:52 +0000644
njn695c16e2005-03-27 03:40:28 +0000645 return scss.scss_per_sig[sigNo].scss_handler == VKI_SIG_IGN;
jsgf855d93d2003-10-13 22:26:55 +0000646}
sewardjb48e5002002-05-13 00:16:03 +0000647
sewardj018f7622002-05-15 21:13:39 +0000648/* ---------------------------------------------------------------------
649 Compute the SKSS required by the current SCSS.
650 ------------------------------------------------------------------ */
651
sewardj4f29ddf2002-05-03 22:29:04 +0000652static
sewardj018f7622002-05-15 21:13:39 +0000653void pp_SKSS ( void )
654{
655 Int sig;
656 VG_(printf)("\n\nSKSS:\n");
nethercote73b526f2004-10-31 18:48:21 +0000657 for (sig = 1; sig <= _VKI_NSIG; sig++) {
dirk61780382007-10-01 10:33:41 +0000658 VG_(printf)("sig %d: handler %p, flags 0x%x\n", sig,
njn695c16e2005-03-27 03:40:28 +0000659 skss.skss_per_sig[sig].skss_handler,
660 skss.skss_per_sig[sig].skss_flags );
sewardj77e466c2002-04-14 02:29:29 +0000661
sewardj018f7622002-05-15 21:13:39 +0000662 }
sewardj018f7622002-05-15 21:13:39 +0000663}
664
sewardj018f7622002-05-15 21:13:39 +0000665/* This is the core, clever bit. Computation is as follows:
666
667 For each signal
668 handler = if client has a handler, then our handler
jsgf855d93d2003-10-13 22:26:55 +0000669 else if client is DFL, then our handler as well
670 else (client must be IGN)
sewardjb5f6f512005-03-10 23:59:00 +0000671 then hander is IGN
sewardj018f7622002-05-15 21:13:39 +0000672*/
673static
674void calculate_SKSS_from_SCSS ( SKSS* dst )
675{
676 Int sig;
sewardj018f7622002-05-15 21:13:39 +0000677 UInt scss_flags;
678 UInt skss_flags;
679
nethercote73b526f2004-10-31 18:48:21 +0000680 for (sig = 1; sig <= _VKI_NSIG; sig++) {
jsgf855d93d2003-10-13 22:26:55 +0000681 void *skss_handler;
682 void *scss_handler;
683
njn695c16e2005-03-27 03:40:28 +0000684 scss_handler = scss.scss_per_sig[sig].scss_handler;
685 scss_flags = scss.scss_per_sig[sig].scss_flags;
sewardj018f7622002-05-15 21:13:39 +0000686
jsgf855d93d2003-10-13 22:26:55 +0000687 switch(sig) {
688 case VKI_SIGSEGV:
689 case VKI_SIGBUS:
690 case VKI_SIGFPE:
691 case VKI_SIGILL:
sewardjb5f6f512005-03-10 23:59:00 +0000692 case VKI_SIGTRAP:
jsgf855d93d2003-10-13 22:26:55 +0000693 /* For these, we always want to catch them and report, even
694 if the client code doesn't. */
njn695c16e2005-03-27 03:40:28 +0000695 skss_handler = sync_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000696 break;
697
sewardjb5f6f512005-03-10 23:59:00 +0000698 case VKI_SIGCONT:
699 /* Let the kernel handle SIGCONT unless the client is actually
700 catching it. */
njn5a350be2009-04-30 03:05:05 +0000701 case VKI_SIGCHLD:
702 case VKI_SIGWINCH:
703 case VKI_SIGURG:
704 /* For signals which are have a default action of Ignore,
705 only set a handler if the client has set a signal handler.
706 Otherwise the kernel will interrupt a syscall which
707 wouldn't have otherwise been interrupted. */
njn695c16e2005-03-27 03:40:28 +0000708 if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_DFL)
sewardjb5f6f512005-03-10 23:59:00 +0000709 skss_handler = VKI_SIG_DFL;
njn695c16e2005-03-27 03:40:28 +0000710 else if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_IGN)
jsgf855d93d2003-10-13 22:26:55 +0000711 skss_handler = VKI_SIG_IGN;
sewardjb5f6f512005-03-10 23:59:00 +0000712 else
njn695c16e2005-03-27 03:40:28 +0000713 skss_handler = async_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000714 break;
jsgf855d93d2003-10-13 22:26:55 +0000715
sewardjb5f6f512005-03-10 23:59:00 +0000716 default:
njna530fc62005-03-13 04:46:36 +0000717 // VKI_SIGVG* are runtime variables, so we can't make them
718 // cases in the switch, so we handle them in the 'default' case.
njn351d0062005-06-21 22:23:59 +0000719 if (sig == VG_SIGVGKILL)
sewardjb5f6f512005-03-10 23:59:00 +0000720 skss_handler = sigvgkill_handler;
sewardjb5f6f512005-03-10 23:59:00 +0000721 else {
722 if (scss_handler == VKI_SIG_IGN)
723 skss_handler = VKI_SIG_IGN;
724 else
njn695c16e2005-03-27 03:40:28 +0000725 skss_handler = async_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +0000726 }
727 break;
728 }
sewardj018f7622002-05-15 21:13:39 +0000729
sewardj018f7622002-05-15 21:13:39 +0000730 /* Flags */
731
732 skss_flags = 0;
jsgf855d93d2003-10-13 22:26:55 +0000733
sewardjb5f6f512005-03-10 23:59:00 +0000734 /* SA_NOCLDSTOP, SA_NOCLDWAIT: pass to kernel */
735 skss_flags |= scss_flags & (VKI_SA_NOCLDSTOP | VKI_SA_NOCLDWAIT);
jsgf855d93d2003-10-13 22:26:55 +0000736
sewardj018f7622002-05-15 21:13:39 +0000737 /* SA_ONESHOT: ignore client setting */
sewardjb5f6f512005-03-10 23:59:00 +0000738
sewardja8d8e232005-06-07 20:04:56 +0000739 /* SA_RESTART: ignore client setting and always set it for us.
740 Though we never rely on the kernel to restart a
jsgf855d93d2003-10-13 22:26:55 +0000741 syscall, we observe whether it wanted to restart the syscall
sewardja8d8e232005-06-07 20:04:56 +0000742 or not, which is needed by
743 VG_(fixup_guest_state_after_syscall_interrupted) */
sewardj018f7622002-05-15 21:13:39 +0000744 skss_flags |= VKI_SA_RESTART;
jsgf855d93d2003-10-13 22:26:55 +0000745
746 /* SA_NOMASK: ignore it */
747
sewardj2342c972002-05-22 23:34:20 +0000748 /* SA_ONSTACK: client setting is irrelevant here */
sewardjb5f6f512005-03-10 23:59:00 +0000749 /* We don't set a signal stack, so ignore */
sewardj018f7622002-05-15 21:13:39 +0000750
jsgf855d93d2003-10-13 22:26:55 +0000751 /* always ask for SA_SIGINFO */
752 skss_flags |= VKI_SA_SIGINFO;
sewardj018f7622002-05-15 21:13:39 +0000753
fitzhardinge4f10ada2004-06-03 10:00:42 +0000754 /* use our own restorer */
755 skss_flags |= VKI_SA_RESTORER;
756
jsgf855d93d2003-10-13 22:26:55 +0000757 /* Create SKSS entry for this signal. */
sewardj6a3c26e2002-05-23 17:09:43 +0000758 if (sig != VKI_SIGKILL && sig != VKI_SIGSTOP)
759 dst->skss_per_sig[sig].skss_handler = skss_handler;
760 else
761 dst->skss_per_sig[sig].skss_handler = VKI_SIG_DFL;
762
sewardj018f7622002-05-15 21:13:39 +0000763 dst->skss_per_sig[sig].skss_flags = skss_flags;
764 }
765
766 /* Sanity checks. */
nethercote5fd72bb2004-11-04 19:28:38 +0000767 vg_assert(dst->skss_per_sig[VKI_SIGKILL].skss_handler == VKI_SIG_DFL);
768 vg_assert(dst->skss_per_sig[VKI_SIGSTOP].skss_handler == VKI_SIG_DFL);
sewardj018f7622002-05-15 21:13:39 +0000769
770 if (0)
771 pp_SKSS();
772}
773
774
775/* ---------------------------------------------------------------------
776 After a possible SCSS change, update SKSS and the kernel itself.
777 ------------------------------------------------------------------ */
778
njn9abd6082005-06-17 21:31:45 +0000779// We need two levels of macro-expansion here to convert __NR_rt_sigreturn
780// to a number before converting it to a string... sigh.
sewardj03d8aa82005-10-14 11:25:49 +0000781extern void my_sigreturn(void);
njn9abd6082005-06-17 21:31:45 +0000782
783#if defined(VGP_x86_linux)
njn5a350be2009-04-30 03:05:05 +0000784# define _MY_SIGRETURN(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000785 ".text\n" \
njn9abd6082005-06-17 21:31:45 +0000786 "my_sigreturn:\n" \
787 " movl $" #name ", %eax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000788 " int $0x80\n" \
789 ".previous\n"
sewardj59570ff2010-01-01 11:59:33 +0000790
njn9abd6082005-06-17 21:31:45 +0000791#elif defined(VGP_amd64_linux)
njn5a350be2009-04-30 03:05:05 +0000792# define _MY_SIGRETURN(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000793 ".text\n" \
njn9abd6082005-06-17 21:31:45 +0000794 "my_sigreturn:\n" \
795 " movq $" #name ", %rax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000796 " syscall\n" \
797 ".previous\n"
sewardj59570ff2010-01-01 11:59:33 +0000798
cerion85665ca2005-06-20 15:51:07 +0000799#elif defined(VGP_ppc32_linux)
njn5a350be2009-04-30 03:05:05 +0000800# define _MY_SIGRETURN(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000801 ".text\n" \
cerion85665ca2005-06-20 15:51:07 +0000802 "my_sigreturn:\n" \
803 " li 0, " #name "\n" \
sewardj2fedc642005-11-19 02:02:57 +0000804 " sc\n" \
805 ".previous\n"
sewardj59570ff2010-01-01 11:59:33 +0000806
sewardj2c48c7b2005-11-29 13:05:56 +0000807#elif defined(VGP_ppc64_linux)
njn5a350be2009-04-30 03:05:05 +0000808# define _MY_SIGRETURN(name) \
cerion297c88f2005-12-22 15:53:12 +0000809 ".align 2\n" \
810 ".globl my_sigreturn\n" \
811 ".section \".opd\",\"aw\"\n" \
812 ".align 3\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000813 "my_sigreturn:\n" \
cerion297c88f2005-12-22 15:53:12 +0000814 ".quad .my_sigreturn,.TOC.@tocbase,0\n" \
815 ".previous\n" \
816 ".type .my_sigreturn,@function\n" \
817 ".globl .my_sigreturn\n" \
818 ".my_sigreturn:\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000819 " li 0, " #name "\n" \
cerion297c88f2005-12-22 15:53:12 +0000820 " sc\n"
sewardj59570ff2010-01-01 11:59:33 +0000821
822#elif defined(VGP_arm_linux)
823# define _MY_SIGRETURN(name) \
824 ".text\n" \
825 "my_sigreturn:\n\t" \
826 " mov r7, #" #name "\n\t" \
827 " svc 0x00000000\n" \
828 ".previous\n"
829
sewardj489bfec2006-10-17 02:00:29 +0000830#elif defined(VGP_ppc32_aix5)
njn5a350be2009-04-30 03:05:05 +0000831# define _MY_SIGRETURN(name) \
sewardj489bfec2006-10-17 02:00:29 +0000832 ".globl my_sigreturn\n" \
833 "my_sigreturn:\n" \
834 ".long 0\n"
835#elif defined(VGP_ppc64_aix5)
njn5a350be2009-04-30 03:05:05 +0000836# define _MY_SIGRETURN(name) \
sewardj489bfec2006-10-17 02:00:29 +0000837 ".globl my_sigreturn\n" \
838 "my_sigreturn:\n" \
839 ".long 0\n"
sewardj59570ff2010-01-01 11:59:33 +0000840
njnf76d27a2009-05-28 01:53:07 +0000841#elif defined(VGP_x86_darwin)
842# define _MY_SIGRETURN(name) \
843 ".text\n" \
844 "my_sigreturn:\n" \
845 "movl $" VG_STRINGIFY(__NR_DARWIN_FAKE_SIGRETURN) ",%eax\n" \
846 "int $0x80"
sewardj59570ff2010-01-01 11:59:33 +0000847
njnf76d27a2009-05-28 01:53:07 +0000848#elif defined(VGP_amd64_darwin)
849 // DDD: todo
850# define _MY_SIGRETURN(name) \
851 ".text\n" \
852 "my_sigreturn:\n" \
853 "ud2\n"
sewardj59570ff2010-01-01 11:59:33 +0000854
njn9abd6082005-06-17 21:31:45 +0000855#else
856# error Unknown platform
857#endif
858
njn5a350be2009-04-30 03:05:05 +0000859#define MY_SIGRETURN(name) _MY_SIGRETURN(name)
njn9abd6082005-06-17 21:31:45 +0000860asm(
njn5a350be2009-04-30 03:05:05 +0000861 MY_SIGRETURN(__NR_rt_sigreturn)
njn9abd6082005-06-17 21:31:45 +0000862);
863
864
nethercote9dd11512004-08-04 15:31:30 +0000865static void handle_SCSS_change ( Bool force_update )
sewardj018f7622002-05-15 21:13:39 +0000866{
nethercote73b526f2004-10-31 18:48:21 +0000867 Int res, sig;
868 SKSS skss_old;
njncda2f0f2009-05-18 02:12:08 +0000869 vki_sigaction_toK_t ksa;
870 vki_sigaction_fromK_t ksa_old;
sewardj018f7622002-05-15 21:13:39 +0000871
sewardj018f7622002-05-15 21:13:39 +0000872 /* Remember old SKSS and calculate new one. */
njn695c16e2005-03-27 03:40:28 +0000873 skss_old = skss;
874 calculate_SKSS_from_SCSS ( &skss );
sewardj018f7622002-05-15 21:13:39 +0000875
876 /* Compare the new SKSS entries vs the old ones, and update kernel
877 where they differ. */
sewardjb5f6f512005-03-10 23:59:00 +0000878 for (sig = 1; sig <= VG_(max_signal); sig++) {
sewardj018f7622002-05-15 21:13:39 +0000879
880 /* Trying to do anything with SIGKILL is pointless; just ignore
881 it. */
882 if (sig == VKI_SIGKILL || sig == VKI_SIGSTOP)
883 continue;
884
sewardj018f7622002-05-15 21:13:39 +0000885 if (!force_update) {
886 if ((skss_old.skss_per_sig[sig].skss_handler
njn695c16e2005-03-27 03:40:28 +0000887 == skss.skss_per_sig[sig].skss_handler)
sewardj018f7622002-05-15 21:13:39 +0000888 && (skss_old.skss_per_sig[sig].skss_flags
njn695c16e2005-03-27 03:40:28 +0000889 == skss.skss_per_sig[sig].skss_flags))
sewardj018f7622002-05-15 21:13:39 +0000890 /* no difference */
891 continue;
892 }
893
njn695c16e2005-03-27 03:40:28 +0000894 ksa.ksa_handler = skss.skss_per_sig[sig].skss_handler;
895 ksa.sa_flags = skss.skss_per_sig[sig].skss_flags;
njnf76d27a2009-05-28 01:53:07 +0000896# if !defined(VGP_ppc32_linux) && \
897 !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
898 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn9abd6082005-06-17 21:31:45 +0000899 ksa.sa_restorer = my_sigreturn;
sewardjce2a6152005-07-08 18:25:13 +0000900# endif
sewardj162bebd2005-07-09 10:43:45 +0000901 /* Re above ifdef (also the assertion below), PaulM says:
902 The sa_restorer field is not used at all on ppc. Glibc
903 converts the sigaction you give it into a kernel sigaction,
904 but it doesn't put anything in the sa_restorer field.
905 */
fitzhardinge4f10ada2004-06-03 10:00:42 +0000906
sewardjb5f6f512005-03-10 23:59:00 +0000907 /* block all signals in handler */
nethercote73b526f2004-10-31 18:48:21 +0000908 VG_(sigfillset)( &ksa.sa_mask );
909 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGKILL );
910 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGSTOP );
sewardj018f7622002-05-15 21:13:39 +0000911
sewardjb5f6f512005-03-10 23:59:00 +0000912 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj738856f2009-07-15 14:48:32 +0000913 VG_(dmsg)("setting ksig %d to: hdlr %p, flags 0x%lx, "
914 "mask(msb..lsb) 0x%llx 0x%llx\n",
915 sig, ksa.ksa_handler,
916 (UWord)ksa.sa_flags,
917 _VKI_NSIG_WORDS > 1 ? (ULong)ksa.sa_mask.sig[1] : 0,
918 (ULong)ksa.sa_mask.sig[0]);
sewardj018f7622002-05-15 21:13:39 +0000919
nethercote73b526f2004-10-31 18:48:21 +0000920 res = VG_(sigaction)( sig, &ksa, &ksa_old );
sewardj018f7622002-05-15 21:13:39 +0000921 vg_assert(res == 0);
922
923 /* Since we got the old sigaction more or less for free, might
924 as well extract the maximum sanity-check value from it. */
925 if (!force_update) {
926 vg_assert(ksa_old.ksa_handler
927 == skss_old.skss_per_sig[sig].skss_handler);
nethercote73b526f2004-10-31 18:48:21 +0000928 vg_assert(ksa_old.sa_flags
sewardj018f7622002-05-15 21:13:39 +0000929 == skss_old.skss_per_sig[sig].skss_flags);
njnf76d27a2009-05-28 01:53:07 +0000930# if !defined(VGP_ppc32_linux) && \
931 !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
932 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
nethercote73b526f2004-10-31 18:48:21 +0000933 vg_assert(ksa_old.sa_restorer
njn9abd6082005-06-17 21:31:45 +0000934 == my_sigreturn);
sewardjce2a6152005-07-08 18:25:13 +0000935# endif
nethercote73b526f2004-10-31 18:48:21 +0000936 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGKILL );
937 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGSTOP );
938 vg_assert(VG_(isfullsigset)( &ksa_old.sa_mask ));
sewardj018f7622002-05-15 21:13:39 +0000939 }
940 }
sewardj018f7622002-05-15 21:13:39 +0000941}
942
943
944/* ---------------------------------------------------------------------
945 Update/query SCSS in accordance with client requests.
946 ------------------------------------------------------------------ */
947
sewardj2342c972002-05-22 23:34:20 +0000948/* Logic for this alt-stack stuff copied directly from do_sigaltstack
949 in kernel/signal.[ch] */
950
951/* True if we are on the alternate signal stack. */
sewardjb5f6f512005-03-10 23:59:00 +0000952static Bool on_sig_stack ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000953{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000954 ThreadState *tst = VG_(get_ThreadState)(tid);
955
njn5a350be2009-04-30 03:05:05 +0000956 return (m_SP - (Addr)tst->altstack.ss_sp < (Addr)tst->altstack.ss_size);
sewardj2342c972002-05-22 23:34:20 +0000957}
958
nethercote511e4062004-09-11 13:34:08 +0000959static Int sas_ss_flags ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000960{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000961 ThreadState *tst = VG_(get_ThreadState)(tid);
962
963 return (tst->altstack.ss_size == 0
sewardj2342c972002-05-22 23:34:20 +0000964 ? VKI_SS_DISABLE
nethercote511e4062004-09-11 13:34:08 +0000965 : on_sig_stack(tid, m_SP) ? VKI_SS_ONSTACK : 0);
sewardj2342c972002-05-22 23:34:20 +0000966}
967
968
sewardja8d8e232005-06-07 20:04:56 +0000969SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
sewardj2342c972002-05-22 23:34:20 +0000970{
njn502badb2005-05-08 02:04:49 +0000971 Addr m_SP;
sewardj2342c972002-05-22 23:34:20 +0000972
973 vg_assert(VG_(is_valid_tid)(tid));
njnf536bbb2005-06-13 04:21:38 +0000974 m_SP = VG_(get_SP)(tid);
sewardj2342c972002-05-22 23:34:20 +0000975
976 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +0000977 VG_(dmsg)("sys_sigaltstack: tid %d, "
sewardj738856f2009-07-15 14:48:32 +0000978 "ss %p{%p,sz=%llu,flags=0x%llx}, oss %p (current SP %p)\n",
979 tid, (void*)ss,
980 ss ? ss->ss_sp : 0,
981 (ULong)(ss ? ss->ss_size : 0),
982 (ULong)(ss ? ss->ss_flags : 0),
983 (void*)oss, (void*)m_SP);
sewardj2342c972002-05-22 23:34:20 +0000984
985 if (oss != NULL) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000986 oss->ss_sp = VG_(threads)[tid].altstack.ss_sp;
987 oss->ss_size = VG_(threads)[tid].altstack.ss_size;
njn5a350be2009-04-30 03:05:05 +0000988 oss->ss_flags = VG_(threads)[tid].altstack.ss_flags
989 | sas_ss_flags(tid, m_SP);
sewardj2342c972002-05-22 23:34:20 +0000990 }
991
992 if (ss != NULL) {
njnf536bbb2005-06-13 04:21:38 +0000993 if (on_sig_stack(tid, VG_(get_SP)(tid))) {
sewardja8d8e232005-06-07 20:04:56 +0000994 return VG_(mk_SysRes_Error)( VKI_EPERM );
sewardj2342c972002-05-22 23:34:20 +0000995 }
996 if (ss->ss_flags != VKI_SS_DISABLE
997 && ss->ss_flags != VKI_SS_ONSTACK
998 && ss->ss_flags != 0) {
sewardja8d8e232005-06-07 20:04:56 +0000999 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj2342c972002-05-22 23:34:20 +00001000 }
1001 if (ss->ss_flags == VKI_SS_DISABLE) {
fitzhardinge98c4dc02004-03-16 08:27:29 +00001002 VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
sewardj2342c972002-05-22 23:34:20 +00001003 } else {
1004 if (ss->ss_size < VKI_MINSIGSTKSZ) {
sewardja8d8e232005-06-07 20:04:56 +00001005 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
sewardj2342c972002-05-22 23:34:20 +00001006 }
jsgf855d93d2003-10-13 22:26:55 +00001007
nethercote20283c62004-11-04 19:43:22 +00001008 VG_(threads)[tid].altstack.ss_sp = ss->ss_sp;
1009 VG_(threads)[tid].altstack.ss_size = ss->ss_size;
fitzhardinge98c4dc02004-03-16 08:27:29 +00001010 VG_(threads)[tid].altstack.ss_flags = 0;
sewardj2342c972002-05-22 23:34:20 +00001011 }
sewardj2342c972002-05-22 23:34:20 +00001012 }
sewardja8d8e232005-06-07 20:04:56 +00001013 return VG_(mk_SysRes_Success)( 0 );
sewardj2342c972002-05-22 23:34:20 +00001014}
1015
1016
sewardja8d8e232005-06-07 20:04:56 +00001017SysRes VG_(do_sys_sigaction) ( Int signo,
njncda2f0f2009-05-18 02:12:08 +00001018 const vki_sigaction_toK_t* new_act,
1019 vki_sigaction_fromK_t* old_act )
sewardj018f7622002-05-15 21:13:39 +00001020{
sewardj018f7622002-05-15 21:13:39 +00001021 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001022 VG_(dmsg)("sys_sigaction: sigNo %d, "
sewardj738856f2009-07-15 14:48:32 +00001023 "new %#lx, old %#lx, new flags 0x%llx\n",
1024 signo, (UWord)new_act, (UWord)old_act,
1025 (ULong)(new_act ? new_act->sa_flags : 0));
sewardj018f7622002-05-15 21:13:39 +00001026
1027 /* Rule out various error conditions. The aim is to ensure that if
1028 when the call is passed to the kernel it will definitely
1029 succeed. */
1030
1031 /* Reject out-of-range signal numbers. */
sewardjb5f6f512005-03-10 23:59:00 +00001032 if (signo < 1 || signo > VG_(max_signal)) goto bad_signo;
sewardj018f7622002-05-15 21:13:39 +00001033
jsgf855d93d2003-10-13 22:26:55 +00001034 /* don't let them use our signals */
njn351d0062005-06-21 22:23:59 +00001035 if ( (signo > VG_SIGVGRTUSERMAX)
jsgf855d93d2003-10-13 22:26:55 +00001036 && new_act
sewardja8d8e232005-06-07 20:04:56 +00001037 && !(new_act->ksa_handler == VKI_SIG_DFL
1038 || new_act->ksa_handler == VKI_SIG_IGN) )
nethercote9c42a0f2003-11-17 10:37:19 +00001039 goto bad_signo_reserved;
jsgf855d93d2003-10-13 22:26:55 +00001040
sewardj018f7622002-05-15 21:13:39 +00001041 /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
1042 if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP)
1043 && new_act
1044 && new_act->ksa_handler != VKI_SIG_DFL)
1045 goto bad_sigkill_or_sigstop;
1046
1047 /* If the client supplied non-NULL old_act, copy the relevant SCSS
1048 entry into it. */
1049 if (old_act) {
njn695c16e2005-03-27 03:40:28 +00001050 old_act->ksa_handler = scss.scss_per_sig[signo].scss_handler;
1051 old_act->sa_flags = scss.scss_per_sig[signo].scss_flags;
1052 old_act->sa_mask = scss.scss_per_sig[signo].scss_mask;
njnf76d27a2009-05-28 01:53:07 +00001053# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
1054 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn695c16e2005-03-27 03:40:28 +00001055 old_act->sa_restorer = scss.scss_per_sig[signo].scss_restorer;
sewardj489bfec2006-10-17 02:00:29 +00001056# endif
sewardj018f7622002-05-15 21:13:39 +00001057 }
1058
1059 /* And now copy new SCSS entry from new_act. */
1060 if (new_act) {
njn695c16e2005-03-27 03:40:28 +00001061 scss.scss_per_sig[signo].scss_handler = new_act->ksa_handler;
1062 scss.scss_per_sig[signo].scss_flags = new_act->sa_flags;
1063 scss.scss_per_sig[signo].scss_mask = new_act->sa_mask;
sewardj489bfec2006-10-17 02:00:29 +00001064
njncda2f0f2009-05-18 02:12:08 +00001065 scss.scss_per_sig[signo].scss_restorer = NULL;
njnf76d27a2009-05-28 01:53:07 +00001066# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
1067 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn695c16e2005-03-27 03:40:28 +00001068 scss.scss_per_sig[signo].scss_restorer = new_act->sa_restorer;
sewardj489bfec2006-10-17 02:00:29 +00001069# endif
sewardjb5f6f512005-03-10 23:59:00 +00001070
njncda2f0f2009-05-18 02:12:08 +00001071 scss.scss_per_sig[signo].scss_sa_tramp = NULL;
njnf76d27a2009-05-28 01:53:07 +00001072# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1073 scss.scss_per_sig[signo].scss_sa_tramp = new_act->sa_tramp;
1074# endif
njncda2f0f2009-05-18 02:12:08 +00001075
njn695c16e2005-03-27 03:40:28 +00001076 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGKILL);
1077 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGSTOP);
sewardj018f7622002-05-15 21:13:39 +00001078 }
1079
1080 /* All happy bunnies ... */
1081 if (new_act) {
nethercote9dd11512004-08-04 15:31:30 +00001082 handle_SCSS_change( False /* lazy update */ );
sewardj018f7622002-05-15 21:13:39 +00001083 }
sewardja8d8e232005-06-07 20:04:56 +00001084 return VG_(mk_SysRes_Success)( 0 );
sewardj018f7622002-05-15 21:13:39 +00001085
1086 bad_signo:
sewardjec6e27c2007-11-17 21:31:48 +00001087 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001088 VG_(umsg)("Warning: bad signal number %d in sigaction()\n", signo);
sewardj9a3d8bd2005-05-23 14:47:52 +00001089 }
sewardja8d8e232005-06-07 20:04:56 +00001090 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +00001091
nethercote9c42a0f2003-11-17 10:37:19 +00001092 bad_signo_reserved:
sewardjec6e27c2007-11-17 21:31:48 +00001093 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001094 VG_(umsg)("Warning: ignored attempt to set %s handler in sigaction();\n",
1095 signame(signo));
1096 VG_(umsg)(" the %s signal is used internally by Valgrind\n",
1097 signame(signo));
fitzhardingebf459872003-11-18 16:55:33 +00001098 }
sewardja8d8e232005-06-07 20:04:56 +00001099 return VG_(mk_SysRes_Error)( VKI_EINVAL );
nethercote9c42a0f2003-11-17 10:37:19 +00001100
sewardj018f7622002-05-15 21:13:39 +00001101 bad_sigkill_or_sigstop:
sewardjec6e27c2007-11-17 21:31:48 +00001102 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001103 VG_(umsg)("Warning: ignored attempt to set %s handler in sigaction();\n",
1104 signame(signo));
1105 VG_(umsg)(" the %s signal is uncatchable\n",
1106 signame(signo));
sewardj9a3d8bd2005-05-23 14:47:52 +00001107 }
sewardja8d8e232005-06-07 20:04:56 +00001108 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +00001109}
1110
1111
1112static
1113void do_sigprocmask_bitops ( Int vki_how,
nethercote73b526f2004-10-31 18:48:21 +00001114 vki_sigset_t* orig_set,
1115 vki_sigset_t* modifier )
sewardj018f7622002-05-15 21:13:39 +00001116{
1117 switch (vki_how) {
1118 case VKI_SIG_BLOCK:
nethercote73b526f2004-10-31 18:48:21 +00001119 VG_(sigaddset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +00001120 break;
1121 case VKI_SIG_UNBLOCK:
nethercote73b526f2004-10-31 18:48:21 +00001122 VG_(sigdelset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +00001123 break;
1124 case VKI_SIG_SETMASK:
1125 *orig_set = *modifier;
1126 break;
1127 default:
njne427a662002-10-02 11:08:25 +00001128 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +00001129 break;
1130 }
1131}
1132
tomf7781e92005-11-02 15:31:21 +00001133static
njn5a350be2009-04-30 03:05:05 +00001134HChar* format_sigset ( const vki_sigset_t* set )
tomf7781e92005-11-02 15:31:21 +00001135{
njn5a350be2009-04-30 03:05:05 +00001136 static HChar buf[128];
tomf7781e92005-11-02 15:31:21 +00001137 int w;
1138
1139 VG_(strcpy)(buf, "");
1140
1141 for (w = _VKI_NSIG_WORDS - 1; w >= 0; w--)
1142 {
sewardja8ffda62008-07-18 18:23:24 +00001143# if _VKI_NSIG_BPW == 32
1144 VG_(sprintf)(buf + VG_(strlen)(buf), "%08llx",
1145 set ? (ULong)set->sig[w] : 0);
1146# elif _VKI_NSIG_BPW == 64
1147 VG_(sprintf)(buf + VG_(strlen)(buf), "%16llx",
1148 set ? (ULong)set->sig[w] : 0);
1149# else
1150# error "Unsupported value for _VKI_NSIG_BPW"
1151# endif
tomf7781e92005-11-02 15:31:21 +00001152 }
1153
1154 return buf;
1155}
1156
jsgf855d93d2003-10-13 22:26:55 +00001157/*
1158 This updates the thread's signal mask. There's no such thing as a
1159 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +00001160
1161 Note that the thread signal masks are an implicit part of SCSS,
1162 which is why this routine is allowed to mess with them.
1163*/
1164static
1165void do_setmask ( ThreadId tid,
1166 Int how,
nethercote73b526f2004-10-31 18:48:21 +00001167 vki_sigset_t* newset,
1168 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +00001169{
sewardj018f7622002-05-15 21:13:39 +00001170 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001171 VG_(dmsg)("do_setmask: tid = %d how = %d (%s), newset = %p (%s)\n",
sewardj738856f2009-07-15 14:48:32 +00001172 tid, how,
1173 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
1174 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
1175 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
1176 newset, newset ? format_sigset(newset) : "NULL" );
sewardj018f7622002-05-15 21:13:39 +00001177
jsgf855d93d2003-10-13 22:26:55 +00001178 /* Just do this thread. */
1179 vg_assert(VG_(is_valid_tid)(tid));
1180 if (oldset) {
sewardjb5f6f512005-03-10 23:59:00 +00001181 *oldset = VG_(threads)[tid].sig_mask;
jsgf855d93d2003-10-13 22:26:55 +00001182 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001183 VG_(dmsg)("\toldset=%p %s\n", oldset, format_sigset(oldset));
sewardj018f7622002-05-15 21:13:39 +00001184 }
sewardj018f7622002-05-15 21:13:39 +00001185 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +00001186 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
nethercote73b526f2004-10-31 18:48:21 +00001187 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
1188 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
sewardjb5f6f512005-03-10 23:59:00 +00001189 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
sewardj018f7622002-05-15 21:13:39 +00001190 }
1191}
1192
1193
sewardja8d8e232005-06-07 20:04:56 +00001194SysRes VG_(do_sys_sigprocmask) ( ThreadId tid,
1195 Int how,
1196 vki_sigset_t* set,
1197 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +00001198{
jsgf855d93d2003-10-13 22:26:55 +00001199 switch(how) {
njncda2f0f2009-05-18 02:12:08 +00001200 case VKI_SIG_BLOCK:
1201 case VKI_SIG_UNBLOCK:
1202 case VKI_SIG_SETMASK:
1203 vg_assert(VG_(is_valid_tid)(tid));
1204 do_setmask ( tid, how, set, oldset );
1205 return VG_(mk_SysRes_Success)( 0 );
jsgf855d93d2003-10-13 22:26:55 +00001206
njncda2f0f2009-05-18 02:12:08 +00001207 default:
sewardj738856f2009-07-15 14:48:32 +00001208 VG_(dmsg)("sigprocmask: unknown 'how' field %d\n", how);
njncda2f0f2009-05-18 02:12:08 +00001209 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +00001210 }
1211}
1212
1213
sewardj018f7622002-05-15 21:13:39 +00001214/* ---------------------------------------------------------------------
1215 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
1216 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +00001217
sewardj2e93c502002-04-12 11:12:52 +00001218/* ---------------------------------------------------------------------
1219 Handy utilities to block/restore all host signals.
1220 ------------------------------------------------------------------ */
1221
1222/* Block all host signals, dumping the old mask in *saved_mask. */
njn444eba12005-05-12 03:47:31 +00001223static void block_all_host_signals ( /* OUT */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +00001224{
1225 Int ret;
nethercote73b526f2004-10-31 18:48:21 +00001226 vki_sigset_t block_procmask;
1227 VG_(sigfillset)(&block_procmask);
1228 ret = VG_(sigprocmask)
sewardj2e93c502002-04-12 11:12:52 +00001229 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
1230 vg_assert(ret == 0);
1231}
1232
1233/* Restore the blocking mask using the supplied saved one. */
njn444eba12005-05-12 03:47:31 +00001234static void restore_all_host_signals ( /* IN */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +00001235{
1236 Int ret;
nethercote73b526f2004-10-31 18:48:21 +00001237 ret = VG_(sigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
sewardj2e93c502002-04-12 11:12:52 +00001238 vg_assert(ret == 0);
1239}
sewardjde4a1d02002-03-22 01:27:54 +00001240
njn444eba12005-05-12 03:47:31 +00001241void VG_(clear_out_queued_signals)( ThreadId tid, vki_sigset_t* saved_mask )
1242{
1243 block_all_host_signals(saved_mask);
1244 if (VG_(threads)[tid].sig_queue != NULL) {
1245 VG_(arena_free)(VG_AR_CORE, VG_(threads)[tid].sig_queue);
1246 VG_(threads)[tid].sig_queue = NULL;
1247 }
1248 restore_all_host_signals(saved_mask);
1249}
1250
sewardjde4a1d02002-03-22 01:27:54 +00001251/* ---------------------------------------------------------------------
1252 The signal simulation proper. A simplified version of what the
1253 Linux kernel does.
1254 ------------------------------------------------------------------ */
1255
sewardjde4a1d02002-03-22 01:27:54 +00001256/* Set up a stack frame (VgSigContext) for the client's signal
nethercotefedd8102004-09-13 15:19:34 +00001257 handler. */
sewardj2c5ffbe2005-03-12 13:32:06 +00001258static
njn5a350be2009-04-30 03:05:05 +00001259void push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo,
1260 const struct vki_ucontext *uc )
sewardjde4a1d02002-03-22 01:27:54 +00001261{
nethercote6eec4602004-09-13 14:15:36 +00001262 Addr esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +00001263 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +00001264 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +00001265
sewardjb5f6f512005-03-10 23:59:00 +00001266 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardj018f7622002-05-15 21:13:39 +00001267 vg_assert(VG_(is_valid_tid)(tid));
1268 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +00001269
sewardja672ea32006-04-29 18:03:14 +00001270 if (VG_(clo_trace_signals)) {
sewardj738856f2009-07-15 14:48:32 +00001271 VG_(dmsg)("push_signal_frame (thread %d): signal %d\n", tid, sigNo);
sewardja672ea32006-04-29 18:03:14 +00001272 VG_(get_and_pp_StackTrace)(tid, 10);
1273 }
jsgf855d93d2003-10-13 22:26:55 +00001274
sewardj2342c972002-05-22 23:34:20 +00001275 if (/* this signal asked to run on an alt stack */
njn695c16e2005-03-27 03:40:28 +00001276 (scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +00001277 && /* there is a defined and enabled alt stack, which we're not
1278 already using. Logic from get_sigframe in
1279 arch/i386/kernel/signal.c. */
njnf536bbb2005-06-13 04:21:38 +00001280 sas_ss_flags(tid, VG_(get_SP)(tid)) == 0
sewardj2342c972002-05-22 23:34:20 +00001281 ) {
1282 esp_top_of_frame
fitzhardinge98c4dc02004-03-16 08:27:29 +00001283 = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
sewardj2342c972002-05-22 23:34:20 +00001284 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001285 VG_(dmsg)("delivering signal %d (%s) to thread %d: "
1286 "on ALT STACK (%p-%p; %ld bytes)\n",
1287 sigNo, signame(sigNo), tid, tst->altstack.ss_sp,
1288 (UChar *)tst->altstack.ss_sp + tst->altstack.ss_size,
1289 (Word)tst->altstack.ss_size );
njnfdc28af2003-02-24 10:36:48 +00001290
nethercote7cc9c232004-01-21 15:08:04 +00001291 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +00001292 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
njnfdc28af2003-02-24 10:36:48 +00001293
sewardj2342c972002-05-22 23:34:20 +00001294 } else {
njnaf839f52005-06-23 03:27:57 +00001295 esp_top_of_frame = VG_(get_SP)(tid) - VG_STACK_REDZONE_SZB;
njnfdc28af2003-02-24 10:36:48 +00001296
nethercote7cc9c232004-01-21 15:08:04 +00001297 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +00001298 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
sewardj2342c972002-05-22 23:34:20 +00001299 }
sewardjb5f6f512005-03-10 23:59:00 +00001300
njn695c16e2005-03-27 03:40:28 +00001301 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_IGN);
1302 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_DFL);
sewardjb5f6f512005-03-10 23:59:00 +00001303
1304 /* This may fail if the client stack is busted; if that happens,
1305 the whole process will exit rather than simply calling the
1306 signal handler. */
tomadacaf92007-12-21 10:24:24 +00001307 VG_(sigframe_create) (tid, esp_top_of_frame, siginfo, uc,
sewardj985fabb2005-04-24 14:18:14 +00001308 scss.scss_per_sig[sigNo].scss_handler,
1309 scss.scss_per_sig[sigNo].scss_flags,
1310 &tst->sig_mask,
1311 scss.scss_per_sig[sigNo].scss_restorer);
sewardjde4a1d02002-03-22 01:27:54 +00001312}
1313
sewardjde4a1d02002-03-22 01:27:54 +00001314
jsgf855d93d2003-10-13 22:26:55 +00001315static const Char *signame(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +00001316{
njn5a350be2009-04-30 03:05:05 +00001317 static Char buf[20];
sewardjb48e5002002-05-13 00:16:03 +00001318
jsgf855d93d2003-10-13 22:26:55 +00001319 switch(sigNo) {
sewardj489bfec2006-10-17 02:00:29 +00001320 case VKI_SIGHUP: return "SIGHUP";
1321 case VKI_SIGINT: return "SIGINT";
1322 case VKI_SIGQUIT: return "SIGQUIT";
1323 case VKI_SIGILL: return "SIGILL";
1324 case VKI_SIGTRAP: return "SIGTRAP";
1325 case VKI_SIGABRT: return "SIGABRT";
1326 case VKI_SIGBUS: return "SIGBUS";
1327 case VKI_SIGFPE: return "SIGFPE";
1328 case VKI_SIGKILL: return "SIGKILL";
1329 case VKI_SIGUSR1: return "SIGUSR1";
1330 case VKI_SIGUSR2: return "SIGUSR2";
1331 case VKI_SIGSEGV: return "SIGSEGV";
1332 case VKI_SIGPIPE: return "SIGPIPE";
1333 case VKI_SIGALRM: return "SIGALRM";
1334 case VKI_SIGTERM: return "SIGTERM";
1335# if defined(VKI_SIGSTKFLT)
1336 case VKI_SIGSTKFLT: return "SIGSTKFLT";
1337# endif
1338 case VKI_SIGCHLD: return "SIGCHLD";
1339 case VKI_SIGCONT: return "SIGCONT";
1340 case VKI_SIGSTOP: return "SIGSTOP";
1341 case VKI_SIGTSTP: return "SIGTSTP";
1342 case VKI_SIGTTIN: return "SIGTTIN";
1343 case VKI_SIGTTOU: return "SIGTTOU";
1344 case VKI_SIGURG: return "SIGURG";
1345 case VKI_SIGXCPU: return "SIGXCPU";
1346 case VKI_SIGXFSZ: return "SIGXFSZ";
1347 case VKI_SIGVTALRM: return "SIGVTALRM";
1348 case VKI_SIGPROF: return "SIGPROF";
1349 case VKI_SIGWINCH: return "SIGWINCH";
1350 case VKI_SIGIO: return "SIGIO";
njncda2f0f2009-05-18 02:12:08 +00001351# if defined(VKI_SIGPWR)
sewardj489bfec2006-10-17 02:00:29 +00001352 case VKI_SIGPWR: return "SIGPWR";
njncda2f0f2009-05-18 02:12:08 +00001353# endif
sewardj489bfec2006-10-17 02:00:29 +00001354# if defined(VKI_SIGUNUSED)
1355 case VKI_SIGUNUSED: return "SIGUNUSED";
1356# endif
sewardjde4a1d02002-03-22 01:27:54 +00001357
njncda2f0f2009-05-18 02:12:08 +00001358# if defined(VKI_SIGRTMIN) && defined(VKI_SIGRTMAX)
jsgf855d93d2003-10-13 22:26:55 +00001359 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
sewardjb5f6f512005-03-10 23:59:00 +00001360 VG_(sprintf)(buf, "SIGRT%d", sigNo-VKI_SIGRTMIN);
jsgf855d93d2003-10-13 22:26:55 +00001361 return buf;
njncda2f0f2009-05-18 02:12:08 +00001362# endif
sewardjde4a1d02002-03-22 01:27:54 +00001363
jsgf855d93d2003-10-13 22:26:55 +00001364 default:
1365 VG_(sprintf)(buf, "SIG%d", sigNo);
1366 return buf;
1367 }
1368}
sewardjde4a1d02002-03-22 01:27:54 +00001369
jsgf855d93d2003-10-13 22:26:55 +00001370/* Hit ourselves with a signal using the default handler */
1371void VG_(kill_self)(Int sigNo)
1372{
njnf76d27a2009-05-28 01:53:07 +00001373 Int r;
njncda2f0f2009-05-18 02:12:08 +00001374 vki_sigset_t mask, origmask;
1375 vki_sigaction_toK_t sa, origsa2;
1376 vki_sigaction_fromK_t origsa;
sewardj018f7622002-05-15 21:13:39 +00001377
jsgf855d93d2003-10-13 22:26:55 +00001378 sa.ksa_handler = VKI_SIG_DFL;
nethercote73b526f2004-10-31 18:48:21 +00001379 sa.sa_flags = 0;
njnf76d27a2009-05-28 01:53:07 +00001380# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
1381 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
nethercote73b526f2004-10-31 18:48:21 +00001382 sa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00001383# endif
nethercote73b526f2004-10-31 18:48:21 +00001384 VG_(sigemptyset)(&sa.sa_mask);
sewardj2e93c502002-04-12 11:12:52 +00001385
nethercote73b526f2004-10-31 18:48:21 +00001386 VG_(sigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +00001387
sewardjb5f6f512005-03-10 23:59:00 +00001388 VG_(sigemptyset)(&mask);
1389 VG_(sigaddset)(&mask, sigNo);
1390 VG_(sigprocmask)(VKI_SIG_UNBLOCK, &mask, &origmask);
jsgf855d93d2003-10-13 22:26:55 +00001391
njnf76d27a2009-05-28 01:53:07 +00001392 r = VG_(kill)(VG_(getpid)(), sigNo);
1393 /* This sometimes fails with EPERM on Darwin. I don't know why. */
1394 /* vg_assert(r == 0); */
jsgf855d93d2003-10-13 22:26:55 +00001395
njncda2f0f2009-05-18 02:12:08 +00001396 VG_(convert_sigaction_fromK_to_toK)( &origsa, &origsa2 );
1397 VG_(sigaction)(sigNo, &origsa2, NULL);
nethercote73b526f2004-10-31 18:48:21 +00001398 VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00001399}
1400
njn36fce1b2009-04-28 01:55:01 +00001401// The si_code describes where the signal came from. Some come from the
1402// kernel, eg.: seg faults, illegal opcodes. Some come from the user, eg.:
1403// from kill() (SI_USER), or timer_settime() (SI_TIMER), or an async I/O
1404// request (SI_ASYNCIO). There's lots of implementation-defined leeway in
njnf76d27a2009-05-28 01:53:07 +00001405// POSIX, but the user vs. kernal distinction is what we want here. We also
1406// pass in some other details that can help when si_code is unreliable.
1407static Bool is_signal_from_kernel(ThreadId tid, int signum, int si_code)
njn36fce1b2009-04-28 01:55:01 +00001408{
1409#if defined(VGO_linux) || defined(VGO_aix5)
1410 // On Linux, SI_USER is zero, negative values are from the user, positive
1411 // values are from the kernel. There are SI_FROMUSER and SI_FROMKERNEL
1412 // macros but we don't use them here because other platforms don't have
1413 // them.
1414 return ( si_code > VKI_SI_USER ? True : False );
njnf76d27a2009-05-28 01:53:07 +00001415#elif defined(VGO_darwin)
1416 // On Darwin 9.6.0, the si_code is completely unreliable. It should be the
1417 // case that 0 means "user", and >0 means "kernel". But:
1418 // - For SIGSEGV, it seems quite reliable.
1419 // - For SIGBUS, it's always 2.
1420 // - For SIGFPE, it's often 0, even for kernel ones (eg.
1421 // div-by-integer-zero always gives zero).
1422 // - For SIGILL, it's unclear.
1423 // - For SIGTRAP, it's always 1.
1424 // You can see the "NOTIMP" (not implemented) status of a number of the
1425 // sub-cases in sys/signal.h. Hopefully future versions of Darwin will
1426 // get this right.
1427
1428 // If we're blocked waiting on a syscall, it must be a user signal, because
1429 // the kernel won't generate sync signals within syscalls.
1430 if (VG_(threads)[tid].status == VgTs_WaitSys) {
1431 return False;
1432
1433 // If it's a SIGSEGV, use the proper condition, since it's fairly reliable.
1434 } else if (SIGSEGV == signum) {
1435 return ( si_code > 0 ? True : False );
1436
1437 // If it's anything else, assume it's kernel-generated. Reason being that
1438 // kernel-generated sync signals are more common, and it's probable that
1439 // misdiagnosing a user signal as a kernel signal is better than the
1440 // opposite.
1441 } else {
1442 return True;
1443 }
njn36fce1b2009-04-28 01:55:01 +00001444#else
1445# error Unknown OS
1446#endif
1447}
1448
njn059539d2009-04-28 08:00:23 +00001449// This is an arbitrary si_code that we only use internally. It corresponds
1450// to the value SI_KERNEL on Linux, but that's not really of any significance
1451// as far as I can determine.
1452#define VKI_SEGV_MADE_UP_GPF 0x80
1453
jsgf855d93d2003-10-13 22:26:55 +00001454/*
sewardjb5f6f512005-03-10 23:59:00 +00001455 Perform the default action of a signal. If the signal is fatal, it
1456 marks all threads as needing to exit, but it doesn't actually kill
1457 the process or thread.
jsgf855d93d2003-10-13 22:26:55 +00001458
1459 If we're not being quiet, then print out some more detail about
1460 fatal signals (esp. core dumping signals).
1461 */
njn695c16e2005-03-27 03:40:28 +00001462static void default_action(const vki_siginfo_t *info, ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001463{
1464 Int sigNo = info->si_signo;
sewardjb5f6f512005-03-10 23:59:00 +00001465 Bool terminate = False; /* kills process */
1466 Bool core = False; /* kills process w/ core */
1467 struct vki_rlimit corelim;
1468 Bool could_core;
jsgf855d93d2003-10-13 22:26:55 +00001469
sewardjb5f6f512005-03-10 23:59:00 +00001470 vg_assert(VG_(is_running_thread)(tid));
1471
jsgf855d93d2003-10-13 22:26:55 +00001472 switch(sigNo) {
njncda2f0f2009-05-18 02:12:08 +00001473 case VKI_SIGQUIT: /* core */
1474 case VKI_SIGILL: /* core */
1475 case VKI_SIGABRT: /* core */
1476 case VKI_SIGFPE: /* core */
1477 case VKI_SIGSEGV: /* core */
1478 case VKI_SIGBUS: /* core */
1479 case VKI_SIGTRAP: /* core */
1480 case VKI_SIGXCPU: /* core */
1481 case VKI_SIGXFSZ: /* core */
1482 terminate = True;
1483 core = True;
1484 break;
jsgf855d93d2003-10-13 22:26:55 +00001485
njncda2f0f2009-05-18 02:12:08 +00001486 case VKI_SIGHUP: /* term */
1487 case VKI_SIGINT: /* term */
1488 case VKI_SIGKILL: /* term - we won't see this */
1489 case VKI_SIGPIPE: /* term */
1490 case VKI_SIGALRM: /* term */
1491 case VKI_SIGTERM: /* term */
1492 case VKI_SIGUSR1: /* term */
1493 case VKI_SIGUSR2: /* term */
1494 case VKI_SIGIO: /* term */
1495# if defined(VKI_SIGPWR)
1496 case VKI_SIGPWR: /* term */
1497# endif
1498 case VKI_SIGSYS: /* term */
1499 case VKI_SIGPROF: /* term */
1500 case VKI_SIGVTALRM: /* term */
1501# if defined(VKI_SIGRTMIN) && defined(VKI_SIGRTMAX)
1502 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1503# endif
1504 terminate = True;
1505 break;
jsgf855d93d2003-10-13 22:26:55 +00001506 }
1507
1508 vg_assert(!core || (core && terminate));
1509
fitzhardinge98abfc72003-12-16 02:05:15 +00001510 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001511 VG_(dmsg)("delivering %d (code %d) to default handler; action: %s%s\n",
1512 sigNo, info->si_code, terminate ? "terminate" : "ignore",
1513 core ? "+core" : "");
fitzhardinge98abfc72003-12-16 02:05:15 +00001514
sewardjb5f6f512005-03-10 23:59:00 +00001515 if (!terminate)
1516 return; /* nothing to do */
fitzhardinge4a4d1082004-03-15 23:46:54 +00001517
sewardjb5f6f512005-03-10 23:59:00 +00001518 could_core = core;
1519
1520 if (core) {
1521 /* If they set the core-size limit to zero, don't generate a
1522 core file */
fitzhardinge61a53412004-03-15 23:44:11 +00001523
sewardjb5f6f512005-03-10 23:59:00 +00001524 VG_(getrlimit)(VKI_RLIMIT_CORE, &corelim);
fitzhardinge61a53412004-03-15 23:44:11 +00001525
sewardjb5f6f512005-03-10 23:59:00 +00001526 if (corelim.rlim_cur == 0)
1527 core = False;
1528 }
fitzhardinge61a53412004-03-15 23:44:11 +00001529
njn36fce1b2009-04-28 01:55:01 +00001530 if ( (VG_(clo_verbosity) > 1 ||
njnf76d27a2009-05-28 01:53:07 +00001531 (could_core && is_signal_from_kernel(tid, sigNo, info->si_code))
njn36fce1b2009-04-28 01:55:01 +00001532 ) &&
1533 !VG_(clo_xml) ) {
sewardj738856f2009-07-15 14:48:32 +00001534 VG_(umsg)(
njnb6267bd2009-08-12 00:14:16 +00001535 "\n"
sewardj738856f2009-07-15 14:48:32 +00001536 "Process terminating with default action of signal %d (%s)%s\n",
1537 sigNo, signame(sigNo), core ? ": dumping core" : "");
jsgf855d93d2003-10-13 22:26:55 +00001538
sewardjb5f6f512005-03-10 23:59:00 +00001539 /* Be helpful - decode some more details about this fault */
njnf76d27a2009-05-28 01:53:07 +00001540 if (is_signal_from_kernel(tid, sigNo, info->si_code)) {
sewardjb5f6f512005-03-10 23:59:00 +00001541 const Char *event = NULL;
1542 Bool haveaddr = True;
jsgf855d93d2003-10-13 22:26:55 +00001543
sewardjb5f6f512005-03-10 23:59:00 +00001544 switch(sigNo) {
1545 case VKI_SIGSEGV:
1546 switch(info->si_code) {
sewardj738856f2009-07-15 14:48:32 +00001547 case VKI_SEGV_MAPERR: event = "Access not within mapped region";
1548 break;
1549 case VKI_SEGV_ACCERR: event = "Bad permissions for mapped region";
1550 break;
njn059539d2009-04-28 08:00:23 +00001551 case VKI_SEGV_MADE_UP_GPF:
sewardjb5f6f512005-03-10 23:59:00 +00001552 /* General Protection Fault: The CPU/kernel
1553 isn't telling us anything useful, but this
1554 is commonly the result of exceeding a
sewardj74b4cca2005-10-20 01:37:15 +00001555 segment limit. */
1556 event = "General Protection Fault";
sewardjb5f6f512005-03-10 23:59:00 +00001557 haveaddr = False;
jsgf855d93d2003-10-13 22:26:55 +00001558 break;
1559 }
sewardj45f4e7c2005-09-27 19:20:21 +00001560#if 0
1561 {
1562 HChar buf[110];
1563 VG_(am_show_nsegments)(0,"post segfault");
1564 VG_(sprintf)(buf, "/bin/cat /proc/%d/maps", VG_(getpid)());
1565 VG_(system)(buf);
1566 }
1567#endif
sewardjb5f6f512005-03-10 23:59:00 +00001568 break;
jsgf855d93d2003-10-13 22:26:55 +00001569
sewardjb5f6f512005-03-10 23:59:00 +00001570 case VKI_SIGILL:
1571 switch(info->si_code) {
tom148250b2005-11-12 00:13:20 +00001572 case VKI_ILL_ILLOPC: event = "Illegal opcode"; break;
1573 case VKI_ILL_ILLOPN: event = "Illegal operand"; break;
1574 case VKI_ILL_ILLADR: event = "Illegal addressing mode"; break;
1575 case VKI_ILL_ILLTRP: event = "Illegal trap"; break;
1576 case VKI_ILL_PRVOPC: event = "Privileged opcode"; break;
1577 case VKI_ILL_PRVREG: event = "Privileged register"; break;
1578 case VKI_ILL_COPROC: event = "Coprocessor error"; break;
1579 case VKI_ILL_BADSTK: event = "Internal stack error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001580 }
1581 break;
1582
1583 case VKI_SIGFPE:
1584 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001585 case VKI_FPE_INTDIV: event = "Integer divide by zero"; break;
1586 case VKI_FPE_INTOVF: event = "Integer overflow"; break;
1587 case VKI_FPE_FLTDIV: event = "FP divide by zero"; break;
1588 case VKI_FPE_FLTOVF: event = "FP overflow"; break;
1589 case VKI_FPE_FLTUND: event = "FP underflow"; break;
1590 case VKI_FPE_FLTRES: event = "FP inexact"; break;
1591 case VKI_FPE_FLTINV: event = "FP invalid operation"; break;
1592 case VKI_FPE_FLTSUB: event = "FP subscript out of range"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001593 }
1594 break;
1595
1596 case VKI_SIGBUS:
1597 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001598 case VKI_BUS_ADRALN: event = "Invalid address alignment"; break;
1599 case VKI_BUS_ADRERR: event = "Non-existent physical address"; break;
1600 case VKI_BUS_OBJERR: event = "Hardware error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001601 }
1602 break;
sewardj3059d272007-12-21 01:24:59 +00001603 } /* switch (sigNo) */
sewardjb5f6f512005-03-10 23:59:00 +00001604
1605 if (event != NULL) {
1606 if (haveaddr)
sewardj738856f2009-07-15 14:48:32 +00001607 VG_(umsg)(" %s at address %p\n",
1608 event, info->VKI_SIGINFO_si_addr);
sewardjb5f6f512005-03-10 23:59:00 +00001609 else
sewardj738856f2009-07-15 14:48:32 +00001610 VG_(umsg)(" %s\n", event);
jsgf855d93d2003-10-13 22:26:55 +00001611 }
1612 }
sewardj3059d272007-12-21 01:24:59 +00001613 /* Print a stack trace. Be cautious if the thread's SP is in an
1614 obviously stupid place (not mapped readable) that would
1615 likely cause a segfault. */
1616 if (VG_(is_valid_tid)(tid)) {
1617 ExeContext* ec = VG_(am_is_valid_for_client)
1618 (VG_(get_SP)(tid), sizeof(Addr), VKI_PROT_READ)
1619 ? VG_(record_ExeContext)( tid, 0/*first_ip_delta*/ )
1620 : VG_(record_depth_1_ExeContext)( tid );
1621 vg_assert(ec);
1622 VG_(pp_ExeContext)( ec );
fitzhardinge126c64f2003-12-08 21:58:37 +00001623 }
sewardj95d86c02007-12-18 01:49:23 +00001624 if (sigNo == VKI_SIGSEGV
njnf76d27a2009-05-28 01:53:07 +00001625 && info && is_signal_from_kernel(tid, sigNo, info->si_code)
sewardj95d86c02007-12-18 01:49:23 +00001626 && info->si_code == VKI_SEGV_MAPERR) {
sewardj738856f2009-07-15 14:48:32 +00001627 VG_(umsg)(" If you believe this happened as a result of a stack\n" );
1628 VG_(umsg)(" overflow in your program's main thread (unlikely but\n");
1629 VG_(umsg)(" possible), you can try to increase the size of the\n" );
1630 VG_(umsg)(" main thread stack using the --main-stacksize= flag.\n" );
sewardj95d86c02007-12-18 01:49:23 +00001631 // FIXME: assumes main ThreadId == 1
1632 if (VG_(is_valid_tid)(1)) {
sewardj738856f2009-07-15 14:48:32 +00001633 VG_(umsg)(
1634 " The main thread stack size used in this run was %d.\n",
1635 (Int)VG_(threads)[1].client_stack_szB);
sewardj95d86c02007-12-18 01:49:23 +00001636 }
1637 }
sewardjb5f6f512005-03-10 23:59:00 +00001638 }
1639
1640 if (VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) {
1641 VG_(start_debugger)( tid );
1642 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001643
sewardjb5f6f512005-03-10 23:59:00 +00001644 if (core) {
1645 const static struct vki_rlimit zero = { 0, 0 };
fitzhardinge4a4d1082004-03-15 23:46:54 +00001646
njn67229832005-08-28 04:38:12 +00001647 VG_(make_coredump)(tid, info, corelim.rlim_cur);
fitzhardinged65dcad2004-03-13 02:06:58 +00001648
sewardjb5f6f512005-03-10 23:59:00 +00001649 /* Make sure we don't get a confusing kernel-generated
1650 coredump when we finally exit */
1651 VG_(setrlimit)(VKI_RLIMIT_CORE, &zero);
1652 }
fitzhardinged65dcad2004-03-13 02:06:58 +00001653
sewardjb5f6f512005-03-10 23:59:00 +00001654 /* stash fatal signal in main thread */
sewardj1d887112005-05-30 21:44:08 +00001655 // what's this for?
1656 //VG_(threads)[VG_(master_tid)].os_state.fatalsig = sigNo;
sewardjde4a1d02002-03-22 01:27:54 +00001657
sewardjb5f6f512005-03-10 23:59:00 +00001658 /* everyone dies */
1659 VG_(nuke_all_threads_except)(tid, VgSrc_FatalSig);
1660 VG_(threads)[tid].exitreason = VgSrc_FatalSig;
1661 VG_(threads)[tid].os_state.fatalsig = sigNo;
sewardjb48e5002002-05-13 00:16:03 +00001662}
1663
sewardjb5f6f512005-03-10 23:59:00 +00001664/*
1665 This does the business of delivering a signal to a thread. It may
1666 be called from either a real signal handler, or from normal code to
1667 cause the thread to enter the signal handler.
sewardj5e2f0012004-12-13 14:10:34 +00001668
sewardjb5f6f512005-03-10 23:59:00 +00001669 This updates the thread state, but it does not set it to be
1670 Runnable.
1671*/
njn5a350be2009-04-30 03:05:05 +00001672static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info,
1673 const struct vki_ucontext *uc )
sewardjde4a1d02002-03-22 01:27:54 +00001674{
jsgf855d93d2003-10-13 22:26:55 +00001675 Int sigNo = info->si_signo;
njn695c16e2005-03-27 03:40:28 +00001676 SCSS_Per_Signal *handler = &scss.scss_per_sig[sigNo];
fitzhardinge98abfc72003-12-16 02:05:15 +00001677 void *handler_fn;
jsgf855d93d2003-10-13 22:26:55 +00001678 ThreadState *tst = VG_(get_ThreadState)(tid);
1679
1680 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001681 VG_(dmsg)("delivering signal %d (%s):%d to thread %d\n",
1682 sigNo, signame(sigNo), info->si_code, tid );
jsgf855d93d2003-10-13 22:26:55 +00001683
njn351d0062005-06-21 22:23:59 +00001684 if (sigNo == VG_SIGVGKILL) {
sewardjb5f6f512005-03-10 23:59:00 +00001685 /* If this is a SIGVGKILL, we're expecting it to interrupt any
1686 blocked syscall. It doesn't matter whether the VCPU state is
1687 set to restart or not, because we don't expect it will
1688 execute any more client instructions. */
1689 vg_assert(VG_(is_exiting)(tid));
jsgf855d93d2003-10-13 22:26:55 +00001690 return;
1691 }
1692
sewardjb5f6f512005-03-10 23:59:00 +00001693 /* If the client specifies SIG_IGN, treat it as SIG_DFL.
jsgf855d93d2003-10-13 22:26:55 +00001694
njn9ec0f3e2005-03-13 06:00:47 +00001695 If deliver_signal() is being called on a thread, we want
sewardjb5f6f512005-03-10 23:59:00 +00001696 the signal to get through no matter what; if they're ignoring
1697 it, then we do this override (this is so we can send it SIGSEGV,
1698 etc). */
fitzhardinge98abfc72003-12-16 02:05:15 +00001699 handler_fn = handler->scss_handler;
sewardjb5f6f512005-03-10 23:59:00 +00001700 if (handler_fn == VKI_SIG_IGN)
fitzhardinge98abfc72003-12-16 02:05:15 +00001701 handler_fn = VKI_SIG_DFL;
1702
1703 vg_assert(handler_fn != VKI_SIG_IGN);
jsgf855d93d2003-10-13 22:26:55 +00001704
fitzhardinge98abfc72003-12-16 02:05:15 +00001705 if (handler_fn == VKI_SIG_DFL) {
njn695c16e2005-03-27 03:40:28 +00001706 default_action(info, tid);
jsgf855d93d2003-10-13 22:26:55 +00001707 } else {
1708 /* Create a signal delivery frame, and set the client's %ESP and
1709 %EIP so that when execution continues, we will enter the
1710 signal handler with the frame on top of the client's stack,
sewardjb5f6f512005-03-10 23:59:00 +00001711 as it expects.
1712
1713 Signal delivery can fail if the client stack is too small or
1714 missing, and we can't push the frame. If that happens,
1715 push_signal_frame will cause the whole process to exit when
1716 we next hit the scheduler.
1717 */
jsgf855d93d2003-10-13 22:26:55 +00001718 vg_assert(VG_(is_valid_tid)(tid));
sewardjb5f6f512005-03-10 23:59:00 +00001719
tomadacaf92007-12-21 10:24:24 +00001720 push_signal_frame ( tid, info, uc );
jsgf855d93d2003-10-13 22:26:55 +00001721
1722 if (handler->scss_flags & VKI_SA_ONESHOT) {
1723 /* Do the ONESHOT thing. */
1724 handler->scss_handler = VKI_SIG_DFL;
1725
nethercote9dd11512004-08-04 15:31:30 +00001726 handle_SCSS_change( False /* lazy update */ );
jsgf855d93d2003-10-13 22:26:55 +00001727 }
sewardjb5f6f512005-03-10 23:59:00 +00001728
1729 /* At this point:
1730 tst->sig_mask is the current signal mask
1731 tst->tmp_sig_mask is the same as sig_mask, unless we're in sigsuspend
1732 handler->scss_mask is the mask set by the handler
1733
1734 Handler gets a mask of tmp_sig_mask|handler_mask|signo
1735 */
1736 tst->sig_mask = tst->tmp_sig_mask;
1737 if (!(handler->scss_flags & VKI_SA_NOMASK)) {
1738 VG_(sigaddset_from_set)(&tst->sig_mask, &handler->scss_mask);
1739 VG_(sigaddset)(&tst->sig_mask, sigNo);
sewardjb5f6f512005-03-10 23:59:00 +00001740 tst->tmp_sig_mask = tst->sig_mask;
1741 }
1742 }
1743
1744 /* Thread state is ready to go - just add Runnable */
1745}
1746
njn06244e72005-06-21 22:27:19 +00001747static void resume_scheduler(ThreadId tid)
1748{
1749 ThreadState *tst = VG_(get_ThreadState)(tid);
1750
1751 vg_assert(tst->os_state.lwpid == VG_(gettid)());
1752
1753 if (tst->sched_jmpbuf_valid) {
1754 /* Can't continue; must longjmp back to the scheduler and thus
1755 enter the sighandler immediately. */
sewardj45f4e7c2005-09-27 19:20:21 +00001756 __builtin_longjmp(tst->sched_jmpbuf, True);
njn06244e72005-06-21 22:27:19 +00001757 }
1758}
1759
njn9ec0f3e2005-03-13 06:00:47 +00001760static void synth_fault_common(ThreadId tid, Addr addr, Int si_code)
1761{
1762 vki_siginfo_t info;
1763
1764 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1765
njn5a350be2009-04-30 03:05:05 +00001766 VG_(memset)(&info, 0, sizeof(info));
njn9ec0f3e2005-03-13 06:00:47 +00001767 info.si_signo = VKI_SIGSEGV;
1768 info.si_code = si_code;
sewardj489bfec2006-10-17 02:00:29 +00001769 info.VKI_SIGINFO_si_addr = (void*)addr;
njn9ec0f3e2005-03-13 06:00:47 +00001770
1771 /* If they're trying to block the signal, force it to be delivered */
1772 if (VG_(sigismember)(&VG_(threads)[tid].sig_mask, VKI_SIGSEGV))
1773 VG_(set_default_handler)(VKI_SIGSEGV);
1774
tomadacaf92007-12-21 10:24:24 +00001775 deliver_signal(tid, &info, NULL);
njn9ec0f3e2005-03-13 06:00:47 +00001776}
1777
1778// Synthesize a fault where the address is OK, but the page
1779// permissions are bad.
1780void VG_(synth_fault_perms)(ThreadId tid, Addr addr)
1781{
njn059539d2009-04-28 08:00:23 +00001782 synth_fault_common(tid, addr, VKI_SEGV_ACCERR);
njn9ec0f3e2005-03-13 06:00:47 +00001783}
1784
1785// Synthesize a fault where the address there's nothing mapped at the address.
1786void VG_(synth_fault_mapping)(ThreadId tid, Addr addr)
1787{
njn059539d2009-04-28 08:00:23 +00001788 synth_fault_common(tid, addr, VKI_SEGV_MAPERR);
njn9ec0f3e2005-03-13 06:00:47 +00001789}
1790
1791// Synthesize a misc memory fault.
1792void VG_(synth_fault)(ThreadId tid)
1793{
njn059539d2009-04-28 08:00:23 +00001794 synth_fault_common(tid, 0, VKI_SEGV_MADE_UP_GPF);
njn9ec0f3e2005-03-13 06:00:47 +00001795}
1796
1797// Synthesise a SIGILL.
1798void VG_(synth_sigill)(ThreadId tid, Addr addr)
1799{
1800 vki_siginfo_t info;
1801
1802 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1803
njn5a350be2009-04-30 03:05:05 +00001804 VG_(memset)(&info, 0, sizeof(info));
njn9ec0f3e2005-03-13 06:00:47 +00001805 info.si_signo = VKI_SIGILL;
sewardj489bfec2006-10-17 02:00:29 +00001806 info.si_code = VKI_ILL_ILLOPC; /* jrs: no idea what this should be */
1807 info.VKI_SIGINFO_si_addr = (void*)addr;
njn9ec0f3e2005-03-13 06:00:47 +00001808
njn06244e72005-06-21 22:27:19 +00001809 resume_scheduler(tid);
tomadacaf92007-12-21 10:24:24 +00001810 deliver_signal(tid, &info, NULL);
njn9ec0f3e2005-03-13 06:00:47 +00001811}
1812
sewardj1c0ce7a2009-07-01 08:10:49 +00001813// Synthesise a SIGBUS.
1814void VG_(synth_sigbus)(ThreadId tid)
1815{
1816 vki_siginfo_t info;
1817
1818 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1819
1820 VG_(memset)(&info, 0, sizeof(info));
1821 info.si_signo = VKI_SIGBUS;
1822 /* There are several meanings to SIGBUS (as per POSIX, presumably),
1823 but the most widely understood is "invalid address alignment",
1824 so let's use that. */
1825 info.si_code = VKI_BUS_ADRALN;
1826 /* If we knew the invalid address in question, we could put it
1827 in .si_addr. Oh well. */
1828 /* info.VKI_SIGINFO_si_addr = (void*)addr; */
1829
1830 resume_scheduler(tid);
1831 deliver_signal(tid, &info, NULL);
1832}
1833
sewardj86df1552006-02-07 20:56:41 +00001834// Synthesise a SIGTRAP.
1835void VG_(synth_sigtrap)(ThreadId tid)
1836{
1837 vki_siginfo_t info;
tomadacaf92007-12-21 10:24:24 +00001838 struct vki_ucontext uc;
njnf76d27a2009-05-28 01:53:07 +00001839# if defined(VGP_x86_darwin)
1840 struct __darwin_mcontext32 mc;
1841# elif defined(VGP_amd64_darwin)
1842 struct __darwin_mcontext64 mc;
1843# endif
sewardj86df1552006-02-07 20:56:41 +00001844
1845 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1846
njn5a350be2009-04-30 03:05:05 +00001847 VG_(memset)(&info, 0, sizeof(info));
1848 VG_(memset)(&uc, 0, sizeof(uc));
sewardj86df1552006-02-07 20:56:41 +00001849 info.si_signo = VKI_SIGTRAP;
tomadacaf92007-12-21 10:24:24 +00001850 info.si_code = VKI_TRAP_BRKPT; /* tjh: only ever called for a brkpt ins */
njncda2f0f2009-05-18 02:12:08 +00001851
1852# if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
tomadacaf92007-12-21 10:24:24 +00001853 uc.uc_mcontext.trapno = 3; /* tjh: this is the x86 trap number
1854 for a breakpoint trap... */
tom8b243022008-06-13 08:37:49 +00001855 uc.uc_mcontext.err = 0; /* tjh: no error code for x86
1856 breakpoint trap... */
njnf76d27a2009-05-28 01:53:07 +00001857# elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1858 /* the same thing, but using Darwin field/struct names */
1859 VG_(memset)(&mc, 0, sizeof(mc));
1860 uc.uc_mcontext = &mc;
1861 uc.uc_mcontext->__es.__trapno = 3;
1862 uc.uc_mcontext->__es.__err = 0;
njncda2f0f2009-05-18 02:12:08 +00001863# endif
sewardj86df1552006-02-07 20:56:41 +00001864
1865 resume_scheduler(tid);
tomadacaf92007-12-21 10:24:24 +00001866 deliver_signal(tid, &info, &uc);
sewardj86df1552006-02-07 20:56:41 +00001867}
1868
sewardjb5f6f512005-03-10 23:59:00 +00001869/* Make a signal pending for a thread, for later delivery.
1870 VG_(poll_signals) will arrange for it to be delivered at the right
1871 time.
1872
1873 tid==0 means add it to the process-wide queue, and not sent it to a
1874 specific thread.
1875*/
sewardj2c5ffbe2005-03-12 13:32:06 +00001876static
sewardjb5f6f512005-03-10 23:59:00 +00001877void queue_signal(ThreadId tid, const vki_siginfo_t *si)
1878{
1879 ThreadState *tst;
1880 SigQueue *sq;
1881 vki_sigset_t savedmask;
1882
1883 tst = VG_(get_ThreadState)(tid);
1884
1885 /* Protect the signal queue against async deliveries */
njn444eba12005-05-12 03:47:31 +00001886 block_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001887
1888 if (tst->sig_queue == NULL) {
sewardj9c606bd2008-09-18 18:12:50 +00001889 tst->sig_queue = VG_(arena_malloc)(VG_AR_CORE, "signals.qs.1",
1890 sizeof(*tst->sig_queue));
sewardjb5f6f512005-03-10 23:59:00 +00001891 VG_(memset)(tst->sig_queue, 0, sizeof(*tst->sig_queue));
1892 }
1893 sq = tst->sig_queue;
1894
1895 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001896 VG_(dmsg)("Queueing signal %d (idx %d) to thread %d\n",
1897 si->si_signo, sq->next, tid);
sewardjb5f6f512005-03-10 23:59:00 +00001898
1899 /* Add signal to the queue. If the queue gets overrun, then old
1900 queued signals may get lost.
1901
1902 XXX We should also keep a sigset of pending signals, so that at
1903 least a non-siginfo signal gets deliviered.
1904 */
1905 if (sq->sigs[sq->next].si_signo != 0)
sewardj738856f2009-07-15 14:48:32 +00001906 VG_(umsg)("Signal %d being dropped from thread %d's queue\n",
1907 sq->sigs[sq->next].si_signo, tid);
sewardjb5f6f512005-03-10 23:59:00 +00001908
1909 sq->sigs[sq->next] = *si;
1910 sq->next = (sq->next+1) % N_QUEUED_SIGNALS;
1911
njn444eba12005-05-12 03:47:31 +00001912 restore_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001913}
1914
1915/*
1916 Returns the next queued signal for thread tid which is in "set".
1917 tid==0 means process-wide signal. Set si_signo to 0 when the
1918 signal has been delivered.
1919
1920 Must be called with all signals blocked, to protect against async
1921 deliveries.
1922*/
1923static vki_siginfo_t *next_queued(ThreadId tid, const vki_sigset_t *set)
1924{
1925 ThreadState *tst = VG_(get_ThreadState)(tid);
1926 SigQueue *sq;
1927 Int idx;
1928 vki_siginfo_t *ret = NULL;
1929
1930 sq = tst->sig_queue;
1931 if (sq == NULL)
1932 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001933
sewardjb5f6f512005-03-10 23:59:00 +00001934 idx = sq->next;
1935 do {
1936 if (0)
1937 VG_(printf)("idx=%d si_signo=%d inset=%d\n", idx,
sewardj738856f2009-07-15 14:48:32 +00001938 sq->sigs[idx].si_signo,
1939 VG_(sigismember)(set, sq->sigs[idx].si_signo));
jsgf855d93d2003-10-13 22:26:55 +00001940
sewardj738856f2009-07-15 14:48:32 +00001941 if (sq->sigs[idx].si_signo != 0
1942 && VG_(sigismember)(set, sq->sigs[idx].si_signo)) {
sewardjb5f6f512005-03-10 23:59:00 +00001943 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001944 VG_(dmsg)("Returning queued signal %d (idx %d) for thread %d\n",
1945 sq->sigs[idx].si_signo, idx, tid);
sewardjb5f6f512005-03-10 23:59:00 +00001946 ret = &sq->sigs[idx];
1947 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001948 }
1949
sewardjb5f6f512005-03-10 23:59:00 +00001950 idx = (idx + 1) % N_QUEUED_SIGNALS;
1951 } while(idx != sq->next);
1952 out:
sewardj489bfec2006-10-17 02:00:29 +00001953 return ret;
jsgf855d93d2003-10-13 22:26:55 +00001954}
1955
njn3b6b2aa2009-04-30 03:30:09 +00001956static int sanitize_si_code(int si_code)
1957{
1958#if defined(VGO_linux)
1959 /* The linux kernel uses the top 16 bits of si_code for it's own
1960 use and only exports the bottom 16 bits to user space - at least
1961 that is the theory, but it turns out that there are some kernels
1962 around that forget to mask out the top 16 bits so we do it here.
1963
1964 The kernel treats the bottom 16 bits as signed and (when it does
1965 mask them off) sign extends them when exporting to user space so
1966 we do the same thing here. */
1967 return (Short)si_code;
njnf76d27a2009-05-28 01:53:07 +00001968#elif defined(VGO_aix5) || defined(VGO_darwin)
njn3b6b2aa2009-04-30 03:30:09 +00001969 return si_code;
njn52040a42009-04-30 04:00:13 +00001970#else
1971# error Unknown OS
njn3b6b2aa2009-04-30 03:30:09 +00001972#endif
1973}
1974
jsgf855d93d2003-10-13 22:26:55 +00001975/*
sewardjb5f6f512005-03-10 23:59:00 +00001976 Receive an async signal from the kernel.
jsgf855d93d2003-10-13 22:26:55 +00001977
sewardjb5f6f512005-03-10 23:59:00 +00001978 This should only happen when the thread is blocked in a syscall,
1979 since that's the only time this set of signals is unblocked.
jsgf855d93d2003-10-13 22:26:55 +00001980*/
1981static
njn5a350be2009-04-30 03:05:05 +00001982void async_signalhandler ( Int sigNo,
1983 vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00001984{
njn5a350be2009-04-30 03:05:05 +00001985 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
1986 ThreadState* tst = VG_(get_ThreadState)(tid);
njncda2f0f2009-05-18 02:12:08 +00001987 SysRes sres;
jsgf855d93d2003-10-13 22:26:55 +00001988
njn5a350be2009-04-30 03:05:05 +00001989 /* The thread isn't currently running, make it so before going on */
1990 vg_assert(tst->status == VgTs_WaitSys);
1991 VG_(acquire_BigLock)(tid, "async_signalhandler");
1992
njn3b6b2aa2009-04-30 03:30:09 +00001993 info->si_code = sanitize_si_code(info->si_code);
tom9f4a7bf2005-11-13 00:01:20 +00001994
sewardjb5f6f512005-03-10 23:59:00 +00001995 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001996 VG_(dmsg)("async signal handler: signal=%d, tid=%d, si_code=%d\n",
1997 sigNo, tid, info->si_code);
sewardjb5f6f512005-03-10 23:59:00 +00001998
njncda2f0f2009-05-18 02:12:08 +00001999 /* Update thread state properly. The signal can only have been
2000 delivered whilst we were in
2001 coregrind/m_syswrap/syscall-<PLAT>.S, and only then in the
2002 window between the two sigprocmask calls, since at all other
2003 times, we run with async signals on the host blocked. Hence
2004 make enquiries on the basis that we were in or very close to a
2005 syscall, and attempt to fix up the guest state accordingly.
2006
2007 (normal async signals occurring during computation are blocked,
2008 but periodically polled for using VG_(sigtimedwait_zero), and
2009 delivered at a point convenient for us. Hence this routine only
2010 deals with signals that are delivered to a thread during a
2011 syscall.) */
2012
2013 /* First, extract a SysRes from the ucontext_t* given to this
2014 handler. If it is subsequently established by
2015 VG_(fixup_guest_state_after_syscall_interrupted) that the
2016 syscall was complete but the results had not been committed yet
2017 to the guest state, then it'll have to commit the results itself
2018 "by hand", and so we need to extract the SysRes. Of course if
2019 the thread was not in that particular window then the
2020 SysRes will be meaningless, but that's OK too because
2021 VG_(fixup_guest_state_after_syscall_interrupted) will detect
2022 that the thread was not in said window and ignore the SysRes. */
2023
njnf76d27a2009-05-28 01:53:07 +00002024 /* To make matters more complex still, on Darwin we need to know
2025 the "class" of the syscall under consideration in order to be
2026 able to extract the a correct SysRes. The class will have been
2027 saved just before the syscall, by VG_(client_syscall), into this
2028 thread's tst->arch.vex.guest_SC_CLASS. Hence: */
2029# if defined(VGO_darwin)
2030 sres = VG_UCONTEXT_SYSCALL_SYSRES(uc, tst->arch.vex.guest_SC_CLASS);
2031# else
njncda2f0f2009-05-18 02:12:08 +00002032 sres = VG_UCONTEXT_SYSCALL_SYSRES(uc);
njnf76d27a2009-05-28 01:53:07 +00002033# endif
njncda2f0f2009-05-18 02:12:08 +00002034
2035 /* (1) */
sewardja8d8e232005-06-07 20:04:56 +00002036 VG_(fixup_guest_state_after_syscall_interrupted)(
2037 tid,
njnaf839f52005-06-23 03:27:57 +00002038 VG_UCONTEXT_INSTR_PTR(uc),
njncda2f0f2009-05-18 02:12:08 +00002039 sres,
sewardja8d8e232005-06-07 20:04:56 +00002040 !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
2041 );
sewardjb5f6f512005-03-10 23:59:00 +00002042
njncda2f0f2009-05-18 02:12:08 +00002043 /* (2) */
sewardjb5f6f512005-03-10 23:59:00 +00002044 /* Set up the thread's state to deliver a signal */
njn07ef6c02005-05-18 19:43:09 +00002045 if (!is_sig_ign(info->si_signo))
tomadacaf92007-12-21 10:24:24 +00002046 deliver_signal(tid, info, uc);
sewardjb5f6f512005-03-10 23:59:00 +00002047
njncda2f0f2009-05-18 02:12:08 +00002048 /* It's crucial that (1) and (2) happen in the order (1) then (2)
2049 and not the other way around. (1) fixes up the guest thread
2050 state to reflect the fact that the syscall was interrupted --
2051 either to restart the syscall or to return EINTR. (2) then sets
2052 up the thread state to deliver the signal. Then we resume
2053 execution. First, the signal handler is run, since that's the
2054 second adjustment we made to the thread state. If that returns,
2055 then we resume at the guest state created by (1), viz, either
2056 the syscall returns EINTR or is restarted.
2057
2058 If (2) was done before (1) the outcome would be completely
2059 different, and wrong. */
2060
sewardjb5f6f512005-03-10 23:59:00 +00002061 /* longjmp back to the thread's main loop to start executing the
2062 handler. */
njn06244e72005-06-21 22:27:19 +00002063 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002064
njn5a350be2009-04-30 03:05:05 +00002065 VG_(core_panic)("async_signalhandler: got unexpected signal "
2066 "while outside of scheduler");
jsgf855d93d2003-10-13 22:26:55 +00002067}
2068
sewardjb5f6f512005-03-10 23:59:00 +00002069/* Extend the stack to cover addr. maxsize is the limit the stack can grow to.
2070
2071 Returns True on success, False on failure.
2072
2073 Succeeds without doing anything if addr is already within a segment.
2074
2075 Failure could be caused by:
2076 - addr not below a growable segment
2077 - new stack size would exceed maxsize
2078 - mmap failed for some other reason
2079 */
2080Bool VG_(extend_stack)(Addr addr, UInt maxsize)
2081{
sewardj45f4e7c2005-09-27 19:20:21 +00002082 SizeT udelta;
sewardjb5f6f512005-03-10 23:59:00 +00002083
2084 /* Find the next Segment above addr */
sewardj489bfec2006-10-17 02:00:29 +00002085 NSegment const* seg
2086 = VG_(am_find_nsegment)(addr);
2087 NSegment const* seg_next
2088 = seg ? VG_(am_next_nsegment)( (NSegment*)seg, True/*fwds*/ )
2089 : NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00002090
2091 if (seg && seg->kind == SkAnonC)
2092 /* addr is already mapped. Nothing to do. */
sewardjb5f6f512005-03-10 23:59:00 +00002093 return True;
2094
sewardj45f4e7c2005-09-27 19:20:21 +00002095 /* Check that the requested new base is in a shrink-down
2096 reservation section which abuts an anonymous mapping that
2097 belongs to the client. */
2098 if ( ! (seg
2099 && seg->kind == SkResvn
2100 && seg->smode == SmUpper
2101 && seg_next
2102 && seg_next->kind == SkAnonC
2103 && seg->end+1 == seg_next->start))
sewardjb5f6f512005-03-10 23:59:00 +00002104 return False;
2105
sewardj45f4e7c2005-09-27 19:20:21 +00002106 udelta = VG_PGROUNDUP(seg_next->start - addr);
2107 VG_(debugLog)(1, "signals",
2108 "extending a stack base 0x%llx down by %lld\n",
2109 (ULong)seg_next->start, (ULong)udelta);
2110 if (! VG_(am_extend_into_adjacent_reservation_client)
sewardj489bfec2006-10-17 02:00:29 +00002111 ( (NSegment*)seg_next, -(SSizeT)udelta )) {
sewardj45f4e7c2005-09-27 19:20:21 +00002112 VG_(debugLog)(1, "signals", "extending a stack base: FAILED\n");
sewardjb5f6f512005-03-10 23:59:00 +00002113 return False;
sewardj45f4e7c2005-09-27 19:20:21 +00002114 }
sewardjb5f6f512005-03-10 23:59:00 +00002115
rjwalsh0140af52005-06-04 20:42:33 +00002116 /* When we change the main stack, we have to let the stack handling
2117 code know about it. */
sewardj45f4e7c2005-09-27 19:20:21 +00002118 VG_(change_stack)(VG_(clstk_id), addr, VG_(clstk_end));
sewardjb5f6f512005-03-10 23:59:00 +00002119
2120 if (VG_(clo_sanity_level) > 2)
2121 VG_(sanity_check_general)(False);
2122
2123 return True;
2124}
2125
sewardj489bfec2006-10-17 02:00:29 +00002126static void (*fault_catcher)(Int sig, Addr addr) = NULL;
sewardjb5f6f512005-03-10 23:59:00 +00002127
2128void VG_(set_fault_catcher)(void (*catcher)(Int, Addr))
2129{
sewardj489bfec2006-10-17 02:00:29 +00002130 if (0)
2131 VG_(debugLog)(0, "signals", "set fault catcher to %p\n", catcher);
njn50ae1a72005-04-08 23:28:23 +00002132 vg_assert2(NULL == catcher || NULL == fault_catcher,
2133 "Fault catcher is already registered");
sewardjb5f6f512005-03-10 23:59:00 +00002134
2135 fault_catcher = catcher;
2136}
2137
njn96986052009-04-30 07:41:24 +00002138static
njn2d5ff4f2009-05-03 22:53:19 +00002139void sync_signalhandler_from_user ( ThreadId tid,
njn96986052009-04-30 07:41:24 +00002140 Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
2141{
2142 ThreadId qtid;
2143
njn2d5ff4f2009-05-03 22:53:19 +00002144 /* If some user-process sent us a sync signal (ie. it's not the result
njn96986052009-04-30 07:41:24 +00002145 of a faulting instruction), then how we treat it depends on when it
2146 arrives... */
2147
2148 if (VG_(threads)[tid].status == VgTs_WaitSys) {
2149 /* Signal arrived while we're blocked in a syscall. This means that
2150 the client's signal mask was applied. In other words, so we can't
2151 get here unless the client wants this signal right now. This means
2152 we can simply use the async_signalhandler. */
2153 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002154 VG_(dmsg)("Delivering user-sent sync signal %d as async signal\n",
2155 sigNo);
njn96986052009-04-30 07:41:24 +00002156
2157 async_signalhandler(sigNo, info, uc);
2158 VG_(core_panic)("async_signalhandler returned!?\n");
2159
2160 } else {
2161 /* Signal arrived while in generated client code, or while running
2162 Valgrind core code. That means that every thread has these signals
2163 unblocked, so we can't rely on the kernel to route them properly, so
2164 we need to queue them manually. */
2165 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002166 VG_(dmsg)("Routing user-sent sync signal %d via queue\n", sigNo);
njn96986052009-04-30 07:41:24 +00002167
2168# if defined(VGO_linux)
2169 /* On Linux, first we have to do a sanity check of the siginfo. */
2170 if (info->VKI_SIGINFO_si_pid == 0) {
2171 /* There's a per-user limit of pending siginfo signals. If
2172 you exceed this, by having more than that number of
2173 pending signals with siginfo, then new signals are
2174 delivered without siginfo. This condition can be caused
2175 by any unrelated program you're running at the same time
2176 as Valgrind, if it has a large number of pending siginfo
2177 signals which it isn't taking delivery of.
2178
2179 Since we depend on siginfo to work out why we were sent a
2180 signal and what we should do about it, we really can't
2181 continue unless we get it. */
sewardj738856f2009-07-15 14:48:32 +00002182 VG_(umsg)("Signal %d (%s) appears to have lost its siginfo; "
2183 "I can't go on.\n", sigNo, signame(sigNo));
njn96986052009-04-30 07:41:24 +00002184 VG_(printf)(
2185" This may be because one of your programs has consumed your ration of\n"
2186" siginfo structures. For more information, see:\n"
2187" http://kerneltrap.org/mailarchive/1/message/25599/thread\n"
2188" Basically, some program on your system is building up a large queue of\n"
2189" pending signals, and this causes the siginfo data for other signals to\n"
2190" be dropped because it's exceeding a system limit. However, Valgrind\n"
2191" absolutely needs siginfo for SIGSEGV. A workaround is to track down the\n"
2192" offending program and avoid running it while using Valgrind, but there\n"
2193" is no easy way to do this. Apparently the problem was fixed in kernel\n"
2194" 2.6.12.\n");
2195
2196 /* It's a fatal signal, so we force the default handler. */
2197 VG_(set_default_handler)(sigNo);
2198 deliver_signal(tid, info, uc);
2199 resume_scheduler(tid);
2200 VG_(exit)(99); /* If we can't resume, then just exit */
2201 }
2202# endif
2203
2204 qtid = 0; /* shared pending by default */
2205# if defined(VGO_linux)
2206 if (info->si_code == VKI_SI_TKILL)
2207 qtid = tid; /* directed to us specifically */
2208# endif
2209 queue_signal(qtid, info);
2210 }
2211}
2212
2213/* Returns True if the sync signal was due to the stack requiring extension
2214 and the extension was successful.
2215*/
2216static Bool extend_stack_if_appropriate(ThreadId tid, vki_siginfo_t* info)
2217{
2218 Addr fault;
2219 Addr esp;
2220 NSegment const* seg;
2221 NSegment const* seg_next;
2222
2223 if (info->si_signo != VKI_SIGSEGV)
2224 return False;
2225
2226 fault = (Addr)info->VKI_SIGINFO_si_addr;
2227 esp = VG_(get_SP)(tid);
2228 seg = VG_(am_find_nsegment)(fault);
2229 seg_next = seg ? VG_(am_next_nsegment)( (NSegment*)seg, True/*fwds*/ )
2230 : NULL;
2231
2232 if (VG_(clo_trace_signals)) {
2233 if (seg == NULL)
sewardj738856f2009-07-15 14:48:32 +00002234 VG_(dmsg)("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
2235 "seg=NULL\n",
2236 info->si_code, fault, tid, esp);
njn96986052009-04-30 07:41:24 +00002237 else
sewardj738856f2009-07-15 14:48:32 +00002238 VG_(dmsg)("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
2239 "seg=%#lx-%#lx\n",
2240 info->si_code, fault, tid, esp, seg->start, seg->end);
njn96986052009-04-30 07:41:24 +00002241 }
2242
2243 if (info->si_code == VKI_SEGV_MAPERR
2244 && seg
2245 && seg->kind == SkResvn
2246 && seg->smode == SmUpper
2247 && seg_next
2248 && seg_next->kind == SkAnonC
2249 && seg->end+1 == seg_next->start
2250 && fault >= (esp - VG_STACK_REDZONE_SZB)) {
2251 /* If the fault address is above esp but below the current known
2252 stack segment base, and it was a fault because there was
2253 nothing mapped there (as opposed to a permissions fault),
2254 then extend the stack segment.
2255 */
2256 Addr base = VG_PGROUNDDN(esp - VG_STACK_REDZONE_SZB);
2257 if (VG_(extend_stack)(base, VG_(threads)[tid].client_stack_szB)) {
2258 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002259 VG_(dmsg)(" -> extended stack base to %#lx\n",
2260 VG_PGROUNDDN(fault));
njn96986052009-04-30 07:41:24 +00002261 return True;
2262 } else {
sewardj738856f2009-07-15 14:48:32 +00002263 VG_(umsg)("Stack overflow in thread %d: can't grow stack to %#lx\n",
2264 tid, fault);
njn96986052009-04-30 07:41:24 +00002265 return False;
2266 }
2267 } else {
2268 return False;
2269 }
2270}
2271
2272static
njn2d5ff4f2009-05-03 22:53:19 +00002273void sync_signalhandler_from_kernel ( ThreadId tid,
njn96986052009-04-30 07:41:24 +00002274 Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
2275{
2276 /* Check to see if some part of Valgrind itself is interested in faults.
2277 The fault catcher should never be set whilst we're in generated code, so
2278 check for that. AFAIK the only use of the catcher right now is
2279 memcheck's leak detector. */
2280 if (fault_catcher) {
2281 vg_assert(VG_(in_generated_code) == False);
2282
2283 (*fault_catcher)(sigNo, (Addr)info->VKI_SIGINFO_si_addr);
2284 /* If the catcher returns, then it didn't handle the fault,
2285 so carry on panicking. */
2286 }
2287
2288 if (extend_stack_if_appropriate(tid, info)) {
2289 /* Stack extension occurred, so we don't need to do anything else; upon
2290 returning from this function, we'll restart the host (hence guest)
2291 instruction. */
2292 } else {
2293 /* OK, this is a signal we really have to deal with. If it came
2294 from the client's code, then we can jump back into the scheduler
2295 and have it delivered. Otherwise it's a Valgrind bug. */
2296 ThreadState *tst = VG_(get_ThreadState)(tid);
2297
2298 if (VG_(sigismember)(&tst->sig_mask, sigNo)) {
2299 /* signal is blocked, but they're not allowed to block faults */
2300 VG_(set_default_handler)(sigNo);
2301 }
2302
2303 if (VG_(in_generated_code)) {
2304 /* Can't continue; must longjmp back to the scheduler and thus
2305 enter the sighandler immediately. */
2306 deliver_signal(tid, info, uc);
2307 resume_scheduler(tid);
2308 }
2309
2310 /* If resume_scheduler returns or its our fault, it means we
2311 don't have longjmp set up, implying that we weren't running
2312 client code, and therefore it was actually generated by
2313 Valgrind internally.
2314 */
sewardj738856f2009-07-15 14:48:32 +00002315 VG_(dmsg)("VALGRIND INTERNAL ERROR: Valgrind received "
2316 "a signal %d (%s) - exiting\n",
2317 sigNo, signame(sigNo));
njn96986052009-04-30 07:41:24 +00002318
sewardj738856f2009-07-15 14:48:32 +00002319 VG_(dmsg)("si_code=%x; Faulting address: %p; sp: %#lx\n",
2320 info->si_code, info->VKI_SIGINFO_si_addr,
2321 VG_UCONTEXT_STACK_PTR(uc));
njn96986052009-04-30 07:41:24 +00002322
2323 if (0)
2324 VG_(kill_self)(sigNo); /* generate a core dump */
2325
2326 //if (tid == 0) /* could happen after everyone has exited */
2327 // tid = VG_(master_tid);
2328 vg_assert(tid != 0);
2329
sewardj59570ff2010-01-01 11:59:33 +00002330 UnwindStartRegs startRegs;
2331 VG_(memset)(&startRegs, 0, sizeof(startRegs));
2332
2333 VG_UCONTEXT_TO_UnwindStartRegs(&startRegs, uc);
2334 VG_(core_panic_at)("Killed by fatal signal", &startRegs);
njn96986052009-04-30 07:41:24 +00002335 }
2336}
sewardjb5f6f512005-03-10 23:59:00 +00002337
jsgf855d93d2003-10-13 22:26:55 +00002338/*
sewardj2a99cf62004-11-24 10:44:19 +00002339 Receive a sync signal from the host.
jsgf855d93d2003-10-13 22:26:55 +00002340*/
2341static
njn5a350be2009-04-30 03:05:05 +00002342void sync_signalhandler ( Int sigNo,
2343 vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00002344{
sewardj42781722006-12-17 19:36:06 +00002345 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
njn2d5ff4f2009-05-03 22:53:19 +00002346 Bool from_user;
jsgf855d93d2003-10-13 22:26:55 +00002347
njn5a350be2009-04-30 03:05:05 +00002348 if (0)
2349 VG_(printf)("sync_sighandler(%d, %p, %p)\n", sigNo, info, uc);
2350
jsgf855d93d2003-10-13 22:26:55 +00002351 vg_assert(info != NULL);
2352 vg_assert(info->si_signo == sigNo);
2353 vg_assert(sigNo == VKI_SIGSEGV ||
2354 sigNo == VKI_SIGBUS ||
2355 sigNo == VKI_SIGFPE ||
sewardjb5f6f512005-03-10 23:59:00 +00002356 sigNo == VKI_SIGILL ||
2357 sigNo == VKI_SIGTRAP);
jsgf855d93d2003-10-13 22:26:55 +00002358
njn3b6b2aa2009-04-30 03:30:09 +00002359 info->si_code = sanitize_si_code(info->si_code);
tom9f4a7bf2005-11-13 00:01:20 +00002360
njnf76d27a2009-05-28 01:53:07 +00002361 from_user = !is_signal_from_kernel(tid, sigNo, info->si_code);
njn81f52d12009-04-30 03:49:06 +00002362
2363 if (VG_(clo_trace_signals)) {
sewardj738856f2009-07-15 14:48:32 +00002364 VG_(dmsg)("sync signal handler: "
2365 "signal=%d, si_code=%d, EIP=%#lx, eip=%#lx, from %s\n",
2366 sigNo, info->si_code, VG_(get_IP)(tid),
2367 VG_UCONTEXT_INSTR_PTR(uc),
2368 ( from_user ? "user" : "kernel" ));
njn81f52d12009-04-30 03:49:06 +00002369 }
2370 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
2371
njn36fce1b2009-04-28 01:55:01 +00002372 /* // debug code:
2373 if (0) {
2374 VG_(printf)("info->si_signo %d\n", info->si_signo);
2375 VG_(printf)("info->si_errno %d\n", info->si_errno);
2376 VG_(printf)("info->si_code %d\n", info->si_code);
2377 VG_(printf)("info->si_pid %d\n", info->si_pid);
2378 VG_(printf)("info->si_uid %d\n", info->si_uid);
2379 VG_(printf)("info->si_status %d\n", info->si_status);
2380 VG_(printf)("info->si_addr %p\n", info->si_addr);
2381 }
2382 */
2383
2384 /* Figure out if the signal is being sent from outside the process.
2385 (Why do we care?) If the signal is from the user rather than the
njn96986052009-04-30 07:41:24 +00002386 kernel, then treat it more like an async signal than a sync signal --
njn36fce1b2009-04-28 01:55:01 +00002387 that is, merely queue it for later delivery. */
njn2d5ff4f2009-05-03 22:53:19 +00002388 if (from_user) {
njnc8a91072009-05-20 06:51:11 +00002389 sync_signalhandler_from_user( tid, sigNo, info, uc);
njn96986052009-04-30 07:41:24 +00002390 } else {
njnc8a91072009-05-20 06:51:11 +00002391 sync_signalhandler_from_kernel(tid, sigNo, info, uc);
jsgf855d93d2003-10-13 22:26:55 +00002392 }
2393}
2394
2395
2396/*
sewardjb5f6f512005-03-10 23:59:00 +00002397 Kill this thread. Makes it leave any syscall it might be currently
2398 blocked in, and return to the scheduler. This doesn't mark the thread
2399 as exiting; that's the caller's job.
jsgf855d93d2003-10-13 22:26:55 +00002400 */
njn5a350be2009-04-30 03:05:05 +00002401static void sigvgkill_handler(int signo, vki_siginfo_t *si,
2402 struct vki_ucontext *uc)
jsgf855d93d2003-10-13 22:26:55 +00002403{
sewardj42781722006-12-17 19:36:06 +00002404 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
sewardj489bfec2006-10-17 02:00:29 +00002405 ThreadStatus at_signal = VG_(threads)[tid].status;
sewardjb5f6f512005-03-10 23:59:00 +00002406
2407 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002408 VG_(dmsg)("sigvgkill for lwp %d tid %d\n", VG_(gettid)(), tid);
sewardj489bfec2006-10-17 02:00:29 +00002409
sewardjad0a3a82006-12-17 18:58:55 +00002410 VG_(acquire_BigLock)(tid, "sigvgkill_handler");
sewardjb5f6f512005-03-10 23:59:00 +00002411
njn351d0062005-06-21 22:23:59 +00002412 vg_assert(signo == VG_SIGVGKILL);
jsgf855d93d2003-10-13 22:26:55 +00002413 vg_assert(si->si_signo == signo);
2414
sewardj489bfec2006-10-17 02:00:29 +00002415 /* jrs 2006 August 3: the following assertion seems incorrect to
2416 me, and fails on AIX. sigvgkill could be sent to a thread which
2417 is runnable - see VG_(nuke_all_threads_except) in the scheduler.
2418 Hence comment these out ..
2419
2420 vg_assert(VG_(threads)[tid].status == VgTs_WaitSys);
2421 VG_(post_syscall)(tid);
2422
2423 and instead do:
2424 */
2425 if (at_signal == VgTs_WaitSys)
2426 VG_(post_syscall)(tid);
2427 /* jrs 2006 August 3 ends */
sewardjb5f6f512005-03-10 23:59:00 +00002428
njn06244e72005-06-21 22:27:19 +00002429 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002430
2431 VG_(core_panic)("sigvgkill_handler couldn't return to the scheduler\n");
sewardjde4a1d02002-03-22 01:27:54 +00002432}
2433
sewardjde4a1d02002-03-22 01:27:54 +00002434static __attribute((unused))
njncda2f0f2009-05-18 02:12:08 +00002435void pp_ksigaction ( vki_sigaction_toK_t* sa )
sewardjde4a1d02002-03-22 01:27:54 +00002436{
2437 Int i;
njn695c16e2005-03-27 03:40:28 +00002438 VG_(printf)("pp_ksigaction: handler %p, flags 0x%x, restorer %p\n",
sewardj489bfec2006-10-17 02:00:29 +00002439 sa->ksa_handler,
2440 (UInt)sa->sa_flags,
njnf76d27a2009-05-28 01:53:07 +00002441# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
2442 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
sewardj489bfec2006-10-17 02:00:29 +00002443 sa->sa_restorer
2444# else
sewardja8ffda62008-07-18 18:23:24 +00002445 (void*)0
sewardj489bfec2006-10-17 02:00:29 +00002446# endif
2447 );
njn695c16e2005-03-27 03:40:28 +00002448 VG_(printf)("pp_ksigaction: { ");
sewardjb5f6f512005-03-10 23:59:00 +00002449 for (i = 1; i <= VG_(max_signal); i++)
nethercote73b526f2004-10-31 18:48:21 +00002450 if (VG_(sigismember(&(sa->sa_mask),i)))
sewardjde4a1d02002-03-22 01:27:54 +00002451 VG_(printf)("%d ", i);
2452 VG_(printf)("}\n");
2453}
2454
jsgf855d93d2003-10-13 22:26:55 +00002455/*
sewardjb5f6f512005-03-10 23:59:00 +00002456 Force signal handler to default
jsgf855d93d2003-10-13 22:26:55 +00002457 */
sewardjb5f6f512005-03-10 23:59:00 +00002458void VG_(set_default_handler)(Int signo)
2459{
njncda2f0f2009-05-18 02:12:08 +00002460 vki_sigaction_toK_t sa;
sewardjb5f6f512005-03-10 23:59:00 +00002461
2462 sa.ksa_handler = VKI_SIG_DFL;
2463 sa.sa_flags = 0;
njnf76d27a2009-05-28 01:53:07 +00002464# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
2465 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
sewardjb5f6f512005-03-10 23:59:00 +00002466 sa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00002467# endif
sewardjb5f6f512005-03-10 23:59:00 +00002468 VG_(sigemptyset)(&sa.sa_mask);
2469
2470 VG_(do_sys_sigaction)(signo, &sa, NULL);
2471}
2472
2473/*
2474 Poll for pending signals, and set the next one up for delivery.
2475 */
2476void VG_(poll_signals)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00002477{
sewardjb5f6f512005-03-10 23:59:00 +00002478 vki_siginfo_t si, *sip;
2479 vki_sigset_t pollset;
2480 ThreadState *tst = VG_(get_ThreadState)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002481 vki_sigset_t saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002482
sewardjb5f6f512005-03-10 23:59:00 +00002483 /* look for all the signals this thread isn't blocking */
njncda2f0f2009-05-18 02:12:08 +00002484 /* pollset = ~tst->sig_mask */
2485 VG_(sigcomplementset)( &pollset, &tst->sig_mask );
jsgf855d93d2003-10-13 22:26:55 +00002486
njn444eba12005-05-12 03:47:31 +00002487 block_all_host_signals(&saved_mask); // protect signal queue
sewardjb5f6f512005-03-10 23:59:00 +00002488
2489 /* First look for any queued pending signals */
2490 sip = next_queued(tid, &pollset); /* this thread */
2491
2492 if (sip == NULL)
2493 sip = next_queued(0, &pollset); /* process-wide */
2494
2495 /* If there was nothing queued, ask the kernel for a pending signal */
sewardj489bfec2006-10-17 02:00:29 +00002496 if (sip == NULL && VG_(sigtimedwait_zero)(&pollset, &si) > 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002497 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002498 VG_(dmsg)("poll_signals: got signal %d for thread %d\n",
2499 si.si_signo, tid);
sewardjb5f6f512005-03-10 23:59:00 +00002500 sip = &si;
thughes8abf3922004-10-16 10:59:49 +00002501 }
fitzhardingee1c06d82003-10-30 07:21:44 +00002502
sewardjb5f6f512005-03-10 23:59:00 +00002503 if (sip != NULL) {
2504 /* OK, something to do; deliver it */
2505 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002506 VG_(dmsg)("Polling found signal %d for tid %d\n", sip->si_signo, tid);
njn07ef6c02005-05-18 19:43:09 +00002507 if (!is_sig_ign(sip->si_signo))
tomadacaf92007-12-21 10:24:24 +00002508 deliver_signal(tid, sip, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002509 else if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002510 VG_(dmsg)(" signal %d ignored\n", sip->si_signo);
sewardjb5f6f512005-03-10 23:59:00 +00002511
2512 sip->si_signo = 0; /* remove from signal queue, if that's
2513 where it came from */
jsgf855d93d2003-10-13 22:26:55 +00002514 }
2515
njn444eba12005-05-12 03:47:31 +00002516 restore_all_host_signals(&saved_mask);
sewardjb5f6f512005-03-10 23:59:00 +00002517}
2518
sewardj018f7622002-05-15 21:13:39 +00002519/* At startup, copy the process' real signal state to the SCSS.
2520 Whilst doing this, block all real signals. Then calculate SKSS and
2521 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00002522*/
2523void VG_(sigstartup_actions) ( void )
2524{
njncda2f0f2009-05-18 02:12:08 +00002525 Int i, ret, vKI_SIGRTMIN;
nethercote73b526f2004-10-31 18:48:21 +00002526 vki_sigset_t saved_procmask;
njncda2f0f2009-05-18 02:12:08 +00002527 vki_sigaction_fromK_t sa;
2528
2529 VG_(memset)(&scss, 0, sizeof(scss));
2530 VG_(memset)(&skss, 0, sizeof(skss));
2531
2532# if defined(VKI_SIGRTMIN)
2533 vKI_SIGRTMIN = VKI_SIGRTMIN;
2534# else
2535 vKI_SIGRTMIN = 0; /* eg Darwin */
2536# endif
sewardjde4a1d02002-03-22 01:27:54 +00002537
sewardj2e93c502002-04-12 11:12:52 +00002538 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00002539 /* Block all signals. saved_procmask remembers the previous mask,
2540 which the first thread inherits.
2541 */
njn444eba12005-05-12 03:47:31 +00002542 block_all_host_signals( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00002543
sewardj018f7622002-05-15 21:13:39 +00002544 /* Copy per-signal settings to SCSS. */
nethercote73b526f2004-10-31 18:48:21 +00002545 for (i = 1; i <= _VKI_NSIG; i++) {
sewardj018f7622002-05-15 21:13:39 +00002546 /* Get the old host action */
nethercote73b526f2004-10-31 18:48:21 +00002547 ret = VG_(sigaction)(i, NULL, &sa);
sewardj018f7622002-05-15 21:13:39 +00002548
njnea2d6fd2010-07-01 00:20:20 +00002549# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
njnf76d27a2009-05-28 01:53:07 +00002550 /* apparently we may not even ask about the disposition of these
2551 signals, let alone change them */
2552 if (ret != 0 && (i == VKI_SIGKILL || i == VKI_SIGSTOP))
2553 continue;
2554# endif
2555
sewardjb5f6f512005-03-10 23:59:00 +00002556 if (ret != 0)
2557 break;
2558
2559 /* Try setting it back to see if this signal is really
2560 available */
njncda2f0f2009-05-18 02:12:08 +00002561 if (vKI_SIGRTMIN > 0 /* it actually exists on this platform */
2562 && i >= vKI_SIGRTMIN) {
2563 vki_sigaction_toK_t tsa, sa2;
sewardjb5f6f512005-03-10 23:59:00 +00002564
njn695c16e2005-03-27 03:40:28 +00002565 tsa.ksa_handler = (void *)sync_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +00002566 tsa.sa_flags = VKI_SA_SIGINFO;
njnf76d27a2009-05-28 01:53:07 +00002567# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
2568 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
sewardjb5f6f512005-03-10 23:59:00 +00002569 tsa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00002570# endif
sewardjb5f6f512005-03-10 23:59:00 +00002571 VG_(sigfillset)(&tsa.sa_mask);
2572
2573 /* try setting it to some arbitrary handler */
2574 if (VG_(sigaction)(i, &tsa, NULL) != 0) {
2575 /* failed - not really usable */
2576 break;
2577 }
2578
njncda2f0f2009-05-18 02:12:08 +00002579 VG_(convert_sigaction_fromK_to_toK)( &sa, &sa2 );
2580 ret = VG_(sigaction)(i, &sa2, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002581 vg_assert(ret == 0);
2582 }
2583
2584 VG_(max_signal) = i;
2585
2586 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
njn8a7b41b2007-09-23 00:51:24 +00002587 VG_(printf)("snaffling handler 0x%lx for signal %d\n",
sewardj018f7622002-05-15 21:13:39 +00002588 (Addr)(sa.ksa_handler), i );
2589
njn695c16e2005-03-27 03:40:28 +00002590 scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
2591 scss.scss_per_sig[i].scss_flags = sa.sa_flags;
2592 scss.scss_per_sig[i].scss_mask = sa.sa_mask;
njncda2f0f2009-05-18 02:12:08 +00002593
2594 scss.scss_per_sig[i].scss_restorer = NULL;
njnf76d27a2009-05-28 01:53:07 +00002595# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
2596 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn695c16e2005-03-27 03:40:28 +00002597 scss.scss_per_sig[i].scss_restorer = sa.sa_restorer;
sewardj489bfec2006-10-17 02:00:29 +00002598# endif
njncda2f0f2009-05-18 02:12:08 +00002599
2600 scss.scss_per_sig[i].scss_sa_tramp = NULL;
njnf76d27a2009-05-28 01:53:07 +00002601# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
2602 scss.scss_per_sig[i].scss_sa_tramp = NULL;
2603 /*sa.sa_tramp;*/
2604 /* We can't know what it was, because Darwin's sys_sigaction
2605 doesn't tell us. */
2606# endif
sewardj018f7622002-05-15 21:13:39 +00002607 }
2608
sewardjb5f6f512005-03-10 23:59:00 +00002609 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002610 VG_(dmsg)("Max kernel-supported signal is %d\n", VG_(max_signal));
sewardjb5f6f512005-03-10 23:59:00 +00002611
jsgf855d93d2003-10-13 22:26:55 +00002612 /* Our private internal signals are treated as ignored */
njn351d0062005-06-21 22:23:59 +00002613 scss.scss_per_sig[VG_SIGVGKILL].scss_handler = VKI_SIG_IGN;
2614 scss.scss_per_sig[VG_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
2615 VG_(sigfillset)(&scss.scss_per_sig[VG_SIGVGKILL].scss_mask);
jsgf855d93d2003-10-13 22:26:55 +00002616
sewardj018f7622002-05-15 21:13:39 +00002617 /* Copy the process' signal mask into the root thread. */
sewardj1d887112005-05-30 21:44:08 +00002618 vg_assert(VG_(threads)[1].status == VgTs_Init);
2619 for (i = 2; i < VG_N_THREADS; i++)
2620 vg_assert(VG_(threads)[i].status == VgTs_Empty);
2621
2622 VG_(threads)[1].sig_mask = saved_procmask;
2623 VG_(threads)[1].tmp_sig_mask = saved_procmask;
sewardj7a61d912002-04-25 01:27:35 +00002624
sewardj018f7622002-05-15 21:13:39 +00002625 /* Calculate SKSS and apply it. This also sets the initial kernel
2626 mask we need to run with. */
nethercote9dd11512004-08-04 15:31:30 +00002627 handle_SCSS_change( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00002628
sewardjb5f6f512005-03-10 23:59:00 +00002629 /* Leave with all signals still blocked; the thread scheduler loop
2630 will set the appropriate mask at the appropriate time. */
sewardjde4a1d02002-03-22 01:27:54 +00002631}
2632
sewardjde4a1d02002-03-22 01:27:54 +00002633/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00002634/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00002635/*--------------------------------------------------------------------*/