blob: 5dc5f2f57469e3e6e95c442f92c0bedae3c62f6a [file] [log] [blame]
florian15fa8a22015-03-03 14:56:17 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
sewardjde4a1d02002-03-22 01:27:54 +00002
3/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00004/*--- Implementation of POSIX signals. m_signals.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00005/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00006
sewardjde4a1d02002-03-22 01:27:54 +00007/*
njnb9c427c2004-12-01 14:14:42 +00008 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
sewardjde4a1d02002-03-22 01:27:54 +000010
sewardj0f157dd2013-10-18 14:27:36 +000011 Copyright (C) 2000-2013 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000012 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
njn25e49d8e72002-09-23 09:36:25 +000029 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000030*/
31
jsgf855d93d2003-10-13 22:26:55 +000032/*
sewardjb5f6f512005-03-10 23:59:00 +000033 Signal handling.
jsgf855d93d2003-10-13 22:26:55 +000034
sewardjb5f6f512005-03-10 23:59:00 +000035 There are 4 distinct classes of signal:
jsgf855d93d2003-10-13 22:26:55 +000036
sewardjb5f6f512005-03-10 23:59:00 +000037 1. Synchronous, instruction-generated (SIGILL, FPE, BUS, SEGV and
38 TRAP): these are signals as a result of an instruction fault. If
39 we get one while running client code, then we just do the
40 appropriate thing. If it happens while running Valgrind code, then
41 it indicates a Valgrind bug. Note that we "manually" implement
42 automatic stack growth, such that if a fault happens near the
43 client process stack, it is extended in the same way the kernel
44 would, and the fault is never reported to the client program.
jsgf855d93d2003-10-13 22:26:55 +000045
njn1ee02e32009-05-04 06:54:04 +000046 2. Asynchronous variants of the above signals: If the kernel tries
sewardjb5f6f512005-03-10 23:59:00 +000047 to deliver a sync signal while it is blocked, it just kills the
48 process. Therefore, we can't block those signals if we want to be
49 able to report on bugs in Valgrind. This means that we're also
50 open to receiving those signals from other processes, sent with
51 kill. We could get away with just dropping them, since they aren't
52 really signals that processes send to each other.
jsgf855d93d2003-10-13 22:26:55 +000053
sewardjb5f6f512005-03-10 23:59:00 +000054 3. Synchronous, general signals. If a thread/process sends itself
55 a signal with kill, its expected to be synchronous: ie, the signal
56 will have been delivered by the time the syscall finishes.
57
sewardj67b38c32010-01-01 12:44:12 +000058 4. Asynchronous, general signals. All other signals, sent by
sewardjb5f6f512005-03-10 23:59:00 +000059 another process with kill. These are generally blocked, except for
60 two special cases: we poll for them each time we're about to run a
61 thread for a time quanta, and while running blocking syscalls.
jsgf855d93d2003-10-13 22:26:55 +000062
jsgf855d93d2003-10-13 22:26:55 +000063
sewardjebf58442010-03-01 16:42:56 +000064 In addition, we reserve one signal for internal use: SIGVGKILL.
sewardjb5f6f512005-03-10 23:59:00 +000065 SIGVGKILL is used to terminate threads. When one thread wants
66 another to exit, it will set its exitreason and send it SIGVGKILL
67 if it appears to be blocked in a syscall.
68
69
70 We use a kernel thread for each application thread. When the
71 thread allows itself to be open to signals, it sets the thread
72 signal mask to what the client application set it to. This means
73 that we get the kernel to do all signal routing: under Valgrind,
74 signals get delivered in the same way as in the non-Valgrind case
75 (the exception being for the sync signal set, since they're almost
76 always unblocked).
jsgf855d93d2003-10-13 22:26:55 +000077 */
sewardjde4a1d02002-03-22 01:27:54 +000078
njn1ee02e32009-05-04 06:54:04 +000079/*
80 Some more details...
81
82 First off, we take note of the client's requests (via sys_sigaction
83 and sys_sigprocmask) to set the signal state (handlers for each
84 signal, which are process-wide, + a mask for each signal, which is
85 per-thread). This info is duly recorded in the SCSS (static Client
86 signal state) in m_signals.c, and if the client later queries what
87 the state is, we merely fish the relevant info out of SCSS and give
88 it back.
89
90 However, we set the real signal state in the kernel to something
91 entirely different. This is recorded in SKSS, the static Kernel
92 signal state. What's nice (to the extent that anything is nice w.r.t
93 signals) is that there's a pure function to calculate SKSS from SCSS,
94 calculate_SKSS_from_SCSS. So when the client changes SCSS then we
95 recompute the associated SKSS and apply any changes from the previous
96 SKSS through to the kernel.
97
98 Now, that said, the general scheme we have now is, that regardless of
99 what the client puts into the SCSS (viz, asks for), what we would
100 like to do is as follows:
101
102 (1) run code on the virtual CPU with all signals blocked
103
104 (2) at convenient moments for us (that is, when the VCPU stops, and
105 control is back with the scheduler), ask the kernel "do you have
106 any signals for me?" and if it does, collect up the info, and
107 deliver them to the client (by building sigframes).
108
109 And that's almost what we do. The signal polling is done by
110 VG_(poll_signals), which calls through to VG_(sigtimedwait_zero) to
111 do the dirty work. (of which more later).
112
113 By polling signals, rather than catching them, we get to deal with
114 them only at convenient moments, rather than having to recover from
115 taking a signal while generated code is running.
116
117 Now unfortunately .. the above scheme only works for so-called async
118 signals. An async signal is one which isn't associated with any
119 particular instruction, eg Control-C (SIGINT). For those, it doesn't
120 matter if we don't deliver the signal to the client immediately; it
121 only matters that we deliver it eventually. Hence polling is OK.
122
123 But the other group -- sync signals -- are all related by the fact
124 that they are various ways for the host CPU to fail to execute an
125 instruction: SIGILL, SIGSEGV, SIGFPU. And they can't be deferred,
126 because obviously if a host instruction can't execute, well then we
127 have to immediately do Plan B, whatever that is.
128
129 So the next approximation of what happens is:
130
131 (1) run code on vcpu with all async signals blocked
132
133 (2) at convenient moments (when NOT running the vcpu), poll for async
134 signals.
135
136 (1) and (2) together imply that if the host does deliver a signal to
137 async_signalhandler while the VCPU is running, something's
138 seriously wrong.
139
140 (3) when running code on vcpu, don't block sync signals. Instead
141 register sync_signalhandler and catch any such via that. Of
142 course, that means an ugly recovery path if we do -- the
143 sync_signalhandler has to longjump, exiting out of the generated
144 code, and the assembly-dispatcher thingy that runs it, and gets
145 caught in m_scheduler, which then tells m_signals to deliver the
146 signal.
147
148 Now naturally (ha ha) even that might be tolerable, but there's
149 something worse: dealing with signals delivered to threads in
150 syscalls.
151
152 Obviously from the above, SKSS's signal mask (viz, what we really run
153 with) is way different from SCSS's signal mask (viz, what the client
154 thread thought it asked for). (eg) It may well be that the client
155 did not block control-C, so that it just expects to drop dead if it
156 receives ^C whilst blocked in a syscall, but by default we are
157 running with all async signals blocked, and so that signal could be
158 arbitrarily delayed, or perhaps even lost (not sure).
159
160 So what we have to do, when doing any syscall which SfMayBlock, is to
161 quickly switch in the SCSS-specified signal mask just before the
162 syscall, and switch it back just afterwards, and hope that we don't
163 get caught up in some wierd race condition. This is the primary
164 purpose of the ultra-magical pieces of assembly code in
165 coregrind/m_syswrap/syscall-<plat>.S
166
167 -----------
168
169 The ways in which V can come to hear of signals that need to be
170 forwarded to the client as are follows:
171
172 sync signals: can arrive at any time whatsoever. These are caught
173 by sync_signalhandler
174
175 async signals:
176
177 if running generated code
178 then these are blocked, so we don't expect to catch them in
179 async_signalhandler
180
181 else
182 if thread is blocked in a syscall marked SfMayBlock
183 then signals may be delivered to async_sighandler, since we
184 temporarily unblocked them for the duration of the syscall,
185 by using the real (SCSS) mask for this thread
186
187 else we're doing misc housekeeping activities (eg, making a translation,
188 washing our hair, etc). As in the normal case, these signals are
189 blocked, but we can and do poll for them using VG_(poll_signals).
190
191 Now, re VG_(poll_signals), it polls the kernel by doing
192 VG_(sigtimedwait_zero). This is trivial on Linux, since it's just a
193 syscall. But on Darwin and AIX, we have to cobble together the
194 functionality in a tedious, longwinded and probably error-prone way.
sewardj3b290482011-05-06 21:02:55 +0000195
196 Finally, if a gdb is debugging the process under valgrind,
197 the signal can be ignored if gdb tells this. So, before resuming the
198 scheduler/delivering the signal, a call to VG_(gdbserver_report_signal)
199 is done. If this returns True, the signal is delivered.
njn1ee02e32009-05-04 06:54:04 +0000200 */
201
njnc7561b92005-06-19 01:24:32 +0000202#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +0000203#include "pub_core_vki.h"
sewardj489bfec2006-10-17 02:00:29 +0000204#include "pub_core_vkiscnums.h"
sewardj45f4e7c2005-09-27 19:20:21 +0000205#include "pub_core_debuglog.h"
sewardj6c591e12011-04-11 16:17:51 +0000206#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
njnc7561b92005-06-19 01:24:32 +0000207#include "pub_core_threadstate.h"
sewardj14c7cc52007-02-25 15:08:24 +0000208#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +0000209#include "pub_core_clientstate.h"
njn2521d322005-05-08 14:45:13 +0000210#include "pub_core_aspacemgr.h"
njn634a6522005-07-02 01:59:28 +0000211#include "pub_core_debugger.h" // For VG_(start_debugger)
njnd2b17112005-04-19 04:10:25 +0000212#include "pub_core_errormgr.h"
sewardj3b290482011-05-06 21:02:55 +0000213#include "pub_core_gdbserver.h"
njn97405b22005-06-02 03:39:33 +0000214#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +0000215#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +0000216#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +0000217#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +0000218#include "pub_core_libcsignal.h"
njnf536bbb2005-06-13 04:21:38 +0000219#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +0000220#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +0000221#include "pub_core_options.h"
njnc7561b92005-06-19 01:24:32 +0000222#include "pub_core_scheduler.h"
njn0c246472005-05-31 01:00:08 +0000223#include "pub_core_signals.h"
njn24a6efb2005-06-20 03:36:51 +0000224#include "pub_core_sigframe.h" // For VG_(sigframe_create)()
njn945ed2e2005-06-24 03:28:30 +0000225#include "pub_core_stacks.h" // For VG_(change_stack)()
njn24a6efb2005-06-20 03:36:51 +0000226#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
njn9abd6082005-06-17 21:31:45 +0000227#include "pub_core_syscall.h"
njnc1b01812005-06-17 22:19:06 +0000228#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +0000229#include "pub_core_tooliface.h"
sewardjcf4ac712005-11-01 00:03:40 +0000230#include "pub_core_coredump.h"
sewardj985fabb2005-04-24 14:18:14 +0000231
njnd2b17112005-04-19 04:10:25 +0000232
sewardj018f7622002-05-15 21:13:39 +0000233/* ---------------------------------------------------------------------
234 Forwards decls.
235 ------------------------------------------------------------------ */
236
njn5a350be2009-04-30 03:05:05 +0000237static void sync_signalhandler ( Int sigNo, vki_siginfo_t *info,
238 struct vki_ucontext * );
239static void async_signalhandler ( Int sigNo, vki_siginfo_t *info,
240 struct vki_ucontext * );
241static void sigvgkill_handler ( Int sigNo, vki_siginfo_t *info,
242 struct vki_ucontext * );
sewardj018f7622002-05-15 21:13:39 +0000243
sewardjb5f6f512005-03-10 23:59:00 +0000244/* Maximum usable signal. */
245Int VG_(max_signal) = _VKI_NSIG;
nethercote759dda32004-08-07 18:16:56 +0000246
sewardjb5f6f512005-03-10 23:59:00 +0000247#define N_QUEUED_SIGNALS 8
nethercote759dda32004-08-07 18:16:56 +0000248
sewardjb5f6f512005-03-10 23:59:00 +0000249typedef struct SigQueue {
250 Int next;
251 vki_siginfo_t sigs[N_QUEUED_SIGNALS];
252} SigQueue;
nethercote759dda32004-08-07 18:16:56 +0000253
sewardj489bfec2006-10-17 02:00:29 +0000254/* ------ Macros for pulling stuff out of ucontexts ------ */
255
njncda2f0f2009-05-18 02:12:08 +0000256/* Q: what does VG_UCONTEXT_SYSCALL_SYSRES do? A: let's suppose the
njn5a350be2009-04-30 03:05:05 +0000257 machine context (uc) reflects the situation that a syscall had just
258 completed, quite literally -- that is, that the program counter was
259 now at the instruction following the syscall. (or we're slightly
260 downstream, but we're sure no relevant register has yet changed
njncda2f0f2009-05-18 02:12:08 +0000261 value.) Then VG_UCONTEXT_SYSCALL_SYSRES returns a SysRes reflecting
njn5a350be2009-04-30 03:05:05 +0000262 the result of the syscall; it does this by fishing relevant bits of
263 the machine state out of the uc. Of course if the program counter
264 was somewhere else entirely then the result is likely to be
njncda2f0f2009-05-18 02:12:08 +0000265 meaningless, so the caller of VG_UCONTEXT_SYSCALL_SYSRES has to be
njn5a350be2009-04-30 03:05:05 +0000266 very careful to pay attention to the results only when it is sure
267 that the said constraint on the program counter is indeed valid. */
sewardjf5f1e122010-01-02 13:24:58 +0000268
njn605f4882005-05-29 17:50:40 +0000269#if defined(VGP_x86_linux)
njnaf839f52005-06-23 03:27:57 +0000270# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.eip)
271# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp)
sewardjacaec5f2005-08-19 16:02:59 +0000272# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardja8d8e232005-06-07 20:04:56 +0000273 /* Convert the value in uc_mcontext.eax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000274 VG_(mk_SysRes_x86_linux)( (uc)->uc_mcontext.eax )
sewardj59570ff2010-01-01 11:59:33 +0000275# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
276 { (srP)->r_pc = (ULong)((uc)->uc_mcontext.eip); \
277 (srP)->r_sp = (ULong)((uc)->uc_mcontext.esp); \
278 (srP)->misc.X86.r_ebp = (uc)->uc_mcontext.ebp; \
279 }
sewardje7aa4ae2005-06-09 12:43:42 +0000280
njn605f4882005-05-29 17:50:40 +0000281#elif defined(VGP_amd64_linux)
njnaf839f52005-06-23 03:27:57 +0000282# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.rip)
283# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.rsp)
sewardjacaec5f2005-08-19 16:02:59 +0000284# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardje7aa4ae2005-06-09 12:43:42 +0000285 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000286 VG_(mk_SysRes_amd64_linux)( (uc)->uc_mcontext.rax )
sewardj59570ff2010-01-01 11:59:33 +0000287# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
288 { (srP)->r_pc = (uc)->uc_mcontext.rip; \
289 (srP)->r_sp = (uc)->uc_mcontext.rsp; \
290 (srP)->misc.AMD64.r_rbp = (uc)->uc_mcontext.rbp; \
291 }
sewardje7aa4ae2005-06-09 12:43:42 +0000292
cerion85665ca2005-06-20 15:51:07 +0000293#elif defined(VGP_ppc32_linux)
sewardja36dcfa2005-11-25 02:16:58 +0000294/* Comments from Paul Mackerras 25 Nov 05:
295
296 > I'm tracking down a problem where V's signal handling doesn't
297 > work properly on a ppc440gx running 2.4.20. The problem is that
298 > the ucontext being presented to V's sighandler seems completely
299 > bogus.
300
301 > V's kernel headers and hence ucontext layout are derived from
302 > 2.6.9. I compared include/asm-ppc/ucontext.h from 2.4.20 and
303 > 2.6.13.
304
305 > Can I just check my interpretation: the 2.4.20 one contains the
306 > uc_mcontext field in line, whereas the 2.6.13 one has a pointer
307 > to said struct? And so if V is using the 2.6.13 struct then a
308 > 2.4.20 one will make no sense to it.
309
310 Not quite... what is inline in the 2.4.20 version is a
311 sigcontext_struct, not an mcontext. The sigcontext looks like
312 this:
313
314 struct sigcontext_struct {
315 unsigned long _unused[4];
316 int signal;
317 unsigned long handler;
318 unsigned long oldmask;
319 struct pt_regs *regs;
320 };
321
322 The regs pointer of that struct ends up at the same offset as the
323 uc_regs of the 2.6 struct ucontext, and a struct pt_regs is the
324 same as the mc_gregs field of the mcontext. In fact the integer
325 regs are followed in memory by the floating point regs on 2.4.20.
326
327 Thus if you are using the 2.6 definitions, it should work on 2.4.20
328 provided that you go via uc->uc_regs rather than looking in
329 uc->uc_mcontext directly.
330
331 There is another subtlety: 2.4.20 doesn't save the vector regs when
332 delivering a signal, and 2.6.x only saves the vector regs if the
333 process has ever used an altivec instructions. If 2.6.x does save
334 the vector regs, it sets the MSR_VEC bit in
335 uc->uc_regs->mc_gregs[PT_MSR], otherwise it clears it. That bit
336 will always be clear under 2.4.20. So you can use that bit to tell
337 whether uc->uc_regs->mc_vregs is valid. */
sewardjf5f1e122010-01-02 13:24:58 +0000338# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_NIP])
339# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
sewardj39a7c1d2005-11-24 03:54:38 +0000340# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
341 /* Convert the values in uc_mcontext r3,cr into a SysRes. */ \
342 VG_(mk_SysRes_ppc32_linux)( \
sewardja36dcfa2005-11-25 02:16:58 +0000343 (uc)->uc_regs->mc_gregs[VKI_PT_R3], \
344 (((uc)->uc_regs->mc_gregs[VKI_PT_CCR] >> 28) & 1) \
sewardj39a7c1d2005-11-24 03:54:38 +0000345 )
sewardjf5f1e122010-01-02 13:24:58 +0000346# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
347 { (srP)->r_pc = (ULong)((uc)->uc_regs->mc_gregs[VKI_PT_NIP]); \
348 (srP)->r_sp = (ULong)((uc)->uc_regs->mc_gregs[VKI_PT_R1]); \
349 (srP)->misc.PPC32.r_lr = (uc)->uc_regs->mc_gregs[VKI_PT_LNK]; \
350 }
cerion85665ca2005-06-20 15:51:07 +0000351
carllcae0cc22014-08-07 23:17:29 +0000352#elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
sewardjf5f1e122010-01-02 13:24:58 +0000353# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_NIP])
354# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
sewardjdcb6ec82006-01-19 03:44:10 +0000355 /* Dubious hack: if there is an error, only consider the lowest 8
356 bits of r3. memcheck/tests/post-syscall shows a case where an
357 interrupted syscall should have produced a ucontext with 0x4
358 (VKI_EINTR) in r3 but is in fact producing 0x204. */
359 /* Awaiting clarification from PaulM. Evidently 0x204 is
360 ERESTART_RESTARTBLOCK, which shouldn't have made it into user
361 space. */
362 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( struct vki_ucontext* uc )
363 {
364 ULong err = (uc->uc_mcontext.gp_regs[VKI_PT_CCR] >> 28) & 1;
365 ULong r3 = uc->uc_mcontext.gp_regs[VKI_PT_R3];
366 if (err) r3 &= 0xFF;
367 return VG_(mk_SysRes_ppc64_linux)( r3, err );
368 }
sewardjf5f1e122010-01-02 13:24:58 +0000369# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
370 { (srP)->r_pc = (uc)->uc_mcontext.gp_regs[VKI_PT_NIP]; \
371 (srP)->r_sp = (uc)->uc_mcontext.gp_regs[VKI_PT_R1]; \
372 (srP)->misc.PPC64.r_lr = (uc)->uc_mcontext.gp_regs[VKI_PT_LNK]; \
373 }
sewardj2c48c7b2005-11-29 13:05:56 +0000374
sewardj59570ff2010-01-01 11:59:33 +0000375#elif defined(VGP_arm_linux)
376# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.arm_pc)
377# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.arm_sp)
378# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
379 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
380 VG_(mk_SysRes_arm_linux)( (uc)->uc_mcontext.arm_r0 )
381# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
382 { (srP)->r_pc = (uc)->uc_mcontext.arm_pc; \
383 (srP)->r_sp = (uc)->uc_mcontext.arm_sp; \
384 (srP)->misc.ARM.r14 = (uc)->uc_mcontext.arm_lr; \
385 (srP)->misc.ARM.r12 = (uc)->uc_mcontext.arm_ip; \
386 (srP)->misc.ARM.r11 = (uc)->uc_mcontext.arm_fp; \
sewardjfa5ce562010-09-23 22:05:59 +0000387 (srP)->misc.ARM.r7 = (uc)->uc_mcontext.arm_r7; \
sewardj59570ff2010-01-01 11:59:33 +0000388 }
389
sewardjf0c12502014-01-12 12:54:00 +0000390#elif defined(VGP_arm64_linux)
391# define VG_UCONTEXT_INSTR_PTR(uc) ((UWord)((uc)->uc_mcontext.pc))
392# define VG_UCONTEXT_STACK_PTR(uc) ((UWord)((uc)->uc_mcontext.sp))
393# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
394 /* Convert the value in uc_mcontext.regs[0] into a SysRes. */ \
395 VG_(mk_SysRes_arm64_linux)( (uc)->uc_mcontext.regs[0] )
396# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
397 { (srP)->r_pc = (uc)->uc_mcontext.pc; \
398 (srP)->r_sp = (uc)->uc_mcontext.sp; \
399 (srP)->misc.ARM64.x29 = (uc)->uc_mcontext.regs[29]; \
400 (srP)->misc.ARM64.x30 = (uc)->uc_mcontext.regs[30]; \
401 }
402
njnf76d27a2009-05-28 01:53:07 +0000403#elif defined(VGP_x86_darwin)
404
405 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
406 ucontext_t* uc = (ucontext_t*)ucV;
407 struct __darwin_mcontext32* mc = uc->uc_mcontext;
408 struct __darwin_i386_thread_state* ss = &mc->__ss;
409 return ss->__eip;
410 }
411 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
412 ucontext_t* uc = (ucontext_t*)ucV;
413 struct __darwin_mcontext32* mc = uc->uc_mcontext;
414 struct __darwin_i386_thread_state* ss = &mc->__ss;
415 return ss->__esp;
416 }
417 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV,
418 UWord scclass ) {
419 /* this is complicated by the problem that there are 3 different
420 kinds of syscalls, each with its own return convention.
421 NB: scclass is a host word, hence UWord is good for both
422 amd64-darwin and x86-darwin */
423 ucontext_t* uc = (ucontext_t*)ucV;
424 struct __darwin_mcontext32* mc = uc->uc_mcontext;
425 struct __darwin_i386_thread_state* ss = &mc->__ss;
426 /* duplicates logic in m_syswrap.getSyscallStatusFromGuestState */
427 UInt carry = 1 & ss->__eflags;
428 UInt err = 0;
429 UInt wLO = 0;
430 UInt wHI = 0;
431 switch (scclass) {
432 case VG_DARWIN_SYSCALL_CLASS_UNIX:
433 err = carry;
434 wLO = ss->__eax;
435 wHI = ss->__edx;
436 break;
437 case VG_DARWIN_SYSCALL_CLASS_MACH:
438 wLO = ss->__eax;
439 break;
440 case VG_DARWIN_SYSCALL_CLASS_MDEP:
441 wLO = ss->__eax;
442 break;
443 default:
444 vg_assert(0);
445 break;
446 }
447 return VG_(mk_SysRes_x86_darwin)( scclass, err ? True : False,
448 wHI, wLO );
449 }
sewardj67b38c32010-01-01 12:44:12 +0000450 static inline
451 void VG_UCONTEXT_TO_UnwindStartRegs( UnwindStartRegs* srP,
452 void* ucV ) {
453 ucontext_t* uc = (ucontext_t*)(ucV);
njnf76d27a2009-05-28 01:53:07 +0000454 struct __darwin_mcontext32* mc = uc->uc_mcontext;
455 struct __darwin_i386_thread_state* ss = &mc->__ss;
sewardj67b38c32010-01-01 12:44:12 +0000456 srP->r_pc = (ULong)(ss->__eip);
457 srP->r_sp = (ULong)(ss->__esp);
458 srP->misc.X86.r_ebp = (UInt)(ss->__ebp);
njnf76d27a2009-05-28 01:53:07 +0000459 }
460
461#elif defined(VGP_amd64_darwin)
462
463 static inline Addr VG_UCONTEXT_INSTR_PTR( void* ucV ) {
sewardj625c3e72012-03-27 08:44:17 +0000464 ucontext_t* uc = (ucontext_t*)ucV;
465 struct __darwin_mcontext64* mc = uc->uc_mcontext;
466 struct __darwin_x86_thread_state64* ss = &mc->__ss;
467 return ss->__rip;
njnf76d27a2009-05-28 01:53:07 +0000468 }
469 static inline Addr VG_UCONTEXT_STACK_PTR( void* ucV ) {
sewardj625c3e72012-03-27 08:44:17 +0000470 ucontext_t* uc = (ucontext_t*)ucV;
471 struct __darwin_mcontext64* mc = uc->uc_mcontext;
472 struct __darwin_x86_thread_state64* ss = &mc->__ss;
473 return ss->__rsp;
njnf76d27a2009-05-28 01:53:07 +0000474 }
475 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( void* ucV,
476 UWord scclass ) {
sewardj625c3e72012-03-27 08:44:17 +0000477 /* This is copied from the x86-darwin case. I'm not sure if it
478 is correct. */
479 ucontext_t* uc = (ucontext_t*)ucV;
480 struct __darwin_mcontext64* mc = uc->uc_mcontext;
481 struct __darwin_x86_thread_state64* ss = &mc->__ss;
482 /* duplicates logic in m_syswrap.getSyscallStatusFromGuestState */
483 ULong carry = 1 & ss->__rflags;
484 ULong err = 0;
485 ULong wLO = 0;
486 ULong wHI = 0;
487 switch (scclass) {
488 case VG_DARWIN_SYSCALL_CLASS_UNIX:
489 err = carry;
490 wLO = ss->__rax;
491 wHI = ss->__rdx;
492 break;
493 case VG_DARWIN_SYSCALL_CLASS_MACH:
494 wLO = ss->__rax;
495 break;
496 case VG_DARWIN_SYSCALL_CLASS_MDEP:
497 wLO = ss->__rax;
498 break;
499 default:
500 vg_assert(0);
501 break;
502 }
503 return VG_(mk_SysRes_amd64_darwin)( scclass, err ? True : False,
504 wHI, wLO );
njnf76d27a2009-05-28 01:53:07 +0000505 }
njnea2d6fd2010-07-01 00:20:20 +0000506 static inline
507 void VG_UCONTEXT_TO_UnwindStartRegs( UnwindStartRegs* srP,
508 void* ucV ) {
sewardj625c3e72012-03-27 08:44:17 +0000509 ucontext_t* uc = (ucontext_t*)ucV;
510 struct __darwin_mcontext64* mc = uc->uc_mcontext;
511 struct __darwin_x86_thread_state64* ss = &mc->__ss;
512 srP->r_pc = (ULong)(ss->__rip);
513 srP->r_sp = (ULong)(ss->__rsp);
514 srP->misc.AMD64.r_rbp = (ULong)(ss->__rbp);
njnf76d27a2009-05-28 01:53:07 +0000515 }
516
sewardjb5b87402011-03-07 16:05:35 +0000517#elif defined(VGP_s390x_linux)
518
519# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.regs.psw.addr)
520# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.regs.gprs[15])
521# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.regs.gprs[11])
522# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
523 VG_(mk_SysRes_s390x_linux)((uc)->uc_mcontext.regs.gprs[2])
524# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_mcontext.regs.gprs[14])
525
526# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
527 { (srP)->r_pc = (ULong)((uc)->uc_mcontext.regs.psw.addr); \
528 (srP)->r_sp = (ULong)((uc)->uc_mcontext.regs.gprs[15]); \
529 (srP)->misc.S390X.r_fp = (uc)->uc_mcontext.regs.gprs[11]; \
530 (srP)->misc.S390X.r_lr = (uc)->uc_mcontext.regs.gprs[14]; \
531 }
532
sewardj5db15402012-06-07 09:13:21 +0000533#elif defined(VGP_mips32_linux)
534# define VG_UCONTEXT_INSTR_PTR(uc) ((UWord)(((uc)->uc_mcontext.sc_pc)))
535# define VG_UCONTEXT_STACK_PTR(uc) ((UWord)((uc)->uc_mcontext.sc_regs[29]))
536# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.sc_regs[30])
537# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.sc_regs[2])
538# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
539 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
540 VG_(mk_SysRes_mips32_linux)( (uc)->uc_mcontext.sc_regs[2], \
541 (uc)->uc_mcontext.sc_regs[3], \
542 (uc)->uc_mcontext.sc_regs[7])
543
544# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
545 { (srP)->r_pc = (uc)->uc_mcontext.sc_pc; \
546 (srP)->r_sp = (uc)->uc_mcontext.sc_regs[29]; \
547 (srP)->misc.MIPS32.r30 = (uc)->uc_mcontext.sc_regs[30]; \
548 (srP)->misc.MIPS32.r31 = (uc)->uc_mcontext.sc_regs[31]; \
549 (srP)->misc.MIPS32.r28 = (uc)->uc_mcontext.sc_regs[28]; \
550 }
551
petarj4df0bfc2013-02-27 23:17:33 +0000552#elif defined(VGP_mips64_linux)
553# define VG_UCONTEXT_INSTR_PTR(uc) (((uc)->uc_mcontext.sc_pc))
554# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.sc_regs[29])
555# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.sc_regs[30])
556# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.sc_regs[2])
557# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
558 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
559 VG_(mk_SysRes_mips64_linux)((uc)->uc_mcontext.sc_regs[2], \
560 (uc)->uc_mcontext.sc_regs[3], \
561 (uc)->uc_mcontext.sc_regs[7])
562
563# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
564 { (srP)->r_pc = (uc)->uc_mcontext.sc_pc; \
565 (srP)->r_sp = (uc)->uc_mcontext.sc_regs[29]; \
566 (srP)->misc.MIPS64.r30 = (uc)->uc_mcontext.sc_regs[30]; \
567 (srP)->misc.MIPS64.r31 = (uc)->uc_mcontext.sc_regs[31]; \
568 (srP)->misc.MIPS64.r28 = (uc)->uc_mcontext.sc_regs[28]; \
569 }
sewardj112711a2015-04-10 12:30:09 +0000570#elif defined(VGP_tilegx_linux)
571# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.pc)
572# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.sp)
573# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.gregs[52])
574# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.gregs[10])
575# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
576 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
florian72dabf42015-04-20 21:13:03 +0000577 VG_(mk_SysRes_tilegx_linux)((uc)->uc_mcontext.gregs[0])
sewardj112711a2015-04-10 12:30:09 +0000578# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
579 { (srP)->r_pc = (uc)->uc_mcontext.pc; \
580 (srP)->r_sp = (uc)->uc_mcontext.sp; \
581 (srP)->misc.TILEGX.r52 = (uc)->uc_mcontext.gregs[52]; \
582 (srP)->misc.TILEGX.r55 = (uc)->uc_mcontext.lr; \
583 }
584#else
njn605f4882005-05-29 17:50:40 +0000585# error Unknown platform
586#endif
587
sewardj489bfec2006-10-17 02:00:29 +0000588
589/* ------ Macros for pulling stuff out of siginfos ------ */
590
591/* These macros allow use of uniform names when working with
floriand2190292015-01-08 21:05:03 +0000592 both the Linux and Darwin vki definitions. */
sewardj489bfec2006-10-17 02:00:29 +0000593#if defined(VGO_linux)
594# define VKI_SIGINFO_si_addr _sifields._sigfault._addr
595# define VKI_SIGINFO_si_pid _sifields._kill._pid
njnf76d27a2009-05-28 01:53:07 +0000596#elif defined(VGO_darwin)
597# define VKI_SIGINFO_si_addr si_addr
598# define VKI_SIGINFO_si_pid si_pid
sewardj489bfec2006-10-17 02:00:29 +0000599#else
600# error Unknown OS
601#endif
602
603
nethercote759dda32004-08-07 18:16:56 +0000604/* ---------------------------------------------------------------------
sewardj018f7622002-05-15 21:13:39 +0000605 HIGH LEVEL STUFF TO DO WITH SIGNALS: POLICY (MOSTLY)
606 ------------------------------------------------------------------ */
607
sewardjde4a1d02002-03-22 01:27:54 +0000608/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000609 Signal state for this process.
610 ------------------------------------------------------------------ */
611
sewardj018f7622002-05-15 21:13:39 +0000612
nethercote73b526f2004-10-31 18:48:21 +0000613/* Base-ment of these arrays[_VKI_NSIG].
sewardjb48e5002002-05-13 00:16:03 +0000614
nethercote73b526f2004-10-31 18:48:21 +0000615 Valid signal numbers are 1 .. _VKI_NSIG inclusive.
sewardjb48e5002002-05-13 00:16:03 +0000616 Rather than subtracting 1 for indexing these arrays, which
617 is tedious and error-prone, they are simply dimensioned 1 larger,
618 and entry [0] is not used.
619 */
620
sewardjb48e5002002-05-13 00:16:03 +0000621
sewardj018f7622002-05-15 21:13:39 +0000622/* -----------------------------------------------------
623 Static client signal state (SCSS). This is the state
624 that the client thinks it has the kernel in.
625 SCSS records verbatim the client's settings. These
626 are mashed around only when SKSS is calculated from it.
627 -------------------------------------------------- */
sewardjb48e5002002-05-13 00:16:03 +0000628
sewardj018f7622002-05-15 21:13:39 +0000629typedef
630 struct {
631 void* scss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN or ptr to
632 client's handler */
633 UInt scss_flags;
nethercote73b526f2004-10-31 18:48:21 +0000634 vki_sigset_t scss_mask;
sewardjb5f6f512005-03-10 23:59:00 +0000635 void* scss_restorer; /* where sigreturn goes */
njncda2f0f2009-05-18 02:12:08 +0000636 void* scss_sa_tramp; /* sa_tramp setting, Darwin only */
637 /* re _restorer and _sa_tramp, we merely record the values
638 supplied when the client does 'sigaction' and give them back
639 when requested. Otherwise they are simply ignored. */
sewardj018f7622002-05-15 21:13:39 +0000640 }
641 SCSS_Per_Signal;
sewardjb48e5002002-05-13 00:16:03 +0000642
sewardj018f7622002-05-15 21:13:39 +0000643typedef
644 struct {
sewardj2342c972002-05-22 23:34:20 +0000645 /* per-signal info */
nethercote73b526f2004-10-31 18:48:21 +0000646 SCSS_Per_Signal scss_per_sig[1+_VKI_NSIG];
sewardj2342c972002-05-22 23:34:20 +0000647
sewardj018f7622002-05-15 21:13:39 +0000648 /* Additional elements to SCSS not stored here:
649 - for each thread, the thread's blocking mask
650 - for each thread in WaitSIG, the set of waited-on sigs
651 */
652 }
653 SCSS;
sewardjb48e5002002-05-13 00:16:03 +0000654
njn695c16e2005-03-27 03:40:28 +0000655static SCSS scss;
sewardj018f7622002-05-15 21:13:39 +0000656
657
658/* -----------------------------------------------------
659 Static kernel signal state (SKSS). This is the state
660 that we have the kernel in. It is computed from SCSS.
661 -------------------------------------------------- */
662
663/* Let's do:
664 sigprocmask assigns to all thread masks
665 so that at least everything is always consistent
666 Flags:
jsgf855d93d2003-10-13 22:26:55 +0000667 SA_SIGINFO -- we always set it, and honour it for the client
sewardj018f7622002-05-15 21:13:39 +0000668 SA_NOCLDSTOP -- passed to kernel
sewardjb5f6f512005-03-10 23:59:00 +0000669 SA_ONESHOT or SA_RESETHAND -- pass through
jsgf855d93d2003-10-13 22:26:55 +0000670 SA_RESTART -- we observe this but set our handlers to always restart
671 SA_NOMASK or SA_NODEFER -- we observe this, but our handlers block everything
sewardjb5f6f512005-03-10 23:59:00 +0000672 SA_ONSTACK -- pass through
673 SA_NOCLDWAIT -- pass through
sewardjb48e5002002-05-13 00:16:03 +0000674*/
sewardjde4a1d02002-03-22 01:27:54 +0000675
sewardj77e466c2002-04-14 02:29:29 +0000676
sewardj018f7622002-05-15 21:13:39 +0000677typedef
678 struct {
679 void* skss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN
680 or ptr to our handler */
681 UInt skss_flags;
682 /* There is no skss_mask, since we know that we will always ask
jsgf855d93d2003-10-13 22:26:55 +0000683 for all signals to be blocked in our sighandlers. */
sewardj018f7622002-05-15 21:13:39 +0000684 /* Also there is no skss_restorer. */
685 }
686 SKSS_Per_Signal;
sewardjde4a1d02002-03-22 01:27:54 +0000687
sewardj018f7622002-05-15 21:13:39 +0000688typedef
689 struct {
nethercote73b526f2004-10-31 18:48:21 +0000690 SKSS_Per_Signal skss_per_sig[1+_VKI_NSIG];
sewardj018f7622002-05-15 21:13:39 +0000691 }
692 SKSS;
693
njn695c16e2005-03-27 03:40:28 +0000694static SKSS skss;
sewardjde4a1d02002-03-22 01:27:54 +0000695
sewardj3b290482011-05-06 21:02:55 +0000696/* returns True if signal is to be ignored.
697 To check this, possibly call gdbserver with tid. */
698static Bool is_sig_ign(Int sigNo, ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +0000699{
nethercote73b526f2004-10-31 18:48:21 +0000700 vg_assert(sigNo >= 1 && sigNo <= _VKI_NSIG);
sewardj2e93c502002-04-12 11:12:52 +0000701
sewardj3b290482011-05-06 21:02:55 +0000702 return scss.scss_per_sig[sigNo].scss_handler == VKI_SIG_IGN
703 || !VG_(gdbserver_report_signal) (sigNo, tid);
jsgf855d93d2003-10-13 22:26:55 +0000704}
sewardjb48e5002002-05-13 00:16:03 +0000705
sewardj018f7622002-05-15 21:13:39 +0000706/* ---------------------------------------------------------------------
707 Compute the SKSS required by the current SCSS.
708 ------------------------------------------------------------------ */
709
sewardj4f29ddf2002-05-03 22:29:04 +0000710static
sewardj018f7622002-05-15 21:13:39 +0000711void pp_SKSS ( void )
712{
713 Int sig;
714 VG_(printf)("\n\nSKSS:\n");
nethercote73b526f2004-10-31 18:48:21 +0000715 for (sig = 1; sig <= _VKI_NSIG; sig++) {
dirk61780382007-10-01 10:33:41 +0000716 VG_(printf)("sig %d: handler %p, flags 0x%x\n", sig,
njn695c16e2005-03-27 03:40:28 +0000717 skss.skss_per_sig[sig].skss_handler,
718 skss.skss_per_sig[sig].skss_flags );
sewardj77e466c2002-04-14 02:29:29 +0000719
sewardj018f7622002-05-15 21:13:39 +0000720 }
sewardj018f7622002-05-15 21:13:39 +0000721}
722
sewardj018f7622002-05-15 21:13:39 +0000723/* This is the core, clever bit. Computation is as follows:
724
725 For each signal
726 handler = if client has a handler, then our handler
jsgf855d93d2003-10-13 22:26:55 +0000727 else if client is DFL, then our handler as well
728 else (client must be IGN)
sewardjb5f6f512005-03-10 23:59:00 +0000729 then hander is IGN
sewardj018f7622002-05-15 21:13:39 +0000730*/
731static
732void calculate_SKSS_from_SCSS ( SKSS* dst )
733{
734 Int sig;
sewardj018f7622002-05-15 21:13:39 +0000735 UInt scss_flags;
736 UInt skss_flags;
737
nethercote73b526f2004-10-31 18:48:21 +0000738 for (sig = 1; sig <= _VKI_NSIG; sig++) {
jsgf855d93d2003-10-13 22:26:55 +0000739 void *skss_handler;
740 void *scss_handler;
741
njn695c16e2005-03-27 03:40:28 +0000742 scss_handler = scss.scss_per_sig[sig].scss_handler;
743 scss_flags = scss.scss_per_sig[sig].scss_flags;
sewardj018f7622002-05-15 21:13:39 +0000744
jsgf855d93d2003-10-13 22:26:55 +0000745 switch(sig) {
746 case VKI_SIGSEGV:
747 case VKI_SIGBUS:
748 case VKI_SIGFPE:
749 case VKI_SIGILL:
sewardjb5f6f512005-03-10 23:59:00 +0000750 case VKI_SIGTRAP:
jsgf855d93d2003-10-13 22:26:55 +0000751 /* For these, we always want to catch them and report, even
752 if the client code doesn't. */
njn695c16e2005-03-27 03:40:28 +0000753 skss_handler = sync_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000754 break;
755
sewardjb5f6f512005-03-10 23:59:00 +0000756 case VKI_SIGCONT:
757 /* Let the kernel handle SIGCONT unless the client is actually
758 catching it. */
njn5a350be2009-04-30 03:05:05 +0000759 case VKI_SIGCHLD:
760 case VKI_SIGWINCH:
761 case VKI_SIGURG:
762 /* For signals which are have a default action of Ignore,
763 only set a handler if the client has set a signal handler.
764 Otherwise the kernel will interrupt a syscall which
765 wouldn't have otherwise been interrupted. */
njn695c16e2005-03-27 03:40:28 +0000766 if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_DFL)
sewardjb5f6f512005-03-10 23:59:00 +0000767 skss_handler = VKI_SIG_DFL;
njn695c16e2005-03-27 03:40:28 +0000768 else if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_IGN)
jsgf855d93d2003-10-13 22:26:55 +0000769 skss_handler = VKI_SIG_IGN;
sewardjb5f6f512005-03-10 23:59:00 +0000770 else
njn695c16e2005-03-27 03:40:28 +0000771 skss_handler = async_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000772 break;
jsgf855d93d2003-10-13 22:26:55 +0000773
sewardjb5f6f512005-03-10 23:59:00 +0000774 default:
njna530fc62005-03-13 04:46:36 +0000775 // VKI_SIGVG* are runtime variables, so we can't make them
776 // cases in the switch, so we handle them in the 'default' case.
njn351d0062005-06-21 22:23:59 +0000777 if (sig == VG_SIGVGKILL)
sewardjb5f6f512005-03-10 23:59:00 +0000778 skss_handler = sigvgkill_handler;
sewardjb5f6f512005-03-10 23:59:00 +0000779 else {
780 if (scss_handler == VKI_SIG_IGN)
781 skss_handler = VKI_SIG_IGN;
782 else
njn695c16e2005-03-27 03:40:28 +0000783 skss_handler = async_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +0000784 }
785 break;
786 }
sewardj018f7622002-05-15 21:13:39 +0000787
sewardj018f7622002-05-15 21:13:39 +0000788 /* Flags */
789
790 skss_flags = 0;
jsgf855d93d2003-10-13 22:26:55 +0000791
sewardjb5f6f512005-03-10 23:59:00 +0000792 /* SA_NOCLDSTOP, SA_NOCLDWAIT: pass to kernel */
793 skss_flags |= scss_flags & (VKI_SA_NOCLDSTOP | VKI_SA_NOCLDWAIT);
jsgf855d93d2003-10-13 22:26:55 +0000794
sewardj018f7622002-05-15 21:13:39 +0000795 /* SA_ONESHOT: ignore client setting */
sewardjb5f6f512005-03-10 23:59:00 +0000796
sewardja8d8e232005-06-07 20:04:56 +0000797 /* SA_RESTART: ignore client setting and always set it for us.
798 Though we never rely on the kernel to restart a
jsgf855d93d2003-10-13 22:26:55 +0000799 syscall, we observe whether it wanted to restart the syscall
sewardja8d8e232005-06-07 20:04:56 +0000800 or not, which is needed by
801 VG_(fixup_guest_state_after_syscall_interrupted) */
sewardj018f7622002-05-15 21:13:39 +0000802 skss_flags |= VKI_SA_RESTART;
jsgf855d93d2003-10-13 22:26:55 +0000803
804 /* SA_NOMASK: ignore it */
805
sewardj2342c972002-05-22 23:34:20 +0000806 /* SA_ONSTACK: client setting is irrelevant here */
sewardjb5f6f512005-03-10 23:59:00 +0000807 /* We don't set a signal stack, so ignore */
sewardj018f7622002-05-15 21:13:39 +0000808
jsgf855d93d2003-10-13 22:26:55 +0000809 /* always ask for SA_SIGINFO */
810 skss_flags |= VKI_SA_SIGINFO;
sewardj018f7622002-05-15 21:13:39 +0000811
fitzhardinge4f10ada2004-06-03 10:00:42 +0000812 /* use our own restorer */
813 skss_flags |= VKI_SA_RESTORER;
814
jsgf855d93d2003-10-13 22:26:55 +0000815 /* Create SKSS entry for this signal. */
sewardj6a3c26e2002-05-23 17:09:43 +0000816 if (sig != VKI_SIGKILL && sig != VKI_SIGSTOP)
817 dst->skss_per_sig[sig].skss_handler = skss_handler;
818 else
819 dst->skss_per_sig[sig].skss_handler = VKI_SIG_DFL;
820
sewardj018f7622002-05-15 21:13:39 +0000821 dst->skss_per_sig[sig].skss_flags = skss_flags;
822 }
823
824 /* Sanity checks. */
nethercote5fd72bb2004-11-04 19:28:38 +0000825 vg_assert(dst->skss_per_sig[VKI_SIGKILL].skss_handler == VKI_SIG_DFL);
826 vg_assert(dst->skss_per_sig[VKI_SIGSTOP].skss_handler == VKI_SIG_DFL);
sewardj018f7622002-05-15 21:13:39 +0000827
828 if (0)
829 pp_SKSS();
830}
831
832
833/* ---------------------------------------------------------------------
834 After a possible SCSS change, update SKSS and the kernel itself.
835 ------------------------------------------------------------------ */
836
njn9abd6082005-06-17 21:31:45 +0000837// We need two levels of macro-expansion here to convert __NR_rt_sigreturn
838// to a number before converting it to a string... sigh.
sewardj03d8aa82005-10-14 11:25:49 +0000839extern void my_sigreturn(void);
njn9abd6082005-06-17 21:31:45 +0000840
841#if defined(VGP_x86_linux)
njn5a350be2009-04-30 03:05:05 +0000842# define _MY_SIGRETURN(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000843 ".text\n" \
philippe9fdca562012-04-16 22:06:47 +0000844 ".globl my_sigreturn\n" \
njn9abd6082005-06-17 21:31:45 +0000845 "my_sigreturn:\n" \
846 " movl $" #name ", %eax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000847 " int $0x80\n" \
848 ".previous\n"
sewardj59570ff2010-01-01 11:59:33 +0000849
njn9abd6082005-06-17 21:31:45 +0000850#elif defined(VGP_amd64_linux)
njn5a350be2009-04-30 03:05:05 +0000851# define _MY_SIGRETURN(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000852 ".text\n" \
philippe9fdca562012-04-16 22:06:47 +0000853 ".globl my_sigreturn\n" \
njn9abd6082005-06-17 21:31:45 +0000854 "my_sigreturn:\n" \
855 " movq $" #name ", %rax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000856 " syscall\n" \
857 ".previous\n"
sewardj59570ff2010-01-01 11:59:33 +0000858
cerion85665ca2005-06-20 15:51:07 +0000859#elif defined(VGP_ppc32_linux)
njn5a350be2009-04-30 03:05:05 +0000860# define _MY_SIGRETURN(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000861 ".text\n" \
philippe9fdca562012-04-16 22:06:47 +0000862 ".globl my_sigreturn\n" \
cerion85665ca2005-06-20 15:51:07 +0000863 "my_sigreturn:\n" \
864 " li 0, " #name "\n" \
sewardj2fedc642005-11-19 02:02:57 +0000865 " sc\n" \
866 ".previous\n"
sewardj59570ff2010-01-01 11:59:33 +0000867
carllcae0cc22014-08-07 23:17:29 +0000868#elif defined(VGP_ppc64be_linux)
njn5a350be2009-04-30 03:05:05 +0000869# define _MY_SIGRETURN(name) \
cerion297c88f2005-12-22 15:53:12 +0000870 ".align 2\n" \
871 ".globl my_sigreturn\n" \
872 ".section \".opd\",\"aw\"\n" \
873 ".align 3\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000874 "my_sigreturn:\n" \
cerion297c88f2005-12-22 15:53:12 +0000875 ".quad .my_sigreturn,.TOC.@tocbase,0\n" \
876 ".previous\n" \
877 ".type .my_sigreturn,@function\n" \
878 ".globl .my_sigreturn\n" \
879 ".my_sigreturn:\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000880 " li 0, " #name "\n" \
cerion297c88f2005-12-22 15:53:12 +0000881 " sc\n"
sewardj59570ff2010-01-01 11:59:33 +0000882
carll582d5822014-08-07 23:35:54 +0000883#elif defined(VGP_ppc64le_linux)
884/* Little Endian supports ELF version 2. In the future, it may
885 * support other versions.
886 */
887# define _MY_SIGRETURN(name) \
888 ".align 2\n" \
889 ".globl my_sigreturn\n" \
890 ".type .my_sigreturn,@function\n" \
891 "my_sigreturn:\n" \
892 "#if _CALL_ELF == 2 \n" \
893 "0: addis 2,12,.TOC.-0b@ha\n" \
894 " addi 2,2,.TOC.-0b@l\n" \
895 " .localentry my_sigreturn,.-my_sigreturn\n" \
896 "#endif \n" \
897 " sc\n" \
898 " .size my_sigreturn,.-my_sigreturn\n"
899
sewardj59570ff2010-01-01 11:59:33 +0000900#elif defined(VGP_arm_linux)
901# define _MY_SIGRETURN(name) \
902 ".text\n" \
philippe9fdca562012-04-16 22:06:47 +0000903 ".globl my_sigreturn\n" \
sewardj59570ff2010-01-01 11:59:33 +0000904 "my_sigreturn:\n\t" \
905 " mov r7, #" #name "\n\t" \
906 " svc 0x00000000\n" \
907 ".previous\n"
908
sewardjf0c12502014-01-12 12:54:00 +0000909#elif defined(VGP_arm64_linux)
910# define _MY_SIGRETURN(name) \
911 ".text\n" \
912 ".globl my_sigreturn\n" \
913 "my_sigreturn:\n\t" \
914 " mov x8, #" #name "\n\t" \
915 " svc 0x0\n" \
916 ".previous\n"
917
njnf76d27a2009-05-28 01:53:07 +0000918#elif defined(VGP_x86_darwin)
919# define _MY_SIGRETURN(name) \
920 ".text\n" \
philippe9fdca562012-04-16 22:06:47 +0000921 ".globl my_sigreturn\n" \
njnf76d27a2009-05-28 01:53:07 +0000922 "my_sigreturn:\n" \
923 "movl $" VG_STRINGIFY(__NR_DARWIN_FAKE_SIGRETURN) ",%eax\n" \
924 "int $0x80"
sewardj59570ff2010-01-01 11:59:33 +0000925
njnf76d27a2009-05-28 01:53:07 +0000926#elif defined(VGP_amd64_darwin)
927 // DDD: todo
928# define _MY_SIGRETURN(name) \
929 ".text\n" \
philippe9fdca562012-04-16 22:06:47 +0000930 ".globl my_sigreturn\n" \
njnf76d27a2009-05-28 01:53:07 +0000931 "my_sigreturn:\n" \
932 "ud2\n"
sewardj59570ff2010-01-01 11:59:33 +0000933
sewardjb5b87402011-03-07 16:05:35 +0000934#elif defined(VGP_s390x_linux)
935# define _MY_SIGRETURN(name) \
936 ".text\n" \
philippe9fdca562012-04-16 22:06:47 +0000937 ".globl my_sigreturn\n" \
sewardjb5b87402011-03-07 16:05:35 +0000938 "my_sigreturn:\n" \
939 " svc " #name "\n" \
940 ".previous\n"
941
sewardj5db15402012-06-07 09:13:21 +0000942#elif defined(VGP_mips32_linux)
943# define _MY_SIGRETURN(name) \
944 ".text\n" \
945 "my_sigreturn:\n" \
946 " li $2, " #name "\n" /* apparently $2 is v0 */ \
947 " syscall\n" \
948 ".previous\n"
949
petarj4df0bfc2013-02-27 23:17:33 +0000950#elif defined(VGP_mips64_linux)
951# define _MY_SIGRETURN(name) \
952 ".text\n" \
953 "my_sigreturn:\n" \
954 " li $2, " #name "\n" \
955 " syscall\n" \
956 ".previous\n"
957
sewardj112711a2015-04-10 12:30:09 +0000958#elif defined(VGP_tilegx_linux)
959# define _MY_SIGRETURN(name) \
960 ".text\n" \
961 "my_sigreturn:\n" \
962 " moveli r10 ," #name "\n" \
963 " swint1\n" \
964 ".previous\n"
965
njn9abd6082005-06-17 21:31:45 +0000966#else
967# error Unknown platform
968#endif
969
njn5a350be2009-04-30 03:05:05 +0000970#define MY_SIGRETURN(name) _MY_SIGRETURN(name)
njn9abd6082005-06-17 21:31:45 +0000971asm(
njn5a350be2009-04-30 03:05:05 +0000972 MY_SIGRETURN(__NR_rt_sigreturn)
njn9abd6082005-06-17 21:31:45 +0000973);
974
975
nethercote9dd11512004-08-04 15:31:30 +0000976static void handle_SCSS_change ( Bool force_update )
sewardj018f7622002-05-15 21:13:39 +0000977{
nethercote73b526f2004-10-31 18:48:21 +0000978 Int res, sig;
979 SKSS skss_old;
njncda2f0f2009-05-18 02:12:08 +0000980 vki_sigaction_toK_t ksa;
981 vki_sigaction_fromK_t ksa_old;
sewardj018f7622002-05-15 21:13:39 +0000982
sewardj018f7622002-05-15 21:13:39 +0000983 /* Remember old SKSS and calculate new one. */
njn695c16e2005-03-27 03:40:28 +0000984 skss_old = skss;
985 calculate_SKSS_from_SCSS ( &skss );
sewardj018f7622002-05-15 21:13:39 +0000986
987 /* Compare the new SKSS entries vs the old ones, and update kernel
988 where they differ. */
sewardjb5f6f512005-03-10 23:59:00 +0000989 for (sig = 1; sig <= VG_(max_signal); sig++) {
sewardj018f7622002-05-15 21:13:39 +0000990
991 /* Trying to do anything with SIGKILL is pointless; just ignore
992 it. */
993 if (sig == VKI_SIGKILL || sig == VKI_SIGSTOP)
994 continue;
995
sewardj018f7622002-05-15 21:13:39 +0000996 if (!force_update) {
997 if ((skss_old.skss_per_sig[sig].skss_handler
njn695c16e2005-03-27 03:40:28 +0000998 == skss.skss_per_sig[sig].skss_handler)
sewardj018f7622002-05-15 21:13:39 +0000999 && (skss_old.skss_per_sig[sig].skss_flags
njn695c16e2005-03-27 03:40:28 +00001000 == skss.skss_per_sig[sig].skss_flags))
sewardj018f7622002-05-15 21:13:39 +00001001 /* no difference */
1002 continue;
1003 }
1004
njn695c16e2005-03-27 03:40:28 +00001005 ksa.ksa_handler = skss.skss_per_sig[sig].skss_handler;
1006 ksa.sa_flags = skss.skss_per_sig[sig].skss_flags;
njnf76d27a2009-05-28 01:53:07 +00001007# if !defined(VGP_ppc32_linux) && \
sewardj5db15402012-06-07 09:13:21 +00001008 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin) && \
1009 !defined(VGP_mips32_linux)
njn9abd6082005-06-17 21:31:45 +00001010 ksa.sa_restorer = my_sigreturn;
sewardjce2a6152005-07-08 18:25:13 +00001011# endif
sewardj162bebd2005-07-09 10:43:45 +00001012 /* Re above ifdef (also the assertion below), PaulM says:
1013 The sa_restorer field is not used at all on ppc. Glibc
1014 converts the sigaction you give it into a kernel sigaction,
1015 but it doesn't put anything in the sa_restorer field.
1016 */
fitzhardinge4f10ada2004-06-03 10:00:42 +00001017
sewardjb5f6f512005-03-10 23:59:00 +00001018 /* block all signals in handler */
nethercote73b526f2004-10-31 18:48:21 +00001019 VG_(sigfillset)( &ksa.sa_mask );
1020 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGKILL );
1021 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGSTOP );
sewardj018f7622002-05-15 21:13:39 +00001022
sewardjb5f6f512005-03-10 23:59:00 +00001023 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj738856f2009-07-15 14:48:32 +00001024 VG_(dmsg)("setting ksig %d to: hdlr %p, flags 0x%lx, "
1025 "mask(msb..lsb) 0x%llx 0x%llx\n",
1026 sig, ksa.ksa_handler,
1027 (UWord)ksa.sa_flags,
1028 _VKI_NSIG_WORDS > 1 ? (ULong)ksa.sa_mask.sig[1] : 0,
1029 (ULong)ksa.sa_mask.sig[0]);
sewardj018f7622002-05-15 21:13:39 +00001030
nethercote73b526f2004-10-31 18:48:21 +00001031 res = VG_(sigaction)( sig, &ksa, &ksa_old );
sewardj018f7622002-05-15 21:13:39 +00001032 vg_assert(res == 0);
1033
1034 /* Since we got the old sigaction more or less for free, might
1035 as well extract the maximum sanity-check value from it. */
1036 if (!force_update) {
1037 vg_assert(ksa_old.ksa_handler
1038 == skss_old.skss_per_sig[sig].skss_handler);
nethercote73b526f2004-10-31 18:48:21 +00001039 vg_assert(ksa_old.sa_flags
sewardj018f7622002-05-15 21:13:39 +00001040 == skss_old.skss_per_sig[sig].skss_flags);
njnf76d27a2009-05-28 01:53:07 +00001041# if !defined(VGP_ppc32_linux) && \
sewardj5db15402012-06-07 09:13:21 +00001042 !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin) && \
petarj4df0bfc2013-02-27 23:17:33 +00001043 !defined(VGP_mips32_linux) && !defined(VGP_mips64_linux)
sewardjf0c12502014-01-12 12:54:00 +00001044 vg_assert(ksa_old.sa_restorer == my_sigreturn);
sewardjce2a6152005-07-08 18:25:13 +00001045# endif
nethercote73b526f2004-10-31 18:48:21 +00001046 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGKILL );
1047 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGSTOP );
1048 vg_assert(VG_(isfullsigset)( &ksa_old.sa_mask ));
sewardj018f7622002-05-15 21:13:39 +00001049 }
1050 }
sewardj018f7622002-05-15 21:13:39 +00001051}
1052
1053
1054/* ---------------------------------------------------------------------
1055 Update/query SCSS in accordance with client requests.
1056 ------------------------------------------------------------------ */
1057
sewardj2342c972002-05-22 23:34:20 +00001058/* Logic for this alt-stack stuff copied directly from do_sigaltstack
1059 in kernel/signal.[ch] */
1060
1061/* True if we are on the alternate signal stack. */
sewardjb5f6f512005-03-10 23:59:00 +00001062static Bool on_sig_stack ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +00001063{
fitzhardinge98c4dc02004-03-16 08:27:29 +00001064 ThreadState *tst = VG_(get_ThreadState)(tid);
1065
njn5a350be2009-04-30 03:05:05 +00001066 return (m_SP - (Addr)tst->altstack.ss_sp < (Addr)tst->altstack.ss_size);
sewardj2342c972002-05-22 23:34:20 +00001067}
1068
nethercote511e4062004-09-11 13:34:08 +00001069static Int sas_ss_flags ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +00001070{
fitzhardinge98c4dc02004-03-16 08:27:29 +00001071 ThreadState *tst = VG_(get_ThreadState)(tid);
1072
1073 return (tst->altstack.ss_size == 0
sewardj2342c972002-05-22 23:34:20 +00001074 ? VKI_SS_DISABLE
nethercote511e4062004-09-11 13:34:08 +00001075 : on_sig_stack(tid, m_SP) ? VKI_SS_ONSTACK : 0);
sewardj2342c972002-05-22 23:34:20 +00001076}
1077
1078
sewardja8d8e232005-06-07 20:04:56 +00001079SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
sewardj2342c972002-05-22 23:34:20 +00001080{
njn502badb2005-05-08 02:04:49 +00001081 Addr m_SP;
sewardj2342c972002-05-22 23:34:20 +00001082
1083 vg_assert(VG_(is_valid_tid)(tid));
njnf536bbb2005-06-13 04:21:38 +00001084 m_SP = VG_(get_SP)(tid);
sewardj2342c972002-05-22 23:34:20 +00001085
1086 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001087 VG_(dmsg)("sys_sigaltstack: tid %d, "
sewardj738856f2009-07-15 14:48:32 +00001088 "ss %p{%p,sz=%llu,flags=0x%llx}, oss %p (current SP %p)\n",
1089 tid, (void*)ss,
1090 ss ? ss->ss_sp : 0,
1091 (ULong)(ss ? ss->ss_size : 0),
1092 (ULong)(ss ? ss->ss_flags : 0),
1093 (void*)oss, (void*)m_SP);
sewardj2342c972002-05-22 23:34:20 +00001094
1095 if (oss != NULL) {
fitzhardinge98c4dc02004-03-16 08:27:29 +00001096 oss->ss_sp = VG_(threads)[tid].altstack.ss_sp;
1097 oss->ss_size = VG_(threads)[tid].altstack.ss_size;
njn5a350be2009-04-30 03:05:05 +00001098 oss->ss_flags = VG_(threads)[tid].altstack.ss_flags
1099 | sas_ss_flags(tid, m_SP);
sewardj2342c972002-05-22 23:34:20 +00001100 }
1101
1102 if (ss != NULL) {
njnf536bbb2005-06-13 04:21:38 +00001103 if (on_sig_stack(tid, VG_(get_SP)(tid))) {
sewardja8d8e232005-06-07 20:04:56 +00001104 return VG_(mk_SysRes_Error)( VKI_EPERM );
sewardj2342c972002-05-22 23:34:20 +00001105 }
1106 if (ss->ss_flags != VKI_SS_DISABLE
1107 && ss->ss_flags != VKI_SS_ONSTACK
1108 && ss->ss_flags != 0) {
sewardja8d8e232005-06-07 20:04:56 +00001109 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj2342c972002-05-22 23:34:20 +00001110 }
1111 if (ss->ss_flags == VKI_SS_DISABLE) {
fitzhardinge98c4dc02004-03-16 08:27:29 +00001112 VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
sewardj2342c972002-05-22 23:34:20 +00001113 } else {
1114 if (ss->ss_size < VKI_MINSIGSTKSZ) {
sewardja8d8e232005-06-07 20:04:56 +00001115 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
sewardj2342c972002-05-22 23:34:20 +00001116 }
jsgf855d93d2003-10-13 22:26:55 +00001117
nethercote20283c62004-11-04 19:43:22 +00001118 VG_(threads)[tid].altstack.ss_sp = ss->ss_sp;
1119 VG_(threads)[tid].altstack.ss_size = ss->ss_size;
fitzhardinge98c4dc02004-03-16 08:27:29 +00001120 VG_(threads)[tid].altstack.ss_flags = 0;
sewardj2342c972002-05-22 23:34:20 +00001121 }
sewardj2342c972002-05-22 23:34:20 +00001122 }
sewardja8d8e232005-06-07 20:04:56 +00001123 return VG_(mk_SysRes_Success)( 0 );
sewardj2342c972002-05-22 23:34:20 +00001124}
1125
1126
sewardja8d8e232005-06-07 20:04:56 +00001127SysRes VG_(do_sys_sigaction) ( Int signo,
njncda2f0f2009-05-18 02:12:08 +00001128 const vki_sigaction_toK_t* new_act,
1129 vki_sigaction_fromK_t* old_act )
sewardj018f7622002-05-15 21:13:39 +00001130{
sewardj018f7622002-05-15 21:13:39 +00001131 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001132 VG_(dmsg)("sys_sigaction: sigNo %d, "
sewardj738856f2009-07-15 14:48:32 +00001133 "new %#lx, old %#lx, new flags 0x%llx\n",
1134 signo, (UWord)new_act, (UWord)old_act,
1135 (ULong)(new_act ? new_act->sa_flags : 0));
sewardj018f7622002-05-15 21:13:39 +00001136
1137 /* Rule out various error conditions. The aim is to ensure that if
1138 when the call is passed to the kernel it will definitely
1139 succeed. */
1140
1141 /* Reject out-of-range signal numbers. */
sewardjb5f6f512005-03-10 23:59:00 +00001142 if (signo < 1 || signo > VG_(max_signal)) goto bad_signo;
sewardj018f7622002-05-15 21:13:39 +00001143
jsgf855d93d2003-10-13 22:26:55 +00001144 /* don't let them use our signals */
njn351d0062005-06-21 22:23:59 +00001145 if ( (signo > VG_SIGVGRTUSERMAX)
jsgf855d93d2003-10-13 22:26:55 +00001146 && new_act
sewardja8d8e232005-06-07 20:04:56 +00001147 && !(new_act->ksa_handler == VKI_SIG_DFL
1148 || new_act->ksa_handler == VKI_SIG_IGN) )
nethercote9c42a0f2003-11-17 10:37:19 +00001149 goto bad_signo_reserved;
jsgf855d93d2003-10-13 22:26:55 +00001150
sewardj018f7622002-05-15 21:13:39 +00001151 /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
1152 if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP)
1153 && new_act
1154 && new_act->ksa_handler != VKI_SIG_DFL)
1155 goto bad_sigkill_or_sigstop;
1156
1157 /* If the client supplied non-NULL old_act, copy the relevant SCSS
1158 entry into it. */
1159 if (old_act) {
njn695c16e2005-03-27 03:40:28 +00001160 old_act->ksa_handler = scss.scss_per_sig[signo].scss_handler;
1161 old_act->sa_flags = scss.scss_per_sig[signo].scss_flags;
1162 old_act->sa_mask = scss.scss_per_sig[signo].scss_mask;
sewardj6e9de462011-06-28 07:25:29 +00001163# if !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn695c16e2005-03-27 03:40:28 +00001164 old_act->sa_restorer = scss.scss_per_sig[signo].scss_restorer;
sewardj489bfec2006-10-17 02:00:29 +00001165# endif
sewardj018f7622002-05-15 21:13:39 +00001166 }
1167
1168 /* And now copy new SCSS entry from new_act. */
1169 if (new_act) {
njn695c16e2005-03-27 03:40:28 +00001170 scss.scss_per_sig[signo].scss_handler = new_act->ksa_handler;
1171 scss.scss_per_sig[signo].scss_flags = new_act->sa_flags;
1172 scss.scss_per_sig[signo].scss_mask = new_act->sa_mask;
sewardj489bfec2006-10-17 02:00:29 +00001173
njncda2f0f2009-05-18 02:12:08 +00001174 scss.scss_per_sig[signo].scss_restorer = NULL;
sewardj6e9de462011-06-28 07:25:29 +00001175# if !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn695c16e2005-03-27 03:40:28 +00001176 scss.scss_per_sig[signo].scss_restorer = new_act->sa_restorer;
sewardj489bfec2006-10-17 02:00:29 +00001177# endif
sewardjb5f6f512005-03-10 23:59:00 +00001178
njncda2f0f2009-05-18 02:12:08 +00001179 scss.scss_per_sig[signo].scss_sa_tramp = NULL;
njnf76d27a2009-05-28 01:53:07 +00001180# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1181 scss.scss_per_sig[signo].scss_sa_tramp = new_act->sa_tramp;
1182# endif
njncda2f0f2009-05-18 02:12:08 +00001183
njn695c16e2005-03-27 03:40:28 +00001184 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGKILL);
1185 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGSTOP);
sewardj018f7622002-05-15 21:13:39 +00001186 }
1187
1188 /* All happy bunnies ... */
1189 if (new_act) {
nethercote9dd11512004-08-04 15:31:30 +00001190 handle_SCSS_change( False /* lazy update */ );
sewardj018f7622002-05-15 21:13:39 +00001191 }
sewardja8d8e232005-06-07 20:04:56 +00001192 return VG_(mk_SysRes_Success)( 0 );
sewardj018f7622002-05-15 21:13:39 +00001193
1194 bad_signo:
sewardjec6e27c2007-11-17 21:31:48 +00001195 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001196 VG_(umsg)("Warning: bad signal number %d in sigaction()\n", signo);
sewardj9a3d8bd2005-05-23 14:47:52 +00001197 }
sewardja8d8e232005-06-07 20:04:56 +00001198 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +00001199
nethercote9c42a0f2003-11-17 10:37:19 +00001200 bad_signo_reserved:
sewardjec6e27c2007-11-17 21:31:48 +00001201 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001202 VG_(umsg)("Warning: ignored attempt to set %s handler in sigaction();\n",
philippe886fde32012-03-29 21:56:47 +00001203 VG_(signame)(signo));
sewardj738856f2009-07-15 14:48:32 +00001204 VG_(umsg)(" the %s signal is used internally by Valgrind\n",
philippe886fde32012-03-29 21:56:47 +00001205 VG_(signame)(signo));
fitzhardingebf459872003-11-18 16:55:33 +00001206 }
sewardja8d8e232005-06-07 20:04:56 +00001207 return VG_(mk_SysRes_Error)( VKI_EINVAL );
nethercote9c42a0f2003-11-17 10:37:19 +00001208
sewardj018f7622002-05-15 21:13:39 +00001209 bad_sigkill_or_sigstop:
sewardjec6e27c2007-11-17 21:31:48 +00001210 if (VG_(showing_core_errors)() && !VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001211 VG_(umsg)("Warning: ignored attempt to set %s handler in sigaction();\n",
philippe886fde32012-03-29 21:56:47 +00001212 VG_(signame)(signo));
sewardj738856f2009-07-15 14:48:32 +00001213 VG_(umsg)(" the %s signal is uncatchable\n",
philippe886fde32012-03-29 21:56:47 +00001214 VG_(signame)(signo));
sewardj9a3d8bd2005-05-23 14:47:52 +00001215 }
sewardja8d8e232005-06-07 20:04:56 +00001216 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +00001217}
1218
1219
1220static
1221void do_sigprocmask_bitops ( Int vki_how,
nethercote73b526f2004-10-31 18:48:21 +00001222 vki_sigset_t* orig_set,
1223 vki_sigset_t* modifier )
sewardj018f7622002-05-15 21:13:39 +00001224{
1225 switch (vki_how) {
1226 case VKI_SIG_BLOCK:
nethercote73b526f2004-10-31 18:48:21 +00001227 VG_(sigaddset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +00001228 break;
1229 case VKI_SIG_UNBLOCK:
nethercote73b526f2004-10-31 18:48:21 +00001230 VG_(sigdelset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +00001231 break;
1232 case VKI_SIG_SETMASK:
1233 *orig_set = *modifier;
1234 break;
1235 default:
njne427a662002-10-02 11:08:25 +00001236 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +00001237 break;
1238 }
1239}
1240
tomf7781e92005-11-02 15:31:21 +00001241static
njn5a350be2009-04-30 03:05:05 +00001242HChar* format_sigset ( const vki_sigset_t* set )
tomf7781e92005-11-02 15:31:21 +00001243{
florian7b7d5942014-12-19 20:29:22 +00001244 static HChar buf[_VKI_NSIG_WORDS * 16 + 1];
tomf7781e92005-11-02 15:31:21 +00001245 int w;
1246
1247 VG_(strcpy)(buf, "");
1248
1249 for (w = _VKI_NSIG_WORDS - 1; w >= 0; w--)
1250 {
sewardja8ffda62008-07-18 18:23:24 +00001251# if _VKI_NSIG_BPW == 32
1252 VG_(sprintf)(buf + VG_(strlen)(buf), "%08llx",
1253 set ? (ULong)set->sig[w] : 0);
1254# elif _VKI_NSIG_BPW == 64
1255 VG_(sprintf)(buf + VG_(strlen)(buf), "%16llx",
1256 set ? (ULong)set->sig[w] : 0);
1257# else
1258# error "Unsupported value for _VKI_NSIG_BPW"
1259# endif
tomf7781e92005-11-02 15:31:21 +00001260 }
1261
1262 return buf;
1263}
1264
jsgf855d93d2003-10-13 22:26:55 +00001265/*
1266 This updates the thread's signal mask. There's no such thing as a
1267 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +00001268
1269 Note that the thread signal masks are an implicit part of SCSS,
1270 which is why this routine is allowed to mess with them.
1271*/
1272static
1273void do_setmask ( ThreadId tid,
1274 Int how,
nethercote73b526f2004-10-31 18:48:21 +00001275 vki_sigset_t* newset,
1276 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +00001277{
sewardj018f7622002-05-15 21:13:39 +00001278 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001279 VG_(dmsg)("do_setmask: tid = %d how = %d (%s), newset = %p (%s)\n",
sewardj738856f2009-07-15 14:48:32 +00001280 tid, how,
1281 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
1282 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
1283 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
1284 newset, newset ? format_sigset(newset) : "NULL" );
sewardj018f7622002-05-15 21:13:39 +00001285
jsgf855d93d2003-10-13 22:26:55 +00001286 /* Just do this thread. */
1287 vg_assert(VG_(is_valid_tid)(tid));
1288 if (oldset) {
sewardjb5f6f512005-03-10 23:59:00 +00001289 *oldset = VG_(threads)[tid].sig_mask;
jsgf855d93d2003-10-13 22:26:55 +00001290 if (VG_(clo_trace_signals))
njn18a71e82010-07-06 04:21:47 +00001291 VG_(dmsg)("\toldset=%p %s\n", oldset, format_sigset(oldset));
sewardj018f7622002-05-15 21:13:39 +00001292 }
sewardj018f7622002-05-15 21:13:39 +00001293 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +00001294 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
nethercote73b526f2004-10-31 18:48:21 +00001295 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
1296 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
sewardjb5f6f512005-03-10 23:59:00 +00001297 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
sewardj018f7622002-05-15 21:13:39 +00001298 }
1299}
1300
1301
sewardja8d8e232005-06-07 20:04:56 +00001302SysRes VG_(do_sys_sigprocmask) ( ThreadId tid,
1303 Int how,
1304 vki_sigset_t* set,
1305 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +00001306{
jsgf855d93d2003-10-13 22:26:55 +00001307 switch(how) {
njncda2f0f2009-05-18 02:12:08 +00001308 case VKI_SIG_BLOCK:
1309 case VKI_SIG_UNBLOCK:
1310 case VKI_SIG_SETMASK:
1311 vg_assert(VG_(is_valid_tid)(tid));
1312 do_setmask ( tid, how, set, oldset );
1313 return VG_(mk_SysRes_Success)( 0 );
jsgf855d93d2003-10-13 22:26:55 +00001314
njncda2f0f2009-05-18 02:12:08 +00001315 default:
sewardj738856f2009-07-15 14:48:32 +00001316 VG_(dmsg)("sigprocmask: unknown 'how' field %d\n", how);
njncda2f0f2009-05-18 02:12:08 +00001317 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +00001318 }
1319}
1320
1321
sewardj018f7622002-05-15 21:13:39 +00001322/* ---------------------------------------------------------------------
1323 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
1324 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +00001325
sewardj2e93c502002-04-12 11:12:52 +00001326/* ---------------------------------------------------------------------
1327 Handy utilities to block/restore all host signals.
1328 ------------------------------------------------------------------ */
1329
1330/* Block all host signals, dumping the old mask in *saved_mask. */
njn444eba12005-05-12 03:47:31 +00001331static void block_all_host_signals ( /* OUT */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +00001332{
1333 Int ret;
nethercote73b526f2004-10-31 18:48:21 +00001334 vki_sigset_t block_procmask;
1335 VG_(sigfillset)(&block_procmask);
1336 ret = VG_(sigprocmask)
sewardj2e93c502002-04-12 11:12:52 +00001337 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
1338 vg_assert(ret == 0);
1339}
1340
1341/* Restore the blocking mask using the supplied saved one. */
njn444eba12005-05-12 03:47:31 +00001342static void restore_all_host_signals ( /* IN */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +00001343{
1344 Int ret;
nethercote73b526f2004-10-31 18:48:21 +00001345 ret = VG_(sigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
sewardj2e93c502002-04-12 11:12:52 +00001346 vg_assert(ret == 0);
1347}
sewardjde4a1d02002-03-22 01:27:54 +00001348
njn444eba12005-05-12 03:47:31 +00001349void VG_(clear_out_queued_signals)( ThreadId tid, vki_sigset_t* saved_mask )
1350{
1351 block_all_host_signals(saved_mask);
1352 if (VG_(threads)[tid].sig_queue != NULL) {
florian77eb20b2014-09-11 21:19:17 +00001353 VG_(free)(VG_(threads)[tid].sig_queue);
njn444eba12005-05-12 03:47:31 +00001354 VG_(threads)[tid].sig_queue = NULL;
1355 }
1356 restore_all_host_signals(saved_mask);
1357}
1358
sewardjde4a1d02002-03-22 01:27:54 +00001359/* ---------------------------------------------------------------------
1360 The signal simulation proper. A simplified version of what the
1361 Linux kernel does.
1362 ------------------------------------------------------------------ */
1363
sewardjde4a1d02002-03-22 01:27:54 +00001364/* Set up a stack frame (VgSigContext) for the client's signal
nethercotefedd8102004-09-13 15:19:34 +00001365 handler. */
sewardj2c5ffbe2005-03-12 13:32:06 +00001366static
njn5a350be2009-04-30 03:05:05 +00001367void push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo,
1368 const struct vki_ucontext *uc )
sewardjde4a1d02002-03-22 01:27:54 +00001369{
nethercote6eec4602004-09-13 14:15:36 +00001370 Addr esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +00001371 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +00001372 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +00001373
sewardjb5f6f512005-03-10 23:59:00 +00001374 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardj018f7622002-05-15 21:13:39 +00001375 vg_assert(VG_(is_valid_tid)(tid));
1376 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +00001377
sewardja672ea32006-04-29 18:03:14 +00001378 if (VG_(clo_trace_signals)) {
sewardj738856f2009-07-15 14:48:32 +00001379 VG_(dmsg)("push_signal_frame (thread %d): signal %d\n", tid, sigNo);
sewardja672ea32006-04-29 18:03:14 +00001380 VG_(get_and_pp_StackTrace)(tid, 10);
1381 }
jsgf855d93d2003-10-13 22:26:55 +00001382
sewardj2342c972002-05-22 23:34:20 +00001383 if (/* this signal asked to run on an alt stack */
njn695c16e2005-03-27 03:40:28 +00001384 (scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +00001385 && /* there is a defined and enabled alt stack, which we're not
1386 already using. Logic from get_sigframe in
1387 arch/i386/kernel/signal.c. */
njnf536bbb2005-06-13 04:21:38 +00001388 sas_ss_flags(tid, VG_(get_SP)(tid)) == 0
sewardj2342c972002-05-22 23:34:20 +00001389 ) {
1390 esp_top_of_frame
fitzhardinge98c4dc02004-03-16 08:27:29 +00001391 = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
sewardj2342c972002-05-22 23:34:20 +00001392 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001393 VG_(dmsg)("delivering signal %d (%s) to thread %d: "
1394 "on ALT STACK (%p-%p; %ld bytes)\n",
philippe886fde32012-03-29 21:56:47 +00001395 sigNo, VG_(signame)(sigNo), tid, tst->altstack.ss_sp,
sewardj738856f2009-07-15 14:48:32 +00001396 (UChar *)tst->altstack.ss_sp + tst->altstack.ss_size,
1397 (Word)tst->altstack.ss_size );
njnfdc28af2003-02-24 10:36:48 +00001398
nethercote7cc9c232004-01-21 15:08:04 +00001399 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +00001400 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
njnfdc28af2003-02-24 10:36:48 +00001401
sewardj2342c972002-05-22 23:34:20 +00001402 } else {
njnaf839f52005-06-23 03:27:57 +00001403 esp_top_of_frame = VG_(get_SP)(tid) - VG_STACK_REDZONE_SZB;
njnfdc28af2003-02-24 10:36:48 +00001404
nethercote7cc9c232004-01-21 15:08:04 +00001405 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +00001406 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
sewardj2342c972002-05-22 23:34:20 +00001407 }
sewardjb5f6f512005-03-10 23:59:00 +00001408
njn695c16e2005-03-27 03:40:28 +00001409 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_IGN);
1410 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_DFL);
sewardjb5f6f512005-03-10 23:59:00 +00001411
1412 /* This may fail if the client stack is busted; if that happens,
1413 the whole process will exit rather than simply calling the
1414 signal handler. */
tomadacaf92007-12-21 10:24:24 +00001415 VG_(sigframe_create) (tid, esp_top_of_frame, siginfo, uc,
sewardj985fabb2005-04-24 14:18:14 +00001416 scss.scss_per_sig[sigNo].scss_handler,
1417 scss.scss_per_sig[sigNo].scss_flags,
1418 &tst->sig_mask,
1419 scss.scss_per_sig[sigNo].scss_restorer);
sewardjde4a1d02002-03-22 01:27:54 +00001420}
1421
sewardjde4a1d02002-03-22 01:27:54 +00001422
florian2b8059a2012-10-14 16:45:23 +00001423const HChar *VG_(signame)(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +00001424{
florianf44ff622014-12-20 16:52:08 +00001425 static HChar buf[20]; // large enough
sewardjb48e5002002-05-13 00:16:03 +00001426
jsgf855d93d2003-10-13 22:26:55 +00001427 switch(sigNo) {
sewardj489bfec2006-10-17 02:00:29 +00001428 case VKI_SIGHUP: return "SIGHUP";
1429 case VKI_SIGINT: return "SIGINT";
1430 case VKI_SIGQUIT: return "SIGQUIT";
1431 case VKI_SIGILL: return "SIGILL";
1432 case VKI_SIGTRAP: return "SIGTRAP";
1433 case VKI_SIGABRT: return "SIGABRT";
1434 case VKI_SIGBUS: return "SIGBUS";
1435 case VKI_SIGFPE: return "SIGFPE";
1436 case VKI_SIGKILL: return "SIGKILL";
1437 case VKI_SIGUSR1: return "SIGUSR1";
1438 case VKI_SIGUSR2: return "SIGUSR2";
1439 case VKI_SIGSEGV: return "SIGSEGV";
1440 case VKI_SIGPIPE: return "SIGPIPE";
1441 case VKI_SIGALRM: return "SIGALRM";
1442 case VKI_SIGTERM: return "SIGTERM";
1443# if defined(VKI_SIGSTKFLT)
1444 case VKI_SIGSTKFLT: return "SIGSTKFLT";
1445# endif
1446 case VKI_SIGCHLD: return "SIGCHLD";
1447 case VKI_SIGCONT: return "SIGCONT";
1448 case VKI_SIGSTOP: return "SIGSTOP";
1449 case VKI_SIGTSTP: return "SIGTSTP";
1450 case VKI_SIGTTIN: return "SIGTTIN";
1451 case VKI_SIGTTOU: return "SIGTTOU";
1452 case VKI_SIGURG: return "SIGURG";
1453 case VKI_SIGXCPU: return "SIGXCPU";
1454 case VKI_SIGXFSZ: return "SIGXFSZ";
1455 case VKI_SIGVTALRM: return "SIGVTALRM";
1456 case VKI_SIGPROF: return "SIGPROF";
1457 case VKI_SIGWINCH: return "SIGWINCH";
1458 case VKI_SIGIO: return "SIGIO";
njncda2f0f2009-05-18 02:12:08 +00001459# if defined(VKI_SIGPWR)
sewardj489bfec2006-10-17 02:00:29 +00001460 case VKI_SIGPWR: return "SIGPWR";
njncda2f0f2009-05-18 02:12:08 +00001461# endif
sewardj489bfec2006-10-17 02:00:29 +00001462# if defined(VKI_SIGUNUSED)
1463 case VKI_SIGUNUSED: return "SIGUNUSED";
1464# endif
sewardjde4a1d02002-03-22 01:27:54 +00001465
njncda2f0f2009-05-18 02:12:08 +00001466# if defined(VKI_SIGRTMIN) && defined(VKI_SIGRTMAX)
jsgf855d93d2003-10-13 22:26:55 +00001467 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
sewardjb5f6f512005-03-10 23:59:00 +00001468 VG_(sprintf)(buf, "SIGRT%d", sigNo-VKI_SIGRTMIN);
jsgf855d93d2003-10-13 22:26:55 +00001469 return buf;
njncda2f0f2009-05-18 02:12:08 +00001470# endif
sewardjde4a1d02002-03-22 01:27:54 +00001471
jsgf855d93d2003-10-13 22:26:55 +00001472 default:
1473 VG_(sprintf)(buf, "SIG%d", sigNo);
1474 return buf;
1475 }
1476}
sewardjde4a1d02002-03-22 01:27:54 +00001477
jsgf855d93d2003-10-13 22:26:55 +00001478/* Hit ourselves with a signal using the default handler */
1479void VG_(kill_self)(Int sigNo)
1480{
njnf76d27a2009-05-28 01:53:07 +00001481 Int r;
njncda2f0f2009-05-18 02:12:08 +00001482 vki_sigset_t mask, origmask;
1483 vki_sigaction_toK_t sa, origsa2;
1484 vki_sigaction_fromK_t origsa;
sewardj018f7622002-05-15 21:13:39 +00001485
jsgf855d93d2003-10-13 22:26:55 +00001486 sa.ksa_handler = VKI_SIG_DFL;
nethercote73b526f2004-10-31 18:48:21 +00001487 sa.sa_flags = 0;
sewardj6e9de462011-06-28 07:25:29 +00001488# if !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
nethercote73b526f2004-10-31 18:48:21 +00001489 sa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00001490# endif
nethercote73b526f2004-10-31 18:48:21 +00001491 VG_(sigemptyset)(&sa.sa_mask);
sewardj2e93c502002-04-12 11:12:52 +00001492
nethercote73b526f2004-10-31 18:48:21 +00001493 VG_(sigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +00001494
sewardjb5f6f512005-03-10 23:59:00 +00001495 VG_(sigemptyset)(&mask);
1496 VG_(sigaddset)(&mask, sigNo);
1497 VG_(sigprocmask)(VKI_SIG_UNBLOCK, &mask, &origmask);
jsgf855d93d2003-10-13 22:26:55 +00001498
njnf76d27a2009-05-28 01:53:07 +00001499 r = VG_(kill)(VG_(getpid)(), sigNo);
sewardjc7ffc942011-03-28 16:26:42 +00001500# if defined(VGO_linux)
njnf76d27a2009-05-28 01:53:07 +00001501 /* This sometimes fails with EPERM on Darwin. I don't know why. */
sewardjc7ffc942011-03-28 16:26:42 +00001502 vg_assert(r == 0);
1503# endif
jsgf855d93d2003-10-13 22:26:55 +00001504
njncda2f0f2009-05-18 02:12:08 +00001505 VG_(convert_sigaction_fromK_to_toK)( &origsa, &origsa2 );
1506 VG_(sigaction)(sigNo, &origsa2, NULL);
nethercote73b526f2004-10-31 18:48:21 +00001507 VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00001508}
1509
njn36fce1b2009-04-28 01:55:01 +00001510// The si_code describes where the signal came from. Some come from the
1511// kernel, eg.: seg faults, illegal opcodes. Some come from the user, eg.:
1512// from kill() (SI_USER), or timer_settime() (SI_TIMER), or an async I/O
1513// request (SI_ASYNCIO). There's lots of implementation-defined leeway in
njnf76d27a2009-05-28 01:53:07 +00001514// POSIX, but the user vs. kernal distinction is what we want here. We also
1515// pass in some other details that can help when si_code is unreliable.
1516static Bool is_signal_from_kernel(ThreadId tid, int signum, int si_code)
njn36fce1b2009-04-28 01:55:01 +00001517{
sewardj6e9de462011-06-28 07:25:29 +00001518# if defined(VGO_linux)
njn36fce1b2009-04-28 01:55:01 +00001519 // On Linux, SI_USER is zero, negative values are from the user, positive
1520 // values are from the kernel. There are SI_FROMUSER and SI_FROMKERNEL
1521 // macros but we don't use them here because other platforms don't have
1522 // them.
1523 return ( si_code > VKI_SI_USER ? True : False );
sewardj6e9de462011-06-28 07:25:29 +00001524
1525# elif defined(VGO_darwin)
njnf76d27a2009-05-28 01:53:07 +00001526 // On Darwin 9.6.0, the si_code is completely unreliable. It should be the
1527 // case that 0 means "user", and >0 means "kernel". But:
1528 // - For SIGSEGV, it seems quite reliable.
1529 // - For SIGBUS, it's always 2.
1530 // - For SIGFPE, it's often 0, even for kernel ones (eg.
1531 // div-by-integer-zero always gives zero).
1532 // - For SIGILL, it's unclear.
1533 // - For SIGTRAP, it's always 1.
1534 // You can see the "NOTIMP" (not implemented) status of a number of the
1535 // sub-cases in sys/signal.h. Hopefully future versions of Darwin will
1536 // get this right.
1537
1538 // If we're blocked waiting on a syscall, it must be a user signal, because
1539 // the kernel won't generate sync signals within syscalls.
1540 if (VG_(threads)[tid].status == VgTs_WaitSys) {
1541 return False;
1542
1543 // If it's a SIGSEGV, use the proper condition, since it's fairly reliable.
1544 } else if (SIGSEGV == signum) {
1545 return ( si_code > 0 ? True : False );
1546
1547 // If it's anything else, assume it's kernel-generated. Reason being that
1548 // kernel-generated sync signals are more common, and it's probable that
1549 // misdiagnosing a user signal as a kernel signal is better than the
1550 // opposite.
1551 } else {
1552 return True;
1553 }
sewardj6e9de462011-06-28 07:25:29 +00001554# else
1555# error Unknown OS
1556# endif
njn36fce1b2009-04-28 01:55:01 +00001557}
1558
njn059539d2009-04-28 08:00:23 +00001559// This is an arbitrary si_code that we only use internally. It corresponds
1560// to the value SI_KERNEL on Linux, but that's not really of any significance
1561// as far as I can determine.
1562#define VKI_SEGV_MADE_UP_GPF 0x80
1563
jsgf855d93d2003-10-13 22:26:55 +00001564/*
sewardjb5f6f512005-03-10 23:59:00 +00001565 Perform the default action of a signal. If the signal is fatal, it
1566 marks all threads as needing to exit, but it doesn't actually kill
1567 the process or thread.
jsgf855d93d2003-10-13 22:26:55 +00001568
1569 If we're not being quiet, then print out some more detail about
1570 fatal signals (esp. core dumping signals).
1571 */
njn695c16e2005-03-27 03:40:28 +00001572static void default_action(const vki_siginfo_t *info, ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001573{
1574 Int sigNo = info->si_signo;
sewardjb5f6f512005-03-10 23:59:00 +00001575 Bool terminate = False; /* kills process */
1576 Bool core = False; /* kills process w/ core */
1577 struct vki_rlimit corelim;
1578 Bool could_core;
jsgf855d93d2003-10-13 22:26:55 +00001579
sewardjb5f6f512005-03-10 23:59:00 +00001580 vg_assert(VG_(is_running_thread)(tid));
1581
jsgf855d93d2003-10-13 22:26:55 +00001582 switch(sigNo) {
njncda2f0f2009-05-18 02:12:08 +00001583 case VKI_SIGQUIT: /* core */
1584 case VKI_SIGILL: /* core */
1585 case VKI_SIGABRT: /* core */
1586 case VKI_SIGFPE: /* core */
1587 case VKI_SIGSEGV: /* core */
1588 case VKI_SIGBUS: /* core */
1589 case VKI_SIGTRAP: /* core */
1590 case VKI_SIGXCPU: /* core */
1591 case VKI_SIGXFSZ: /* core */
1592 terminate = True;
1593 core = True;
1594 break;
jsgf855d93d2003-10-13 22:26:55 +00001595
njncda2f0f2009-05-18 02:12:08 +00001596 case VKI_SIGHUP: /* term */
1597 case VKI_SIGINT: /* term */
1598 case VKI_SIGKILL: /* term - we won't see this */
1599 case VKI_SIGPIPE: /* term */
1600 case VKI_SIGALRM: /* term */
1601 case VKI_SIGTERM: /* term */
1602 case VKI_SIGUSR1: /* term */
1603 case VKI_SIGUSR2: /* term */
1604 case VKI_SIGIO: /* term */
1605# if defined(VKI_SIGPWR)
1606 case VKI_SIGPWR: /* term */
1607# endif
1608 case VKI_SIGSYS: /* term */
1609 case VKI_SIGPROF: /* term */
1610 case VKI_SIGVTALRM: /* term */
1611# if defined(VKI_SIGRTMIN) && defined(VKI_SIGRTMAX)
1612 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1613# endif
1614 terminate = True;
1615 break;
jsgf855d93d2003-10-13 22:26:55 +00001616 }
1617
1618 vg_assert(!core || (core && terminate));
1619
fitzhardinge98abfc72003-12-16 02:05:15 +00001620 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001621 VG_(dmsg)("delivering %d (code %d) to default handler; action: %s%s\n",
1622 sigNo, info->si_code, terminate ? "terminate" : "ignore",
1623 core ? "+core" : "");
fitzhardinge98abfc72003-12-16 02:05:15 +00001624
sewardjb5f6f512005-03-10 23:59:00 +00001625 if (!terminate)
1626 return; /* nothing to do */
fitzhardinge4a4d1082004-03-15 23:46:54 +00001627
sewardjb5f6f512005-03-10 23:59:00 +00001628 could_core = core;
1629
1630 if (core) {
1631 /* If they set the core-size limit to zero, don't generate a
1632 core file */
fitzhardinge61a53412004-03-15 23:44:11 +00001633
sewardjb5f6f512005-03-10 23:59:00 +00001634 VG_(getrlimit)(VKI_RLIMIT_CORE, &corelim);
fitzhardinge61a53412004-03-15 23:44:11 +00001635
sewardjb5f6f512005-03-10 23:59:00 +00001636 if (corelim.rlim_cur == 0)
1637 core = False;
1638 }
fitzhardinge61a53412004-03-15 23:44:11 +00001639
njn36fce1b2009-04-28 01:55:01 +00001640 if ( (VG_(clo_verbosity) > 1 ||
njnf76d27a2009-05-28 01:53:07 +00001641 (could_core && is_signal_from_kernel(tid, sigNo, info->si_code))
njn36fce1b2009-04-28 01:55:01 +00001642 ) &&
1643 !VG_(clo_xml) ) {
sewardj738856f2009-07-15 14:48:32 +00001644 VG_(umsg)(
njnb6267bd2009-08-12 00:14:16 +00001645 "\n"
sewardj738856f2009-07-15 14:48:32 +00001646 "Process terminating with default action of signal %d (%s)%s\n",
philippe886fde32012-03-29 21:56:47 +00001647 sigNo, VG_(signame)(sigNo), core ? ": dumping core" : "");
jsgf855d93d2003-10-13 22:26:55 +00001648
sewardjb5f6f512005-03-10 23:59:00 +00001649 /* Be helpful - decode some more details about this fault */
njnf76d27a2009-05-28 01:53:07 +00001650 if (is_signal_from_kernel(tid, sigNo, info->si_code)) {
florian2b8059a2012-10-14 16:45:23 +00001651 const HChar *event = NULL;
sewardjb5f6f512005-03-10 23:59:00 +00001652 Bool haveaddr = True;
jsgf855d93d2003-10-13 22:26:55 +00001653
sewardjb5f6f512005-03-10 23:59:00 +00001654 switch(sigNo) {
1655 case VKI_SIGSEGV:
1656 switch(info->si_code) {
sewardj738856f2009-07-15 14:48:32 +00001657 case VKI_SEGV_MAPERR: event = "Access not within mapped region";
1658 break;
1659 case VKI_SEGV_ACCERR: event = "Bad permissions for mapped region";
1660 break;
njn059539d2009-04-28 08:00:23 +00001661 case VKI_SEGV_MADE_UP_GPF:
sewardjb5f6f512005-03-10 23:59:00 +00001662 /* General Protection Fault: The CPU/kernel
1663 isn't telling us anything useful, but this
1664 is commonly the result of exceeding a
sewardj74b4cca2005-10-20 01:37:15 +00001665 segment limit. */
1666 event = "General Protection Fault";
sewardjb5f6f512005-03-10 23:59:00 +00001667 haveaddr = False;
jsgf855d93d2003-10-13 22:26:55 +00001668 break;
1669 }
sewardj45f4e7c2005-09-27 19:20:21 +00001670#if 0
1671 {
florian7b7d5942014-12-19 20:29:22 +00001672 HChar buf[50]; // large enough
sewardj45f4e7c2005-09-27 19:20:21 +00001673 VG_(am_show_nsegments)(0,"post segfault");
1674 VG_(sprintf)(buf, "/bin/cat /proc/%d/maps", VG_(getpid)());
1675 VG_(system)(buf);
1676 }
1677#endif
sewardjb5f6f512005-03-10 23:59:00 +00001678 break;
jsgf855d93d2003-10-13 22:26:55 +00001679
sewardjb5f6f512005-03-10 23:59:00 +00001680 case VKI_SIGILL:
1681 switch(info->si_code) {
tom148250b2005-11-12 00:13:20 +00001682 case VKI_ILL_ILLOPC: event = "Illegal opcode"; break;
1683 case VKI_ILL_ILLOPN: event = "Illegal operand"; break;
1684 case VKI_ILL_ILLADR: event = "Illegal addressing mode"; break;
1685 case VKI_ILL_ILLTRP: event = "Illegal trap"; break;
1686 case VKI_ILL_PRVOPC: event = "Privileged opcode"; break;
1687 case VKI_ILL_PRVREG: event = "Privileged register"; break;
1688 case VKI_ILL_COPROC: event = "Coprocessor error"; break;
1689 case VKI_ILL_BADSTK: event = "Internal stack error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001690 }
1691 break;
1692
1693 case VKI_SIGFPE:
1694 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001695 case VKI_FPE_INTDIV: event = "Integer divide by zero"; break;
1696 case VKI_FPE_INTOVF: event = "Integer overflow"; break;
1697 case VKI_FPE_FLTDIV: event = "FP divide by zero"; break;
1698 case VKI_FPE_FLTOVF: event = "FP overflow"; break;
1699 case VKI_FPE_FLTUND: event = "FP underflow"; break;
1700 case VKI_FPE_FLTRES: event = "FP inexact"; break;
1701 case VKI_FPE_FLTINV: event = "FP invalid operation"; break;
1702 case VKI_FPE_FLTSUB: event = "FP subscript out of range"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001703 }
1704 break;
1705
1706 case VKI_SIGBUS:
1707 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001708 case VKI_BUS_ADRALN: event = "Invalid address alignment"; break;
1709 case VKI_BUS_ADRERR: event = "Non-existent physical address"; break;
1710 case VKI_BUS_OBJERR: event = "Hardware error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001711 }
1712 break;
sewardj3059d272007-12-21 01:24:59 +00001713 } /* switch (sigNo) */
sewardjb5f6f512005-03-10 23:59:00 +00001714
1715 if (event != NULL) {
1716 if (haveaddr)
sewardj738856f2009-07-15 14:48:32 +00001717 VG_(umsg)(" %s at address %p\n",
1718 event, info->VKI_SIGINFO_si_addr);
sewardjb5f6f512005-03-10 23:59:00 +00001719 else
sewardj738856f2009-07-15 14:48:32 +00001720 VG_(umsg)(" %s\n", event);
jsgf855d93d2003-10-13 22:26:55 +00001721 }
1722 }
sewardj3059d272007-12-21 01:24:59 +00001723 /* Print a stack trace. Be cautious if the thread's SP is in an
1724 obviously stupid place (not mapped readable) that would
1725 likely cause a segfault. */
1726 if (VG_(is_valid_tid)(tid)) {
florian2baf7532012-07-26 02:41:31 +00001727 Word first_ip_delta = 0;
florianede9caf2012-07-15 01:31:45 +00001728#if defined(VGO_linux)
1729 /* Make sure that the address stored in the stack pointer is
1730 located in a mapped page. That is not necessarily so. E.g.
1731 consider the scenario where the stack pointer was decreased
1732 and now has a value that is just below the end of a page that has
1733 not been mapped yet. In that case VG_(am_is_valid_for_client)
1734 will consider the address of the stack pointer invalid and that
1735 would cause a back-trace of depth 1 to be printed, instead of a
1736 full back-trace. */
1737 if (tid == 1) { // main thread
1738 Addr esp = VG_(get_SP)(tid);
1739 Addr base = VG_PGROUNDDN(esp - VG_STACK_REDZONE_SZB);
florian15fa8a22015-03-03 14:56:17 +00001740 if (VG_(extend_stack)(tid, base)) {
florianede9caf2012-07-15 01:31:45 +00001741 if (VG_(clo_trace_signals))
1742 VG_(dmsg)(" -> extended stack base to %#lx\n",
1743 VG_PGROUNDDN(esp));
1744 }
1745 }
1746#endif
florian2baf7532012-07-26 02:41:31 +00001747#if defined(VGA_s390x)
1748 if (sigNo == VKI_SIGILL) {
1749 /* The guest instruction address has been adjusted earlier to
1750 point to the insn following the one that could not be decoded.
1751 When printing the back-trace here we need to undo that
1752 adjustment so the first line in the back-trace reports the
1753 correct address. */
1754 Addr addr = (Addr)info->VKI_SIGINFO_si_addr;
1755 UChar byte = ((UChar *)addr)[0];
1756 Int insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
1757
1758 first_ip_delta = -insn_length;
1759 }
1760#endif
sewardj3059d272007-12-21 01:24:59 +00001761 ExeContext* ec = VG_(am_is_valid_for_client)
1762 (VG_(get_SP)(tid), sizeof(Addr), VKI_PROT_READ)
florian2baf7532012-07-26 02:41:31 +00001763 ? VG_(record_ExeContext)( tid, first_ip_delta )
florianbb4f5da2012-07-23 15:40:41 +00001764 : VG_(record_depth_1_ExeContext)( tid,
florian2baf7532012-07-26 02:41:31 +00001765 first_ip_delta );
sewardj3059d272007-12-21 01:24:59 +00001766 vg_assert(ec);
1767 VG_(pp_ExeContext)( ec );
fitzhardinge126c64f2003-12-08 21:58:37 +00001768 }
sewardj95d86c02007-12-18 01:49:23 +00001769 if (sigNo == VKI_SIGSEGV
florianfcd96352013-01-21 20:29:54 +00001770 && is_signal_from_kernel(tid, sigNo, info->si_code)
sewardj95d86c02007-12-18 01:49:23 +00001771 && info->si_code == VKI_SEGV_MAPERR) {
sewardj738856f2009-07-15 14:48:32 +00001772 VG_(umsg)(" If you believe this happened as a result of a stack\n" );
1773 VG_(umsg)(" overflow in your program's main thread (unlikely but\n");
1774 VG_(umsg)(" possible), you can try to increase the size of the\n" );
1775 VG_(umsg)(" main thread stack using the --main-stacksize= flag.\n" );
sewardj95d86c02007-12-18 01:49:23 +00001776 // FIXME: assumes main ThreadId == 1
1777 if (VG_(is_valid_tid)(1)) {
sewardj738856f2009-07-15 14:48:32 +00001778 VG_(umsg)(
philippedfa54a52013-03-13 21:44:07 +00001779 " The main thread stack size used in this run was %lu.\n",
1780 VG_(threads)[1].client_stack_szB);
sewardj95d86c02007-12-18 01:49:23 +00001781 }
1782 }
sewardjb5f6f512005-03-10 23:59:00 +00001783 }
1784
philippe2d1f2562014-09-19 08:57:29 +00001785 if (VG_(clo_vgdb) != Vg_VgdbNo
1786 && VG_(dyn_vgdb_error) <= VG_(get_n_errs_shown)() + 1) {
1787 /* Note: we add + 1 to n_errs_shown as the fatal signal was not
1788 reported through error msg, and so was not counted. */
1789 VG_(gdbserver_report_fatal_signal) (sigNo, tid);
1790 }
1791
sewardjb5f6f512005-03-10 23:59:00 +00001792 if (VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) {
1793 VG_(start_debugger)( tid );
1794 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001795
sewardjb5f6f512005-03-10 23:59:00 +00001796 if (core) {
1797 const static struct vki_rlimit zero = { 0, 0 };
fitzhardinge4a4d1082004-03-15 23:46:54 +00001798
njn67229832005-08-28 04:38:12 +00001799 VG_(make_coredump)(tid, info, corelim.rlim_cur);
fitzhardinged65dcad2004-03-13 02:06:58 +00001800
sewardjb5f6f512005-03-10 23:59:00 +00001801 /* Make sure we don't get a confusing kernel-generated
1802 coredump when we finally exit */
1803 VG_(setrlimit)(VKI_RLIMIT_CORE, &zero);
1804 }
fitzhardinged65dcad2004-03-13 02:06:58 +00001805
sewardjb5f6f512005-03-10 23:59:00 +00001806 /* stash fatal signal in main thread */
sewardj1d887112005-05-30 21:44:08 +00001807 // what's this for?
1808 //VG_(threads)[VG_(master_tid)].os_state.fatalsig = sigNo;
sewardjde4a1d02002-03-22 01:27:54 +00001809
sewardjb5f6f512005-03-10 23:59:00 +00001810 /* everyone dies */
1811 VG_(nuke_all_threads_except)(tid, VgSrc_FatalSig);
1812 VG_(threads)[tid].exitreason = VgSrc_FatalSig;
1813 VG_(threads)[tid].os_state.fatalsig = sigNo;
sewardjb48e5002002-05-13 00:16:03 +00001814}
1815
sewardjb5f6f512005-03-10 23:59:00 +00001816/*
1817 This does the business of delivering a signal to a thread. It may
1818 be called from either a real signal handler, or from normal code to
1819 cause the thread to enter the signal handler.
sewardj5e2f0012004-12-13 14:10:34 +00001820
sewardjb5f6f512005-03-10 23:59:00 +00001821 This updates the thread state, but it does not set it to be
1822 Runnable.
1823*/
njn5a350be2009-04-30 03:05:05 +00001824static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info,
1825 const struct vki_ucontext *uc )
sewardjde4a1d02002-03-22 01:27:54 +00001826{
jsgf855d93d2003-10-13 22:26:55 +00001827 Int sigNo = info->si_signo;
njn695c16e2005-03-27 03:40:28 +00001828 SCSS_Per_Signal *handler = &scss.scss_per_sig[sigNo];
fitzhardinge98abfc72003-12-16 02:05:15 +00001829 void *handler_fn;
jsgf855d93d2003-10-13 22:26:55 +00001830 ThreadState *tst = VG_(get_ThreadState)(tid);
1831
1832 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001833 VG_(dmsg)("delivering signal %d (%s):%d to thread %d\n",
philippe886fde32012-03-29 21:56:47 +00001834 sigNo, VG_(signame)(sigNo), info->si_code, tid );
jsgf855d93d2003-10-13 22:26:55 +00001835
njn351d0062005-06-21 22:23:59 +00001836 if (sigNo == VG_SIGVGKILL) {
sewardjb5f6f512005-03-10 23:59:00 +00001837 /* If this is a SIGVGKILL, we're expecting it to interrupt any
1838 blocked syscall. It doesn't matter whether the VCPU state is
1839 set to restart or not, because we don't expect it will
1840 execute any more client instructions. */
1841 vg_assert(VG_(is_exiting)(tid));
jsgf855d93d2003-10-13 22:26:55 +00001842 return;
1843 }
1844
sewardjb5f6f512005-03-10 23:59:00 +00001845 /* If the client specifies SIG_IGN, treat it as SIG_DFL.
jsgf855d93d2003-10-13 22:26:55 +00001846
njn9ec0f3e2005-03-13 06:00:47 +00001847 If deliver_signal() is being called on a thread, we want
sewardjb5f6f512005-03-10 23:59:00 +00001848 the signal to get through no matter what; if they're ignoring
1849 it, then we do this override (this is so we can send it SIGSEGV,
1850 etc). */
fitzhardinge98abfc72003-12-16 02:05:15 +00001851 handler_fn = handler->scss_handler;
sewardjb5f6f512005-03-10 23:59:00 +00001852 if (handler_fn == VKI_SIG_IGN)
fitzhardinge98abfc72003-12-16 02:05:15 +00001853 handler_fn = VKI_SIG_DFL;
1854
1855 vg_assert(handler_fn != VKI_SIG_IGN);
jsgf855d93d2003-10-13 22:26:55 +00001856
fitzhardinge98abfc72003-12-16 02:05:15 +00001857 if (handler_fn == VKI_SIG_DFL) {
njn695c16e2005-03-27 03:40:28 +00001858 default_action(info, tid);
jsgf855d93d2003-10-13 22:26:55 +00001859 } else {
1860 /* Create a signal delivery frame, and set the client's %ESP and
1861 %EIP so that when execution continues, we will enter the
1862 signal handler with the frame on top of the client's stack,
sewardjb5f6f512005-03-10 23:59:00 +00001863 as it expects.
1864
1865 Signal delivery can fail if the client stack is too small or
1866 missing, and we can't push the frame. If that happens,
1867 push_signal_frame will cause the whole process to exit when
1868 we next hit the scheduler.
1869 */
jsgf855d93d2003-10-13 22:26:55 +00001870 vg_assert(VG_(is_valid_tid)(tid));
sewardjb5f6f512005-03-10 23:59:00 +00001871
tomadacaf92007-12-21 10:24:24 +00001872 push_signal_frame ( tid, info, uc );
jsgf855d93d2003-10-13 22:26:55 +00001873
1874 if (handler->scss_flags & VKI_SA_ONESHOT) {
1875 /* Do the ONESHOT thing. */
1876 handler->scss_handler = VKI_SIG_DFL;
1877
nethercote9dd11512004-08-04 15:31:30 +00001878 handle_SCSS_change( False /* lazy update */ );
jsgf855d93d2003-10-13 22:26:55 +00001879 }
sewardjb5f6f512005-03-10 23:59:00 +00001880
1881 /* At this point:
1882 tst->sig_mask is the current signal mask
1883 tst->tmp_sig_mask is the same as sig_mask, unless we're in sigsuspend
1884 handler->scss_mask is the mask set by the handler
1885
1886 Handler gets a mask of tmp_sig_mask|handler_mask|signo
1887 */
1888 tst->sig_mask = tst->tmp_sig_mask;
1889 if (!(handler->scss_flags & VKI_SA_NOMASK)) {
1890 VG_(sigaddset_from_set)(&tst->sig_mask, &handler->scss_mask);
1891 VG_(sigaddset)(&tst->sig_mask, sigNo);
sewardjb5f6f512005-03-10 23:59:00 +00001892 tst->tmp_sig_mask = tst->sig_mask;
1893 }
1894 }
1895
1896 /* Thread state is ready to go - just add Runnable */
1897}
1898
njn06244e72005-06-21 22:27:19 +00001899static void resume_scheduler(ThreadId tid)
1900{
1901 ThreadState *tst = VG_(get_ThreadState)(tid);
1902
1903 vg_assert(tst->os_state.lwpid == VG_(gettid)());
1904
1905 if (tst->sched_jmpbuf_valid) {
1906 /* Can't continue; must longjmp back to the scheduler and thus
1907 enter the sighandler immediately. */
sewardj6c591e12011-04-11 16:17:51 +00001908 VG_MINIMAL_LONGJMP(tst->sched_jmpbuf);
njn06244e72005-06-21 22:27:19 +00001909 }
1910}
1911
njn9ec0f3e2005-03-13 06:00:47 +00001912static void synth_fault_common(ThreadId tid, Addr addr, Int si_code)
1913{
1914 vki_siginfo_t info;
1915
1916 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1917
njn5a350be2009-04-30 03:05:05 +00001918 VG_(memset)(&info, 0, sizeof(info));
njn9ec0f3e2005-03-13 06:00:47 +00001919 info.si_signo = VKI_SIGSEGV;
1920 info.si_code = si_code;
sewardj489bfec2006-10-17 02:00:29 +00001921 info.VKI_SIGINFO_si_addr = (void*)addr;
njn9ec0f3e2005-03-13 06:00:47 +00001922
philippe448e2bf2013-03-03 17:52:31 +00001923 /* Even if gdbserver indicates to ignore the signal, we must deliver it.
1924 So ignore the return value of VG_(gdbserver_report_signal). */
1925 (void) VG_(gdbserver_report_signal) (VKI_SIGSEGV, tid);
sewardj3b290482011-05-06 21:02:55 +00001926
njn9ec0f3e2005-03-13 06:00:47 +00001927 /* If they're trying to block the signal, force it to be delivered */
1928 if (VG_(sigismember)(&VG_(threads)[tid].sig_mask, VKI_SIGSEGV))
1929 VG_(set_default_handler)(VKI_SIGSEGV);
1930
tomadacaf92007-12-21 10:24:24 +00001931 deliver_signal(tid, &info, NULL);
njn9ec0f3e2005-03-13 06:00:47 +00001932}
1933
1934// Synthesize a fault where the address is OK, but the page
1935// permissions are bad.
1936void VG_(synth_fault_perms)(ThreadId tid, Addr addr)
1937{
njn059539d2009-04-28 08:00:23 +00001938 synth_fault_common(tid, addr, VKI_SEGV_ACCERR);
njn9ec0f3e2005-03-13 06:00:47 +00001939}
1940
1941// Synthesize a fault where the address there's nothing mapped at the address.
1942void VG_(synth_fault_mapping)(ThreadId tid, Addr addr)
1943{
njn059539d2009-04-28 08:00:23 +00001944 synth_fault_common(tid, addr, VKI_SEGV_MAPERR);
njn9ec0f3e2005-03-13 06:00:47 +00001945}
1946
1947// Synthesize a misc memory fault.
1948void VG_(synth_fault)(ThreadId tid)
1949{
njn059539d2009-04-28 08:00:23 +00001950 synth_fault_common(tid, 0, VKI_SEGV_MADE_UP_GPF);
njn9ec0f3e2005-03-13 06:00:47 +00001951}
1952
1953// Synthesise a SIGILL.
1954void VG_(synth_sigill)(ThreadId tid, Addr addr)
1955{
1956 vki_siginfo_t info;
1957
1958 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1959
njn5a350be2009-04-30 03:05:05 +00001960 VG_(memset)(&info, 0, sizeof(info));
njn9ec0f3e2005-03-13 06:00:47 +00001961 info.si_signo = VKI_SIGILL;
sewardj489bfec2006-10-17 02:00:29 +00001962 info.si_code = VKI_ILL_ILLOPC; /* jrs: no idea what this should be */
1963 info.VKI_SIGINFO_si_addr = (void*)addr;
njn9ec0f3e2005-03-13 06:00:47 +00001964
sewardj3b290482011-05-06 21:02:55 +00001965 if (VG_(gdbserver_report_signal) (VKI_SIGILL, tid)) {
1966 resume_scheduler(tid);
1967 deliver_signal(tid, &info, NULL);
1968 }
1969 else
1970 resume_scheduler(tid);
njn9ec0f3e2005-03-13 06:00:47 +00001971}
1972
sewardj1c0ce7a2009-07-01 08:10:49 +00001973// Synthesise a SIGBUS.
1974void VG_(synth_sigbus)(ThreadId tid)
1975{
1976 vki_siginfo_t info;
1977
1978 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1979
1980 VG_(memset)(&info, 0, sizeof(info));
1981 info.si_signo = VKI_SIGBUS;
1982 /* There are several meanings to SIGBUS (as per POSIX, presumably),
1983 but the most widely understood is "invalid address alignment",
1984 so let's use that. */
1985 info.si_code = VKI_BUS_ADRALN;
1986 /* If we knew the invalid address in question, we could put it
1987 in .si_addr. Oh well. */
1988 /* info.VKI_SIGINFO_si_addr = (void*)addr; */
1989
sewardj3b290482011-05-06 21:02:55 +00001990 if (VG_(gdbserver_report_signal) (VKI_SIGBUS, tid)) {
1991 resume_scheduler(tid);
1992 deliver_signal(tid, &info, NULL);
1993 }
1994 else
1995 resume_scheduler(tid);
sewardj1c0ce7a2009-07-01 08:10:49 +00001996}
1997
sewardj86df1552006-02-07 20:56:41 +00001998// Synthesise a SIGTRAP.
1999void VG_(synth_sigtrap)(ThreadId tid)
2000{
2001 vki_siginfo_t info;
tomadacaf92007-12-21 10:24:24 +00002002 struct vki_ucontext uc;
njnf76d27a2009-05-28 01:53:07 +00002003# if defined(VGP_x86_darwin)
2004 struct __darwin_mcontext32 mc;
2005# elif defined(VGP_amd64_darwin)
2006 struct __darwin_mcontext64 mc;
2007# endif
sewardj86df1552006-02-07 20:56:41 +00002008
2009 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
2010
njn5a350be2009-04-30 03:05:05 +00002011 VG_(memset)(&info, 0, sizeof(info));
2012 VG_(memset)(&uc, 0, sizeof(uc));
sewardj86df1552006-02-07 20:56:41 +00002013 info.si_signo = VKI_SIGTRAP;
tomadacaf92007-12-21 10:24:24 +00002014 info.si_code = VKI_TRAP_BRKPT; /* tjh: only ever called for a brkpt ins */
njncda2f0f2009-05-18 02:12:08 +00002015
2016# if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
tomadacaf92007-12-21 10:24:24 +00002017 uc.uc_mcontext.trapno = 3; /* tjh: this is the x86 trap number
2018 for a breakpoint trap... */
tom8b243022008-06-13 08:37:49 +00002019 uc.uc_mcontext.err = 0; /* tjh: no error code for x86
2020 breakpoint trap... */
njnf76d27a2009-05-28 01:53:07 +00002021# elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
2022 /* the same thing, but using Darwin field/struct names */
2023 VG_(memset)(&mc, 0, sizeof(mc));
2024 uc.uc_mcontext = &mc;
2025 uc.uc_mcontext->__es.__trapno = 3;
2026 uc.uc_mcontext->__es.__err = 0;
njncda2f0f2009-05-18 02:12:08 +00002027# endif
sewardj86df1552006-02-07 20:56:41 +00002028
sewardjb5b87402011-03-07 16:05:35 +00002029 /* fixs390: do we need to do anything here for s390 ? */
sewardj3b290482011-05-06 21:02:55 +00002030 if (VG_(gdbserver_report_signal) (VKI_SIGTRAP, tid)) {
2031 resume_scheduler(tid);
2032 deliver_signal(tid, &info, &uc);
2033 }
2034 else
2035 resume_scheduler(tid);
sewardj86df1552006-02-07 20:56:41 +00002036}
2037
petarj80e5c172012-10-19 14:45:17 +00002038// Synthesise a SIGFPE.
2039void VG_(synth_sigfpe)(ThreadId tid, UInt code)
2040{
petarj4df0bfc2013-02-27 23:17:33 +00002041// Only tested on mips32 and mips64
2042#if !defined(VGA_mips32) && !defined(VGA_mips64)
petarj80e5c172012-10-19 14:45:17 +00002043 vg_assert(0);
2044#else
2045 vki_siginfo_t info;
2046 struct vki_ucontext uc;
2047
2048 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
2049
2050 VG_(memset)(&info, 0, sizeof(info));
2051 VG_(memset)(&uc, 0, sizeof(uc));
2052 info.si_signo = VKI_SIGFPE;
2053 info.si_code = code;
2054
2055 if (VG_(gdbserver_report_signal) (VKI_SIGFPE, tid)) {
2056 resume_scheduler(tid);
2057 deliver_signal(tid, &info, &uc);
2058 }
2059 else
2060 resume_scheduler(tid);
2061#endif
2062}
2063
sewardjb5f6f512005-03-10 23:59:00 +00002064/* Make a signal pending for a thread, for later delivery.
2065 VG_(poll_signals) will arrange for it to be delivered at the right
2066 time.
2067
2068 tid==0 means add it to the process-wide queue, and not sent it to a
2069 specific thread.
2070*/
sewardj2c5ffbe2005-03-12 13:32:06 +00002071static
sewardjb5f6f512005-03-10 23:59:00 +00002072void queue_signal(ThreadId tid, const vki_siginfo_t *si)
2073{
2074 ThreadState *tst;
2075 SigQueue *sq;
2076 vki_sigset_t savedmask;
2077
2078 tst = VG_(get_ThreadState)(tid);
2079
2080 /* Protect the signal queue against async deliveries */
njn444eba12005-05-12 03:47:31 +00002081 block_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00002082
2083 if (tst->sig_queue == NULL) {
florian77eb20b2014-09-11 21:19:17 +00002084 tst->sig_queue = VG_(malloc)("signals.qs.1", sizeof(*tst->sig_queue));
sewardjb5f6f512005-03-10 23:59:00 +00002085 VG_(memset)(tst->sig_queue, 0, sizeof(*tst->sig_queue));
2086 }
2087 sq = tst->sig_queue;
2088
2089 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002090 VG_(dmsg)("Queueing signal %d (idx %d) to thread %d\n",
2091 si->si_signo, sq->next, tid);
sewardjb5f6f512005-03-10 23:59:00 +00002092
2093 /* Add signal to the queue. If the queue gets overrun, then old
2094 queued signals may get lost.
2095
2096 XXX We should also keep a sigset of pending signals, so that at
2097 least a non-siginfo signal gets deliviered.
2098 */
2099 if (sq->sigs[sq->next].si_signo != 0)
sewardj738856f2009-07-15 14:48:32 +00002100 VG_(umsg)("Signal %d being dropped from thread %d's queue\n",
2101 sq->sigs[sq->next].si_signo, tid);
sewardjb5f6f512005-03-10 23:59:00 +00002102
2103 sq->sigs[sq->next] = *si;
2104 sq->next = (sq->next+1) % N_QUEUED_SIGNALS;
2105
njn444eba12005-05-12 03:47:31 +00002106 restore_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00002107}
2108
2109/*
2110 Returns the next queued signal for thread tid which is in "set".
2111 tid==0 means process-wide signal. Set si_signo to 0 when the
2112 signal has been delivered.
2113
2114 Must be called with all signals blocked, to protect against async
2115 deliveries.
2116*/
2117static vki_siginfo_t *next_queued(ThreadId tid, const vki_sigset_t *set)
2118{
2119 ThreadState *tst = VG_(get_ThreadState)(tid);
2120 SigQueue *sq;
2121 Int idx;
2122 vki_siginfo_t *ret = NULL;
2123
2124 sq = tst->sig_queue;
2125 if (sq == NULL)
2126 goto out;
jsgf855d93d2003-10-13 22:26:55 +00002127
sewardjb5f6f512005-03-10 23:59:00 +00002128 idx = sq->next;
2129 do {
2130 if (0)
2131 VG_(printf)("idx=%d si_signo=%d inset=%d\n", idx,
sewardj738856f2009-07-15 14:48:32 +00002132 sq->sigs[idx].si_signo,
2133 VG_(sigismember)(set, sq->sigs[idx].si_signo));
jsgf855d93d2003-10-13 22:26:55 +00002134
sewardj738856f2009-07-15 14:48:32 +00002135 if (sq->sigs[idx].si_signo != 0
2136 && VG_(sigismember)(set, sq->sigs[idx].si_signo)) {
sewardjb5f6f512005-03-10 23:59:00 +00002137 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002138 VG_(dmsg)("Returning queued signal %d (idx %d) for thread %d\n",
2139 sq->sigs[idx].si_signo, idx, tid);
sewardjb5f6f512005-03-10 23:59:00 +00002140 ret = &sq->sigs[idx];
2141 goto out;
jsgf855d93d2003-10-13 22:26:55 +00002142 }
2143
sewardjb5f6f512005-03-10 23:59:00 +00002144 idx = (idx + 1) % N_QUEUED_SIGNALS;
2145 } while(idx != sq->next);
2146 out:
sewardj489bfec2006-10-17 02:00:29 +00002147 return ret;
jsgf855d93d2003-10-13 22:26:55 +00002148}
2149
njn3b6b2aa2009-04-30 03:30:09 +00002150static int sanitize_si_code(int si_code)
2151{
2152#if defined(VGO_linux)
2153 /* The linux kernel uses the top 16 bits of si_code for it's own
2154 use and only exports the bottom 16 bits to user space - at least
2155 that is the theory, but it turns out that there are some kernels
2156 around that forget to mask out the top 16 bits so we do it here.
2157
2158 The kernel treats the bottom 16 bits as signed and (when it does
2159 mask them off) sign extends them when exporting to user space so
2160 we do the same thing here. */
2161 return (Short)si_code;
sewardj6e9de462011-06-28 07:25:29 +00002162#elif defined(VGO_darwin)
njn3b6b2aa2009-04-30 03:30:09 +00002163 return si_code;
njn52040a42009-04-30 04:00:13 +00002164#else
2165# error Unknown OS
njn3b6b2aa2009-04-30 03:30:09 +00002166#endif
2167}
2168
jsgf855d93d2003-10-13 22:26:55 +00002169/*
sewardjb5f6f512005-03-10 23:59:00 +00002170 Receive an async signal from the kernel.
jsgf855d93d2003-10-13 22:26:55 +00002171
sewardjb5f6f512005-03-10 23:59:00 +00002172 This should only happen when the thread is blocked in a syscall,
2173 since that's the only time this set of signals is unblocked.
jsgf855d93d2003-10-13 22:26:55 +00002174*/
2175static
njn5a350be2009-04-30 03:05:05 +00002176void async_signalhandler ( Int sigNo,
2177 vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00002178{
njn5a350be2009-04-30 03:05:05 +00002179 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
2180 ThreadState* tst = VG_(get_ThreadState)(tid);
njncda2f0f2009-05-18 02:12:08 +00002181 SysRes sres;
jsgf855d93d2003-10-13 22:26:55 +00002182
njn5a350be2009-04-30 03:05:05 +00002183 /* The thread isn't currently running, make it so before going on */
2184 vg_assert(tst->status == VgTs_WaitSys);
2185 VG_(acquire_BigLock)(tid, "async_signalhandler");
2186
njn3b6b2aa2009-04-30 03:30:09 +00002187 info->si_code = sanitize_si_code(info->si_code);
tom9f4a7bf2005-11-13 00:01:20 +00002188
sewardjb5f6f512005-03-10 23:59:00 +00002189 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002190 VG_(dmsg)("async signal handler: signal=%d, tid=%d, si_code=%d\n",
2191 sigNo, tid, info->si_code);
sewardjb5f6f512005-03-10 23:59:00 +00002192
njncda2f0f2009-05-18 02:12:08 +00002193 /* Update thread state properly. The signal can only have been
2194 delivered whilst we were in
2195 coregrind/m_syswrap/syscall-<PLAT>.S, and only then in the
2196 window between the two sigprocmask calls, since at all other
2197 times, we run with async signals on the host blocked. Hence
2198 make enquiries on the basis that we were in or very close to a
2199 syscall, and attempt to fix up the guest state accordingly.
2200
2201 (normal async signals occurring during computation are blocked,
2202 but periodically polled for using VG_(sigtimedwait_zero), and
2203 delivered at a point convenient for us. Hence this routine only
2204 deals with signals that are delivered to a thread during a
2205 syscall.) */
2206
2207 /* First, extract a SysRes from the ucontext_t* given to this
2208 handler. If it is subsequently established by
2209 VG_(fixup_guest_state_after_syscall_interrupted) that the
2210 syscall was complete but the results had not been committed yet
2211 to the guest state, then it'll have to commit the results itself
2212 "by hand", and so we need to extract the SysRes. Of course if
2213 the thread was not in that particular window then the
2214 SysRes will be meaningless, but that's OK too because
2215 VG_(fixup_guest_state_after_syscall_interrupted) will detect
2216 that the thread was not in said window and ignore the SysRes. */
2217
njnf76d27a2009-05-28 01:53:07 +00002218 /* To make matters more complex still, on Darwin we need to know
2219 the "class" of the syscall under consideration in order to be
2220 able to extract the a correct SysRes. The class will have been
2221 saved just before the syscall, by VG_(client_syscall), into this
2222 thread's tst->arch.vex.guest_SC_CLASS. Hence: */
2223# if defined(VGO_darwin)
2224 sres = VG_UCONTEXT_SYSCALL_SYSRES(uc, tst->arch.vex.guest_SC_CLASS);
2225# else
njncda2f0f2009-05-18 02:12:08 +00002226 sres = VG_UCONTEXT_SYSCALL_SYSRES(uc);
njnf76d27a2009-05-28 01:53:07 +00002227# endif
njncda2f0f2009-05-18 02:12:08 +00002228
2229 /* (1) */
sewardja8d8e232005-06-07 20:04:56 +00002230 VG_(fixup_guest_state_after_syscall_interrupted)(
2231 tid,
njnaf839f52005-06-23 03:27:57 +00002232 VG_UCONTEXT_INSTR_PTR(uc),
njncda2f0f2009-05-18 02:12:08 +00002233 sres,
sewardja8d8e232005-06-07 20:04:56 +00002234 !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
2235 );
sewardjb5f6f512005-03-10 23:59:00 +00002236
njncda2f0f2009-05-18 02:12:08 +00002237 /* (2) */
sewardjb5f6f512005-03-10 23:59:00 +00002238 /* Set up the thread's state to deliver a signal */
sewardj3b290482011-05-06 21:02:55 +00002239 if (!is_sig_ign(info->si_signo, tid))
tomadacaf92007-12-21 10:24:24 +00002240 deliver_signal(tid, info, uc);
sewardjb5f6f512005-03-10 23:59:00 +00002241
njncda2f0f2009-05-18 02:12:08 +00002242 /* It's crucial that (1) and (2) happen in the order (1) then (2)
2243 and not the other way around. (1) fixes up the guest thread
2244 state to reflect the fact that the syscall was interrupted --
2245 either to restart the syscall or to return EINTR. (2) then sets
2246 up the thread state to deliver the signal. Then we resume
2247 execution. First, the signal handler is run, since that's the
2248 second adjustment we made to the thread state. If that returns,
2249 then we resume at the guest state created by (1), viz, either
2250 the syscall returns EINTR or is restarted.
2251
2252 If (2) was done before (1) the outcome would be completely
2253 different, and wrong. */
2254
sewardjb5f6f512005-03-10 23:59:00 +00002255 /* longjmp back to the thread's main loop to start executing the
2256 handler. */
njn06244e72005-06-21 22:27:19 +00002257 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002258
njn5a350be2009-04-30 03:05:05 +00002259 VG_(core_panic)("async_signalhandler: got unexpected signal "
2260 "while outside of scheduler");
jsgf855d93d2003-10-13 22:26:55 +00002261}
2262
florian017d8f52015-03-23 17:13:04 +00002263/* Extend the stack of thread #tid to cover addr. It is expected that
2264 addr either points into an already mapped anonymous segment or into a
2265 reservation segment abutting the stack segment. Everything else is a bug.
sewardjb5f6f512005-03-10 23:59:00 +00002266
2267 Returns True on success, False on failure.
2268
2269 Succeeds without doing anything if addr is already within a segment.
2270
2271 Failure could be caused by:
florian017d8f52015-03-23 17:13:04 +00002272 - addr not below a growable segment
florian15fa8a22015-03-03 14:56:17 +00002273 - new stack size would exceed the stack limit for the given thread
sewardjb5f6f512005-03-10 23:59:00 +00002274 - mmap failed for some other reason
florian15fa8a22015-03-03 14:56:17 +00002275*/
2276Bool VG_(extend_stack)(ThreadId tid, Addr addr)
sewardjb5f6f512005-03-10 23:59:00 +00002277{
sewardj45f4e7c2005-09-27 19:20:21 +00002278 SizeT udelta;
sewardjb5f6f512005-03-10 23:59:00 +00002279
florian15fa8a22015-03-03 14:56:17 +00002280 /* Get the segment containing addr. */
2281 const NSegment* seg = VG_(am_find_nsegment)(addr);
florian017d8f52015-03-23 17:13:04 +00002282 vg_assert(seg != NULL);
sewardj45f4e7c2005-09-27 19:20:21 +00002283
florianbe38cdd2015-03-02 21:10:46 +00002284 /* TODO: the test "seg->kind == SkAnonC" is really inadequate,
2285 because although it tests whether the segment is mapped
2286 _somehow_, it doesn't check that it has the right permissions
2287 (r,w, maybe x) ? */
florian15fa8a22015-03-03 14:56:17 +00002288 if (seg->kind == SkAnonC)
sewardj45f4e7c2005-09-27 19:20:21 +00002289 /* addr is already mapped. Nothing to do. */
sewardjb5f6f512005-03-10 23:59:00 +00002290 return True;
2291
florian15fa8a22015-03-03 14:56:17 +00002292 const NSegment* seg_next = VG_(am_next_nsegment)( seg, True/*fwds*/ );
florian017d8f52015-03-23 17:13:04 +00002293 vg_assert(seg_next != NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002294
sewardj45f4e7c2005-09-27 19:20:21 +00002295 udelta = VG_PGROUNDUP(seg_next->start - addr);
florian15fa8a22015-03-03 14:56:17 +00002296
sewardj45f4e7c2005-09-27 19:20:21 +00002297 VG_(debugLog)(1, "signals",
2298 "extending a stack base 0x%llx down by %lld\n",
2299 (ULong)seg_next->start, (ULong)udelta);
florian15fa8a22015-03-03 14:56:17 +00002300 Bool overflow;
sewardj45f4e7c2005-09-27 19:20:21 +00002301 if (! VG_(am_extend_into_adjacent_reservation_client)
florian15fa8a22015-03-03 14:56:17 +00002302 ( seg_next->start, -(SSizeT)udelta, &overflow )) {
2303 Addr new_stack_base = seg_next->start - udelta;
2304 if (overflow)
2305 VG_(umsg)("Stack overflow in thread #%d: can't grow stack to %#lx\n",
2306 tid, new_stack_base);
2307 else
2308 VG_(umsg)("Cannot map memory to grow the stack for thread #%d "
2309 "to %#lx\n", tid, new_stack_base);
sewardjb5f6f512005-03-10 23:59:00 +00002310 return False;
sewardj45f4e7c2005-09-27 19:20:21 +00002311 }
sewardjb5f6f512005-03-10 23:59:00 +00002312
rjwalsh0140af52005-06-04 20:42:33 +00002313 /* When we change the main stack, we have to let the stack handling
2314 code know about it. */
sewardj45f4e7c2005-09-27 19:20:21 +00002315 VG_(change_stack)(VG_(clstk_id), addr, VG_(clstk_end));
sewardjb5f6f512005-03-10 23:59:00 +00002316
2317 if (VG_(clo_sanity_level) > 2)
2318 VG_(sanity_check_general)(False);
2319
2320 return True;
2321}
2322
sewardj489bfec2006-10-17 02:00:29 +00002323static void (*fault_catcher)(Int sig, Addr addr) = NULL;
sewardjb5f6f512005-03-10 23:59:00 +00002324
2325void VG_(set_fault_catcher)(void (*catcher)(Int, Addr))
2326{
sewardj489bfec2006-10-17 02:00:29 +00002327 if (0)
2328 VG_(debugLog)(0, "signals", "set fault catcher to %p\n", catcher);
njn50ae1a72005-04-08 23:28:23 +00002329 vg_assert2(NULL == catcher || NULL == fault_catcher,
2330 "Fault catcher is already registered");
sewardjb5f6f512005-03-10 23:59:00 +00002331
2332 fault_catcher = catcher;
2333}
2334
njn96986052009-04-30 07:41:24 +00002335static
njn2d5ff4f2009-05-03 22:53:19 +00002336void sync_signalhandler_from_user ( ThreadId tid,
njn96986052009-04-30 07:41:24 +00002337 Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
2338{
2339 ThreadId qtid;
2340
njn2d5ff4f2009-05-03 22:53:19 +00002341 /* If some user-process sent us a sync signal (ie. it's not the result
njn96986052009-04-30 07:41:24 +00002342 of a faulting instruction), then how we treat it depends on when it
2343 arrives... */
2344
2345 if (VG_(threads)[tid].status == VgTs_WaitSys) {
2346 /* Signal arrived while we're blocked in a syscall. This means that
2347 the client's signal mask was applied. In other words, so we can't
2348 get here unless the client wants this signal right now. This means
2349 we can simply use the async_signalhandler. */
2350 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002351 VG_(dmsg)("Delivering user-sent sync signal %d as async signal\n",
2352 sigNo);
njn96986052009-04-30 07:41:24 +00002353
2354 async_signalhandler(sigNo, info, uc);
2355 VG_(core_panic)("async_signalhandler returned!?\n");
2356
2357 } else {
2358 /* Signal arrived while in generated client code, or while running
2359 Valgrind core code. That means that every thread has these signals
2360 unblocked, so we can't rely on the kernel to route them properly, so
2361 we need to queue them manually. */
2362 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002363 VG_(dmsg)("Routing user-sent sync signal %d via queue\n", sigNo);
njn96986052009-04-30 07:41:24 +00002364
2365# if defined(VGO_linux)
2366 /* On Linux, first we have to do a sanity check of the siginfo. */
2367 if (info->VKI_SIGINFO_si_pid == 0) {
2368 /* There's a per-user limit of pending siginfo signals. If
2369 you exceed this, by having more than that number of
2370 pending signals with siginfo, then new signals are
2371 delivered without siginfo. This condition can be caused
2372 by any unrelated program you're running at the same time
2373 as Valgrind, if it has a large number of pending siginfo
2374 signals which it isn't taking delivery of.
2375
2376 Since we depend on siginfo to work out why we were sent a
2377 signal and what we should do about it, we really can't
2378 continue unless we get it. */
sewardj738856f2009-07-15 14:48:32 +00002379 VG_(umsg)("Signal %d (%s) appears to have lost its siginfo; "
philippe886fde32012-03-29 21:56:47 +00002380 "I can't go on.\n", sigNo, VG_(signame)(sigNo));
njn96986052009-04-30 07:41:24 +00002381 VG_(printf)(
2382" This may be because one of your programs has consumed your ration of\n"
2383" siginfo structures. For more information, see:\n"
2384" http://kerneltrap.org/mailarchive/1/message/25599/thread\n"
2385" Basically, some program on your system is building up a large queue of\n"
2386" pending signals, and this causes the siginfo data for other signals to\n"
2387" be dropped because it's exceeding a system limit. However, Valgrind\n"
2388" absolutely needs siginfo for SIGSEGV. A workaround is to track down the\n"
2389" offending program and avoid running it while using Valgrind, but there\n"
2390" is no easy way to do this. Apparently the problem was fixed in kernel\n"
2391" 2.6.12.\n");
2392
2393 /* It's a fatal signal, so we force the default handler. */
2394 VG_(set_default_handler)(sigNo);
2395 deliver_signal(tid, info, uc);
2396 resume_scheduler(tid);
2397 VG_(exit)(99); /* If we can't resume, then just exit */
2398 }
2399# endif
2400
2401 qtid = 0; /* shared pending by default */
2402# if defined(VGO_linux)
2403 if (info->si_code == VKI_SI_TKILL)
2404 qtid = tid; /* directed to us specifically */
2405# endif
2406 queue_signal(qtid, info);
2407 }
2408}
2409
sewardjb5b87402011-03-07 16:05:35 +00002410/* Returns the reported fault address for an exact address */
2411static Addr fault_mask(Addr in)
2412{
2413 /* We have to use VG_PGROUNDDN because faults on s390x only deliver
2414 the page address but not the address within a page.
2415 */
2416# if defined(VGA_s390x)
2417 return VG_PGROUNDDN(in);
2418# else
2419 return in;
2420#endif
2421}
2422
njn96986052009-04-30 07:41:24 +00002423/* Returns True if the sync signal was due to the stack requiring extension
2424 and the extension was successful.
2425*/
2426static Bool extend_stack_if_appropriate(ThreadId tid, vki_siginfo_t* info)
2427{
2428 Addr fault;
2429 Addr esp;
florian4465bd52015-04-14 19:59:21 +00002430 NSegment const *seg, *seg_next;
njn96986052009-04-30 07:41:24 +00002431
2432 if (info->si_signo != VKI_SIGSEGV)
2433 return False;
2434
2435 fault = (Addr)info->VKI_SIGINFO_si_addr;
2436 esp = VG_(get_SP)(tid);
2437 seg = VG_(am_find_nsegment)(fault);
florian4465bd52015-04-14 19:59:21 +00002438 seg_next = seg ? VG_(am_next_nsegment)( seg, True/*fwds*/ )
2439 : NULL;
njn96986052009-04-30 07:41:24 +00002440
2441 if (VG_(clo_trace_signals)) {
2442 if (seg == NULL)
sewardj738856f2009-07-15 14:48:32 +00002443 VG_(dmsg)("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
2444 "seg=NULL\n",
2445 info->si_code, fault, tid, esp);
njn96986052009-04-30 07:41:24 +00002446 else
sewardj738856f2009-07-15 14:48:32 +00002447 VG_(dmsg)("SIGSEGV: si_code=%d faultaddr=%#lx tid=%d ESP=%#lx "
2448 "seg=%#lx-%#lx\n",
2449 info->si_code, fault, tid, esp, seg->start, seg->end);
njn96986052009-04-30 07:41:24 +00002450 }
2451
2452 if (info->si_code == VKI_SEGV_MAPERR
2453 && seg
florian4465bd52015-04-14 19:59:21 +00002454 && seg->kind == SkResvn
2455 && seg->smode == SmUpper
2456 && seg_next
2457 && seg_next->kind == SkAnonC
sewardjb5b87402011-03-07 16:05:35 +00002458 && fault >= fault_mask(esp - VG_STACK_REDZONE_SZB)) {
njn96986052009-04-30 07:41:24 +00002459 /* If the fault address is above esp but below the current known
2460 stack segment base, and it was a fault because there was
2461 nothing mapped there (as opposed to a permissions fault),
2462 then extend the stack segment.
2463 */
2464 Addr base = VG_PGROUNDDN(esp - VG_STACK_REDZONE_SZB);
florian15fa8a22015-03-03 14:56:17 +00002465 if (VG_(extend_stack)(tid, base)) {
njn96986052009-04-30 07:41:24 +00002466 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002467 VG_(dmsg)(" -> extended stack base to %#lx\n",
2468 VG_PGROUNDDN(fault));
njn96986052009-04-30 07:41:24 +00002469 return True;
2470 } else {
njn96986052009-04-30 07:41:24 +00002471 return False;
2472 }
2473 } else {
2474 return False;
2475 }
2476}
2477
2478static
njn2d5ff4f2009-05-03 22:53:19 +00002479void sync_signalhandler_from_kernel ( ThreadId tid,
njn96986052009-04-30 07:41:24 +00002480 Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
2481{
2482 /* Check to see if some part of Valgrind itself is interested in faults.
2483 The fault catcher should never be set whilst we're in generated code, so
2484 check for that. AFAIK the only use of the catcher right now is
2485 memcheck's leak detector. */
2486 if (fault_catcher) {
2487 vg_assert(VG_(in_generated_code) == False);
2488
2489 (*fault_catcher)(sigNo, (Addr)info->VKI_SIGINFO_si_addr);
2490 /* If the catcher returns, then it didn't handle the fault,
2491 so carry on panicking. */
2492 }
2493
2494 if (extend_stack_if_appropriate(tid, info)) {
2495 /* Stack extension occurred, so we don't need to do anything else; upon
2496 returning from this function, we'll restart the host (hence guest)
2497 instruction. */
2498 } else {
2499 /* OK, this is a signal we really have to deal with. If it came
2500 from the client's code, then we can jump back into the scheduler
2501 and have it delivered. Otherwise it's a Valgrind bug. */
2502 ThreadState *tst = VG_(get_ThreadState)(tid);
2503
2504 if (VG_(sigismember)(&tst->sig_mask, sigNo)) {
2505 /* signal is blocked, but they're not allowed to block faults */
2506 VG_(set_default_handler)(sigNo);
2507 }
2508
2509 if (VG_(in_generated_code)) {
sewardj3b290482011-05-06 21:02:55 +00002510 if (VG_(gdbserver_report_signal) (sigNo, tid)
2511 || VG_(sigismember)(&tst->sig_mask, sigNo)) {
2512 /* Can't continue; must longjmp back to the scheduler and thus
2513 enter the sighandler immediately. */
2514 deliver_signal(tid, info, uc);
2515 resume_scheduler(tid);
2516 }
2517 else
2518 resume_scheduler(tid);
njn96986052009-04-30 07:41:24 +00002519 }
2520
2521 /* If resume_scheduler returns or its our fault, it means we
2522 don't have longjmp set up, implying that we weren't running
2523 client code, and therefore it was actually generated by
2524 Valgrind internally.
2525 */
sewardj738856f2009-07-15 14:48:32 +00002526 VG_(dmsg)("VALGRIND INTERNAL ERROR: Valgrind received "
2527 "a signal %d (%s) - exiting\n",
philippe886fde32012-03-29 21:56:47 +00002528 sigNo, VG_(signame)(sigNo));
njn96986052009-04-30 07:41:24 +00002529
sewardj738856f2009-07-15 14:48:32 +00002530 VG_(dmsg)("si_code=%x; Faulting address: %p; sp: %#lx\n",
2531 info->si_code, info->VKI_SIGINFO_si_addr,
2532 VG_UCONTEXT_STACK_PTR(uc));
njn96986052009-04-30 07:41:24 +00002533
2534 if (0)
2535 VG_(kill_self)(sigNo); /* generate a core dump */
2536
2537 //if (tid == 0) /* could happen after everyone has exited */
2538 // tid = VG_(master_tid);
2539 vg_assert(tid != 0);
2540
sewardj59570ff2010-01-01 11:59:33 +00002541 UnwindStartRegs startRegs;
2542 VG_(memset)(&startRegs, 0, sizeof(startRegs));
2543
2544 VG_UCONTEXT_TO_UnwindStartRegs(&startRegs, uc);
2545 VG_(core_panic_at)("Killed by fatal signal", &startRegs);
njn96986052009-04-30 07:41:24 +00002546 }
2547}
sewardjb5f6f512005-03-10 23:59:00 +00002548
jsgf855d93d2003-10-13 22:26:55 +00002549/*
sewardj2a99cf62004-11-24 10:44:19 +00002550 Receive a sync signal from the host.
jsgf855d93d2003-10-13 22:26:55 +00002551*/
2552static
njn5a350be2009-04-30 03:05:05 +00002553void sync_signalhandler ( Int sigNo,
2554 vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00002555{
sewardj42781722006-12-17 19:36:06 +00002556 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
njn2d5ff4f2009-05-03 22:53:19 +00002557 Bool from_user;
jsgf855d93d2003-10-13 22:26:55 +00002558
njn5a350be2009-04-30 03:05:05 +00002559 if (0)
2560 VG_(printf)("sync_sighandler(%d, %p, %p)\n", sigNo, info, uc);
2561
jsgf855d93d2003-10-13 22:26:55 +00002562 vg_assert(info != NULL);
2563 vg_assert(info->si_signo == sigNo);
2564 vg_assert(sigNo == VKI_SIGSEGV ||
2565 sigNo == VKI_SIGBUS ||
2566 sigNo == VKI_SIGFPE ||
sewardjb5f6f512005-03-10 23:59:00 +00002567 sigNo == VKI_SIGILL ||
2568 sigNo == VKI_SIGTRAP);
jsgf855d93d2003-10-13 22:26:55 +00002569
njn3b6b2aa2009-04-30 03:30:09 +00002570 info->si_code = sanitize_si_code(info->si_code);
tom9f4a7bf2005-11-13 00:01:20 +00002571
njnf76d27a2009-05-28 01:53:07 +00002572 from_user = !is_signal_from_kernel(tid, sigNo, info->si_code);
njn81f52d12009-04-30 03:49:06 +00002573
2574 if (VG_(clo_trace_signals)) {
sewardj738856f2009-07-15 14:48:32 +00002575 VG_(dmsg)("sync signal handler: "
2576 "signal=%d, si_code=%d, EIP=%#lx, eip=%#lx, from %s\n",
2577 sigNo, info->si_code, VG_(get_IP)(tid),
2578 VG_UCONTEXT_INSTR_PTR(uc),
2579 ( from_user ? "user" : "kernel" ));
njn81f52d12009-04-30 03:49:06 +00002580 }
2581 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
2582
njn36fce1b2009-04-28 01:55:01 +00002583 /* // debug code:
2584 if (0) {
2585 VG_(printf)("info->si_signo %d\n", info->si_signo);
2586 VG_(printf)("info->si_errno %d\n", info->si_errno);
2587 VG_(printf)("info->si_code %d\n", info->si_code);
2588 VG_(printf)("info->si_pid %d\n", info->si_pid);
2589 VG_(printf)("info->si_uid %d\n", info->si_uid);
2590 VG_(printf)("info->si_status %d\n", info->si_status);
2591 VG_(printf)("info->si_addr %p\n", info->si_addr);
2592 }
2593 */
2594
2595 /* Figure out if the signal is being sent from outside the process.
2596 (Why do we care?) If the signal is from the user rather than the
njn96986052009-04-30 07:41:24 +00002597 kernel, then treat it more like an async signal than a sync signal --
njn36fce1b2009-04-28 01:55:01 +00002598 that is, merely queue it for later delivery. */
njn2d5ff4f2009-05-03 22:53:19 +00002599 if (from_user) {
njnc8a91072009-05-20 06:51:11 +00002600 sync_signalhandler_from_user( tid, sigNo, info, uc);
njn96986052009-04-30 07:41:24 +00002601 } else {
njnc8a91072009-05-20 06:51:11 +00002602 sync_signalhandler_from_kernel(tid, sigNo, info, uc);
jsgf855d93d2003-10-13 22:26:55 +00002603 }
2604}
2605
2606
2607/*
sewardjb5f6f512005-03-10 23:59:00 +00002608 Kill this thread. Makes it leave any syscall it might be currently
2609 blocked in, and return to the scheduler. This doesn't mark the thread
2610 as exiting; that's the caller's job.
jsgf855d93d2003-10-13 22:26:55 +00002611 */
njn5a350be2009-04-30 03:05:05 +00002612static void sigvgkill_handler(int signo, vki_siginfo_t *si,
2613 struct vki_ucontext *uc)
jsgf855d93d2003-10-13 22:26:55 +00002614{
sewardj42781722006-12-17 19:36:06 +00002615 ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
sewardj489bfec2006-10-17 02:00:29 +00002616 ThreadStatus at_signal = VG_(threads)[tid].status;
sewardjb5f6f512005-03-10 23:59:00 +00002617
2618 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002619 VG_(dmsg)("sigvgkill for lwp %d tid %d\n", VG_(gettid)(), tid);
sewardj489bfec2006-10-17 02:00:29 +00002620
sewardjad0a3a82006-12-17 18:58:55 +00002621 VG_(acquire_BigLock)(tid, "sigvgkill_handler");
sewardjb5f6f512005-03-10 23:59:00 +00002622
njn351d0062005-06-21 22:23:59 +00002623 vg_assert(signo == VG_SIGVGKILL);
jsgf855d93d2003-10-13 22:26:55 +00002624 vg_assert(si->si_signo == signo);
2625
sewardj489bfec2006-10-17 02:00:29 +00002626 /* jrs 2006 August 3: the following assertion seems incorrect to
2627 me, and fails on AIX. sigvgkill could be sent to a thread which
2628 is runnable - see VG_(nuke_all_threads_except) in the scheduler.
2629 Hence comment these out ..
2630
2631 vg_assert(VG_(threads)[tid].status == VgTs_WaitSys);
2632 VG_(post_syscall)(tid);
2633
2634 and instead do:
2635 */
2636 if (at_signal == VgTs_WaitSys)
2637 VG_(post_syscall)(tid);
2638 /* jrs 2006 August 3 ends */
sewardjb5f6f512005-03-10 23:59:00 +00002639
njn06244e72005-06-21 22:27:19 +00002640 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002641
2642 VG_(core_panic)("sigvgkill_handler couldn't return to the scheduler\n");
sewardjde4a1d02002-03-22 01:27:54 +00002643}
2644
sewardjde4a1d02002-03-22 01:27:54 +00002645static __attribute((unused))
njncda2f0f2009-05-18 02:12:08 +00002646void pp_ksigaction ( vki_sigaction_toK_t* sa )
sewardjde4a1d02002-03-22 01:27:54 +00002647{
2648 Int i;
njn695c16e2005-03-27 03:40:28 +00002649 VG_(printf)("pp_ksigaction: handler %p, flags 0x%x, restorer %p\n",
sewardj489bfec2006-10-17 02:00:29 +00002650 sa->ksa_handler,
2651 (UInt)sa->sa_flags,
sewardj6e9de462011-06-28 07:25:29 +00002652# if !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
sewardj489bfec2006-10-17 02:00:29 +00002653 sa->sa_restorer
2654# else
sewardja8ffda62008-07-18 18:23:24 +00002655 (void*)0
sewardj489bfec2006-10-17 02:00:29 +00002656# endif
2657 );
njn695c16e2005-03-27 03:40:28 +00002658 VG_(printf)("pp_ksigaction: { ");
sewardjb5f6f512005-03-10 23:59:00 +00002659 for (i = 1; i <= VG_(max_signal); i++)
nethercote73b526f2004-10-31 18:48:21 +00002660 if (VG_(sigismember(&(sa->sa_mask),i)))
sewardjde4a1d02002-03-22 01:27:54 +00002661 VG_(printf)("%d ", i);
2662 VG_(printf)("}\n");
2663}
2664
jsgf855d93d2003-10-13 22:26:55 +00002665/*
sewardjb5f6f512005-03-10 23:59:00 +00002666 Force signal handler to default
jsgf855d93d2003-10-13 22:26:55 +00002667 */
sewardjb5f6f512005-03-10 23:59:00 +00002668void VG_(set_default_handler)(Int signo)
2669{
njncda2f0f2009-05-18 02:12:08 +00002670 vki_sigaction_toK_t sa;
sewardjb5f6f512005-03-10 23:59:00 +00002671
2672 sa.ksa_handler = VKI_SIG_DFL;
2673 sa.sa_flags = 0;
sewardj6e9de462011-06-28 07:25:29 +00002674# if !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
sewardjb5f6f512005-03-10 23:59:00 +00002675 sa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00002676# endif
sewardjb5f6f512005-03-10 23:59:00 +00002677 VG_(sigemptyset)(&sa.sa_mask);
2678
2679 VG_(do_sys_sigaction)(signo, &sa, NULL);
2680}
2681
2682/*
2683 Poll for pending signals, and set the next one up for delivery.
2684 */
2685void VG_(poll_signals)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00002686{
sewardjb5f6f512005-03-10 23:59:00 +00002687 vki_siginfo_t si, *sip;
2688 vki_sigset_t pollset;
2689 ThreadState *tst = VG_(get_ThreadState)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002690 vki_sigset_t saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002691
sewardjb5f6f512005-03-10 23:59:00 +00002692 /* look for all the signals this thread isn't blocking */
njncda2f0f2009-05-18 02:12:08 +00002693 /* pollset = ~tst->sig_mask */
2694 VG_(sigcomplementset)( &pollset, &tst->sig_mask );
jsgf855d93d2003-10-13 22:26:55 +00002695
njn444eba12005-05-12 03:47:31 +00002696 block_all_host_signals(&saved_mask); // protect signal queue
sewardjb5f6f512005-03-10 23:59:00 +00002697
2698 /* First look for any queued pending signals */
2699 sip = next_queued(tid, &pollset); /* this thread */
2700
2701 if (sip == NULL)
2702 sip = next_queued(0, &pollset); /* process-wide */
2703
2704 /* If there was nothing queued, ask the kernel for a pending signal */
sewardj489bfec2006-10-17 02:00:29 +00002705 if (sip == NULL && VG_(sigtimedwait_zero)(&pollset, &si) > 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002706 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002707 VG_(dmsg)("poll_signals: got signal %d for thread %d\n",
2708 si.si_signo, tid);
sewardjb5f6f512005-03-10 23:59:00 +00002709 sip = &si;
thughes8abf3922004-10-16 10:59:49 +00002710 }
fitzhardingee1c06d82003-10-30 07:21:44 +00002711
sewardjb5f6f512005-03-10 23:59:00 +00002712 if (sip != NULL) {
2713 /* OK, something to do; deliver it */
2714 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002715 VG_(dmsg)("Polling found signal %d for tid %d\n", sip->si_signo, tid);
sewardj3b290482011-05-06 21:02:55 +00002716 if (!is_sig_ign(sip->si_signo, tid))
tomadacaf92007-12-21 10:24:24 +00002717 deliver_signal(tid, sip, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002718 else if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002719 VG_(dmsg)(" signal %d ignored\n", sip->si_signo);
sewardjb5f6f512005-03-10 23:59:00 +00002720
2721 sip->si_signo = 0; /* remove from signal queue, if that's
2722 where it came from */
jsgf855d93d2003-10-13 22:26:55 +00002723 }
2724
njn444eba12005-05-12 03:47:31 +00002725 restore_all_host_signals(&saved_mask);
sewardjb5f6f512005-03-10 23:59:00 +00002726}
2727
sewardj018f7622002-05-15 21:13:39 +00002728/* At startup, copy the process' real signal state to the SCSS.
2729 Whilst doing this, block all real signals. Then calculate SKSS and
2730 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00002731*/
2732void VG_(sigstartup_actions) ( void )
2733{
njncda2f0f2009-05-18 02:12:08 +00002734 Int i, ret, vKI_SIGRTMIN;
nethercote73b526f2004-10-31 18:48:21 +00002735 vki_sigset_t saved_procmask;
njncda2f0f2009-05-18 02:12:08 +00002736 vki_sigaction_fromK_t sa;
2737
2738 VG_(memset)(&scss, 0, sizeof(scss));
2739 VG_(memset)(&skss, 0, sizeof(skss));
2740
2741# if defined(VKI_SIGRTMIN)
2742 vKI_SIGRTMIN = VKI_SIGRTMIN;
2743# else
2744 vKI_SIGRTMIN = 0; /* eg Darwin */
2745# endif
sewardjde4a1d02002-03-22 01:27:54 +00002746
sewardj2e93c502002-04-12 11:12:52 +00002747 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00002748 /* Block all signals. saved_procmask remembers the previous mask,
2749 which the first thread inherits.
2750 */
njn444eba12005-05-12 03:47:31 +00002751 block_all_host_signals( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00002752
sewardj018f7622002-05-15 21:13:39 +00002753 /* Copy per-signal settings to SCSS. */
nethercote73b526f2004-10-31 18:48:21 +00002754 for (i = 1; i <= _VKI_NSIG; i++) {
sewardj018f7622002-05-15 21:13:39 +00002755 /* Get the old host action */
nethercote73b526f2004-10-31 18:48:21 +00002756 ret = VG_(sigaction)(i, NULL, &sa);
sewardj018f7622002-05-15 21:13:39 +00002757
njnea2d6fd2010-07-01 00:20:20 +00002758# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
njnf76d27a2009-05-28 01:53:07 +00002759 /* apparently we may not even ask about the disposition of these
2760 signals, let alone change them */
2761 if (ret != 0 && (i == VKI_SIGKILL || i == VKI_SIGSTOP))
2762 continue;
2763# endif
2764
sewardjb5f6f512005-03-10 23:59:00 +00002765 if (ret != 0)
2766 break;
2767
2768 /* Try setting it back to see if this signal is really
2769 available */
njncda2f0f2009-05-18 02:12:08 +00002770 if (vKI_SIGRTMIN > 0 /* it actually exists on this platform */
2771 && i >= vKI_SIGRTMIN) {
2772 vki_sigaction_toK_t tsa, sa2;
sewardjb5f6f512005-03-10 23:59:00 +00002773
njn695c16e2005-03-27 03:40:28 +00002774 tsa.ksa_handler = (void *)sync_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +00002775 tsa.sa_flags = VKI_SA_SIGINFO;
sewardj6e9de462011-06-28 07:25:29 +00002776# if !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
sewardjb5f6f512005-03-10 23:59:00 +00002777 tsa.sa_restorer = 0;
sewardj489bfec2006-10-17 02:00:29 +00002778# endif
sewardjb5f6f512005-03-10 23:59:00 +00002779 VG_(sigfillset)(&tsa.sa_mask);
2780
2781 /* try setting it to some arbitrary handler */
2782 if (VG_(sigaction)(i, &tsa, NULL) != 0) {
2783 /* failed - not really usable */
2784 break;
2785 }
2786
njncda2f0f2009-05-18 02:12:08 +00002787 VG_(convert_sigaction_fromK_to_toK)( &sa, &sa2 );
2788 ret = VG_(sigaction)(i, &sa2, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002789 vg_assert(ret == 0);
2790 }
2791
2792 VG_(max_signal) = i;
2793
2794 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
njn8a7b41b2007-09-23 00:51:24 +00002795 VG_(printf)("snaffling handler 0x%lx for signal %d\n",
sewardj018f7622002-05-15 21:13:39 +00002796 (Addr)(sa.ksa_handler), i );
2797
njn695c16e2005-03-27 03:40:28 +00002798 scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
2799 scss.scss_per_sig[i].scss_flags = sa.sa_flags;
2800 scss.scss_per_sig[i].scss_mask = sa.sa_mask;
njncda2f0f2009-05-18 02:12:08 +00002801
2802 scss.scss_per_sig[i].scss_restorer = NULL;
sewardj6e9de462011-06-28 07:25:29 +00002803# if !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin)
njn695c16e2005-03-27 03:40:28 +00002804 scss.scss_per_sig[i].scss_restorer = sa.sa_restorer;
sewardj489bfec2006-10-17 02:00:29 +00002805# endif
njncda2f0f2009-05-18 02:12:08 +00002806
2807 scss.scss_per_sig[i].scss_sa_tramp = NULL;
njnf76d27a2009-05-28 01:53:07 +00002808# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
2809 scss.scss_per_sig[i].scss_sa_tramp = NULL;
2810 /*sa.sa_tramp;*/
2811 /* We can't know what it was, because Darwin's sys_sigaction
2812 doesn't tell us. */
2813# endif
sewardj018f7622002-05-15 21:13:39 +00002814 }
2815
sewardjb5f6f512005-03-10 23:59:00 +00002816 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00002817 VG_(dmsg)("Max kernel-supported signal is %d\n", VG_(max_signal));
sewardjb5f6f512005-03-10 23:59:00 +00002818
jsgf855d93d2003-10-13 22:26:55 +00002819 /* Our private internal signals are treated as ignored */
njn351d0062005-06-21 22:23:59 +00002820 scss.scss_per_sig[VG_SIGVGKILL].scss_handler = VKI_SIG_IGN;
2821 scss.scss_per_sig[VG_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
2822 VG_(sigfillset)(&scss.scss_per_sig[VG_SIGVGKILL].scss_mask);
jsgf855d93d2003-10-13 22:26:55 +00002823
sewardj018f7622002-05-15 21:13:39 +00002824 /* Copy the process' signal mask into the root thread. */
sewardj1d887112005-05-30 21:44:08 +00002825 vg_assert(VG_(threads)[1].status == VgTs_Init);
2826 for (i = 2; i < VG_N_THREADS; i++)
2827 vg_assert(VG_(threads)[i].status == VgTs_Empty);
2828
2829 VG_(threads)[1].sig_mask = saved_procmask;
2830 VG_(threads)[1].tmp_sig_mask = saved_procmask;
sewardj7a61d912002-04-25 01:27:35 +00002831
sewardj018f7622002-05-15 21:13:39 +00002832 /* Calculate SKSS and apply it. This also sets the initial kernel
2833 mask we need to run with. */
nethercote9dd11512004-08-04 15:31:30 +00002834 handle_SCSS_change( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00002835
sewardjb5f6f512005-03-10 23:59:00 +00002836 /* Leave with all signals still blocked; the thread scheduler loop
2837 will set the appropriate mask at the appropriate time. */
sewardjde4a1d02002-03-22 01:27:54 +00002838}
2839
sewardjde4a1d02002-03-22 01:27:54 +00002840/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00002841/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00002842/*--------------------------------------------------------------------*/