2 /*--------------------------------------------------------------------*/
3 /*--- Signal-related libc stuff. m_libcsignal.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2017 Julian Seward
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
31 #include "pub_core_basics.h"
32 #include "pub_core_debuglog.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_vkiscnums.h"
35 #include "pub_core_libcbase.h"
36 #include "pub_core_libcassert.h"
37 #include "pub_core_syscall.h"
38 #include "pub_core_libcsignal.h" /* self */
40 #if !defined(VGO_solaris)
41 # define _VKI_MAXSIG (_VKI_NSIG - 1)
43 STATIC_ASSERT((_VKI_MAXSIG
% _VKI_NSIG_BPW
) != 0);
45 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
46 of syscalls rather than the vanilla version, if a _nocancel version
47 is available. See docs/internals/Darwin-notes.txt for the reason
50 /* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
51 success and -1 on error. */
52 /* In the sigset routines below, be aware that _VKI_NSIG_BPW can be
53 either 32 or 64, and hence the sig[] words can either be 32- or
54 64-bits. And which they are it doesn't necessarily follow from the
57 /* Functions VG_(isemptysigset) and VG_(isfullsigset) check only bits that
58 represent valid signals (i.e. signals <= _VKI_MAXSIG). The same applies
59 for the comparison in VG_(iseqsigset). This is important because when
60 a signal set is received from an operating system then bits which represent
61 signals > _VKI_MAXSIG can have unexpected values for Valgrind. This is
62 mainly specific to the Solaris kernel which clears these bits. */
64 Int
VG_(sigfillset
)( vki_sigset_t
* set
)
69 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
74 Int
VG_(sigemptyset
)( vki_sigset_t
* set
)
79 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
84 Bool
VG_(isemptysigset
)( const vki_sigset_t
* set
)
87 vg_assert(set
!= NULL
);
88 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++) {
89 if (_VKI_NSIG_BPW
* (i
+ 1) <= (_VKI_MAXSIG
+ 1)) {
90 /* Full word check. */
91 if (set
->sig
[i
] != 0) return False
;
94 /* Partial word check. */
95 ULong mask
= ((ULong
)1UL << (_VKI_MAXSIG
% _VKI_NSIG_BPW
)) - 1;
96 if ((set
->sig
[i
] & mask
) != 0) return False
;
103 Bool
VG_(isfullsigset
)( const vki_sigset_t
* set
)
106 vg_assert(set
!= NULL
);
107 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++) {
108 if (_VKI_NSIG_BPW
* (i
+ 1) <= (_VKI_MAXSIG
+ 1)) {
109 /* Full word check. */
110 if (set
->sig
[i
] != ~0) return False
;
113 /* Partial word check. */
114 ULong mask
= ((ULong
)1UL << (_VKI_MAXSIG
% _VKI_NSIG_BPW
)) - 1;
115 if ((set
->sig
[i
] & mask
) != mask
) return False
;
122 Bool
VG_(iseqsigset
)( const vki_sigset_t
* set1
, const vki_sigset_t
* set2
)
125 vg_assert(set1
!= NULL
&& set2
!= NULL
);
126 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++) {
127 if (_VKI_NSIG_BPW
* (i
+ 1) <= (_VKI_MAXSIG
+ 1)) {
128 /* Full word comparison. */
129 if (set1
->sig
[i
] != set2
->sig
[i
]) return False
;
132 /* Partial word comparison. */
133 ULong mask
= ((ULong
)1UL << (_VKI_MAXSIG
% _VKI_NSIG_BPW
)) - 1;
134 if ((set1
->sig
[i
] & mask
) != (set2
->sig
[i
] & mask
)) return False
;
142 Int
VG_(sigaddset
)( vki_sigset_t
* set
, Int signum
)
146 if (signum
< 1 || signum
> _VKI_NSIG
)
149 set
->sig
[signum
/ _VKI_NSIG_BPW
] |= (1ULL << (signum
% _VKI_NSIG_BPW
));
153 Int
VG_(sigdelset
)( vki_sigset_t
* set
, Int signum
)
157 if (signum
< 1 || signum
> _VKI_NSIG
)
160 set
->sig
[signum
/ _VKI_NSIG_BPW
] &= ~(1ULL << (signum
% _VKI_NSIG_BPW
));
164 Int
VG_(sigismember
) ( const vki_sigset_t
* set
, Int signum
)
168 if (signum
< 1 || signum
> _VKI_NSIG
)
171 if (1 & ((set
->sig
[signum
/ _VKI_NSIG_BPW
]) >> (signum
% _VKI_NSIG_BPW
)))
177 /* Add all signals in src to dst. */
178 void VG_(sigaddset_from_set
)( vki_sigset_t
* dst
, const vki_sigset_t
* src
)
181 vg_assert(dst
!= NULL
&& src
!= NULL
);
182 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
183 dst
->sig
[i
] |= src
->sig
[i
];
186 /* Remove all signals in src from dst. */
187 void VG_(sigdelset_from_set
)( vki_sigset_t
* dst
, const vki_sigset_t
* src
)
190 vg_assert(dst
!= NULL
&& src
!= NULL
);
191 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
192 dst
->sig
[i
] &= ~(src
->sig
[i
]);
195 /* dst = dst `intersect` src. */
196 void VG_(sigintersectset
)( vki_sigset_t
* dst
, const vki_sigset_t
* src
)
199 vg_assert(dst
!= NULL
&& src
!= NULL
);
200 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
201 dst
->sig
[i
] &= src
->sig
[i
];
205 void VG_(sigcomplementset
)( vki_sigset_t
* dst
, const vki_sigset_t
* src
)
208 vg_assert(dst
!= NULL
&& src
!= NULL
);
209 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
210 dst
->sig
[i
] = ~ src
->sig
[i
];
214 /* The functions sigaction, sigprocmask, sigpending and sigsuspend
215 return 0 on success and -1 on error.
217 Int
VG_(sigprocmask
)( Int how
, const vki_sigset_t
* set
, vki_sigset_t
* oldset
)
219 # if defined(VGO_linux) || defined(VGO_solaris)
220 # if defined(__NR_rt_sigprocmask)
221 SysRes res
= VG_(do_syscall4
)(__NR_rt_sigprocmask
,
222 how
, (UWord
)set
, (UWord
)oldset
,
223 _VKI_NSIG_WORDS
* sizeof(UWord
));
225 SysRes res
= VG_(do_syscall3
)(__NR_sigprocmask
,
226 how
, (UWord
)set
, (UWord
)oldset
);
229 # elif defined(VGO_darwin)
230 /* On Darwin, __NR_sigprocmask appears to affect the entire
231 process, not just this thread. Hence need to use
232 __NR___pthread_sigmask instead. */
233 SysRes res
= VG_(do_syscall3
)(__NR___pthread_sigmask
,
234 how
, (UWord
)set
, (UWord
)oldset
);
238 return sr_isError(res
) ? -1 : 0;
242 #if defined(VGO_darwin)
243 /* A helper function for sigaction on Darwin. */
245 void darwin_signal_demux(void* a1
, UWord a2
, UWord a3
, void* a4
, void* a5
) {
246 VG_(debugLog
)(2, "libcsignal",
247 "PRE demux sig, a2 = %lu, signo = %lu\n", a2
, a3
);
249 ((void(*)(int))a1
) (a3
);
251 ((void(*)(int,void*,void*))a1
) (a3
,a4
,a5
);
252 VG_(debugLog
)(2, "libcsignal",
253 "POST demux sig, a2 = %lu, signo = %lu\n", a2
, a3
);
254 VG_(do_syscall2
)(__NR_sigreturn
, (UWord
)a5
, 0x1E);
256 __asm__
__volatile__("ud2");
260 Int
VG_(sigaction
) ( Int signum
,
261 const vki_sigaction_toK_t
* act
,
262 vki_sigaction_fromK_t
* oldact
)
264 # if defined(VGO_linux)
265 /* Normal case: vki_sigaction_toK_t and vki_sigaction_fromK_t are
267 SysRes res
= VG_(do_syscall4
)(__NR_rt_sigaction
,
268 signum
, (UWord
)act
, (UWord
)oldact
,
269 _VKI_NSIG_WORDS
* sizeof(UWord
));
270 return sr_isError(res
) ? -1 : 0;
272 # elif defined(VGO_darwin)
273 /* If we're passing a new action to the kernel, make a copy of the
274 new action, install our own sa_tramp field in it, and ignore
275 whatever we were provided with. This is OK because all the
276 sigaction requests come from m_signals, and are not directly
277 what the client program requested, so there is no chance that we
278 will inadvertently ignore the sa_tramp field requested by the
279 client. (In fact m_signals does ignore it when building signal
280 frames for the client, but that's a completely different
283 If we're receiving an old action from the kernel, be very
284 paranoid and make sure the kernel doesn't trash bits of memory
285 that we don't expect it to. */
288 vki_sigaction_toK_t actCopy
;
291 vki_sigaction_fromK_t oa
;
296 vki_sigaction_toK_t
* real_act
;
297 vki_sigaction_fromK_t
* real_oldact
;
299 real_act
= act
? &actCopy
: NULL
;
300 real_oldact
= oldact
? &oldactCopy
.oa
: NULL
;
301 VG_(memset
)(&oldactCopy
, 0x55, sizeof(oldactCopy
));
304 real_act
->sa_tramp
= (void*)&darwin_signal_demux
;
306 res
= VG_(do_syscall3
)(__NR_sigaction
,
307 signum
, (UWord
)real_act
, (UWord
)real_oldact
);
309 vg_assert(oldactCopy
.before
[0] == 0x5555555555555555ULL
);
310 vg_assert(oldactCopy
.before
[1] == 0x5555555555555555ULL
);
311 vg_assert(oldactCopy
.after
[0] == 0x5555555555555555ULL
);
312 vg_assert(oldactCopy
.after
[1] == 0x5555555555555555ULL
);
313 *oldact
= *real_oldact
;
315 return sr_isError(res
) ? -1 : 0;
317 # elif defined(VGO_solaris)
318 /* vki_sigaction_toK_t and vki_sigaction_fromK_t are identical types. */
319 SysRes res
= VG_(do_syscall3
)(__NR_sigaction
,
320 signum
, (UWord
)act
, (UWord
)oldact
);
321 return sr_isError(res
) ? -1 : 0;
324 # error "Unsupported OS"
329 /* See explanation in pub_core_libcsignal.h. */
331 VG_(convert_sigaction_fromK_to_toK
)( const vki_sigaction_fromK_t
* fromK
,
332 /*OUT*/vki_sigaction_toK_t
* toK
)
334 # if defined(VGO_linux) || defined(VGO_solaris)
336 # elif defined(VGO_darwin)
337 toK
->ksa_handler
= fromK
->ksa_handler
;
338 toK
->sa_tramp
= NULL
; /* the cause of all the difficulty */
339 toK
->sa_mask
= fromK
->sa_mask
;
340 toK
->sa_flags
= fromK
->sa_flags
;
342 # error "Unsupported OS"
347 Int
VG_(kill
)( Int pid
, Int signo
)
349 # if defined(VGO_linux) || defined(VGO_solaris)
350 SysRes res
= VG_(do_syscall2
)(__NR_kill
, pid
, signo
);
351 # elif defined(VGO_darwin)
352 SysRes res
= VG_(do_syscall3
)(__NR_kill
,
353 pid
, signo
, 1/*posix-compliant*/);
355 # error "Unsupported OS"
357 return sr_isError(res
) ? -1 : 0;
360 Int
VG_(tkill
)( Int lwpid
, Int signo
)
362 # if defined(__NR_tkill)
363 SysRes res
= VG_(mk_SysRes_Error
)(VKI_ENOSYS
);
364 res
= VG_(do_syscall2
)(__NR_tkill
, lwpid
, signo
);
365 if (sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)
366 res
= VG_(do_syscall2
)(__NR_kill
, lwpid
, signo
);
367 return sr_isError(res
) ? -1 : 0;
369 # elif defined(VGO_darwin)
370 // Note that the __pthread_kill syscall takes a Mach thread, not a pthread.
372 res
= VG_(do_syscall2
)(__NR___pthread_kill
, lwpid
, signo
);
373 return sr_isError(res
) ? -1 : 0;
375 # elif defined(VGO_solaris)
377 # if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL)
378 # if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL_TAKES_PID)
379 res
= VG_(do_syscall6
)(__NR_lwp_sigqueue
, 0, lwpid
, signo
,
382 res
= VG_(do_syscall5
)(__NR_lwp_sigqueue
, lwpid
, signo
,
386 res
= VG_(do_syscall2
)(__NR_lwp_kill
, lwpid
, signo
);
388 return sr_isError(res
) ? -1 : 0;
391 # error "Unsupported plat"
395 /* ---------------------- sigtimedwait_zero ----------------------- */
397 /* A cut-down version of POSIX sigtimedwait: poll for pending signals
398 mentioned in the sigset_t, and if any are present, select one
399 arbitrarily, return its number (which must be > 0), and put
400 auxiliary info about it in the siginfo_t, and make it
401 not-pending-any-more. If none are pending, return zero. The _zero
402 refers to the fact that there is zero timeout, so if no signals are
403 pending it returns immediately. Perhaps a better name would be
404 'sigpoll'. Returns -1 on error, 0 if no signals pending, and n > 0
405 if signal n was selected.
407 The Linux implementation is trivial: do the corresponding syscall.
409 The Darwin implementation is horrible and probably broken in a dozen
410 obscure ways. I suspect it's only thread-safe because V forces
411 single-threadedness. */
413 /* ---------- sigtimedwait_zero: Linux ----------- */
415 #if defined(VGO_linux)
416 Int
VG_(sigtimedwait_zero
)( const vki_sigset_t
*set
,
417 vki_siginfo_t
*info
)
419 static const struct vki_timespec zero
= { 0, 0 };
420 SysRes res
= VG_(do_syscall4
)(__NR_rt_sigtimedwait
, (UWord
)set
, (UWord
)info
,
421 (UWord
)&zero
, sizeof(*set
));
422 return sr_isError(res
) ? -1 : sr_Res(res
);
425 /* ---------- sigtimedwait_zero: Darwin ----------- */
427 #elif defined(VGO_darwin)
429 //static void show_set ( HChar* str, const vki_sigset_t* set ) {
431 // VG_(printf)("%s { ", str);
432 // for (i = 1; i <= _VKI_NSIG; i++) {
433 // if (VG_(sigismember)(set, i))
434 // VG_(printf)("%u ", i);
436 // VG_(printf)("}\n");
439 /* The general idea is:
440 - use sigpending to find out which signals are pending
442 - temporarily set its handler to sigtimedwait_zero_handler
443 - use sigsuspend atomically unblock it and wait for the signal.
444 Upon return, sigsuspend restores the signal mask to what it
446 - Restore the handler for the signal to whatever it was before.
449 /* A signal handler which does nothing (it doesn't need to). It does
450 however check that it's not handing a sync signal for which
451 returning is meaningless. */
452 static void sigtimedwait_zero_handler ( Int sig
)
454 /* XXX this is wrong -- get rid of these. We could
455 get _any_ signal here */
456 vg_assert(sig
!= VKI_SIGILL
);
457 vg_assert(sig
!= VKI_SIGSEGV
);
458 vg_assert(sig
!= VKI_SIGBUS
);
459 vg_assert(sig
!= VKI_SIGTRAP
);
463 Int
VG_(sigtimedwait_zero
)( const vki_sigset_t
*set
,
464 vki_siginfo_t
*info
)
466 const Bool debug
= False
;
469 vki_sigset_t pending
, blocked
, allbutone
;
470 vki_sigaction_toK_t sa
, saved_sa2
;
471 vki_sigaction_fromK_t saved_sa
;
473 //show_set("STWZ: looking for", set);
475 /* Find out what's pending: Darwin sigpending */
476 sr
= VG_(do_syscall1
)(__NR_sigpending
, (UWord
)&pending
);
477 vg_assert(!sr_isError(sr
));
479 /* don't try for signals not in 'set' */
480 /* pending = pending `intersect` set */
481 VG_(sigintersectset
)(&pending
, (const vki_sigset_t
*)set
);
483 /* don't try for signals not blocked at the moment */
484 ir
= VG_(sigprocmask
)(VKI_SIG_SETMASK
, NULL
, &blocked
);
487 /* pending = pending `intersect` blocked */
488 VG_(sigintersectset
)(&pending
, &blocked
);
490 /* decide which signal we're going to snarf */
491 for (i
= 1; i
< _VKI_NSIG
; i
++)
492 if (VG_(sigismember
)(&pending
,i
))
499 VG_(debugLog
)(0, "libcsignal",
500 "sigtimedwait_zero: snarfing signal %d\n", i
);
503 pre: i is blocked and pending
504 pre: we are the only thread running
506 /* Set up alternative signal handler */
507 VG_(sigfillset
)(&sa
.sa_mask
);
508 sa
.ksa_handler
= &sigtimedwait_zero_handler
;
510 ir
= VG_(sigaction
)(i
, &sa
, &saved_sa
);
513 /* Switch signal masks and wait for the signal. This should happen
514 immediately, since we've already established it is pending and
516 VG_(sigfillset
)(&allbutone
);
517 VG_(sigdelset
)(&allbutone
, i
);
518 /* Note: pass the sig mask by value here, not reference (!) */
519 vg_assert(_VKI_NSIG_WORDS
== 1);
520 sr
= VG_(do_syscall3
)(__NR_sigsuspend_nocancel
,
521 (UWord
)allbutone
.sig
[0], 0,0);
523 VG_(debugLog
)(0, "libcsignal",
524 "sigtimedwait_zero: sigsuspend got "
526 sr_isError(sr
) ? "FAIL" : "SUCCESS",
527 sr_isError(sr
) ? sr_Err(sr
) : sr_Res(sr
));
528 vg_assert(sr_isError(sr
));
529 vg_assert(sr_Err(sr
) == VKI_EINTR
);
531 /* Restore signal's handler to whatever it was before */
532 VG_(convert_sigaction_fromK_to_toK
)( &saved_sa
, &saved_sa2
);
533 ir
= VG_(sigaction
)(i
, &saved_sa2
, NULL
);
536 /* This is bogus - we could get more info from the sighandler. */
537 VG_(memset
)( info
, 0, sizeof(*info
) );
543 #elif defined(VGO_solaris)
544 Int
VG_(sigtimedwait_zero
)( const vki_sigset_t
*set
, vki_siginfo_t
*info
)
546 /* Trivial as on Linux. */
547 static const struct vki_timespec zero
= { 0, 0 };
548 SysRes res
= VG_(do_syscall3
)(__NR_sigtimedwait
, (UWord
)set
, (UWord
)info
,
550 return sr_isError(res
) ? -1 : sr_Res(res
);
557 /*--------------------------------------------------------------------*/
559 /*--------------------------------------------------------------------*/