blob: 8f4bbda42e27774f81194850753c2f238c316792 [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.
sewardj3b290482011-05-06 21:02:55 +0000194
195 Finally, if a gdb is debugging the process under valgrind,
196 the signal can be ignored if gdb tells this. So, before resuming the
197 scheduler/delivering the signal, a call to VG_(gdbserver_report_signal)
198 is done. If this returns True, the signal is delivered.
njn1ee02e32009-05-04 06:54:04 +0000199 */
200
njnc7561b92005-06-19 01:24:32 +0000201#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +0000202#include "pub_core_vki.h"
sewardj489bfec2006-10-17 02:00:29 +0000203#include "pub_core_vkiscnums.h"
sewardj45f4e7c2005-09-27 19:20:21 +0000204#include "pub_core_debuglog.h"
sewardj6c591e12011-04-11 16:17:51 +0000205#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
njnc7561b92005-06-19 01:24:32 +0000206#include "pub_core_threadstate.h"
sewardj14c7cc52007-02-25 15:08:24 +0000207#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +0000208#include "pub_core_clientstate.h"
njn2521d322005-05-08 14:45:13 +0000209#include "pub_core_aspacemgr.h"
njn634a6522005-07-02 01:59:28 +0000210#include "pub_core_debugger.h" // For VG_(start_debugger)
njnd2b17112005-04-19 04:10:25 +0000211#include "pub_core_errormgr.h"
sewardj3b290482011-05-06 21:02:55 +0000212#include "pub_core_gdbserver.h"
njn97405b22005-06-02 03:39:33 +0000213#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +0000214#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +0000215#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +0000216#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +0000217#include "pub_core_libcsignal.h"
njnf536bbb2005-06-13 04:21:38 +0000218#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +0000219#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +0000220#include "pub_core_options.h"
njnc7561b92005-06-19 01:24:32 +0000221#include "pub_core_scheduler.h"
njn0c246472005-05-31 01:00:08 +0000222#include "pub_core_signals.h"
njn24a6efb2005-06-20 03:36:51 +0000223#include "pub_core_sigframe.h" // For VG_(sigframe_create)()
njn945ed2e2005-06-24 03:28:30 +0000224#include "pub_core_stacks.h" // For VG_(change_stack)()
njn24a6efb2005-06-20 03:36:51 +0000225#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
njn9abd6082005-06-17 21:31:45 +0000226#include "pub_core_syscall.h"
njnc1b01812005-06-17 22:19:06 +0000227#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +0000228#include "pub_core_tooliface.h"
sewardjcf4ac712005-11-01 00:03:40 +0000229#include "pub_core_coredump.h"
sewardj985fabb2005-04-24 14:18:14 +0000230
njnd2b17112005-04-19 04:10:25 +0000231
sewardj018f7622002-05-15 21:13:39 +0000232/* ---------------------------------------------------------------------
233 Forwards decls.
234 ------------------------------------------------------------------ */
235
njn5a350be2009-04-30 03:05:05 +0000236static void sync_signalhandler ( Int sigNo, vki_siginfo_t *info,
237 struct vki_ucontext * );
238static void async_signalhandler ( Int sigNo, vki_siginfo_t *info,
239 struct vki_ucontext * );
240static void sigvgkill_handler ( Int sigNo, vki_siginfo_t *info,
241 struct vki_ucontext * );
sewardj018f7622002-05-15 21:13:39 +0000242
jsgf855d93d2003-10-13 22:26:55 +0000243static const Char *signame(Int sigNo);
sewardj018f7622002-05-15 21:13:39 +0000244
sewardjb5f6f512005-03-10 23:59:00 +0000245/* Maximum usable signal. */
246Int VG_(max_signal) = _VKI_NSIG;
nethercote759dda32004-08-07 18:16:56 +0000247
sewardjb5f6f512005-03-10 23:59:00 +0000248#define N_QUEUED_SIGNALS 8
nethercote759dda32004-08-07 18:16:56 +0000249
sewardjb5f6f512005-03-10 23:59:00 +0000250typedef struct SigQueue {
251 Int next;
252 vki_siginfo_t sigs[N_QUEUED_SIGNALS];
253} SigQueue;
nethercote759dda32004-08-07 18:16:56 +0000254
sewardj489bfec2006-10-17 02:00:29 +0000255/* ------ Macros for pulling stuff out of ucontexts ------ */
256
njncda2f0f2009-05-18 02:12:08 +0000257/* Q: what does VG_UCONTEXT_SYSCALL_SYSRES do? A: let's suppose the
njn5a350be2009-04-30 03:05:05 +0000258 machine context (uc) reflects the situation that a syscall had just
259 completed, quite literally -- that is, that the program counter was
260 now at the instruction following the syscall. (or we're slightly
261 downstream, but we're sure no relevant register has yet changed
njncda2f0f2009-05-18 02:12:08 +0000262 value.) Then VG_UCONTEXT_SYSCALL_SYSRES returns a SysRes reflecting
njn5a350be2009-04-30 03:05:05 +0000263 the result of the syscall; it does this by fishing relevant bits of
264 the machine state out of the uc. Of course if the program counter
265 was somewhere else entirely then the result is likely to be
njncda2f0f2009-05-18 02:12:08 +0000266 meaningless, so the caller of VG_UCONTEXT_SYSCALL_SYSRES has to be
njn5a350be2009-04-30 03:05:05 +0000267 very careful to pay attention to the results only when it is sure
268 that the said constraint on the program counter is indeed valid. */
sewardjf5f1e122010-01-02 13:24:58 +0000269
njn605f4882005-05-29 17:50:40 +0000270#if defined(VGP_x86_linux)
njnaf839f52005-06-23 03:27:57 +0000271# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.eip)
272# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp)
sewardjacaec5f2005-08-19 16:02:59 +0000273# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardja8d8e232005-06-07 20:04:56 +0000274 /* Convert the value in uc_mcontext.eax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000275 VG_(mk_SysRes_x86_linux)( (uc)->uc_mcontext.eax )
sewardj59570ff2010-01-01 11:59:33 +0000276# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
277 { (srP)->r_pc = (ULong)((uc)->uc_mcontext.eip); \
278 (srP)->r_sp = (ULong)((uc)->uc_mcontext.esp); \
279 (srP)->misc.X86.r_ebp = (uc)->uc_mcontext.ebp; \
280 }
sewardje7aa4ae2005-06-09 12:43:42 +0000281
njn605f4882005-05-29 17:50:40 +0000282#elif defined(VGP_amd64_linux)
njnaf839f52005-06-23 03:27:57 +0000283# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.rip)
284# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.rsp)
sewardjacaec5f2005-08-19 16:02:59 +0000285# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardje7aa4ae2005-06-09 12:43:42 +0000286 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000287 VG_(mk_SysRes_amd64_linux)( (uc)->uc_mcontext.rax )
sewardj59570ff2010-01-01 11:59:33 +0000288# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
289 { (srP)->r_pc = (uc)->uc_mcontext.rip; \
290 (srP)->r_sp = (uc)->uc_mcontext.rsp; \
291 (srP)->misc.AMD64.r_rbp = (uc)->uc_mcontext.rbp; \
292 }
sewardje7aa4ae2005-06-09 12:43:42 +0000293
cerion85665ca2005-06-20 15:51:07 +0000294#elif defined(VGP_ppc32_linux)
sewardja36dcfa2005-11-25 02:16:58 +0000295/* Comments from Paul Mackerras 25 Nov 05:
296
297 > I'm tracking down a problem where V's signal handling doesn't
298 > work properly on a ppc440gx running 2.4.20. The problem is that
299 > the ucontext being presented to V's sighandler seems completely
300 > bogus.
301
302 > V's kernel headers and hence ucontext layout are derived from
303 > 2.6.9. I compared include/asm-ppc/ucontext.h from 2.4.20 and
304 > 2.6.13.
305
306 > Can I just check my interpretation: the 2.4.20 one contains the
307 > uc_mcontext field in line, whereas the 2.6.13 one has a pointer
308 > to said struct? And so if V is using the 2.6.13 struct then a
309 > 2.4.20 one will make no sense to it.
310
311 Not quite... what is inline in the 2.4.20 version is a
312 sigcontext_struct, not an mcontext. The sigcontext looks like
313 this:
314
315 struct sigcontext_struct {
316 unsigned long _unused[4];
317 int signal;
318 unsigned long handler;
319 unsigned long oldmask;
320 struct pt_regs *regs;
321 };
322
323 The regs pointer of that struct ends up at the same offset as the
324 uc_regs of the 2.6 struct ucontext, and a struct pt_regs is the
325 same as the mc_gregs field of the mcontext. In fact the integer
326 regs are followed in memory by the floating point regs on 2.4.20.
327
328 Thus if you are using the 2.6 definitions, it should work on 2.4.20
329 provided that you go via uc->uc_regs rather than looking in
330 uc->uc_mcontext directly.
331
332 There is another subtlety: 2.4.20 doesn't save the vector regs when
333 delivering a signal, and 2.6.x only saves the vector regs if the
334 process has ever used an altivec instructions. If 2.6.x does save
335 the vector regs, it sets the MSR_VEC bit in
336 uc->uc_regs->mc_gregs[PT_MSR], otherwise it clears it. That bit
337 will always be clear under 2.4.20. So you can use that bit to tell
338 whether uc->uc_regs->mc_vregs is valid. */
sewardjf5f1e122010-01-02 13:24:58 +0000339# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_NIP])
340# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
sewardj39a7c1d2005-11-24 03:54:38 +0000341# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
342 /* Convert the values in uc_mcontext r3,cr into a SysRes. */ \
343 VG_(mk_SysRes_ppc32_linux)( \
sewardja36dcfa2005-11-25 02:16:58 +0000344 (uc)->uc_regs->mc_gregs[VKI_PT_R3], \
345 (((uc)->uc_regs->mc_gregs[VKI_PT_CCR] >> 28) & 1) \
sewardj39a7c1d2005-11-24 03:54:38 +0000346 )
sewardjf5f1e122010-01-02 13:24:58 +0000347# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
348 { (srP)->r_pc = (ULong)((uc)->uc_regs->mc_gregs[VKI_PT_NIP]); \
349 (srP)->r_sp = (ULong)((uc)->uc_regs->mc_gregs[VKI_PT_R1]); \
350 (srP)->misc.PPC32.r_lr = (uc)->uc_regs->mc_gregs[VKI_PT_LNK]; \
351 }
cerion85665ca2005-06-20 15:51:07 +0000352
sewardj2c48c7b2005-11-29 13:05:56 +0000353#elif defined(VGP_ppc64_linux)
sewardjf5f1e122010-01-02 13:24:58 +0000354# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_NIP])
355# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
sewardjdcb6ec82006-01-19 03:44:10 +0000356 /* Dubious hack: if there is an error, only consider the lowest 8
357 bits of r3. memcheck/tests/post-syscall shows a case where an
358 interrupted syscall should have produced a ucontext with 0x4
359 (VKI_EINTR) in r3 but is in fact producing 0x204. */
360 /* Awaiting clarification from PaulM. Evidently 0x204 is
361 ERESTART_RESTARTBLOCK, which shouldn't have made it into user
362 space. */
363 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( struct vki_ucontext* uc )
364 {
365 ULong err = (uc->uc_mcontext.gp_regs[VKI_PT_CCR] >> 28) & 1;
366 ULong r3 = uc->uc_mcontext.gp_regs[VKI_PT_R3];
367 if (err) r3 &= 0xFF;
368 return VG_(mk_SysRes_ppc64_linux)( r3, err );
369 }
sewardjf5f1e122010-01-02 13:24:58 +0000370# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
371 { (srP)->r_pc = (uc)->uc_mcontext.gp_regs[VKI_PT_NIP]; \
372 (srP)->r_sp = (uc)->uc_mcontext.gp_regs[VKI_PT_R1]; \
373 (srP)->misc.PPC64.r_lr = (uc)->uc_mcontext.gp_regs[VKI_PT_LNK]; \
374 }
sewardj2c48c7b2005-11-29 13:05:56 +0000375
sewardj59570ff2010-01-01 11:59:33 +0000376#elif defined(VGP_arm_linux)
377# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.arm_pc)
378# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.arm_sp)
379# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
380 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
381 VG_(mk_SysRes_arm_linux)( (uc)->uc_mcontext.arm_r0 )
382# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
383 { (srP)->r_pc = (uc)->uc_mcontext.arm_pc; \
384 (srP)->r_sp = (uc)->uc_mcontext.arm_sp; \
385 (srP)->misc.ARM.r14 = (uc)->uc_mcontext.arm_lr; \
386 (srP)->misc.ARM.r12 = (uc)->uc_mcontext.arm_ip; \
387 (srP)->misc.ARM.r11 = (uc)->uc_mcontext.arm_fp; \
sewardjfa5ce562010-09-23 22:05:59 +0000388 (srP)->misc.ARM.r7 = (uc)->uc_mcontext.arm_r7; \
sewardj59570ff2010-01-01 11:59:33 +0000389 }
390
sewardj489bfec2006-10-17 02:00:29 +0000391#elif defined(VGP_ppc32_aix5)
392
393 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
394# include <ucontext.h>
395 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
396 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
397 ucontext_t* uc = (ucontext_t*)ucV;
398 struct __jmpbuf* mc = &(uc->uc_mcontext);
399 struct mstsave* jc = &mc->jmp_context;
400 return jc->iar;
401 }
402 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
403 ucontext_t* uc = (ucontext_t*)ucV;
404 struct __jmpbuf* mc = &(uc->uc_mcontext);
405 struct mstsave* jc = &mc->jmp_context;
406 return jc->gpr[1];
407 }
sewardj489bfec2006-10-17 02:00:29 +0000408 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV ) {
409 ucontext_t* uc = (ucontext_t*)ucV;
410 struct __jmpbuf* mc = &(uc->uc_mcontext);
411 struct mstsave* jc = &mc->jmp_context;
412 return VG_(mk_SysRes_ppc32_aix5)( jc->gpr[3], jc->gpr[4] );
413 }
414 static inline Addr VG_UCONTEXT_LINK_REG( void* ucV ) {
415 ucontext_t* uc = (ucontext_t*)ucV;
416 struct __jmpbuf* mc = &(uc->uc_mcontext);
417 struct mstsave* jc = &mc->jmp_context;
418 return jc->lr;
419 }
420 static inline Addr VG_UCONTEXT_FRAME_PTR( void* ucV ) {
421 return VG_UCONTEXT_STACK_PTR(ucV);
422 }
423
424#elif defined(VGP_ppc64_aix5)
425
426 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
427# include <ucontext.h>
428 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
429 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
430 ucontext_t* uc = (ucontext_t*)ucV;
431 struct __jmpbuf* mc = &(uc->uc_mcontext);
432 struct __context64* jc = &mc->jmp_context;
433 return jc->iar;
434 }
435 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
436 ucontext_t* uc = (ucontext_t*)ucV;
437 struct __jmpbuf* mc = &(uc->uc_mcontext);
438 struct __context64* jc = &mc->jmp_context;
439 return jc->gpr[1];
440 }
sewardj489bfec2006-10-17 02:00:29 +0000441 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV ) {
442 ucontext_t* uc = (ucontext_t*)ucV;
443 struct __jmpbuf* mc = &(uc->uc_mcontext);
444 struct __context64* jc = &mc->jmp_context;
445 return VG_(mk_SysRes_ppc32_aix5)( jc->gpr[3], jc->gpr[4] );
446 }
447 static inline Addr VG_UCONTEXT_LINK_REG( void* ucV ) {
448 ucontext_t* uc = (ucontext_t*)ucV;
449 struct __jmpbuf* mc = &(uc->uc_mcontext);
450 struct __context64* jc = &mc->jmp_context;
451 return jc->lr;
452 }
453 static inline Addr VG_UCONTEXT_FRAME_PTR( void* ucV ) {
454 return VG_UCONTEXT_STACK_PTR(ucV);
455 }
456
njnf76d27a2009-05-28 01:53:07 +0000457#elif defined(VGP_x86_darwin)
458
459 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
460 ucontext_t* uc = (ucontext_t*)ucV;
461 struct __darwin_mcontext32* mc = uc->uc_mcontext;
462 struct __darwin_i386_thread_state* ss = &mc->__ss;
463 return ss->__eip;
464 }
465 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
466 ucontext_t* uc = (ucontext_t*)ucV;
467 struct __darwin_mcontext32* mc = uc->uc_mcontext;
468 struct __darwin_i386_thread_state* ss = &mc->__ss;
469 return ss->__esp;
470 }
471 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV,
472 UWord scclass ) {
473 /* this is complicated by the problem that there are 3 different
474 kinds of syscalls, each with its own return convention.
475 NB: scclass is a host word, hence UWord is good for both
476 amd64-darwin and x86-darwin */
477 ucontext_t* uc = (ucontext_t*)ucV;
478 struct __darwin_mcontext32* mc = uc->uc_mcontext;
479 struct __darwin_i386_thread_state* ss = &mc->__ss;
480 /* duplicates logic in m_syswrap.getSyscallStatusFromGuestState */
481 UInt carry = 1 & ss->__eflags;
482 UInt err = 0;
483 UInt wLO = 0;
484 UInt wHI = 0;
485 switch (scclass) {
486 case VG_DARWIN_SYSCALL_CLASS_UNIX:
487 err = carry;
488 wLO = ss->__eax;
489 wHI = ss->__edx;
490 break;
491 case VG_DARWIN_SYSCALL_CLASS_MACH:
492 wLO = ss->__eax;
493 break;
494 case VG_DARWIN_SYSCALL_CLASS_MDEP:
495 wLO = ss->__eax;
496 break;
497 default:
498 vg_assert(0);
499 break;
500 }
501 return VG_(mk_SysRes_x86_darwin)( scclass, err ? True : False,
502 wHI, wLO );
503 }
sewardj67b38c32010-01-01 12:44:12 +0000504 static inline
505 void VG_UCONTEXT_TO_UnwindStartRegs( UnwindStartRegs* srP,
506 void* ucV ) {
507 ucontext_t* uc = (ucontext_t*)(ucV);
njnf76d27a2009-05-28 01:53:07 +0000508 struct __darwin_mcontext32* mc = uc->uc_mcontext;
509 struct __darwin_i386_thread_state* ss = &mc->__ss;
sewardj67b38c32010-01-01 12:44:12 +0000510 srP->r_pc = (ULong)(ss->__eip);
511 srP->r_sp = (ULong)(ss->__esp);
512 srP->misc.X86.r_ebp = (UInt)(ss->__ebp);
njnf76d27a2009-05-28 01:53:07 +0000513 }
514
515#elif defined(VGP_amd64_darwin)
516
517 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
518 I_die_here;
519 }
520 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
521 I_die_here;
522 }
523 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV,
524 UWord scclass ) {
525 I_die_here;
526 }
njnea2d6fd2010-07-01 00:20:20 +0000527 static inline
528 void VG_UCONTEXT_TO_UnwindStartRegs( UnwindStartRegs* srP,
529 void* ucV ) {
njnf76d27a2009-05-28 01:53:07 +0000530 I_die_here;
531 }
532
sewardjb5b87402011-03-07 16:05:35 +0000533#elif defined(VGP_s390x_linux)
534
535# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.regs.psw.addr)
536# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.regs.gprs[15])
537# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.regs.gprs[11])
538# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
539 VG_(mk_SysRes_s390x_linux)((uc)->uc_mcontext.regs.gprs[2])
540# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_mcontext.regs.gprs[14])
541
542# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
543 { (srP)->r_pc = (ULong)((uc)->uc_mcontext.regs.psw.addr); \
544 (srP)->r_sp = (ULong)((uc)->uc_mcontext.regs.gprs[15]); \
545 (srP)->misc.S390X.r_fp = (uc)->uc_mcontext.regs.gprs[11]; \
546 (srP)->misc.S390X.r_lr = (uc)->uc_mcontext.regs.gprs[14]; \
547 }
548
549
sewardj489bfec2006-10-17 02:00:29 +0000550#else
njn605f4882005-05-29 17:50:40 +0000551# error Unknown platform
552#endif
553
sewardj489bfec2006-10-17 02:00:29 +0000554
555/* ------ Macros for pulling stuff out of siginfos ------ */
556
557/* These macros allow use of uniform names when working with
558 both the Linux and AIX vki definitions. */
559#if defined(VGO_linux)
560# define VKI_SIGINFO_si_addr _sifields._sigfault._addr
561# define VKI_SIGINFO_si_pid _sifields._kill._pid
562#elif defined(VGO_aix5)
563# define VKI_SIGINFO_si_addr si_addr
564# define VKI_SIGINFO_si_pid si_pid
njnf76d27a2009-05-28 01:53:07 +0000565#elif defined(VGO_darwin)
566# define VKI_SIGINFO_si_addr si_addr
567# define VKI_SIGINFO_si_pid si_pid
sewardj489bfec2006-10-17 02:00:29 +0000568#else
569# error Unknown OS
570#endif
571
572
nethercote759dda32004-08-07 18:16:56 +0000573/* ---------------------------------------------------------------------
sewardj018f7622002-05-15 21:13:39 +0000574 HIGH LEVEL STUFF TO DO WITH SIGNALS: POLICY (MOSTLY)
575 ------------------------------------------------------------------ */
576
sewardjde4a1d02002-03-22 01:27:54 +0000577/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000578 Signal state for this process.
579 ------------------------------------------------------------------ */
580
sewardj018f7622002-05-15 21:13:39 +0000581
nethercote73b526f2004-10-31 18:48:21 +0000582/* Base-ment of these arrays[_VKI_NSIG].
sewardjb48e5002002-05-13 00:16:03 +0000583
nethercote73b526f2004-10-31 18:48:21 +0000584 Valid signal numbers are 1 .. _VKI_NSIG inclusive.
sewardjb48e5002002-05-13 00:16:03 +0000585 Rather than subtracting 1 for indexing these arrays, which
586 is tedious and error-prone, they are simply dimensioned 1 larger,
587 and entry [0] is not used.
588 */
589
sewardjb48e5002002-05-13 00:16:03 +0000590
sewardj018f7622002-05-15 21:13:39 +0000591/* -----------------------------------------------------
592 Static client signal state (SCSS). This is the state
593 that the client thinks it has the kernel in.
594 SCSS records verbatim the client's settings. These
595 are mashed around only when SKSS is calculated from it.
596 -------------------------------------------------- */
sewardjb48e5002002-05-13 00:16:03 +0000597
sewardj018f7622002-05-15 21:13:39 +0000598typedef
599 struct {
600 void* scss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN or ptr to
601 client's handler */
602 UInt scss_flags;
nethercote73b526f2004-10-31 18:48:21 +0000603 vki_sigset_t scss_mask;
sewardjb5f6f512005-03-10 23:59:00 +0000604 void* scss_restorer; /* where sigreturn goes */
njncda2f0f2009-05-18 02:12:08 +0000605 void* scss_sa_tramp; /* sa_tramp setting, Darwin only */
606 /* re _restorer and _sa_tramp, we merely record the values
607 supplied when the client does 'sigaction' and give them back
608 when requested. Otherwise they are simply ignored. */
sewardj018f7622002-05-15 21:13:39 +0000609 }
610 SCSS_Per_Signal;
sewardjb48e5002002-05-13 00:16:03 +0000611
sewardj018f7622002-05-15 21:13:39 +0000612typedef
613 struct {
sewardj2342c972002-05-22 23:34:20 +0000614 /* per-signal info */
nethercote73b526f2004-10-31 18:48:21 +0000615 SCSS_Per_Signal scss_per_sig[1+_VKI_NSIG];
sewardj2342c972002-05-22 23:34:20 +0000616
sewardj018f7622002-05-15 21:13:39 +0000617 /* Additional elements to SCSS not stored here:
618 - for each thread, the thread's blocking mask
619 - for each thread in WaitSIG, the set of waited-on sigs
620 */
621 }
622 SCSS;
sewardjb48e5002002-05-13 00:16:03 +0000623
njn695c16e2005-03-27 03:40:28 +0000624static SCSS scss;
sewardj018f7622002-05-15 21:13:39 +0000625
626
627/* -----------------------------------------------------
628 Static kernel signal state (SKSS). This is the state
629 that we have the kernel in. It is computed from SCSS.
630 -------------------------------------------------- */
631
632/* Let's do:
633 sigprocmask assigns to all thread masks
634 so that at least everything is always consistent
635 Flags:
jsgf855d93d2003-10-13 22:26:55 +0000636 SA_SIGINFO -- we always set it, and honour it for the client
sewardj018f7622002-05-15 21:13:39 +0000637 SA_NOCLDSTOP -- passed to kernel
sewardjb5f6f512005-03-10 23:59:00 +0000638 SA_ONESHOT or SA_RESETHAND -- pass through
jsgf855d93d2003-10-13 22:26:55 +0000639 SA_RESTART -- we observe this but set our handlers to always restart
640 SA_NOMASK or SA_NODEFER -- we observe this, but our handlers block everything
sewardjb5f6f512005-03-10 23:59:00 +0000641 SA_ONSTACK -- pass through
642 SA_NOCLDWAIT -- pass through
sewardjb48e5002002-05-13 00:16:03 +0000643*/
sewardjde4a1d02002-03-22 01:27:54 +0000644
sewardj77e466c2002-04-14 02:29:29 +0000645
sewardj018f7622002-05-15 21:13:39 +0000646typedef
647 struct {
648 void* skss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN
649 or ptr to our handler */
650 UInt skss_flags;
651 /* There is no skss_mask, since we know that we will always ask
jsgf855d93d2003-10-13 22:26:55 +0000652 for all signals to be blocked in our sighandlers. */
sewardj018f7622002-05-15 21:13:39 +0000653 /* Also there is no skss_restorer. */
654 }
655 SKSS_Per_Signal;
sewardjde4a1d02002-03-22 01:27:54 +0000656
sewardj018f7622002-05-15 21:13:39 +0000657typedef
658 struct {
nethercote73b526f2004-10-31 18:48:21 +0000659 SKSS_Per_Signal skss_per_sig[1+_VKI_NSIG];
sewardj018f7622002-05-15 21:13:39 +0000660 }
661 SKSS;
662
njn695c16e2005-03-27 03:40:28 +0000663static SKSS skss;
sewardjde4a1d02002-03-22 01:27:54 +0000664
sewardj3b290482011-05-06 21:02:55 +0000665/* returns True if signal is to be ignored.
666 To check this, possibly call gdbserver with tid. */
667static Bool is_sig_ign(Int sigNo, ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +0000668{
nethercote73b526f2004-10-31 18:48:21 +0000669 vg_assert(sigNo >= 1 && sigNo <= _VKI_NSIG);
sewardj2e93c502002-04-12 11:12:52 +0000670
sewardj3b290482011-05-06 21:02:55 +0000671 return scss.scss_per_sig[sigNo].scss_handler == VKI_SIG_IGN
672 || !VG_(gdbserver_report_signal) (sigNo, tid);
jsgf855d93d2003-10-13 22:26:55 +0000673}
sewardjb48e5002002-05-13 00:16:03 +0000674
sewardj018f7622002-05-15 21:13:39 +0000675/* ---------------------------------------------------------------------
676 Compute the SKSS required by the current SCSS.
677 ------------------------------------------------------------------ */
678
sewardj4f29ddf2002-05-03 22:29:04 +0000679static
sewardj018f7622002-05-15 21:13:39 +0000680void pp_SKSS ( void )
681{
682 Int sig;
683 VG_(printf)("\n\nSKSS:\n");
nethercote73b526f2004-10-31 18:48:21 +0000684 for (sig = 1; sig <= _VKI_NSIG; sig++) {
dirk61780382007-10-01 10:33:41 +0000685 VG_(printf)("sig %d: handler %p, flags 0x%x\n", sig,
njn695c16e2005-03-27 03:40:28 +0000686 skss.skss_per_sig[sig].skss_handler,
687 skss.skss_per_sig[sig].skss_flags );
sewardj77e466c2002-04-14 02:29:29 +0000688
sewardj018f7622002-05-15 21:13:39 +0000689 }
sewardj018f7622002-05-15 21:13:39 +0000690}
691
sewardj018f7622002-05-15 21:13:39 +0000692/* This is the core, clever bit. Computation is as follows:
693
694 For each signal
695 handler = if client has a handler, then our handler
jsgf855d93d2003-10-13 22:26:55 +0000696 else if client is DFL, then our handler as well
697 else (client must be IGN)
sewardjb5f6f512005-03-10 23:59:00 +0000698 then hander is IGN
sewardj018f7622002-05-15 21:13:39 +0000699*/
700static
701void calculate_SKSS_from_SCSS ( SKSS* dst )
702{
703 Int sig;
sewardj018f7622002-05-15 21:13:39 +0000704 UInt scss_flags;
705 UInt skss_flags;
706
nethercote73b526f2004-10-31 18:48:21 +0000707 for (sig = 1; sig <= _VKI_NSIG; sig++) {
jsgf855d93d2003-10-13 22:26:55 +0000708 void *skss_handler;
709 void *scss_handler;
710
njn695c16e2005-03-27 03:40:28 +0000711 scss_handler = scss.scss_per_sig[sig].scss_handler;
712 scss_flags = scss.scss_per_sig[sig].scss_flags;
sewardj018f7622002-05-15 21:13:39 +0000713
jsgf855d93d2003-10-13 22:26:55 +0000714 switch(sig) {
715 case VKI_SIGSEGV:
716 case VKI_SIGBUS:
717 case VKI_SIGFPE:
718 case VKI_SIGILL:
sewardjb5f6f512005-03-10 23:59:00 +0000719 case VKI_SIGTRAP:
jsgf855d93d2003-10-13 22:26:55 +0000720 /* For these, we always want to catch them and report, even
721 if the client code doesn't. */
njn695c16e2005-03-27 03:40:28 +0000722 skss_handler = sync_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000723 break;
724
sewardjb5f6f512005-03-10 23:59:00 +0000725 case VKI_SIGCONT:
726 /* Let the kernel handle SIGCONT unless the client is actually
727 catching it. */
njn5a350be2009-04-30 03:05:05 +0000728 case VKI_SIGCHLD:
729 case VKI_SIGWINCH:
730 case VKI_SIGURG:
731 /* For signals which are have a default action of Ignore,
732 only set a handler if the client has set a signal handler.
733 Otherwise the kernel will interrupt a syscall which
734 wouldn't have otherwise been interrupted. */
njn695c16e2005-03-27 03:40:28 +0000735 if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_DFL)
sewardjb5f6f512005-03-10 23:59:00 +0000736 skss_handler = VKI_SIG_DFL;
njn695c16e2005-03-27 03:40:28 +0000737 else if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_IGN)
jsgf855d93d2003-10-13 22:26:55 +0000738 skss_handler = VKI_SIG_IGN;
sewardjb5f6f512005-03-10 23:59:00 +0000739 else
njn695c16e2005-03-27 03:40:28 +0000740 skss_handler = async_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000741 break;
jsgf855d93d2003-10-13 22:26:55 +0000742
sewardjb5f6f512005-03-10 23:59:00 +0000743 default:
njna530fc62005-03-13 04:46:36 +0000744 // VKI_SIGVG* are runtime variables, so we can't make them
745 // cases in the switch, so we handle them in the 'default' case.
njn351d0062005-06-21 22:23:59 +0000746 if (sig == VG_SIGVGKILL)
sewardjb5f6f512005-03-10 23:59:00 +0000747 skss_handler = sigvgkill_handler;
sewardjb5f6f512005-03-10 23:59:00 +0000748 else {
749 if (scss_handler == VKI_SIG_IGN)
750 skss_handler = VKI_SIG_IGN;
751 else
njn695c16e2005-03-27 03:40:28 +0000752 skss_handler = async_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +0000753 }
754 break;
755 }
sewardj018f7622002-05-15 21:13:39 +0000756
sewardj018f7622002-05-15 21:13:39 +0000757 /* Flags */
758
759 skss_flags = 0;
jsgf855d93d2003-10-13 22:26:55 +0000760
sewardjb5f6f512005-03-10 23:59:00 +0000761 /* SA_NOCLDSTOP, SA_NOCLDWAIT: pass to kernel */
762 skss_flags |= scss_flags & (VKI_SA_NOCLDSTOP | VKI_SA_NOCLDWAIT);
jsgf855d93d2003-10-13 22:26:55 +0000763
sewardj018f7622002-05-15 21:13:39 +0000764 /* SA_ONESHOT: ignore client setting */
sewardjb5f6f512005-03-10 23:59:00 +0000765
sewardja8d8e232005-06-07 20:04:56 +0000766 /* SA_RESTART: ignore client setting and always set it for us.
767 Though we never rely on the kernel to restart a
jsgf855d93d2003-10-13 22:26:55 +0000768 syscall, we observe whether it wanted to restart the syscall
sewardja8d8e232005-06-07 20:04:56 +0000769 or not, which is needed by
770 VG_(fixup_guest_state_after_syscall_interrupted) */
sewardj018f7622002-05-15 21:13:39 +0000771 skss_flags |= VKI_SA_RESTART;
jsgf855d93d2003-10-13 22:26:55 +0000772
773 /* SA_NOMASK: ignore it */
774
sewardj2342c972002-05-22 23:34:20 +0000775 /* SA_ONSTACK: client setting is irrelevant here */
sewardjb5f6f512005-03-10 23:59:00 +0000776 /* We don't set a signal stack, so ignore */
sewardj018f7622002-05-15 21:13:39 +0000777
jsgf855d93d2003-10-13 22:26:55 +0000778 /* always ask for SA_SIGINFO */
779 skss_flags |= VKI_SA_SIGINFO;
sewardj018f7622002-05-15 21:13:39 +0000780
fitzhardinge4f10ada2004-06-03 10:00:42 +0000781 /* use our own restorer */
782 skss_flags |= VKI_SA_RESTORER;
783
jsgf855d93d2003-10-13 22:26:55 +0000784 /* Create SKSS entry for this signal. */
sewardj6a3c26e2002-05-23 17:09:43 +0000785 if (sig != VKI_SIGKILL && sig != VKI_SIGSTOP)
786 dst->skss_per_sig[sig].skss_handler = skss_handler;
787 else
788 dst->skss_per_sig[sig].skss_handler = VKI_SIG_DFL;
789
sewardj018f7622002-05-15 21:13:39 +0000790 dst->skss_per_sig[sig].skss_flags = skss_flags;
791 }
792
793 /* Sanity checks. */
nethercote5fd72bb2004-11-04 19:28:38 +0000794 vg_assert(dst->skss_per_sig[VKI_SIGKILL].skss_handler == VKI_SIG_DFL);
795 vg_assert(dst->skss_per_sig[VKI_SIGSTOP].skss_handler == VKI_SIG_DFL);
sewardj018f7622002-05-15 21:13:39 +0000796
797 if (0)
798 pp_SKSS();
799}
800
801
802/* ---------------------------------------------------------------------
803 After a possible SCSS change, update SKSS and the kernel itself.
804 ------------------------------------------------------------------ */
805
njn9abd6082005-06-17 21:31:45 +0000806// We need two levels of macro-expansion here to convert __NR_rt_sigreturn
807// to a number before converting it to a string... sigh.
sewardj03d8aa82005-10-14 11:25:49 +0000808extern void my_sigreturn(void);
njn9abd6082005-06-17 21:31:45 +0000809
810#if defined(VGP_x86_linux)
njn5a350be2009-04-30 03:05:05 +0000811# define _MY_SIGRETURN(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000812 ".text\n" \
njn9abd6082005-06-17 21:31:45 +0000813 "my_sigreturn:\n" \
814 " movl $" #name ", %eax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000815 " int $0x80\n" \
816 ".previous\n"
sewardj59570ff2010-01-01 11:59:33 +0000817
njn9abd6082005-06-17 21:31:45 +0000818#elif defined(VGP_amd64_linux)
njn5a350be2009-04-30 03:05:05 +0000819# define _MY_SIGRETURN(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000820 ".text\n" \
njn9abd6082005-06-17 21:31:45 +0000821 "my_sigreturn:\n" \
822 " movq $" #name ", %rax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000823 " syscall\n" \
824 ".previous\n"
sewardj59570ff2010-01-01 11:59:33 +0000825
cerion85665ca2005-06-20 15:51:07 +0000826#elif defined(VGP_ppc32_linux)
njn5a350be2009-04-30 03:05:05 +0000827# define _MY_SIGRETURN(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000828 ".text\n" \
cerion85665ca2005-06-20 15:51:07 +0000829 "my_sigreturn:\n" \
830 " li 0, " #name "\n" \
sewardj2fedc642005-11-19 02:02:57 +0000831 " sc\n" \
832 ".previous\n"
sewardj59570ff2010-01-01 11:59:33 +0000833
sewardj2c48c7b2005-11-29 13:05:56 +0000834#elif defined(VGP_ppc64_linux)
njn5a350be2009-04-30 03:05:05 +0000835# define _MY_SIGRETURN(name) \
cerion297c88f2005-12-22 15:53:12 +0000836 ".align 2\n" \
837 ".globl my_sigreturn\n" \
838 ".section \".opd\",\"aw\"\n" \
839 ".align 3\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000840 "my_sigreturn:\n" \
cerion297c88f2005-12-22 15:53:12 +0000841 ".quad .my_sigreturn,.TOC.@tocbase,0\n" \
842 ".previous\n" \
843 ".type .my_sigreturn,@function\n" \
844 ".globl .my_sigreturn\n" \
845 ".my_sigreturn:\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000846 " li 0, " #name "\n" \
cerion297c88f2005-12-22 15:53:12 +0000847 " sc\n"
sewardj59570ff2010-01-01 11:59:33 +0000848
849#elif defined(VGP_arm_linux)
850# define _MY_SIGRETURN(name) \
851 ".text\n" \
852 "my_sigreturn:\n\t" \
853 " mov r7, #" #name "\n\t" \
854 " svc 0x00000000\n" \
855 ".previous\n"
856
sewardj489bfec2006-10-17 02:00:29 +0000857#elif defined(VGP_ppc32_aix5)
njn5a350be2009-04-30 03:05:05 +0000858# define _MY_SIGRETURN(name) \
sewardj489bfec2006-10-17 02:00:29 +0000859 ".globl my_sigreturn\n" \
860 "my_sigreturn:\n" \
861 ".long 0\n"
862#elif defined(VGP_ppc64_aix5)
njn5a350be2009-04-30 03:05:05 +0000863# define _MY_SIGRETURN(name) \
sewardj489bfec2006-10-17 02:00:29 +0000864 ".globl my_sigreturn\n" \
865 "my_sigreturn:\n" \
866 ".long 0\n"
sewardj59570ff2010-01-01 11:59:33 +0000867
njnf76d27a2009-05-28 01:53:07 +0000868#elif defined(VGP_x86_darwin)
869# define _MY_SIGRETURN(name) \
870 ".text\n" \
871 "my_sigreturn:\n" \
872 "movl $" VG_STRINGIFY(__NR_DARWIN_FAKE_SIGRETURN) ",%eax\n" \
873 "int $0x80"
sewardj59570ff2010-01-01 11:59:33 +0000874
njnf76d27a2009-05-28 01:53:07 +0000875#elif defined(VGP_amd64_darwin)
876 // DDD: todo
877# define _MY_SIGRETURN(name) \
878 ".text\n" \
879 "my_sigreturn:\n" \
880 "ud2\n"
sewardj59570ff2010-01-01 11:59:33 +0000881
sewardjb5b87402011-03-07 16:05:35 +0000882#elif defined(VGP_s390x_linux)
883# define _MY_SIGRETURN(name) \
884 ".text\n" \
885 "my_sigreturn:\n" \
886 " svc " #name "\n" \
887 ".previous\n"
888
njn9abd6082005-06-17 21:31:45 +0000889#else
890# error Unknown platform
891#endif
892
njn5a350be2009-04-30 03:05:05 +0000893#define MY_SIGRETURN(name) _MY_SIGRETURN(name)
njn9abd6082005-06-17 21:31:45 +0000894asm(
njn5a350be2009-04-30 03:05:05 +0000895 MY_SIGRETURN(__NR_rt_sigreturn)
njn9abd6082005-06-17 21:31:45 +0000896);
897
898
nethercote9dd11512004-08-04 15:31:30 +0000899static void handle_SCSS_change ( Bool force_update )
sewardj018f7622002-05-15 21:13:39 +0000900{
nethercote73b526f2004-10-31 18:48:21 +0000901 Int res, sig;
902 SKSS skss_old;
njncda2f0f2009-05-18 02:12:08 +0000903 vki_sigaction_toK_t ksa;
904 vki_sigaction_fromK_t ksa_old;
sewardj018f7622002-05-15 21:13:39 +0000905
sewardj018f7622002-05-15 21:13:39 +0000906 /* Remember old SKSS and calculate new one. */
njn695c16e2005-03-27 03:40:28 +0000907 skss_old = skss;
908 calculate_SKSS_from_SCSS ( &skss );
sewardj018f7622002-05-15 21:13:39 +0000909
910 /* Compare the new SKSS entries vs the old ones, and update kernel
911 where they differ. */
sewardjb5f6f512005-03-10 23:59:00 +0000912 for (sig = 1; sig <= VG_(max_signal); sig++) {
sewardj018f7622002-05-15 21:13:39 +0000913
914 /* Trying to do anything with SIGKILL is pointless; just ignore
915 it. */
916 if (sig == VKI_SIGKILL || sig == VKI_SIGSTOP)
917 continue;
918
sewardj018f7622002-05-15 21:13:39 +0000919 if (!force_update) {
920 if ((skss_old.skss_per_sig[sig].skss_handler
njn695c16e2005-03-27 03:40:28 +0000921 == skss.skss_per_sig[sig].skss_handler)
sewardj018f7622002-05-15 21:13:39 +0000922 && (skss_old.skss_per_sig[sig].skss_flags
njn695c16e2005-03-27 03:40:28 +0000923 == skss.skss_per_sig[sig].skss_flags))
sewardj018f7622002-05-15 21:13:39 +0000924 /* no difference */
925 continue;
926 }
927
njn695c16e2005-03-27 03:40:28 +0000928 ksa.ksa_handler = skss.skss_per_sig[sig].skss_handler;
929 ksa.sa_flags = skss.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)
njn9abd6082005-06-17 21:31:45 +0000933 ksa.sa_restorer = my_sigreturn;
sewardjce2a6152005-07-08 18:25:13 +0000934# endif
sewardj162bebd2005-07-09 10:43:45 +0000935 /* Re above ifdef (also the assertion below), PaulM says:
936 The sa_restorer field is not used at all on ppc. Glibc
937 converts the sigaction you give it into a kernel sigaction,
938 but it doesn't put anything in the sa_restorer field.
939 */
fitzhardinge4f10ada2004-06-03 10:00:42 +0000940
sewardjb5f6f512005-03-10 23:59:00 +0000941 /* block all signals in handler */
nethercote73b526f2004-10-31 18:48:21 +0000942 VG_(sigfillset)( &ksa.sa_mask );
943 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGKILL );
944 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGSTOP );
sewardj018f7622002-05-15 21:13:39 +0000945
sewardjb5f6f512005-03-10 23:59:00 +0000946 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj738856f2009-07-15 14:48:32 +0000947 VG_(dmsg)("setting ksig %d to: hdlr %p, flags 0x%lx, "
948 "mask(msb..lsb) 0x%llx 0x%llx\n",
949 sig, ksa.ksa_handler,
950 (UWord)ksa.sa_flags,
951 _VKI_NSIG_WORDS > 1 ? (ULong)ksa.sa_mask.sig[1] : 0,
952 (ULong)ksa.sa_mask.sig[0]);
sewardj018f7622002-05-15 21:13:39 +0000953
nethercote73b526f2004-10-31 18:48:21 +0000954 res = VG_(sigaction)( sig, &ksa, &ksa_old );
sewardj018f7622002-05-15 21:13:39 +0000955 vg_assert(res == 0);
956
957 /* Since we got the old sigaction more or less for free, might
958 as well extract the maximum sanity-check value from it. */
959 if (!force_update) {
960 vg_assert(ksa_old.ksa_handler
961 == skss_old.skss_per_sig[sig].skss_handler);
nethercote73b526f2004-10-31 18:48:21 +0000962 vg_assert(ksa_old.sa_flags
sewardj018f7622002-05-15 21:13:39 +0000963 == skss_old.skss_per_sig[sig].skss_flags);
njnf76d27a2009-05-28 01:53:07 +0000964# if !defined(VGP_ppc32_linux) && \
965 !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
966 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
nethercote73b526f2004-10-31 18:48:21 +0000967 vg_assert(ksa_old.sa_restorer
njn9abd6082005-06-17 21:31:45 +0000968 == my_sigreturn);
sewardjce2a6152005-07-08 18:25:13 +0000969# endif
nethercote73b526f2004-10-31 18:48:21 +0000970 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGKILL );
971 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGSTOP );
972 vg_assert(VG_(isfullsigset)( &ksa_old.sa_mask ));
sewardj018f7622002-05-15 21:13:39 +0000973 }
974 }
sewardj018f7622002-05-15 21:13:39 +0000975}
976
977
978/* ---------------------------------------------------------------------
979 Update/query SCSS in accordance with client requests.
980 ------------------------------------------------------------------ */
981
sewardj2342c972002-05-22 23:34:20 +0000982/* Logic for this alt-stack stuff copied directly from do_sigaltstack
983 in kernel/signal.[ch] */
984
985/* True if we are on the alternate signal stack. */
sewardjb5f6f512005-03-10 23:59:00 +0000986static Bool on_sig_stack ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000987{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000988 ThreadState *tst = VG_(get_ThreadState)(tid);
989
njn5a350be2009-04-30 03:05:05 +0000990 return (m_SP - (Addr)tst->altstack.ss_sp < (Addr)tst->altstack.ss_size);
sewardj2342c972002-05-22 23:34:20 +0000991}
992
nethercote511e4062004-09-11 13:34:08 +0000993static Int sas_ss_flags ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000994{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000995 ThreadState *tst = VG_(get_ThreadState)(tid);
996
997 return (tst->altstack.ss_size == 0
sewardj2342c972002-05-22 23:34:20 +0000998 ? VKI_SS_DISABLE
nethercote511e4062004-09-11 13:34:08 +0000999 : on_sig_stack(tid, m_SP) ? VKI_SS_ONSTACK : 0);
sewardj2342c972002-05-22 23:34:20 +00001000}
1001
1002
sewardja8d8e232005-06-07 20:04:56 +00001003SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
sewardj2342c972002-05-22 23:34:20 +00001004{
njn502badb2005-05-08 02:04:49 +00001005 Addr m_SP;
sewardj2342c972002-05-22 23:34:20 +00001006
1007 vg_assert(VG_(is_valid_tid)(tid));
njnf536bbb2005-06-13 04:21:38 +00001008 m_SP = VG_(get_SP)(tid);
sewardj2342c972002-05-22 23:34:20 +00001009
1010 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001011 VG_(dmsg)("sys_sigaltstack: tid %d, "
sewardj738856f2009-07-15 14:48:32 +00001012 "ss %p{%p,sz=%llu,flags=0x%llx}, oss %p (current SP %p)\n",
1013 tid, (void*)ss,
1014 ss ? ss->ss_sp : 0,
1015 (ULong)(ss ? ss->ss_size : 0),
1016 (ULong)(ss ? ss->ss_flags : 0),
1017 (void*)oss, (void*)m_SP);
sewardj2342c972002-05-22 23:34:20 +00001018
1019 if (oss != NULL) {
fitzhardinge98c4dc02004-03-16 08:27:29 +00001020 oss->ss_sp = VG_(threads)[tid].altstack.ss_sp;
1021 oss->ss_size = VG_(threads)[tid].altstack.ss_size;
njn5a350be2009-04-30 03:05:05 +00001022 oss->ss_flags = VG_(threads)[tid].altstack.ss_flags
1023 | sas_ss_flags(tid, m_SP);
sewardj2342c972002-05-22 23:34:20 +00001024 }
1025
1026 if (ss != NULL) {
njnf536bbb2005-06-13 04:21:38 +00001027 if (on_sig_stack(tid, VG_(get_SP)(tid))) {
sewardja8d8e232005-06-07 20:04:56 +00001028 return VG_(mk_SysRes_Error)( VKI_EPERM );
sewardj2342c972002-05-22 23:34:20 +00001029 }
1030 if (ss->ss_flags != VKI_SS_DISABLE
1031 && ss->ss_flags != VKI_SS_ONSTACK
1032 && ss->ss_flags != 0) {
sewardja8d8e232005-06-07 20:04:56 +00001033 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj2342c972002-05-22 23:34:20 +00001034 }
1035 if (ss->ss_flags == VKI_SS_DISABLE) {
fitzhardinge98c4dc02004-03-16 08:27:29 +00001036 VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
sewardj2342c972002-05-22 23:34:20 +00001037 } else {
1038 if (ss->ss_size < VKI_MINSIGSTKSZ) {
sewardja8d8e232005-06-07 20:04:56 +00001039 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
sewardj2342c972002-05-22 23:34:20 +00001040 }
jsgf855d93d2003-10-13 22:26:55 +00001041
nethercote20283c62004-11-04 19:43:22 +00001042 VG_(threads)[tid].altstack.ss_sp = ss->ss_sp;
1043 VG_(threads)[tid].altstack.ss_size = ss->ss_size;
fitzhardinge98c4dc02004-03-16 08:27:29 +00001044 VG_(threads)[tid].altstack.ss_flags = 0;
sewardj2342c972002-05-22 23:34:20 +00001045 }
sewardj2342c972002-05-22 23:34:20 +00001046 }
sewardja8d8e232005-06-07 20:04:56 +00001047 return VG_(mk_SysRes_Success)( 0 );
sewardj2342c972002-05-22 23:34:20 +00001048}
1049
1050
sewardja8d8e232005-06-07 20:04:56 +00001051SysRes VG_(do_sys_sigaction) ( Int signo,
njncda2f0f2009-05-18 02:12:08 +00001052 const vki_sigaction_toK_t* new_act,
1053 vki_sigaction_fromK_t* old_act )
sewardj018f7622002-05-15 21:13:39 +00001054{
sewardj018f7622002-05-15 21:13:39 +00001055 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001056 VG_(dmsg)("sys_sigaction: sigNo %d, "
sewardj738856f2009-07-15 14:48:32 +00001057 "new %#lx, old %#lx, new flags 0x%llx\n",
1058 signo, (UWord)new_act, (UWord)old_act,
1059 (ULong)(new_act ? new_act->sa_flags : 0));
sewardj018f7622002-05-15 21:13:39 +00001060
1061 /* Rule out various error conditions. The aim is to ensure that if
1062 when the call is passed to the kernel it will definitely
1063 succeed. */
1064
1065 /* Reject out-of-range signal numbers. */
sewardjb5f6f512005-03-10 23:59:00 +00001066 if (signo < 1 || signo > VG_(max_signal)) goto bad_signo;
sewardj018f7622002-05-15 21:13:39 +00001067
jsgf855d93d2003-10-13 22:26:55 +00001068 /* don't let them use our signals */
njn351d0062005-06-21 22:23:59 +00001069 if ( (signo > VG_SIGVGRTUSERMAX)
jsgf855d93d2003-10-13 22:26:55 +00001070 && new_act
sewardja8d8e232005-06-07 20:04:56 +00001071 && !(new_act->ksa_handler == VKI_SIG_DFL
1072 || new_act->ksa_handler == VKI_SIG_IGN) )
nethercote9c42a0f2003-11-17 10:37:19 +00001073 goto bad_signo_reserved;
jsgf855d93d2003-10-13 22:26:55 +00001074
sewardj018f7622002-05-15 21:13:39 +00001075 /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
1076 if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP)
1077 && new_act
1078 && new_act->ksa_handler != VKI_SIG_DFL)
1079 goto bad_sigkill_or_sigstop;
1080
1081 /* If the client supplied non-NULL old_act, copy the relevant SCSS
1082 entry into it. */
1083 if (old_act) {
njn695c16e2005-03-27 03:40:28 +00001084 old_act->ksa_handler = scss.scss_per_sig[signo].scss_handler;
1085 old_act->sa_flags = scss.scss_per_sig[signo].scss_flags;
1086 old_act->sa_mask = scss.scss_per_sig[signo].scss_mask;
njnf76d27a2009-05-28 01:53:07 +00001087# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
1088 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn695c16e2005-03-27 03:40:28 +00001089 old_act->sa_restorer = scss.scss_per_sig[signo].scss_restorer;
sewardj489bfec2006-10-17 02:00:29 +00001090# endif
sewardj018f7622002-05-15 21:13:39 +00001091 }
1092
1093 /* And now copy new SCSS entry from new_act. */
1094 if (new_act) {
njn695c16e2005-03-27 03:40:28 +00001095 scss.scss_per_sig[signo].scss_handler = new_act->ksa_handler;
1096 scss.scss_per_sig[signo].scss_flags = new_act->sa_flags;
1097 scss.scss_per_sig[signo].scss_mask = new_act->sa_mask;
sewardj489bfec2006-10-17 02:00:29 +00001098
njncda2f0f2009-05-18 02:12:08 +00001099 scss.scss_per_sig[signo].scss_restorer = NULL;
njnf76d27a2009-05-28 01:53:07 +00001100# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
1101 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn695c16e2005-03-27 03:40:28 +00001102 scss.scss_per_sig[signo].scss_restorer = new_act->sa_restorer;
sewardj489bfec2006-10-17 02:00:29 +00001103# endif
sewardjb5f6f512005-03-10 23:59:00 +00001104
njncda2f0f2009-05-18 02:12:08 +00001105 scss.scss_per_sig[signo].scss_sa_tramp = NULL;
njnf76d27a2009-05-28 01:53:07 +00001106# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1107 scss.scss_per_sig[signo].scss_sa_tramp = new_act->sa_tramp;
1108# endif
njncda2f0f2009-05-18 02:12:08 +00001109
njn695c16e2005-03-27 03:40:28 +00001110 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGKILL);
1111 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGSTOP);
sewardj018f7622002-05-15 21:13:39 +00001112 }
1113
1114 /* All happy bunnies ... */
1115 if (new_act) {
nethercote9dd11512004-08-04 15:31:30 +00001116 handle_SCSS_change( False /* lazy update */ );
sewardj018f7622002-05-15 21:13:39 +00001117 }
sewardja8d8e232005-06-07 20:04:56 +00001118 return VG_(mk_SysRes_Success)( 0 );
sewardj018f7622002-05-15 21:13:39 +00001119
1120 bad_signo:
sewardjec6e27c2007-11-17 21:31:48 +00001121 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001122 VG_(umsg)("Warning: bad signal number %d in sigaction()\n", signo);
sewardj9a3d8bd2005-05-23 14:47:52 +00001123 }
sewardja8d8e232005-06-07 20:04:56 +00001124 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +00001125
nethercote9c42a0f2003-11-17 10:37:19 +00001126 bad_signo_reserved:
sewardjec6e27c2007-11-17 21:31:48 +00001127 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001128 VG_(umsg)("Warning: ignored attempt to set %s handler in sigaction();\n",
1129 signame(signo));
1130 VG_(umsg)(" the %s signal is used internally by Valgrind\n",
1131 signame(signo));
fitzhardingebf459872003-11-18 16:55:33 +00001132 }
sewardja8d8e232005-06-07 20:04:56 +00001133 return VG_(mk_SysRes_Error)( VKI_EINVAL );
nethercote9c42a0f2003-11-17 10:37:19 +00001134
sewardj018f7622002-05-15 21:13:39 +00001135 bad_sigkill_or_sigstop:
sewardjec6e27c2007-11-17 21:31:48 +00001136 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001137 VG_(umsg)("Warning: ignored attempt to set %s handler in sigaction();\n",
1138 signame(signo));
1139 VG_(umsg)(" the %s signal is uncatchable\n",
1140 signame(signo));
sewardj9a3d8bd2005-05-23 14:47:52 +00001141 }
sewardja8d8e232005-06-07 20:04:56 +00001142 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +00001143}
1144
1145
1146static
1147void do_sigprocmask_bitops ( Int vki_how,
nethercote73b526f2004-10-31 18:48:21 +00001148 vki_sigset_t* orig_set,
1149 vki_sigset_t* modifier )
sewardj018f7622002-05-15 21:13:39 +00001150{
1151 switch (vki_how) {
1152 case VKI_SIG_BLOCK:
nethercote73b526f2004-10-31 18:48:21 +00001153 VG_(sigaddset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +00001154 break;
1155 case VKI_SIG_UNBLOCK:
nethercote73b526f2004-10-31 18:48:21 +00001156 VG_(sigdelset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +00001157 break;
1158 case VKI_SIG_SETMASK:
1159 *orig_set = *modifier;
1160 break;
1161 default:
njne427a662002-10-02 11:08:25 +00001162 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +00001163 break;
1164 }
1165}
1166
tomf7781e92005-11-02 15:31:21 +00001167static
njn5a350be2009-04-30 03:05:05 +00001168HChar* format_sigset ( const vki_sigset_t* set )
tomf7781e92005-11-02 15:31:21 +00001169{
njn5a350be2009-04-30 03:05:05 +00001170 static HChar buf[128];
tomf7781e92005-11-02 15:31:21 +00001171 int w;
1172
1173 VG_(strcpy)(buf, "");
1174
1175 for (w = _VKI_NSIG_WORDS - 1; w >= 0; w--)
1176 {
sewardja8ffda62008-07-18 18:23:24 +00001177# if _VKI_NSIG_BPW == 32
1178 VG_(sprintf)(buf + VG_(strlen)(buf), "%08llx",
1179 set ? (ULong)set->sig[w] : 0);
1180# elif _VKI_NSIG_BPW == 64
1181 VG_(sprintf)(buf + VG_(strlen)(buf), "%16llx",
1182 set ? (ULong)set->sig[w] : 0);
1183# else
1184# error "Unsupported value for _VKI_NSIG_BPW"
1185# endif
tomf7781e92005-11-02 15:31:21 +00001186 }
1187
1188 return buf;
1189}
1190
jsgf855d93d2003-10-13 22:26:55 +00001191/*
1192 This updates the thread's signal mask. There's no such thing as a
1193 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +00001194
1195 Note that the thread signal masks are an implicit part of SCSS,
1196 which is why this routine is allowed to mess with them.
1197*/
1198static
1199void do_setmask ( ThreadId tid,
1200 Int how,
nethercote73b526f2004-10-31 18:48:21 +00001201 vki_sigset_t* newset,
1202 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +00001203{
sewardj018f7622002-05-15 21:13:39 +00001204 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001205 VG_(dmsg)("do_setmask: tid = %d how = %d (%s), newset = %p (%s)\n",
sewardj738856f2009-07-15 14:48:32 +00001206 tid, how,
1207 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
1208 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
1209 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
1210 newset, newset ? format_sigset(newset) : "NULL" );
sewardj018f7622002-05-15 21:13:39 +00001211
jsgf855d93d2003-10-13 22:26:55 +00001212 /* Just do this thread. */
1213 vg_assert(VG_(is_valid_tid)(tid));
1214 if (oldset) {
sewardjb5f6f512005-03-10 23:59:00 +00001215 *oldset = VG_(threads)[tid].sig_mask;
jsgf855d93d2003-10-13 22:26:55 +00001216 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001217 VG_(dmsg)("\toldset=%p %s\n", oldset, format_sigset(oldset));
sewardj018f7622002-05-15 21:13:39 +00001218 }
sewardj018f7622002-05-15 21:13:39 +00001219 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +00001220 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
nethercote73b526f2004-10-31 18:48:21 +00001221 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
1222 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
sewardjb5f6f512005-03-10 23:59:00 +00001223 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
sewardj018f7622002-05-15 21:13:39 +00001224 }
1225}
1226
1227
sewardja8d8e232005-06-07 20:04:56 +00001228SysRes VG_(do_sys_sigprocmask) ( ThreadId tid,
1229 Int how,
1230 vki_sigset_t* set,
1231 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +00001232{
jsgf855d93d2003-10-13 22:26:55 +00001233 switch(how) {
njncda2f0f2009-05-18 02:12:08 +00001234 case VKI_SIG_BLOCK:
1235 case VKI_SIG_UNBLOCK:
1236 case VKI_SIG_SETMASK:
1237 vg_assert(VG_(is_valid_tid)(tid));
1238 do_setmask ( tid, how, set, oldset );
1239 return VG_(mk_SysRes_Success)( 0 );
jsgf855d93d2003-10-13 22:26:55 +00001240
njncda2f0f2009-05-18 02:12:08 +00001241 default:
sewardj738856f2009-07-15 14:48:32 +00001242 VG_(dmsg)("sigprocmask: unknown 'how' field %d\n", how);
njncda2f0f2009-05-18 02:12:08 +00001243 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +00001244 }
1245}
1246
1247
sewardj018f7622002-05-15 21:13:39 +00001248/* ---------------------------------------------------------------------
1249 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
1250 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +00001251
sewardj2e93c502002-04-12 11:12:52 +00001252/* ---------------------------------------------------------------------
1253 Handy utilities to block/restore all host signals.
1254 ------------------------------------------------------------------ */
1255
1256/* Block all host signals, dumping the old mask in *saved_mask. */
njn444eba12005-05-12 03:47:31 +00001257static void block_all_host_signals ( /* OUT */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +00001258{
1259 Int ret;
nethercote73b526f2004-10-31 18:48:21 +00001260 vki_sigset_t block_procmask;
1261 VG_(sigfillset)(&block_procmask);
1262 ret = VG_(sigprocmask)
sewardj2e93c502002-04-12 11:12:52 +00001263 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
1264 vg_assert(ret == 0);
1265}
1266
1267/* Restore the blocking mask using the supplied saved one. */
njn444eba12005-05-12 03:47:31 +00001268static void restore_all_host_signals ( /* IN */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +00001269{
1270 Int ret;
nethercote73b526f2004-10-31 18:48:21 +00001271 ret = VG_(sigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
sewardj2e93c502002-04-12 11:12:52 +00001272 vg_assert(ret == 0);
1273}
sewardjde4a1d02002-03-22 01:27:54 +00001274
njn444eba12005-05-12 03:47:31 +00001275void VG_(clear_out_queued_signals)( ThreadId tid, vki_sigset_t* saved_mask )
1276{
1277 block_all_host_signals(saved_mask);
1278 if (VG_(threads)[tid].sig_queue != NULL) {
1279 VG_(arena_free)(VG_AR_CORE, VG_(threads)[tid].sig_queue);
1280 VG_(threads)[tid].sig_queue = NULL;
1281 }
1282 restore_all_host_signals(saved_mask);
1283}
1284
sewardjde4a1d02002-03-22 01:27:54 +00001285/* ---------------------------------------------------------------------
1286 The signal simulation proper. A simplified version of what the
1287 Linux kernel does.
1288 ------------------------------------------------------------------ */
1289
sewardjde4a1d02002-03-22 01:27:54 +00001290/* Set up a stack frame (VgSigContext) for the client's signal
nethercotefedd8102004-09-13 15:19:34 +00001291 handler. */
sewardj2c5ffbe2005-03-12 13:32:06 +00001292static
njn5a350be2009-04-30 03:05:05 +00001293void push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo,
1294 const struct vki_ucontext *uc )
sewardjde4a1d02002-03-22 01:27:54 +00001295{
nethercote6eec4602004-09-13 14:15:36 +00001296 Addr esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +00001297 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +00001298 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +00001299
sewardjb5f6f512005-03-10 23:59:00 +00001300 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardj018f7622002-05-15 21:13:39 +00001301 vg_assert(VG_(is_valid_tid)(tid));
1302 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +00001303
sewardja672ea32006-04-29 18:03:14 +00001304 if (VG_(clo_trace_signals)) {
sewardj738856f2009-07-15 14:48:32 +00001305 VG_(dmsg)("push_signal_frame (thread %d): signal %d\n", tid, sigNo);
sewardja672ea32006-04-29 18:03:14 +00001306 VG_(get_and_pp_StackTrace)(tid, 10);
1307 }
jsgf855d93d2003-10-13 22:26:55 +00001308
sewardj2342c972002-05-22 23:34:20 +00001309 if (/* this signal asked to run on an alt stack */
njn695c16e2005-03-27 03:40:28 +00001310 (scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +00001311 && /* there is a defined and enabled alt stack, which we're not
1312 already using. Logic from get_sigframe in
1313 arch/i386/kernel/signal.c. */
njnf536bbb2005-06-13 04:21:38 +00001314 sas_ss_flags(tid, VG_(get_SP)(tid)) == 0
sewardj2342c972002-05-22 23:34:20 +00001315 ) {
1316 esp_top_of_frame
fitzhardinge98c4dc02004-03-16 08:27:29 +00001317 = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
sewardj2342c972002-05-22 23:34:20 +00001318 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001319 VG_(dmsg)("delivering signal %d (%s) to thread %d: "
1320 "on ALT STACK (%p-%p; %ld bytes)\n",
1321 sigNo, signame(sigNo), tid, tst->altstack.ss_sp,
1322 (UChar *)tst->altstack.ss_sp + tst->altstack.ss_size,
1323 (Word)tst->altstack.ss_size );
njnfdc28af2003-02-24 10:36:48 +00001324
nethercote7cc9c232004-01-21 15:08:04 +00001325 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +00001326 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
njnfdc28af2003-02-24 10:36:48 +00001327
sewardj2342c972002-05-22 23:34:20 +00001328 } else {
njnaf839f52005-06-23 03:27:57 +00001329 esp_top_of_frame = VG_(get_SP)(tid) - VG_STACK_REDZONE_SZB;
njnfdc28af2003-02-24 10:36:48 +00001330
nethercote7cc9c232004-01-21 15:08:04 +00001331 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +00001332 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
sewardj2342c972002-05-22 23:34:20 +00001333 }
sewardjb5f6f512005-03-10 23:59:00 +00001334
njn695c16e2005-03-27 03:40:28 +00001335 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_IGN);
1336 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_DFL);
sewardjb5f6f512005-03-10 23:59:00 +00001337
1338 /* This may fail if the client stack is busted; if that happens,
1339 the whole process will exit rather than simply calling the
1340 signal handler. */
tomadacaf92007-12-21 10:24:24 +00001341 VG_(sigframe_create) (tid, esp_top_of_frame, siginfo, uc,
sewardj985fabb2005-04-24 14:18:14 +00001342 scss.scss_per_sig[sigNo].scss_handler,
1343 scss.scss_per_sig[sigNo].scss_flags,
1344 &tst->sig_mask,
1345 scss.scss_per_sig[sigNo].scss_restorer);
sewardjde4a1d02002-03-22 01:27:54 +00001346}
1347
sewardjde4a1d02002-03-22 01:27:54 +00001348
jsgf855d93d2003-10-13 22:26:55 +00001349static const Char *signame(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +00001350{
njn5a350be2009-04-30 03:05:05 +00001351 static Char buf[20];
sewardjb48e5002002-05-13 00:16:03 +00001352
jsgf855d93d2003-10-13 22:26:55 +00001353 switch(sigNo) {
sewardj489bfec2006-10-17 02:00:29 +00001354 case VKI_SIGHUP: return "SIGHUP";
1355 case VKI_SIGINT: return "SIGINT";
1356 case VKI_SIGQUIT: return "SIGQUIT";
1357 case VKI_SIGILL: return "SIGILL";
1358 case VKI_SIGTRAP: return "SIGTRAP";
1359 case VKI_SIGABRT: return "SIGABRT";
1360 case VKI_SIGBUS: return "SIGBUS";
1361 case VKI_SIGFPE: return "SIGFPE";
1362 case VKI_SIGKILL: return "SIGKILL";
1363 case VKI_SIGUSR1: return "SIGUSR1";
1364 case VKI_SIGUSR2: return "SIGUSR2";
1365 case VKI_SIGSEGV: return "SIGSEGV";
1366 case VKI_SIGPIPE: return "SIGPIPE";
1367 case VKI_SIGALRM: return "SIGALRM";
1368 case VKI_SIGTERM: return "SIGTERM";
1369# if defined(VKI_SIGSTKFLT)
1370 case VKI_SIGSTKFLT: return "SIGSTKFLT";
1371# endif
1372 case VKI_SIGCHLD: return "SIGCHLD";
1373 case VKI_SIGCONT: return "SIGCONT";
1374 case VKI_SIGSTOP: return "SIGSTOP";
1375 case VKI_SIGTSTP: return "SIGTSTP";
1376 case VKI_SIGTTIN: return "SIGTTIN";
1377 case VKI_SIGTTOU: return "SIGTTOU";
1378 case VKI_SIGURG: return "SIGURG";
1379 case VKI_SIGXCPU: return "SIGXCPU";
1380 case VKI_SIGXFSZ: return "SIGXFSZ";
1381 case VKI_SIGVTALRM: return "SIGVTALRM";
1382 case VKI_SIGPROF: return "SIGPROF";
1383 case VKI_SIGWINCH: return "SIGWINCH";
1384 case VKI_SIGIO: return "SIGIO";
njncda2f0f2009-05-18 02:12:08 +00001385# if defined(VKI_SIGPWR)
sewardj489bfec2006-10-17 02:00:29 +00001386 case VKI_SIGPWR: return "SIGPWR";
njncda2f0f2009-05-18 02:12:08 +00001387# endif
sewardj489bfec2006-10-17 02:00:29 +00001388# if defined(VKI_SIGUNUSED)
1389 case VKI_SIGUNUSED: return "SIGUNUSED";
1390# endif
sewardjde4a1d02002-03-22 01:27:54 +00001391
njncda2f0f2009-05-18 02:12:08 +00001392# if defined(VKI_SIGRTMIN) && defined(VKI_SIGRTMAX)
jsgf855d93d2003-10-13 22:26:55 +00001393 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
sewardjb5f6f512005-03-10 23:59:00 +00001394 VG_(sprintf)(buf, "SIGRT%d", sigNo-VKI_SIGRTMIN);
jsgf855d93d2003-10-13 22:26:55 +00001395 return buf;
njncda2f0f2009-05-18 02:12:08 +00001396# endif
sewardjde4a1d02002-03-22 01:27:54 +00001397
jsgf855d93d2003-10-13 22:26:55 +00001398 default:
1399 VG_(sprintf)(buf, "SIG%d", sigNo);
1400 return buf;
1401 }
1402}
sewardjde4a1d02002-03-22 01:27:54 +00001403
jsgf855d93d2003-10-13 22:26:55 +00001404/* Hit ourselves with a signal using the default handler */
1405void VG_(kill_self)(Int sigNo)
1406{
njnf76d27a2009-05-28 01:53:07 +00001407 Int r;
njncda2f0f2009-05-18 02:12:08 +00001408 vki_sigset_t mask, origmask;
1409 vki_sigaction_toK_t sa, origsa2;
1410 vki_sigaction_fromK_t origsa;
sewardj018f7622002-05-15 21:13:39 +00001411
jsgf855d93d2003-10-13 22:26:55 +00001412 sa.ksa_handler = VKI_SIG_DFL;
nethercote73b526f2004-10-31 18:48:21 +00001413 sa.sa_flags = 0;
njnf76d27a2009-05-28 01:53:07 +00001414# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
1415 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
nethercote73b526f2004-10-31 18:48:21 +00001416 sa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00001417# endif
nethercote73b526f2004-10-31 18:48:21 +00001418 VG_(sigemptyset)(&sa.sa_mask);
sewardj2e93c502002-04-12 11:12:52 +00001419
nethercote73b526f2004-10-31 18:48:21 +00001420 VG_(sigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +00001421
sewardjb5f6f512005-03-10 23:59:00 +00001422 VG_(sigemptyset)(&mask);
1423 VG_(sigaddset)(&mask, sigNo);
1424 VG_(sigprocmask)(VKI_SIG_UNBLOCK, &mask, &origmask);
jsgf855d93d2003-10-13 22:26:55 +00001425
njnf76d27a2009-05-28 01:53:07 +00001426 r = VG_(kill)(VG_(getpid)(), sigNo);
sewardjc7ffc942011-03-28 16:26:42 +00001427# if defined(VGO_linux)
njnf76d27a2009-05-28 01:53:07 +00001428 /* This sometimes fails with EPERM on Darwin. I don't know why. */
sewardjc7ffc942011-03-28 16:26:42 +00001429 vg_assert(r == 0);
1430# endif
jsgf855d93d2003-10-13 22:26:55 +00001431
njncda2f0f2009-05-18 02:12:08 +00001432 VG_(convert_sigaction_fromK_to_toK)( &origsa, &origsa2 );
1433 VG_(sigaction)(sigNo, &origsa2, NULL);
nethercote73b526f2004-10-31 18:48:21 +00001434 VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00001435}
1436
njn36fce1b2009-04-28 01:55:01 +00001437// The si_code describes where the signal came from. Some come from the
1438// kernel, eg.: seg faults, illegal opcodes. Some come from the user, eg.:
1439// from kill() (SI_USER), or timer_settime() (SI_TIMER), or an async I/O
1440// request (SI_ASYNCIO). There's lots of implementation-defined leeway in
njnf76d27a2009-05-28 01:53:07 +00001441// POSIX, but the user vs. kernal distinction is what we want here. We also
1442// pass in some other details that can help when si_code is unreliable.
1443static Bool is_signal_from_kernel(ThreadId tid, int signum, int si_code)
njn36fce1b2009-04-28 01:55:01 +00001444{
1445#if defined(VGO_linux) || defined(VGO_aix5)
1446 // On Linux, SI_USER is zero, negative values are from the user, positive
1447 // values are from the kernel. There are SI_FROMUSER and SI_FROMKERNEL
1448 // macros but we don't use them here because other platforms don't have
1449 // them.
1450 return ( si_code > VKI_SI_USER ? True : False );
njnf76d27a2009-05-28 01:53:07 +00001451#elif defined(VGO_darwin)
1452 // On Darwin 9.6.0, the si_code is completely unreliable. It should be the
1453 // case that 0 means "user", and >0 means "kernel". But:
1454 // - For SIGSEGV, it seems quite reliable.
1455 // - For SIGBUS, it's always 2.
1456 // - For SIGFPE, it's often 0, even for kernel ones (eg.
1457 // div-by-integer-zero always gives zero).
1458 // - For SIGILL, it's unclear.
1459 // - For SIGTRAP, it's always 1.
1460 // You can see the "NOTIMP" (not implemented) status of a number of the
1461 // sub-cases in sys/signal.h. Hopefully future versions of Darwin will
1462 // get this right.
1463
1464 // If we're blocked waiting on a syscall, it must be a user signal, because
1465 // the kernel won't generate sync signals within syscalls.
1466 if (VG_(threads)[tid].status == VgTs_WaitSys) {
1467 return False;
1468
1469 // If it's a SIGSEGV, use the proper condition, since it's fairly reliable.
1470 } else if (SIGSEGV == signum) {
1471 return ( si_code > 0 ? True : False );
1472
1473 // If it's anything else, assume it's kernel-generated. Reason being that
1474 // kernel-generated sync signals are more common, and it's probable that
1475 // misdiagnosing a user signal as a kernel signal is better than the
1476 // opposite.
1477 } else {
1478 return True;
1479 }
njn36fce1b2009-04-28 01:55:01 +00001480#else
1481# error Unknown OS
1482#endif
1483}
1484
njn059539d2009-04-28 08:00:23 +00001485// This is an arbitrary si_code that we only use internally. It corresponds
1486// to the value SI_KERNEL on Linux, but that's not really of any significance
1487// as far as I can determine.
1488#define VKI_SEGV_MADE_UP_GPF 0x80
1489
jsgf855d93d2003-10-13 22:26:55 +00001490/*
sewardjb5f6f512005-03-10 23:59:00 +00001491 Perform the default action of a signal. If the signal is fatal, it
1492 marks all threads as needing to exit, but it doesn't actually kill
1493 the process or thread.
jsgf855d93d2003-10-13 22:26:55 +00001494
1495 If we're not being quiet, then print out some more detail about
1496 fatal signals (esp. core dumping signals).
1497 */
njn695c16e2005-03-27 03:40:28 +00001498static void default_action(const vki_siginfo_t *info, ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001499{
1500 Int sigNo = info->si_signo;
sewardjb5f6f512005-03-10 23:59:00 +00001501 Bool terminate = False; /* kills process */
1502 Bool core = False; /* kills process w/ core */
1503 struct vki_rlimit corelim;
1504 Bool could_core;
jsgf855d93d2003-10-13 22:26:55 +00001505
sewardjb5f6f512005-03-10 23:59:00 +00001506 vg_assert(VG_(is_running_thread)(tid));
1507
jsgf855d93d2003-10-13 22:26:55 +00001508 switch(sigNo) {
njncda2f0f2009-05-18 02:12:08 +00001509 case VKI_SIGQUIT: /* core */
1510 case VKI_SIGILL: /* core */
1511 case VKI_SIGABRT: /* core */
1512 case VKI_SIGFPE: /* core */
1513 case VKI_SIGSEGV: /* core */
1514 case VKI_SIGBUS: /* core */
1515 case VKI_SIGTRAP: /* core */
1516 case VKI_SIGXCPU: /* core */
1517 case VKI_SIGXFSZ: /* core */
1518 terminate = True;
1519 core = True;
1520 break;
jsgf855d93d2003-10-13 22:26:55 +00001521
njncda2f0f2009-05-18 02:12:08 +00001522 case VKI_SIGHUP: /* term */
1523 case VKI_SIGINT: /* term */
1524 case VKI_SIGKILL: /* term - we won't see this */
1525 case VKI_SIGPIPE: /* term */
1526 case VKI_SIGALRM: /* term */
1527 case VKI_SIGTERM: /* term */
1528 case VKI_SIGUSR1: /* term */
1529 case VKI_SIGUSR2: /* term */
1530 case VKI_SIGIO: /* term */
1531# if defined(VKI_SIGPWR)
1532 case VKI_SIGPWR: /* term */
1533# endif
1534 case VKI_SIGSYS: /* term */
1535 case VKI_SIGPROF: /* term */
1536 case VKI_SIGVTALRM: /* term */
1537# if defined(VKI_SIGRTMIN) && defined(VKI_SIGRTMAX)
1538 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1539# endif
1540 terminate = True;
1541 break;
jsgf855d93d2003-10-13 22:26:55 +00001542 }
1543
1544 vg_assert(!core || (core && terminate));
1545
fitzhardinge98abfc72003-12-16 02:05:15 +00001546 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001547 VG_(dmsg)("delivering %d (code %d) to default handler; action: %s%s\n",
1548 sigNo, info->si_code, terminate ? "terminate" : "ignore",
1549 core ? "+core" : "");
fitzhardinge98abfc72003-12-16 02:05:15 +00001550
sewardjb5f6f512005-03-10 23:59:00 +00001551 if (!terminate)
1552 return; /* nothing to do */
fitzhardinge4a4d1082004-03-15 23:46:54 +00001553
sewardjb5f6f512005-03-10 23:59:00 +00001554 could_core = core;
1555
1556 if (core) {
1557 /* If they set the core-size limit to zero, don't generate a
1558 core file */
fitzhardinge61a53412004-03-15 23:44:11 +00001559
sewardjb5f6f512005-03-10 23:59:00 +00001560 VG_(getrlimit)(VKI_RLIMIT_CORE, &corelim);
fitzhardinge61a53412004-03-15 23:44:11 +00001561
sewardjb5f6f512005-03-10 23:59:00 +00001562 if (corelim.rlim_cur == 0)
1563 core = False;
1564 }
fitzhardinge61a53412004-03-15 23:44:11 +00001565
njn36fce1b2009-04-28 01:55:01 +00001566 if ( (VG_(clo_verbosity) > 1 ||
njnf76d27a2009-05-28 01:53:07 +00001567 (could_core && is_signal_from_kernel(tid, sigNo, info->si_code))
njn36fce1b2009-04-28 01:55:01 +00001568 ) &&
1569 !VG_(clo_xml) ) {
sewardj738856f2009-07-15 14:48:32 +00001570 VG_(umsg)(
njnb6267bd2009-08-12 00:14:16 +00001571 "\n"
sewardj738856f2009-07-15 14:48:32 +00001572 "Process terminating with default action of signal %d (%s)%s\n",
1573 sigNo, signame(sigNo), core ? ": dumping core" : "");
jsgf855d93d2003-10-13 22:26:55 +00001574
sewardjb5f6f512005-03-10 23:59:00 +00001575 /* Be helpful - decode some more details about this fault */
njnf76d27a2009-05-28 01:53:07 +00001576 if (is_signal_from_kernel(tid, sigNo, info->si_code)) {
sewardjb5f6f512005-03-10 23:59:00 +00001577 const Char *event = NULL;
1578 Bool haveaddr = True;
jsgf855d93d2003-10-13 22:26:55 +00001579
sewardjb5f6f512005-03-10 23:59:00 +00001580 switch(sigNo) {
1581 case VKI_SIGSEGV:
1582 switch(info->si_code) {
sewardj738856f2009-07-15 14:48:32 +00001583 case VKI_SEGV_MAPERR: event = "Access not within mapped region";
1584 break;
1585 case VKI_SEGV_ACCERR: event = "Bad permissions for mapped region";
1586 break;
njn059539d2009-04-28 08:00:23 +00001587 case VKI_SEGV_MADE_UP_GPF:
sewardjb5f6f512005-03-10 23:59:00 +00001588 /* General Protection Fault: The CPU/kernel
1589 isn't telling us anything useful, but this
1590 is commonly the result of exceeding a
sewardj74b4cca2005-10-20 01:37:15 +00001591 segment limit. */
1592 event = "General Protection Fault";
sewardjb5f6f512005-03-10 23:59:00 +00001593 haveaddr = False;
jsgf855d93d2003-10-13 22:26:55 +00001594 break;
1595 }
sewardj45f4e7c2005-09-27 19:20:21 +00001596#if 0
1597 {
1598 HChar buf[110];
1599 VG_(am_show_nsegments)(0,"post segfault");
1600 VG_(sprintf)(buf, "/bin/cat /proc/%d/maps", VG_(getpid)());
1601 VG_(system)(buf);
1602 }
1603#endif
sewardjb5f6f512005-03-10 23:59:00 +00001604 break;
jsgf855d93d2003-10-13 22:26:55 +00001605
sewardjb5f6f512005-03-10 23:59:00 +00001606 case VKI_SIGILL:
1607 switch(info->si_code) {
tom148250b2005-11-12 00:13:20 +00001608 case VKI_ILL_ILLOPC: event = "Illegal opcode"; break;
1609 case VKI_ILL_ILLOPN: event = "Illegal operand"; break;
1610 case VKI_ILL_ILLADR: event = "Illegal addressing mode"; break;
1611 case VKI_ILL_ILLTRP: event = "Illegal trap"; break;
1612 case VKI_ILL_PRVOPC: event = "Privileged opcode"; break;
1613 case VKI_ILL_PRVREG: event = "Privileged register"; break;
1614 case VKI_ILL_COPROC: event = "Coprocessor error"; break;
1615 case VKI_ILL_BADSTK: event = "Internal stack error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001616 }
1617 break;
1618
1619 case VKI_SIGFPE:
1620 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001621 case VKI_FPE_INTDIV: event = "Integer divide by zero"; break;
1622 case VKI_FPE_INTOVF: event = "Integer overflow"; break;
1623 case VKI_FPE_FLTDIV: event = "FP divide by zero"; break;
1624 case VKI_FPE_FLTOVF: event = "FP overflow"; break;
1625 case VKI_FPE_FLTUND: event = "FP underflow"; break;
1626 case VKI_FPE_FLTRES: event = "FP inexact"; break;
1627 case VKI_FPE_FLTINV: event = "FP invalid operation"; break;
1628 case VKI_FPE_FLTSUB: event = "FP subscript out of range"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001629 }
1630 break;
1631
1632 case VKI_SIGBUS:
1633 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001634 case VKI_BUS_ADRALN: event = "Invalid address alignment"; break;
1635 case VKI_BUS_ADRERR: event = "Non-existent physical address"; break;
1636 case VKI_BUS_OBJERR: event = "Hardware error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001637 }
1638 break;
sewardj3059d272007-12-21 01:24:59 +00001639 } /* switch (sigNo) */
sewardjb5f6f512005-03-10 23:59:00 +00001640
1641 if (event != NULL) {
1642 if (haveaddr)
sewardj738856f2009-07-15 14:48:32 +00001643 VG_(umsg)(" %s at address %p\n",
1644 event, info->VKI_SIGINFO_si_addr);
sewardjb5f6f512005-03-10 23:59:00 +00001645 else
sewardj738856f2009-07-15 14:48:32 +00001646 VG_(umsg)(" %s\n", event);
jsgf855d93d2003-10-13 22:26:55 +00001647 }
1648 }
sewardj3059d272007-12-21 01:24:59 +00001649 /* Print a stack trace. Be cautious if the thread's SP is in an
1650 obviously stupid place (not mapped readable) that would
1651 likely cause a segfault. */
1652 if (VG_(is_valid_tid)(tid)) {
1653 ExeContext* ec = VG_(am_is_valid_for_client)
1654 (VG_(get_SP)(tid), sizeof(Addr), VKI_PROT_READ)
1655 ? VG_(record_ExeContext)( tid, 0/*first_ip_delta*/ )
1656 : VG_(record_depth_1_ExeContext)( tid );
1657 vg_assert(ec);
1658 VG_(pp_ExeContext)( ec );
fitzhardinge126c64f2003-12-08 21:58:37 +00001659 }
sewardj95d86c02007-12-18 01:49:23 +00001660 if (sigNo == VKI_SIGSEGV
njnf76d27a2009-05-28 01:53:07 +00001661 && info && is_signal_from_kernel(tid, sigNo, info->si_code)
sewardj95d86c02007-12-18 01:49:23 +00001662 && info->si_code == VKI_SEGV_MAPERR) {
sewardj738856f2009-07-15 14:48:32 +00001663 VG_(umsg)(" If you believe this happened as a result of a stack\n" );
1664 VG_(umsg)(" overflow in your program's main thread (unlikely but\n");
1665 VG_(umsg)(" possible), you can try to increase the size of the\n" );
1666 VG_(umsg)(" main thread stack using the --main-stacksize= flag.\n" );
sewardj95d86c02007-12-18 01:49:23 +00001667 // FIXME: assumes main ThreadId == 1
1668 if (VG_(is_valid_tid)(1)) {
sewardj738856f2009-07-15 14:48:32 +00001669 VG_(umsg)(
1670 " The main thread stack size used in this run was %d.\n",
1671 (Int)VG_(threads)[1].client_stack_szB);
sewardj95d86c02007-12-18 01:49:23 +00001672 }
1673 }
sewardjb5f6f512005-03-10 23:59:00 +00001674 }
1675
1676 if (VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) {
1677 VG_(start_debugger)( tid );
1678 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001679
sewardjb5f6f512005-03-10 23:59:00 +00001680 if (core) {
1681 const static struct vki_rlimit zero = { 0, 0 };
fitzhardinge4a4d1082004-03-15 23:46:54 +00001682
njn67229832005-08-28 04:38:12 +00001683 VG_(make_coredump)(tid, info, corelim.rlim_cur);
fitzhardinged65dcad2004-03-13 02:06:58 +00001684
sewardjb5f6f512005-03-10 23:59:00 +00001685 /* Make sure we don't get a confusing kernel-generated
1686 coredump when we finally exit */
1687 VG_(setrlimit)(VKI_RLIMIT_CORE, &zero);
1688 }
fitzhardinged65dcad2004-03-13 02:06:58 +00001689
sewardjb5f6f512005-03-10 23:59:00 +00001690 /* stash fatal signal in main thread */
sewardj1d887112005-05-30 21:44:08 +00001691 // what's this for?
1692 //VG_(threads)[VG_(master_tid)].os_state.fatalsig = sigNo;
sewardjde4a1d02002-03-22 01:27:54 +00001693
sewardjb5f6f512005-03-10 23:59:00 +00001694 /* everyone dies */
1695 VG_(nuke_all_threads_except)(tid, VgSrc_FatalSig);
1696 VG_(threads)[tid].exitreason = VgSrc_FatalSig;
1697 VG_(threads)[tid].os_state.fatalsig = sigNo;
sewardjb48e5002002-05-13 00:16:03 +00001698}
1699
sewardjb5f6f512005-03-10 23:59:00 +00001700/*
1701 This does the business of delivering a signal to a thread. It may
1702 be called from either a real signal handler, or from normal code to
1703 cause the thread to enter the signal handler.
sewardj5e2f0012004-12-13 14:10:34 +00001704
sewardjb5f6f512005-03-10 23:59:00 +00001705 This updates the thread state, but it does not set it to be
1706 Runnable.
1707*/
njn5a350be2009-04-30 03:05:05 +00001708static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info,
1709 const struct vki_ucontext *uc )
sewardjde4a1d02002-03-22 01:27:54 +00001710{
jsgf855d93d2003-10-13 22:26:55 +00001711 Int sigNo = info->si_signo;
njn695c16e2005-03-27 03:40:28 +00001712 SCSS_Per_Signal *handler = &scss.scss_per_sig[sigNo];
fitzhardinge98abfc72003-12-16 02:05:15 +00001713 void *handler_fn;
jsgf855d93d2003-10-13 22:26:55 +00001714 ThreadState *tst = VG_(get_ThreadState)(tid);
1715
1716 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001717 VG_(dmsg)("delivering signal %d (%s):%d to thread %d\n",
1718 sigNo, signame(sigNo), info->si_code, tid );
jsgf855d93d2003-10-13 22:26:55 +00001719
njn351d0062005-06-21 22:23:59 +00001720 if (sigNo == VG_SIGVGKILL) {
sewardjb5f6f512005-03-10 23:59:00 +00001721 /* If this is a SIGVGKILL, we're expecting it to interrupt any
1722 blocked syscall. It doesn't matter whether the VCPU state is
1723 set to restart or not, because we don't expect it will
1724 execute any more client instructions. */
1725 vg_assert(VG_(is_exiting)(tid));
jsgf855d93d2003-10-13 22:26:55 +00001726 return;
1727 }
1728
sewardjb5f6f512005-03-10 23:59:00 +00001729 /* If the client specifies SIG_IGN, treat it as SIG_DFL.
jsgf855d93d2003-10-13 22:26:55 +00001730
njn9ec0f3e2005-03-13 06:00:47 +00001731 If deliver_signal() is being called on a thread, we want
sewardjb5f6f512005-03-10 23:59:00 +00001732 the signal to get through no matter what; if they're ignoring
1733 it, then we do this override (this is so we can send it SIGSEGV,
1734 etc). */
fitzhardinge98abfc72003-12-16 02:05:15 +00001735 handler_fn = handler->scss_handler;
sewardjb5f6f512005-03-10 23:59:00 +00001736 if (handler_fn == VKI_SIG_IGN)
fitzhardinge98abfc72003-12-16 02:05:15 +00001737 handler_fn = VKI_SIG_DFL;
1738
1739 vg_assert(handler_fn != VKI_SIG_IGN);
jsgf855d93d2003-10-13 22:26:55 +00001740
fitzhardinge98abfc72003-12-16 02:05:15 +00001741 if (handler_fn == VKI_SIG_DFL) {
njn695c16e2005-03-27 03:40:28 +00001742 default_action(info, tid);
jsgf855d93d2003-10-13 22:26:55 +00001743 } else {
1744 /* Create a signal delivery frame, and set the client's %ESP and
1745 %EIP so that when execution continues, we will enter the
1746 signal handler with the frame on top of the client's stack,
sewardjb5f6f512005-03-10 23:59:00 +00001747 as it expects.
1748
1749 Signal delivery can fail if the client stack is too small or
1750 missing, and we can't push the frame. If that happens,
1751 push_signal_frame will cause the whole process to exit when
1752 we next hit the scheduler.
1753 */
jsgf855d93d2003-10-13 22:26:55 +00001754 vg_assert(VG_(is_valid_tid)(tid));
sewardjb5f6f512005-03-10 23:59:00 +00001755
tomadacaf92007-12-21 10:24:24 +00001756 push_signal_frame ( tid, info, uc );
jsgf855d93d2003-10-13 22:26:55 +00001757
1758 if (handler->scss_flags & VKI_SA_ONESHOT) {
1759 /* Do the ONESHOT thing. */
1760 handler->scss_handler = VKI_SIG_DFL;
1761
nethercote9dd11512004-08-04 15:31:30 +00001762 handle_SCSS_change( False /* lazy update */ );
jsgf855d93d2003-10-13 22:26:55 +00001763 }
sewardjb5f6f512005-03-10 23:59:00 +00001764
1765 /* At this point:
1766 tst->sig_mask is the current signal mask
1767 tst->tmp_sig_mask is the same as sig_mask, unless we're in sigsuspend
1768 handler->scss_mask is the mask set by the handler
1769
1770 Handler gets a mask of tmp_sig_mask|handler_mask|signo
1771 */
1772 tst->sig_mask = tst->tmp_sig_mask;
1773 if (!(handler->scss_flags & VKI_SA_NOMASK)) {
1774 VG_(sigaddset_from_set)(&tst->sig_mask, &handler->scss_mask);
1775 VG_(sigaddset)(&tst->sig_mask, sigNo);
sewardjb5f6f512005-03-10 23:59:00 +00001776 tst->tmp_sig_mask = tst->sig_mask;
1777 }
1778 }
1779
1780 /* Thread state is ready to go - just add Runnable */
1781}
1782
njn06244e72005-06-21 22:27:19 +00001783static void resume_scheduler(ThreadId tid)
1784{
1785 ThreadState *tst = VG_(get_ThreadState)(tid);
1786
1787 vg_assert(tst->os_state.lwpid == VG_(gettid)());
1788
1789 if (tst->sched_jmpbuf_valid) {
1790 /* Can't continue; must longjmp back to the scheduler and thus
1791 enter the sighandler immediately. */
sewardj6c591e12011-04-11 16:17:51 +00001792 VG_MINIMAL_LONGJMP(tst->sched_jmpbuf);
njn06244e72005-06-21 22:27:19 +00001793 }
1794}
1795
njn9ec0f3e2005-03-13 06:00:47 +00001796static void synth_fault_common(ThreadId tid, Addr addr, Int si_code)
1797{
1798 vki_siginfo_t info;
1799
1800 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1801
njn5a350be2009-04-30 03:05:05 +00001802 VG_(memset)(&info, 0, sizeof(info));
njn9ec0f3e2005-03-13 06:00:47 +00001803 info.si_signo = VKI_SIGSEGV;
1804 info.si_code = si_code;
sewardj489bfec2006-10-17 02:00:29 +00001805 info.VKI_SIGINFO_si_addr = (void*)addr;
njn9ec0f3e2005-03-13 06:00:47 +00001806
sewardj3b290482011-05-06 21:02:55 +00001807 /* even if gdbserver indicates to ignore the signal, we will deliver it */
1808 VG_(gdbserver_report_signal) (VKI_SIGSEGV, tid);
1809
njn9ec0f3e2005-03-13 06:00:47 +00001810 /* If they're trying to block the signal, force it to be delivered */
1811 if (VG_(sigismember)(&VG_(threads)[tid].sig_mask, VKI_SIGSEGV))
1812 VG_(set_default_handler)(VKI_SIGSEGV);
1813
tomadacaf92007-12-21 10:24:24 +00001814 deliver_signal(tid, &info, NULL);
njn9ec0f3e2005-03-13 06:00:47 +00001815}
1816
1817// Synthesize a fault where the address is OK, but the page
1818// permissions are bad.
1819void VG_(synth_fault_perms)(ThreadId tid, Addr addr)
1820{
njn059539d2009-04-28 08:00:23 +00001821 synth_fault_common(tid, addr, VKI_SEGV_ACCERR);
njn9ec0f3e2005-03-13 06:00:47 +00001822}
1823
1824// Synthesize a fault where the address there's nothing mapped at the address.
1825void VG_(synth_fault_mapping)(ThreadId tid, Addr addr)
1826{
njn059539d2009-04-28 08:00:23 +00001827 synth_fault_common(tid, addr, VKI_SEGV_MAPERR);
njn9ec0f3e2005-03-13 06:00:47 +00001828}
1829
1830// Synthesize a misc memory fault.
1831void VG_(synth_fault)(ThreadId tid)
1832{
njn059539d2009-04-28 08:00:23 +00001833 synth_fault_common(tid, 0, VKI_SEGV_MADE_UP_GPF);
njn9ec0f3e2005-03-13 06:00:47 +00001834}
1835
1836// Synthesise a SIGILL.
1837void VG_(synth_sigill)(ThreadId tid, Addr addr)
1838{
1839 vki_siginfo_t info;
1840
1841 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1842
njn5a350be2009-04-30 03:05:05 +00001843 VG_(memset)(&info, 0, sizeof(info));
njn9ec0f3e2005-03-13 06:00:47 +00001844 info.si_signo = VKI_SIGILL;
sewardj489bfec2006-10-17 02:00:29 +00001845 info.si_code = VKI_ILL_ILLOPC; /* jrs: no idea what this should be */
1846 info.VKI_SIGINFO_si_addr = (void*)addr;
njn9ec0f3e2005-03-13 06:00:47 +00001847
sewardj3b290482011-05-06 21:02:55 +00001848 if (VG_(gdbserver_report_signal) (VKI_SIGILL, tid)) {
1849 resume_scheduler(tid);
1850 deliver_signal(tid, &info, NULL);
1851 }
1852 else
1853 resume_scheduler(tid);
njn9ec0f3e2005-03-13 06:00:47 +00001854}
1855
sewardj1c0ce7a2009-07-01 08:10:49 +00001856// Synthesise a SIGBUS.
1857void VG_(synth_sigbus)(ThreadId tid)
1858{
1859 vki_siginfo_t info;
1860
1861 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1862
1863 VG_(memset)(&info, 0, sizeof(info));
1864 info.si_signo = VKI_SIGBUS;
1865 /* There are several meanings to SIGBUS (as per POSIX, presumably),
1866 but the most widely understood is "invalid address alignment",
1867 so let's use that. */
1868 info.si_code = VKI_BUS_ADRALN;
1869 /* If we knew the invalid address in question, we could put it
1870 in .si_addr. Oh well. */
1871 /* info.VKI_SIGINFO_si_addr = (void*)addr; */
1872
sewardj3b290482011-05-06 21:02:55 +00001873 if (VG_(gdbserver_report_signal) (VKI_SIGBUS, tid)) {
1874 resume_scheduler(tid);
1875 deliver_signal(tid, &info, NULL);
1876 }
1877 else
1878 resume_scheduler(tid);
sewardj1c0ce7a2009-07-01 08:10:49 +00001879}
1880
sewardj86df1552006-02-07 20:56:41 +00001881// Synthesise a SIGTRAP.
1882void VG_(synth_sigtrap)(ThreadId tid)
1883{
1884 vki_siginfo_t info;
tomadacaf92007-12-21 10:24:24 +00001885 struct vki_ucontext uc;
njnf76d27a2009-05-28 01:53:07 +00001886# if defined(VGP_x86_darwin)
1887 struct __darwin_mcontext32 mc;
1888# elif defined(VGP_amd64_darwin)
1889 struct __darwin_mcontext64 mc;
1890# endif
sewardj86df1552006-02-07 20:56:41 +00001891
1892 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1893
njn5a350be2009-04-30 03:05:05 +00001894 VG_(memset)(&info, 0, sizeof(info));
1895 VG_(memset)(&uc, 0, sizeof(uc));
sewardj86df1552006-02-07 20:56:41 +00001896 info.si_signo = VKI_SIGTRAP;
tomadacaf92007-12-21 10:24:24 +00001897 info.si_code = VKI_TRAP_BRKPT; /* tjh: only ever called for a brkpt ins */
njncda2f0f2009-05-18 02:12:08 +00001898
1899# if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
tomadacaf92007-12-21 10:24:24 +00001900 uc.uc_mcontext.trapno = 3; /* tjh: this is the x86 trap number
1901 for a breakpoint trap... */
tom8b243022008-06-13 08:37:49 +00001902 uc.uc_mcontext.err = 0; /* tjh: no error code for x86
1903 breakpoint trap... */
njnf76d27a2009-05-28 01:53:07 +00001904# elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1905 /* the same thing, but using Darwin field/struct names */
1906 VG_(memset)(&mc, 0, sizeof(mc));
1907 uc.uc_mcontext = &mc;
1908 uc.uc_mcontext->__es.__trapno = 3;
1909 uc.uc_mcontext->__es.__err = 0;
njncda2f0f2009-05-18 02:12:08 +00001910# endif
sewardj86df1552006-02-07 20:56:41 +00001911
sewardjb5b87402011-03-07 16:05:35 +00001912 /* fixs390: do we need to do anything here for s390 ? */
sewardj3b290482011-05-06 21:02:55 +00001913 if (VG_(gdbserver_report_signal) (VKI_SIGTRAP, tid)) {
1914 resume_scheduler(tid);
1915 deliver_signal(tid, &info, &uc);
1916 }
1917 else
1918 resume_scheduler(tid);
sewardj86df1552006-02-07 20:56:41 +00001919}
1920
sewardjb5f6f512005-03-10 23:59:00 +00001921/* Make a signal pending for a thread, for later delivery.
1922 VG_(poll_signals) will arrange for it to be delivered at the right
1923 time.
1924
1925 tid==0 means add it to the process-wide queue, and not sent it to a
1926 specific thread.
1927*/
sewardj2c5ffbe2005-03-12 13:32:06 +00001928static
sewardjb5f6f512005-03-10 23:59:00 +00001929void queue_signal(ThreadId tid, const vki_siginfo_t *si)
1930{
1931 ThreadState *tst;
1932 SigQueue *sq;
1933 vki_sigset_t savedmask;
1934
1935 tst = VG_(get_ThreadState)(tid);
1936
1937 /* Protect the signal queue against async deliveries */
njn444eba12005-05-12 03:47:31 +00001938 block_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001939
1940 if (tst->sig_queue == NULL) {
sewardj9c606bd2008-09-18 18:12:50 +00001941 tst->sig_queue = VG_(arena_malloc)(VG_AR_CORE, "signals.qs.1",
1942 sizeof(*tst->sig_queue));
sewardjb5f6f512005-03-10 23:59:00 +00001943 VG_(memset)(tst->sig_queue, 0, sizeof(*tst->sig_queue));
1944 }
1945 sq = tst->sig_queue;
1946
1947 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001948 VG_(dmsg)("Queueing signal %d (idx %d) to thread %d\n",
1949 si->si_signo, sq->next, tid);
sewardjb5f6f512005-03-10 23:59:00 +00001950
1951 /* Add signal to the queue. If the queue gets overrun, then old
1952 queued signals may get lost.
1953
1954 XXX We should also keep a sigset of pending signals, so that at
1955 least a non-siginfo signal gets deliviered.
1956 */
1957 if (sq->sigs[sq->next].si_signo != 0)
sewardj738856f2009-07-15 14:48:32 +00001958 VG_(umsg)("Signal %d being dropped from thread %d's queue\n",
1959 sq->sigs[sq->next].si_signo, tid);
sewardjb5f6f512005-03-10 23:59:00 +00001960
1961 sq->sigs[sq->next] = *si;
1962 sq->next = (sq->next+1) % N_QUEUED_SIGNALS;
1963
njn444eba12005-05-12 03:47:31 +00001964 restore_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001965}
1966
1967/*
1968 Returns the next queued signal for thread tid which is in "set".
1969 tid==0 means process-wide signal. Set si_signo to 0 when the
1970 signal has been delivered.
1971
1972 Must be called with all signals blocked, to protect against async
1973 deliveries.
1974*/
1975static vki_siginfo_t *next_queued(ThreadId tid, const vki_sigset_t *set)
1976{
1977 ThreadState *tst = VG_(get_ThreadState)(tid);
1978 SigQueue *sq;
1979 Int idx;
1980 vki_siginfo_t *ret = NULL;
1981
1982 sq = tst->sig_queue;
1983 if (sq == NULL)
1984 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001985
sewardjb5f6f512005-03-10 23:59:00 +00001986 idx = sq->next;
1987 do {
1988 if (0)
1989 VG_(printf)("idx=%d si_signo=%d inset=%d\n", idx,
sewardj738856f2009-07-15 14:48:32 +00001990 sq->sigs[idx].si_signo,
1991 VG_(sigismember)(set, sq->sigs[idx].si_signo));
jsgf855d93d2003-10-13 22:26:55 +00001992
sewardj738856f2009-07-15 14:48:32 +00001993 if (sq->sigs[idx].si_signo != 0
1994 && VG_(sigismember)(set, sq->sigs[idx].si_signo)) {
sewardjb5f6f512005-03-10 23:59:00 +00001995 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001996 VG_(dmsg)("Returning queued signal %d (idx %d) for thread %d\n",
1997 sq->sigs[idx].si_signo, idx, tid);
sewardjb5f6f512005-03-10 23:59:00 +00001998 ret = &sq->sigs[idx];
1999 goto out;
jsgf855d93d2003-10-13 22:26:55 +00002000 }
2001
sewardjb5f6f512005-03-10 23:59:00 +00002002 idx = (idx + 1) % N_QUEUED_SIGNALS;
2003 } while(idx != sq->next);
2004 out:
sewardj489bfec2006-10-17 02:00:29 +00002005 return ret;
jsgf855d93d2003-10-13 22:26:55 +00002006}
2007
njn3b6b2aa2009-04-30 03:30:09 +00002008static int sanitize_si_code(int si_code)
2009{
2010#if defined(VGO_linux)
2011 /* The linux kernel uses the top 16 bits of si_code for it's own
2012 use and only exports the bottom 16 bits to user space - at least
2013 that is the theory, but it turns out that there are some kernels
2014 around that forget to mask out the top 16 bits so we do it here.
2015
2016 The kernel treats the bottom 16 bits as signed and (when it does
2017 mask them off) sign extends them when exporting to user space so
2018 we do the same thing here. */
2019 return (Short)si_code;
njnf76d27a2009-05-28 01:53:07 +00002020#elif defined(VGO_aix5) || defined(VGO_darwin)
njn3b6b2aa2009-04-30 03:30:09 +00002021 return si_code;
njn52040a42009-04-30 04:00:13 +00002022#else
2023# error Unknown OS
njn3b6b2aa2009-04-30 03:30:09 +00002024#endif
2025}
2026
jsgf855d93d2003-10-13 22:26:55 +00002027/*
sewardjb5f6f512005-03-10 23:59:00 +00002028 Receive an async signal from the kernel.
jsgf855d93d2003-10-13 22:26:55 +00002029
sewardjb5f6f512005-03-10 23:59:00 +00002030 This should only happen when the thread is blocked in a syscall,
2031 since that's the only time this set of signals is unblocked.
jsgf855d93d2003-10-13 22:26:55 +00002032*/
2033static
njn5a350be2009-04-30 03:05:05 +00002034void async_signalhandler ( Int sigNo,
2035 vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00002036{
njn5a350be2009-04-30 03:05:05 +00002037 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
2038 ThreadState* tst = VG_(get_ThreadState)(tid);
njncda2f0f2009-05-18 02:12:08 +00002039 SysRes sres;
jsgf855d93d2003-10-13 22:26:55 +00002040
njn5a350be2009-04-30 03:05:05 +00002041 /* The thread isn't currently running, make it so before going on */
2042 vg_assert(tst->status == VgTs_WaitSys);
2043 VG_(acquire_BigLock)(tid, "async_signalhandler");
2044
njn3b6b2aa2009-04-30 03:30:09 +00002045 info->si_code = sanitize_si_code(info->si_code);
tom9f4a7bf2005-11-13 00:01:20 +00002046
sewardjb5f6f512005-03-10 23:59:00 +00002047 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002048 VG_(dmsg)("async signal handler: signal=%d, tid=%d, si_code=%d\n",
2049 sigNo, tid, info->si_code);
sewardjb5f6f512005-03-10 23:59:00 +00002050
njncda2f0f2009-05-18 02:12:08 +00002051 /* Update thread state properly. The signal can only have been
2052 delivered whilst we were in
2053 coregrind/m_syswrap/syscall-<PLAT>.S, and only then in the
2054 window between the two sigprocmask calls, since at all other
2055 times, we run with async signals on the host blocked. Hence
2056 make enquiries on the basis that we were in or very close to a
2057 syscall, and attempt to fix up the guest state accordingly.
2058
2059 (normal async signals occurring during computation are blocked,
2060 but periodically polled for using VG_(sigtimedwait_zero), and
2061 delivered at a point convenient for us. Hence this routine only
2062 deals with signals that are delivered to a thread during a
2063 syscall.) */
2064
2065 /* First, extract a SysRes from the ucontext_t* given to this
2066 handler. If it is subsequently established by
2067 VG_(fixup_guest_state_after_syscall_interrupted) that the
2068 syscall was complete but the results had not been committed yet
2069 to the guest state, then it'll have to commit the results itself
2070 "by hand", and so we need to extract the SysRes. Of course if
2071 the thread was not in that particular window then the
2072 SysRes will be meaningless, but that's OK too because
2073 VG_(fixup_guest_state_after_syscall_interrupted) will detect
2074 that the thread was not in said window and ignore the SysRes. */
2075
njnf76d27a2009-05-28 01:53:07 +00002076 /* To make matters more complex still, on Darwin we need to know
2077 the "class" of the syscall under consideration in order to be
2078 able to extract the a correct SysRes. The class will have been
2079 saved just before the syscall, by VG_(client_syscall), into this
2080 thread's tst->arch.vex.guest_SC_CLASS. Hence: */
2081# if defined(VGO_darwin)
2082 sres = VG_UCONTEXT_SYSCALL_SYSRES(uc, tst->arch.vex.guest_SC_CLASS);
2083# else
njncda2f0f2009-05-18 02:12:08 +00002084 sres = VG_UCONTEXT_SYSCALL_SYSRES(uc);
njnf76d27a2009-05-28 01:53:07 +00002085# endif
njncda2f0f2009-05-18 02:12:08 +00002086
2087 /* (1) */
sewardja8d8e232005-06-07 20:04:56 +00002088 VG_(fixup_guest_state_after_syscall_interrupted)(
2089 tid,
njnaf839f52005-06-23 03:27:57 +00002090 VG_UCONTEXT_INSTR_PTR(uc),
njncda2f0f2009-05-18 02:12:08 +00002091 sres,
sewardja8d8e232005-06-07 20:04:56 +00002092 !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
2093 );
sewardjb5f6f512005-03-10 23:59:00 +00002094
njncda2f0f2009-05-18 02:12:08 +00002095 /* (2) */
sewardjb5f6f512005-03-10 23:59:00 +00002096 /* Set up the thread's state to deliver a signal */
sewardj3b290482011-05-06 21:02:55 +00002097 if (!is_sig_ign(info->si_signo, tid))
tomadacaf92007-12-21 10:24:24 +00002098 deliver_signal(tid, info, uc);
sewardjb5f6f512005-03-10 23:59:00 +00002099
njncda2f0f2009-05-18 02:12:08 +00002100 /* It's crucial that (1) and (2) happen in the order (1) then (2)
2101 and not the other way around. (1) fixes up the guest thread
2102 state to reflect the fact that the syscall was interrupted --
2103 either to restart the syscall or to return EINTR. (2) then sets
2104 up the thread state to deliver the signal. Then we resume
2105 execution. First, the signal handler is run, since that's the
2106 second adjustment we made to the thread state. If that returns,
2107 then we resume at the guest state created by (1), viz, either
2108 the syscall returns EINTR or is restarted.
2109
2110 If (2) was done before (1) the outcome would be completely
2111 different, and wrong. */
2112
sewardjb5f6f512005-03-10 23:59:00 +00002113 /* longjmp back to the thread's main loop to start executing the
2114 handler. */
njn06244e72005-06-21 22:27:19 +00002115 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002116
njn5a350be2009-04-30 03:05:05 +00002117 VG_(core_panic)("async_signalhandler: got unexpected signal "
2118 "while outside of scheduler");
jsgf855d93d2003-10-13 22:26:55 +00002119}
2120
sewardjb5f6f512005-03-10 23:59:00 +00002121/* Extend the stack to cover addr. maxsize is the limit the stack can grow to.
2122
2123 Returns True on success, False on failure.
2124
2125 Succeeds without doing anything if addr is already within a segment.
2126
2127 Failure could be caused by:
2128 - addr not below a growable segment
2129 - new stack size would exceed maxsize
2130 - mmap failed for some other reason
2131 */
2132Bool VG_(extend_stack)(Addr addr, UInt maxsize)
2133{
sewardj45f4e7c2005-09-27 19:20:21 +00002134 SizeT udelta;
sewardjb5f6f512005-03-10 23:59:00 +00002135
2136 /* Find the next Segment above addr */
sewardj489bfec2006-10-17 02:00:29 +00002137 NSegment const* seg
2138 = VG_(am_find_nsegment)(addr);
2139 NSegment const* seg_next
2140 = seg ? VG_(am_next_nsegment)( (NSegment*)seg, True/*fwds*/ )
2141 : NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00002142
2143 if (seg && seg->kind == SkAnonC)
2144 /* addr is already mapped. Nothing to do. */
sewardjb5f6f512005-03-10 23:59:00 +00002145 return True;
2146
sewardj45f4e7c2005-09-27 19:20:21 +00002147 /* Check that the requested new base is in a shrink-down
2148 reservation section which abuts an anonymous mapping that
2149 belongs to the client. */
2150 if ( ! (seg
2151 && seg->kind == SkResvn
2152 && seg->smode == SmUpper
2153 && seg_next
2154 && seg_next->kind == SkAnonC
2155 && seg->end+1 == seg_next->start))
sewardjb5f6f512005-03-10 23:59:00 +00002156 return False;
2157
sewardj45f4e7c2005-09-27 19:20:21 +00002158 udelta = VG_PGROUNDUP(seg_next->start - addr);
2159 VG_(debugLog)(1, "signals",
2160 "extending a stack base 0x%llx down by %lld\n",
2161 (ULong)seg_next->start, (ULong)udelta);
2162 if (! VG_(am_extend_into_adjacent_reservation_client)
sewardj489bfec2006-10-17 02:00:29 +00002163 ( (NSegment*)seg_next, -(SSizeT)udelta )) {
sewardj45f4e7c2005-09-27 19:20:21 +00002164 VG_(debugLog)(1, "signals", "extending a stack base: FAILED\n");
sewardjb5f6f512005-03-10 23:59:00 +00002165 return False;
sewardj45f4e7c2005-09-27 19:20:21 +00002166 }
sewardjb5f6f512005-03-10 23:59:00 +00002167
rjwalsh0140af52005-06-04 20:42:33 +00002168 /* When we change the main stack, we have to let the stack handling
2169 code know about it. */
sewardj45f4e7c2005-09-27 19:20:21 +00002170 VG_(change_stack)(VG_(clstk_id), addr, VG_(clstk_end));
sewardjb5f6f512005-03-10 23:59:00 +00002171
2172 if (VG_(clo_sanity_level) > 2)
2173 VG_(sanity_check_general)(False);
2174
2175 return True;
2176}
2177
sewardj489bfec2006-10-17 02:00:29 +00002178static void (*fault_catcher)(Int sig, Addr addr) = NULL;
sewardjb5f6f512005-03-10 23:59:00 +00002179
2180void VG_(set_fault_catcher)(void (*catcher)(Int, Addr))
2181{
sewardj489bfec2006-10-17 02:00:29 +00002182 if (0)
2183 VG_(debugLog)(0, "signals", "set fault catcher to %p\n", catcher);
njn50ae1a72005-04-08 23:28:23 +00002184 vg_assert2(NULL == catcher || NULL == fault_catcher,
2185 "Fault catcher is already registered");
sewardjb5f6f512005-03-10 23:59:00 +00002186
2187 fault_catcher = catcher;
2188}
2189
njn96986052009-04-30 07:41:24 +00002190static
njn2d5ff4f2009-05-03 22:53:19 +00002191void sync_signalhandler_from_user ( ThreadId tid,
njn96986052009-04-30 07:41:24 +00002192 Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
2193{
2194 ThreadId qtid;
2195
njn2d5ff4f2009-05-03 22:53:19 +00002196 /* If some user-process sent us a sync signal (ie. it's not the result
njn96986052009-04-30 07:41:24 +00002197 of a faulting instruction), then how we treat it depends on when it
2198 arrives... */
2199
2200 if (VG_(threads)[tid].status == VgTs_WaitSys) {
2201 /* Signal arrived while we're blocked in a syscall. This means that
2202 the client's signal mask was applied. In other words, so we can't
2203 get here unless the client wants this signal right now. This means
2204 we can simply use the async_signalhandler. */
2205 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002206 VG_(dmsg)("Delivering user-sent sync signal %d as async signal\n",
2207 sigNo);
njn96986052009-04-30 07:41:24 +00002208
2209 async_signalhandler(sigNo, info, uc);
2210 VG_(core_panic)("async_signalhandler returned!?\n");
2211
2212 } else {
2213 /* Signal arrived while in generated client code, or while running
2214 Valgrind core code. That means that every thread has these signals
2215 unblocked, so we can't rely on the kernel to route them properly, so
2216 we need to queue them manually. */
2217 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002218 VG_(dmsg)("Routing user-sent sync signal %d via queue\n", sigNo);
njn96986052009-04-30 07:41:24 +00002219
2220# if defined(VGO_linux)
2221 /* On Linux, first we have to do a sanity check of the siginfo. */
2222 if (info->VKI_SIGINFO_si_pid == 0) {
2223 /* There's a per-user limit of pending siginfo signals. If
2224 you exceed this, by having more than that number of
2225 pending signals with siginfo, then new signals are
2226 delivered without siginfo. This condition can be caused
2227 by any unrelated program you're running at the same time
2228 as Valgrind, if it has a large number of pending siginfo
2229 signals which it isn't taking delivery of.
2230
2231 Since we depend on siginfo to work out why we were sent a
2232 signal and what we should do about it, we really can't
2233 continue unless we get it. */
sewardj738856f2009-07-15 14:48:32 +00002234 VG_(umsg)("Signal %d (%s) appears to have lost its siginfo; "
2235 "I can't go on.\n", sigNo, signame(sigNo));
njn96986052009-04-30 07:41:24 +00002236 VG_(printf)(
2237" This may be because one of your programs has consumed your ration of\n"
2238" siginfo structures. For more information, see:\n"
2239" http://kerneltrap.org/mailarchive/1/message/25599/thread\n"
2240" Basically, some program on your system is building up a large queue of\n"
2241" pending signals, and this causes the siginfo data for other signals to\n"
2242" be dropped because it's exceeding a system limit. However, Valgrind\n"
2243" absolutely needs siginfo for SIGSEGV. A workaround is to track down the\n"
2244" offending program and avoid running it while using Valgrind, but there\n"
2245" is no easy way to do this. Apparently the problem was fixed in kernel\n"
2246" 2.6.12.\n");
2247
2248 /* It's a fatal signal, so we force the default handler. */
2249 VG_(set_default_handler)(sigNo);
2250 deliver_signal(tid, info, uc);
2251 resume_scheduler(tid);
2252 VG_(exit)(99); /* If we can't resume, then just exit */
2253 }
2254# endif
2255
2256 qtid = 0; /* shared pending by default */
2257# if defined(VGO_linux)
2258 if (info->si_code == VKI_SI_TKILL)
2259 qtid = tid; /* directed to us specifically */
2260# endif
2261 queue_signal(qtid, info);
2262 }
2263}
2264
sewardjb5b87402011-03-07 16:05:35 +00002265/* Returns the reported fault address for an exact address */
2266static Addr fault_mask(Addr in)
2267{
2268 /* We have to use VG_PGROUNDDN because faults on s390x only deliver
2269 the page address but not the address within a page.
2270 */
2271# if defined(VGA_s390x)
2272 return VG_PGROUNDDN(in);
2273# else
2274 return in;
2275#endif
2276}
2277
njn96986052009-04-30 07:41:24 +00002278/* Returns True if the sync signal was due to the stack requiring extension
2279 and the extension was successful.
2280*/
2281static Bool extend_stack_if_appropriate(ThreadId tid, vki_siginfo_t* info)
2282{
2283 Addr fault;
2284 Addr esp;
2285 NSegment const* seg;
2286 NSegment const* seg_next;
2287
2288 if (info->si_signo != VKI_SIGSEGV)
2289 return False;
2290
2291 fault = (Addr)info->VKI_SIGINFO_si_addr;
2292 esp = VG_(get_SP)(tid);
2293 seg = VG_(am_find_nsegment)(fault);
2294 seg_next = seg ? VG_(am_next_nsegment)( (NSegment*)seg, True/*fwds*/ )
2295 : NULL;
2296
2297 if (VG_(clo_trace_signals)) {
2298 if (seg == NULL)
sewardj738856f2009-07-15 14:48:32 +00002299 VG_(dmsg)("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
2300 "seg=NULL\n",
2301 info->si_code, fault, tid, esp);
njn96986052009-04-30 07:41:24 +00002302 else
sewardj738856f2009-07-15 14:48:32 +00002303 VG_(dmsg)("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
2304 "seg=%#lx-%#lx\n",
2305 info->si_code, fault, tid, esp, seg->start, seg->end);
njn96986052009-04-30 07:41:24 +00002306 }
2307
2308 if (info->si_code == VKI_SEGV_MAPERR
2309 && seg
2310 && seg->kind == SkResvn
2311 && seg->smode == SmUpper
2312 && seg_next
2313 && seg_next->kind == SkAnonC
2314 && seg->end+1 == seg_next->start
sewardjb5b87402011-03-07 16:05:35 +00002315 && fault >= fault_mask(esp - VG_STACK_REDZONE_SZB)) {
njn96986052009-04-30 07:41:24 +00002316 /* If the fault address is above esp but below the current known
2317 stack segment base, and it was a fault because there was
2318 nothing mapped there (as opposed to a permissions fault),
2319 then extend the stack segment.
2320 */
2321 Addr base = VG_PGROUNDDN(esp - VG_STACK_REDZONE_SZB);
2322 if (VG_(extend_stack)(base, VG_(threads)[tid].client_stack_szB)) {
2323 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002324 VG_(dmsg)(" -> extended stack base to %#lx\n",
2325 VG_PGROUNDDN(fault));
njn96986052009-04-30 07:41:24 +00002326 return True;
2327 } else {
sewardj738856f2009-07-15 14:48:32 +00002328 VG_(umsg)("Stack overflow in thread %d: can't grow stack to %#lx\n",
2329 tid, fault);
njn96986052009-04-30 07:41:24 +00002330 return False;
2331 }
2332 } else {
2333 return False;
2334 }
2335}
2336
2337static
njn2d5ff4f2009-05-03 22:53:19 +00002338void sync_signalhandler_from_kernel ( ThreadId tid,
njn96986052009-04-30 07:41:24 +00002339 Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
2340{
2341 /* Check to see if some part of Valgrind itself is interested in faults.
2342 The fault catcher should never be set whilst we're in generated code, so
2343 check for that. AFAIK the only use of the catcher right now is
2344 memcheck's leak detector. */
2345 if (fault_catcher) {
2346 vg_assert(VG_(in_generated_code) == False);
2347
2348 (*fault_catcher)(sigNo, (Addr)info->VKI_SIGINFO_si_addr);
2349 /* If the catcher returns, then it didn't handle the fault,
2350 so carry on panicking. */
2351 }
2352
2353 if (extend_stack_if_appropriate(tid, info)) {
2354 /* Stack extension occurred, so we don't need to do anything else; upon
2355 returning from this function, we'll restart the host (hence guest)
2356 instruction. */
2357 } else {
2358 /* OK, this is a signal we really have to deal with. If it came
2359 from the client's code, then we can jump back into the scheduler
2360 and have it delivered. Otherwise it's a Valgrind bug. */
2361 ThreadState *tst = VG_(get_ThreadState)(tid);
2362
2363 if (VG_(sigismember)(&tst->sig_mask, sigNo)) {
2364 /* signal is blocked, but they're not allowed to block faults */
2365 VG_(set_default_handler)(sigNo);
2366 }
2367
2368 if (VG_(in_generated_code)) {
sewardj3b290482011-05-06 21:02:55 +00002369 if (VG_(gdbserver_report_signal) (sigNo, tid)
2370 || VG_(sigismember)(&tst->sig_mask, sigNo)) {
2371 /* Can't continue; must longjmp back to the scheduler and thus
2372 enter the sighandler immediately. */
2373 deliver_signal(tid, info, uc);
2374 resume_scheduler(tid);
2375 }
2376 else
2377 resume_scheduler(tid);
njn96986052009-04-30 07:41:24 +00002378 }
2379
2380 /* If resume_scheduler returns or its our fault, it means we
2381 don't have longjmp set up, implying that we weren't running
2382 client code, and therefore it was actually generated by
2383 Valgrind internally.
2384 */
sewardj738856f2009-07-15 14:48:32 +00002385 VG_(dmsg)("VALGRIND INTERNAL ERROR: Valgrind received "
2386 "a signal %d (%s) - exiting\n",
2387 sigNo, signame(sigNo));
njn96986052009-04-30 07:41:24 +00002388
sewardj738856f2009-07-15 14:48:32 +00002389 VG_(dmsg)("si_code=%x; Faulting address: %p; sp: %#lx\n",
2390 info->si_code, info->VKI_SIGINFO_si_addr,
2391 VG_UCONTEXT_STACK_PTR(uc));
njn96986052009-04-30 07:41:24 +00002392
2393 if (0)
2394 VG_(kill_self)(sigNo); /* generate a core dump */
2395
2396 //if (tid == 0) /* could happen after everyone has exited */
2397 // tid = VG_(master_tid);
2398 vg_assert(tid != 0);
2399
sewardj59570ff2010-01-01 11:59:33 +00002400 UnwindStartRegs startRegs;
2401 VG_(memset)(&startRegs, 0, sizeof(startRegs));
2402
2403 VG_UCONTEXT_TO_UnwindStartRegs(&startRegs, uc);
2404 VG_(core_panic_at)("Killed by fatal signal", &startRegs);
njn96986052009-04-30 07:41:24 +00002405 }
2406}
sewardjb5f6f512005-03-10 23:59:00 +00002407
jsgf855d93d2003-10-13 22:26:55 +00002408/*
sewardj2a99cf62004-11-24 10:44:19 +00002409 Receive a sync signal from the host.
jsgf855d93d2003-10-13 22:26:55 +00002410*/
2411static
njn5a350be2009-04-30 03:05:05 +00002412void sync_signalhandler ( Int sigNo,
2413 vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00002414{
sewardj42781722006-12-17 19:36:06 +00002415 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
njn2d5ff4f2009-05-03 22:53:19 +00002416 Bool from_user;
jsgf855d93d2003-10-13 22:26:55 +00002417
njn5a350be2009-04-30 03:05:05 +00002418 if (0)
2419 VG_(printf)("sync_sighandler(%d, %p, %p)\n", sigNo, info, uc);
2420
jsgf855d93d2003-10-13 22:26:55 +00002421 vg_assert(info != NULL);
2422 vg_assert(info->si_signo == sigNo);
2423 vg_assert(sigNo == VKI_SIGSEGV ||
2424 sigNo == VKI_SIGBUS ||
2425 sigNo == VKI_SIGFPE ||
sewardjb5f6f512005-03-10 23:59:00 +00002426 sigNo == VKI_SIGILL ||
2427 sigNo == VKI_SIGTRAP);
jsgf855d93d2003-10-13 22:26:55 +00002428
njn3b6b2aa2009-04-30 03:30:09 +00002429 info->si_code = sanitize_si_code(info->si_code);
tom9f4a7bf2005-11-13 00:01:20 +00002430
njnf76d27a2009-05-28 01:53:07 +00002431 from_user = !is_signal_from_kernel(tid, sigNo, info->si_code);
njn81f52d12009-04-30 03:49:06 +00002432
2433 if (VG_(clo_trace_signals)) {
sewardj738856f2009-07-15 14:48:32 +00002434 VG_(dmsg)("sync signal handler: "
2435 "signal=%d, si_code=%d, EIP=%#lx, eip=%#lx, from %s\n",
2436 sigNo, info->si_code, VG_(get_IP)(tid),
2437 VG_UCONTEXT_INSTR_PTR(uc),
2438 ( from_user ? "user" : "kernel" ));
njn81f52d12009-04-30 03:49:06 +00002439 }
2440 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
2441
njn36fce1b2009-04-28 01:55:01 +00002442 /* // debug code:
2443 if (0) {
2444 VG_(printf)("info->si_signo %d\n", info->si_signo);
2445 VG_(printf)("info->si_errno %d\n", info->si_errno);
2446 VG_(printf)("info->si_code %d\n", info->si_code);
2447 VG_(printf)("info->si_pid %d\n", info->si_pid);
2448 VG_(printf)("info->si_uid %d\n", info->si_uid);
2449 VG_(printf)("info->si_status %d\n", info->si_status);
2450 VG_(printf)("info->si_addr %p\n", info->si_addr);
2451 }
2452 */
2453
2454 /* Figure out if the signal is being sent from outside the process.
2455 (Why do we care?) If the signal is from the user rather than the
njn96986052009-04-30 07:41:24 +00002456 kernel, then treat it more like an async signal than a sync signal --
njn36fce1b2009-04-28 01:55:01 +00002457 that is, merely queue it for later delivery. */
njn2d5ff4f2009-05-03 22:53:19 +00002458 if (from_user) {
njnc8a91072009-05-20 06:51:11 +00002459 sync_signalhandler_from_user( tid, sigNo, info, uc);
njn96986052009-04-30 07:41:24 +00002460 } else {
njnc8a91072009-05-20 06:51:11 +00002461 sync_signalhandler_from_kernel(tid, sigNo, info, uc);
jsgf855d93d2003-10-13 22:26:55 +00002462 }
2463}
2464
2465
2466/*
sewardjb5f6f512005-03-10 23:59:00 +00002467 Kill this thread. Makes it leave any syscall it might be currently
2468 blocked in, and return to the scheduler. This doesn't mark the thread
2469 as exiting; that's the caller's job.
jsgf855d93d2003-10-13 22:26:55 +00002470 */
njn5a350be2009-04-30 03:05:05 +00002471static void sigvgkill_handler(int signo, vki_siginfo_t *si,
2472 struct vki_ucontext *uc)
jsgf855d93d2003-10-13 22:26:55 +00002473{
sewardj42781722006-12-17 19:36:06 +00002474 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
sewardj489bfec2006-10-17 02:00:29 +00002475 ThreadStatus at_signal = VG_(threads)[tid].status;
sewardjb5f6f512005-03-10 23:59:00 +00002476
2477 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002478 VG_(dmsg)("sigvgkill for lwp %d tid %d\n", VG_(gettid)(), tid);
sewardj489bfec2006-10-17 02:00:29 +00002479
sewardjad0a3a82006-12-17 18:58:55 +00002480 VG_(acquire_BigLock)(tid, "sigvgkill_handler");
sewardjb5f6f512005-03-10 23:59:00 +00002481
njn351d0062005-06-21 22:23:59 +00002482 vg_assert(signo == VG_SIGVGKILL);
jsgf855d93d2003-10-13 22:26:55 +00002483 vg_assert(si->si_signo == signo);
2484
sewardj489bfec2006-10-17 02:00:29 +00002485 /* jrs 2006 August 3: the following assertion seems incorrect to
2486 me, and fails on AIX. sigvgkill could be sent to a thread which
2487 is runnable - see VG_(nuke_all_threads_except) in the scheduler.
2488 Hence comment these out ..
2489
2490 vg_assert(VG_(threads)[tid].status == VgTs_WaitSys);
2491 VG_(post_syscall)(tid);
2492
2493 and instead do:
2494 */
2495 if (at_signal == VgTs_WaitSys)
2496 VG_(post_syscall)(tid);
2497 /* jrs 2006 August 3 ends */
sewardjb5f6f512005-03-10 23:59:00 +00002498
njn06244e72005-06-21 22:27:19 +00002499 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002500
2501 VG_(core_panic)("sigvgkill_handler couldn't return to the scheduler\n");
sewardjde4a1d02002-03-22 01:27:54 +00002502}
2503
sewardjde4a1d02002-03-22 01:27:54 +00002504static __attribute((unused))
njncda2f0f2009-05-18 02:12:08 +00002505void pp_ksigaction ( vki_sigaction_toK_t* sa )
sewardjde4a1d02002-03-22 01:27:54 +00002506{
2507 Int i;
njn695c16e2005-03-27 03:40:28 +00002508 VG_(printf)("pp_ksigaction: handler %p, flags 0x%x, restorer %p\n",
sewardj489bfec2006-10-17 02:00:29 +00002509 sa->ksa_handler,
2510 (UInt)sa->sa_flags,
njnf76d27a2009-05-28 01:53:07 +00002511# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
2512 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
sewardj489bfec2006-10-17 02:00:29 +00002513 sa->sa_restorer
2514# else
sewardja8ffda62008-07-18 18:23:24 +00002515 (void*)0
sewardj489bfec2006-10-17 02:00:29 +00002516# endif
2517 );
njn695c16e2005-03-27 03:40:28 +00002518 VG_(printf)("pp_ksigaction: { ");
sewardjb5f6f512005-03-10 23:59:00 +00002519 for (i = 1; i <= VG_(max_signal); i++)
nethercote73b526f2004-10-31 18:48:21 +00002520 if (VG_(sigismember(&(sa->sa_mask),i)))
sewardjde4a1d02002-03-22 01:27:54 +00002521 VG_(printf)("%d ", i);
2522 VG_(printf)("}\n");
2523}
2524
jsgf855d93d2003-10-13 22:26:55 +00002525/*
sewardjb5f6f512005-03-10 23:59:00 +00002526 Force signal handler to default
jsgf855d93d2003-10-13 22:26:55 +00002527 */
sewardjb5f6f512005-03-10 23:59:00 +00002528void VG_(set_default_handler)(Int signo)
2529{
njncda2f0f2009-05-18 02:12:08 +00002530 vki_sigaction_toK_t sa;
sewardjb5f6f512005-03-10 23:59:00 +00002531
2532 sa.ksa_handler = VKI_SIG_DFL;
2533 sa.sa_flags = 0;
njnf76d27a2009-05-28 01:53:07 +00002534# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
2535 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
sewardjb5f6f512005-03-10 23:59:00 +00002536 sa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00002537# endif
sewardjb5f6f512005-03-10 23:59:00 +00002538 VG_(sigemptyset)(&sa.sa_mask);
2539
2540 VG_(do_sys_sigaction)(signo, &sa, NULL);
2541}
2542
2543/*
2544 Poll for pending signals, and set the next one up for delivery.
2545 */
2546void VG_(poll_signals)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00002547{
sewardjb5f6f512005-03-10 23:59:00 +00002548 vki_siginfo_t si, *sip;
2549 vki_sigset_t pollset;
2550 ThreadState *tst = VG_(get_ThreadState)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002551 vki_sigset_t saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002552
sewardjb5f6f512005-03-10 23:59:00 +00002553 /* look for all the signals this thread isn't blocking */
njncda2f0f2009-05-18 02:12:08 +00002554 /* pollset = ~tst->sig_mask */
2555 VG_(sigcomplementset)( &pollset, &tst->sig_mask );
jsgf855d93d2003-10-13 22:26:55 +00002556
njn444eba12005-05-12 03:47:31 +00002557 block_all_host_signals(&saved_mask); // protect signal queue
sewardjb5f6f512005-03-10 23:59:00 +00002558
2559 /* First look for any queued pending signals */
2560 sip = next_queued(tid, &pollset); /* this thread */
2561
2562 if (sip == NULL)
2563 sip = next_queued(0, &pollset); /* process-wide */
2564
2565 /* If there was nothing queued, ask the kernel for a pending signal */
sewardj489bfec2006-10-17 02:00:29 +00002566 if (sip == NULL && VG_(sigtimedwait_zero)(&pollset, &si) > 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002567 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002568 VG_(dmsg)("poll_signals: got signal %d for thread %d\n",
2569 si.si_signo, tid);
sewardjb5f6f512005-03-10 23:59:00 +00002570 sip = &si;
thughes8abf3922004-10-16 10:59:49 +00002571 }
fitzhardingee1c06d82003-10-30 07:21:44 +00002572
sewardjb5f6f512005-03-10 23:59:00 +00002573 if (sip != NULL) {
2574 /* OK, something to do; deliver it */
2575 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002576 VG_(dmsg)("Polling found signal %d for tid %d\n", sip->si_signo, tid);
sewardj3b290482011-05-06 21:02:55 +00002577 if (!is_sig_ign(sip->si_signo, tid))
tomadacaf92007-12-21 10:24:24 +00002578 deliver_signal(tid, sip, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002579 else if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002580 VG_(dmsg)(" signal %d ignored\n", sip->si_signo);
sewardjb5f6f512005-03-10 23:59:00 +00002581
2582 sip->si_signo = 0; /* remove from signal queue, if that's
2583 where it came from */
jsgf855d93d2003-10-13 22:26:55 +00002584 }
2585
njn444eba12005-05-12 03:47:31 +00002586 restore_all_host_signals(&saved_mask);
sewardjb5f6f512005-03-10 23:59:00 +00002587}
2588
sewardj018f7622002-05-15 21:13:39 +00002589/* At startup, copy the process' real signal state to the SCSS.
2590 Whilst doing this, block all real signals. Then calculate SKSS and
2591 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00002592*/
2593void VG_(sigstartup_actions) ( void )
2594{
njncda2f0f2009-05-18 02:12:08 +00002595 Int i, ret, vKI_SIGRTMIN;
nethercote73b526f2004-10-31 18:48:21 +00002596 vki_sigset_t saved_procmask;
njncda2f0f2009-05-18 02:12:08 +00002597 vki_sigaction_fromK_t sa;
2598
2599 VG_(memset)(&scss, 0, sizeof(scss));
2600 VG_(memset)(&skss, 0, sizeof(skss));
2601
2602# if defined(VKI_SIGRTMIN)
2603 vKI_SIGRTMIN = VKI_SIGRTMIN;
2604# else
2605 vKI_SIGRTMIN = 0; /* eg Darwin */
2606# endif
sewardjde4a1d02002-03-22 01:27:54 +00002607
sewardj2e93c502002-04-12 11:12:52 +00002608 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00002609 /* Block all signals. saved_procmask remembers the previous mask,
2610 which the first thread inherits.
2611 */
njn444eba12005-05-12 03:47:31 +00002612 block_all_host_signals( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00002613
sewardj018f7622002-05-15 21:13:39 +00002614 /* Copy per-signal settings to SCSS. */
nethercote73b526f2004-10-31 18:48:21 +00002615 for (i = 1; i <= _VKI_NSIG; i++) {
sewardj018f7622002-05-15 21:13:39 +00002616 /* Get the old host action */
nethercote73b526f2004-10-31 18:48:21 +00002617 ret = VG_(sigaction)(i, NULL, &sa);
sewardj018f7622002-05-15 21:13:39 +00002618
njnea2d6fd2010-07-01 00:20:20 +00002619# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
njnf76d27a2009-05-28 01:53:07 +00002620 /* apparently we may not even ask about the disposition of these
2621 signals, let alone change them */
2622 if (ret != 0 && (i == VKI_SIGKILL || i == VKI_SIGSTOP))
2623 continue;
2624# endif
2625
sewardjb5f6f512005-03-10 23:59:00 +00002626 if (ret != 0)
2627 break;
2628
2629 /* Try setting it back to see if this signal is really
2630 available */
njncda2f0f2009-05-18 02:12:08 +00002631 if (vKI_SIGRTMIN > 0 /* it actually exists on this platform */
2632 && i >= vKI_SIGRTMIN) {
2633 vki_sigaction_toK_t tsa, sa2;
sewardjb5f6f512005-03-10 23:59:00 +00002634
njn695c16e2005-03-27 03:40:28 +00002635 tsa.ksa_handler = (void *)sync_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +00002636 tsa.sa_flags = VKI_SA_SIGINFO;
njnf76d27a2009-05-28 01:53:07 +00002637# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
2638 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
sewardjb5f6f512005-03-10 23:59:00 +00002639 tsa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00002640# endif
sewardjb5f6f512005-03-10 23:59:00 +00002641 VG_(sigfillset)(&tsa.sa_mask);
2642
2643 /* try setting it to some arbitrary handler */
2644 if (VG_(sigaction)(i, &tsa, NULL) != 0) {
2645 /* failed - not really usable */
2646 break;
2647 }
2648
njncda2f0f2009-05-18 02:12:08 +00002649 VG_(convert_sigaction_fromK_to_toK)( &sa, &sa2 );
2650 ret = VG_(sigaction)(i, &sa2, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002651 vg_assert(ret == 0);
2652 }
2653
2654 VG_(max_signal) = i;
2655
2656 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
njn8a7b41b2007-09-23 00:51:24 +00002657 VG_(printf)("snaffling handler 0x%lx for signal %d\n",
sewardj018f7622002-05-15 21:13:39 +00002658 (Addr)(sa.ksa_handler), i );
2659
njn695c16e2005-03-27 03:40:28 +00002660 scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
2661 scss.scss_per_sig[i].scss_flags = sa.sa_flags;
2662 scss.scss_per_sig[i].scss_mask = sa.sa_mask;
njncda2f0f2009-05-18 02:12:08 +00002663
2664 scss.scss_per_sig[i].scss_restorer = NULL;
njnf76d27a2009-05-28 01:53:07 +00002665# if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) && \
2666 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn695c16e2005-03-27 03:40:28 +00002667 scss.scss_per_sig[i].scss_restorer = sa.sa_restorer;
sewardj489bfec2006-10-17 02:00:29 +00002668# endif
njncda2f0f2009-05-18 02:12:08 +00002669
2670 scss.scss_per_sig[i].scss_sa_tramp = NULL;
njnf76d27a2009-05-28 01:53:07 +00002671# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
2672 scss.scss_per_sig[i].scss_sa_tramp = NULL;
2673 /*sa.sa_tramp;*/
2674 /* We can't know what it was, because Darwin's sys_sigaction
2675 doesn't tell us. */
2676# endif
sewardj018f7622002-05-15 21:13:39 +00002677 }
2678
sewardjb5f6f512005-03-10 23:59:00 +00002679 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002680 VG_(dmsg)("Max kernel-supported signal is %d\n", VG_(max_signal));
sewardjb5f6f512005-03-10 23:59:00 +00002681
jsgf855d93d2003-10-13 22:26:55 +00002682 /* Our private internal signals are treated as ignored */
njn351d0062005-06-21 22:23:59 +00002683 scss.scss_per_sig[VG_SIGVGKILL].scss_handler = VKI_SIG_IGN;
2684 scss.scss_per_sig[VG_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
2685 VG_(sigfillset)(&scss.scss_per_sig[VG_SIGVGKILL].scss_mask);
jsgf855d93d2003-10-13 22:26:55 +00002686
sewardj018f7622002-05-15 21:13:39 +00002687 /* Copy the process' signal mask into the root thread. */
sewardj1d887112005-05-30 21:44:08 +00002688 vg_assert(VG_(threads)[1].status == VgTs_Init);
2689 for (i = 2; i < VG_N_THREADS; i++)
2690 vg_assert(VG_(threads)[i].status == VgTs_Empty);
2691
2692 VG_(threads)[1].sig_mask = saved_procmask;
2693 VG_(threads)[1].tmp_sig_mask = saved_procmask;
sewardj7a61d912002-04-25 01:27:35 +00002694
sewardj018f7622002-05-15 21:13:39 +00002695 /* Calculate SKSS and apply it. This also sets the initial kernel
2696 mask we need to run with. */
nethercote9dd11512004-08-04 15:31:30 +00002697 handle_SCSS_change( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00002698
sewardjb5f6f512005-03-10 23:59:00 +00002699 /* Leave with all signals still blocked; the thread scheduler loop
2700 will set the appropriate mask at the appropriate time. */
sewardjde4a1d02002-03-22 01:27:54 +00002701}
2702
sewardjde4a1d02002-03-22 01:27:54 +00002703/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00002704/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00002705/*--------------------------------------------------------------------*/