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, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #include "pub_core_basics.h"
30 #include "pub_core_debuglog.h"
31 #include "pub_core_vki.h"
32 #include "pub_core_vkiscnums.h"
33 #include "pub_core_libcbase.h"
34 #include "pub_core_libcassert.h"
35 #include "pub_core_syscall.h"
36 #include "pub_core_libcsignal.h" /* self */
37 #include "pub_core_libcproc.h"
39 #if !defined(VGO_solaris)
40 # define _VKI_MAXSIG (_VKI_NSIG - 1)
42 STATIC_ASSERT((_VKI_MAXSIG
% _VKI_NSIG_BPW
) != 0);
44 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
45 of syscalls rather than the vanilla version, if a _nocancel version
46 is available. See docs/internals/Darwin-notes.txt for the reason
49 /* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
50 success and -1 on error. */
51 /* In the sigset routines below, be aware that _VKI_NSIG_BPW can be
52 either 32 or 64, and hence the sig[] words can either be 32- or
53 64-bits. And which they are it doesn't necessarily follow from the
56 /* Functions VG_(isemptysigset) and VG_(isfullsigset) check only bits that
57 represent valid signals (i.e. signals <= _VKI_MAXSIG). The same applies
58 for the comparison in VG_(iseqsigset). This is important because when
59 a signal set is received from an operating system then bits which represent
60 signals > _VKI_MAXSIG can have unexpected values for Valgrind. This is
61 mainly specific to the Solaris kernel which clears these bits. */
63 Int
VG_(sigfillset
)( vki_sigset_t
* set
)
68 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
73 Int
VG_(sigemptyset
)( vki_sigset_t
* set
)
78 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
83 Bool
VG_(isemptysigset
)( const vki_sigset_t
* set
)
86 vg_assert(set
!= NULL
);
87 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++) {
88 if (_VKI_NSIG_BPW
* (i
+ 1) <= (_VKI_MAXSIG
+ 1)) {
89 /* Full word check. */
90 if (set
->sig
[i
] != 0) return False
;
93 /* Partial word check. */
94 ULong mask
= ((ULong
)1UL << (_VKI_MAXSIG
% _VKI_NSIG_BPW
)) - 1;
95 if ((set
->sig
[i
] & mask
) != 0) return False
;
102 Bool
VG_(isfullsigset
)( const vki_sigset_t
* set
)
105 vg_assert(set
!= NULL
);
106 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++) {
107 if (_VKI_NSIG_BPW
* (i
+ 1) <= (_VKI_MAXSIG
+ 1)) {
108 /* Full word check. */
109 if (set
->sig
[i
] != ~0) return False
;
112 /* Partial word check. */
113 ULong mask
= ((ULong
)1UL << (_VKI_MAXSIG
% _VKI_NSIG_BPW
)) - 1;
114 if ((set
->sig
[i
] & mask
) != mask
) return False
;
121 Bool
VG_(iseqsigset
)( const vki_sigset_t
* set1
, const vki_sigset_t
* set2
)
124 vg_assert(set1
!= NULL
&& set2
!= NULL
);
125 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++) {
126 if (_VKI_NSIG_BPW
* (i
+ 1) <= (_VKI_MAXSIG
+ 1)) {
127 /* Full word comparison. */
128 if (set1
->sig
[i
] != set2
->sig
[i
]) return False
;
131 /* Partial word comparison. */
132 ULong mask
= ((ULong
)1UL << (_VKI_MAXSIG
% _VKI_NSIG_BPW
)) - 1;
133 if ((set1
->sig
[i
] & mask
) != (set2
->sig
[i
] & mask
)) return False
;
141 Int
VG_(sigaddset
)( vki_sigset_t
* set
, Int signum
)
145 if (signum
< 1 || signum
> _VKI_NSIG
)
148 set
->sig
[signum
/ _VKI_NSIG_BPW
] |= (1ULL << (signum
% _VKI_NSIG_BPW
));
152 Int
VG_(sigdelset
)( vki_sigset_t
* set
, Int signum
)
156 if (signum
< 1 || signum
> _VKI_NSIG
)
159 set
->sig
[signum
/ _VKI_NSIG_BPW
] &= ~(1ULL << (signum
% _VKI_NSIG_BPW
));
163 Int
VG_(sigismember
) ( const vki_sigset_t
* set
, Int signum
)
167 if (signum
< 1 || signum
> _VKI_NSIG
)
170 if (1 & ((set
->sig
[signum
/ _VKI_NSIG_BPW
]) >> (signum
% _VKI_NSIG_BPW
)))
176 /* Add all signals in src to dst. */
177 void VG_(sigaddset_from_set
)( vki_sigset_t
* dst
, const vki_sigset_t
* src
)
180 vg_assert(dst
!= NULL
&& src
!= NULL
);
181 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
182 dst
->sig
[i
] |= src
->sig
[i
];
185 /* Remove all signals in src from dst. */
186 void VG_(sigdelset_from_set
)( vki_sigset_t
* dst
, const vki_sigset_t
* src
)
189 vg_assert(dst
!= NULL
&& src
!= NULL
);
190 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
191 dst
->sig
[i
] &= ~(src
->sig
[i
]);
194 /* dst = dst `intersect` src. */
195 void VG_(sigintersectset
)( vki_sigset_t
* dst
, const vki_sigset_t
* src
)
198 vg_assert(dst
!= NULL
&& src
!= NULL
);
199 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
200 dst
->sig
[i
] &= src
->sig
[i
];
204 void VG_(sigcomplementset
)( vki_sigset_t
* dst
, const vki_sigset_t
* src
)
207 vg_assert(dst
!= NULL
&& src
!= NULL
);
208 for (i
= 0; i
< _VKI_NSIG_WORDS
; i
++)
209 dst
->sig
[i
] = ~ src
->sig
[i
];
213 /* The functions sigaction, sigprocmask, sigpending and sigsuspend
214 return 0 on success and -1 on error.
216 Int
VG_(sigprocmask
)( Int how
, const vki_sigset_t
* set
, vki_sigset_t
* oldset
)
218 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
219 # if defined(__NR_rt_sigprocmask)
220 SysRes res
= VG_(do_syscall4
)(__NR_rt_sigprocmask
,
221 how
, (UWord
)set
, (UWord
)oldset
,
222 _VKI_NSIG_WORDS
* sizeof(UWord
));
224 SysRes res
= VG_(do_syscall3
)(__NR_sigprocmask
,
225 how
, (UWord
)set
, (UWord
)oldset
);
228 # elif defined(VGO_darwin)
229 /* On Darwin, __NR_sigprocmask appears to affect the entire
230 process, not just this thread. Hence need to use
231 __NR___pthread_sigmask instead. */
232 SysRes res
= VG_(do_syscall3
)(__NR___pthread_sigmask
,
233 how
, (UWord
)set
, (UWord
)oldset
);
237 return sr_isError(res
) ? -1 : 0;
241 #if defined(VGO_darwin)
242 /* A helper function for sigaction on Darwin. */
244 void darwin_signal_demux(void* a1
, UWord a2
, UWord a3
, void* a4
, void* a5
) {
245 VG_(debugLog
)(2, "libcsignal",
246 "PRE demux sig, a2 = %lu, signo = %lu\n", a2
, a3
);
248 ((void(*)(int))a1
) (a3
);
250 ((void(*)(int,void*,void*))a1
) (a3
,a4
,a5
);
251 VG_(debugLog
)(2, "libcsignal",
252 "POST demux sig, a2 = %lu, signo = %lu\n", a2
, a3
);
253 VG_(do_syscall2
)(__NR_sigreturn
, (UWord
)a5
, 0x1E);
255 __asm__
__volatile__("ud2");
259 Int
VG_(sigaction
) ( Int signum
,
260 const vki_sigaction_toK_t
* act
,
261 vki_sigaction_fromK_t
* oldact
)
263 # if defined(VGO_linux)
264 /* Normal case: vki_sigaction_toK_t and vki_sigaction_fromK_t are
266 SysRes res
= VG_(do_syscall4
)(__NR_rt_sigaction
,
267 signum
, (UWord
)act
, (UWord
)oldact
,
268 _VKI_NSIG_WORDS
* sizeof(UWord
));
269 return sr_isError(res
) ? -1 : 0;
271 # elif defined(VGO_darwin)
272 /* If we're passing a new action to the kernel, make a copy of the
273 new action, install our own sa_tramp field in it, and ignore
274 whatever we were provided with. This is OK because all the
275 sigaction requests come from m_signals, and are not directly
276 what the client program requested, so there is no chance that we
277 will inadvertently ignore the sa_tramp field requested by the
278 client. (In fact m_signals does ignore it when building signal
279 frames for the client, but that's a completely different
282 If we're receiving an old action from the kernel, be very
283 paranoid and make sure the kernel doesn't trash bits of memory
284 that we don't expect it to. */
287 vki_sigaction_toK_t actCopy
;
290 vki_sigaction_fromK_t oa
;
295 vki_sigaction_toK_t
* real_act
;
296 vki_sigaction_fromK_t
* real_oldact
;
298 real_act
= act
? &actCopy
: NULL
;
299 real_oldact
= oldact
? &oldactCopy
.oa
: NULL
;
300 VG_(memset
)(&oldactCopy
, 0x55, sizeof(oldactCopy
));
303 real_act
->sa_tramp
= (void*)&darwin_signal_demux
;
305 res
= VG_(do_syscall3
)(__NR_sigaction
,
306 signum
, (UWord
)real_act
, (UWord
)real_oldact
);
308 vg_assert(oldactCopy
.before
[0] == 0x5555555555555555ULL
);
309 vg_assert(oldactCopy
.before
[1] == 0x5555555555555555ULL
);
310 vg_assert(oldactCopy
.after
[0] == 0x5555555555555555ULL
);
311 vg_assert(oldactCopy
.after
[1] == 0x5555555555555555ULL
);
312 *oldact
= *real_oldact
;
314 return sr_isError(res
) ? -1 : 0;
316 # elif defined(VGO_solaris)
317 /* vki_sigaction_toK_t and vki_sigaction_fromK_t are identical types. */
318 SysRes res
= VG_(do_syscall3
)(__NR_sigaction
,
319 signum
, (UWord
)act
, (UWord
)oldact
);
320 return sr_isError(res
) ? -1 : 0;
322 # elif defined(VGO_freebsd)
323 SysRes res
= VG_(do_syscall3
)(__NR_sigaction
,
324 signum
, (UWord
)act
, (UWord
)oldact
);
325 return sr_isError(res
) ? -1 : 0;
328 # elif defined(VGO_freebsd)
329 SysRes res
= VG_(do_syscall3
)(__NR_sigaction
,
330 signum
, (UWord
)act
, (UWord
)oldact
);
331 return sr_isError(res
) ? -1 : 0;
335 # error "Unsupported OS"
340 /* See explanation in pub_core_libcsignal.h. */
342 VG_(convert_sigaction_fromK_to_toK
)( const vki_sigaction_fromK_t
* fromK
,
343 /*OUT*/vki_sigaction_toK_t
* toK
)
345 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
347 # elif defined(VGO_darwin)
348 toK
->ksa_handler
= fromK
->ksa_handler
;
349 toK
->sa_tramp
= NULL
; /* the cause of all the difficulty */
350 toK
->sa_mask
= fromK
->sa_mask
;
351 toK
->sa_flags
= fromK
->sa_flags
;
353 # error "Unsupported OS"
358 Int
VG_(kill
)( Int pid
, Int signo
)
360 # if defined(VGO_linux) || defined(VGO_solaris)
361 SysRes res
= VG_(do_syscall2
)(__NR_kill
, pid
, signo
);
362 # elif defined(VGO_darwin) || defined(VGO_freebsd)
363 SysRes res
= VG_(do_syscall3
)(__NR_kill
,
364 pid
, signo
, 1/*posix-compliant*/);
366 # error "Unsupported OS"
368 return sr_isError(res
) ? -1 : 0;
371 Int
VG_(tkill
)( Int lwpid
, Int signo
)
373 # if defined(__NR_tkill)
374 SysRes res
= VG_(mk_SysRes_Error
)(VKI_ENOSYS
);
375 res
= VG_(do_syscall2
)(__NR_tkill
, lwpid
, signo
);
376 if (sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)
377 res
= VG_(do_syscall2
)(__NR_kill
, lwpid
, signo
);
378 return sr_isError(res
) ? -1 : 0;
380 # elif defined(VGO_darwin)
381 // Note that the __pthread_kill syscall takes a Mach thread, not a pthread.
383 res
= VG_(do_syscall2
)(__NR___pthread_kill
, lwpid
, signo
);
384 return sr_isError(res
) ? -1 : 0;
386 # elif defined(VGO_solaris)
388 # if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL)
389 # if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL_TAKES_PID)
390 res
= VG_(do_syscall6
)(__NR_lwp_sigqueue
, 0, lwpid
, signo
,
393 res
= VG_(do_syscall5
)(__NR_lwp_sigqueue
, lwpid
, signo
,
397 res
= VG_(do_syscall2
)(__NR_lwp_kill
, lwpid
, signo
);
399 return sr_isError(res
) ? -1 : 0;
401 # elif defined(VGO_freebsd)
403 res
= VG_(do_syscall2
)(__NR_thr_kill
, lwpid
, signo
);
404 return sr_isError(res
) ? -1 : 0;
407 # error "Unsupported plat"
411 /* ---------------------- sigtimedwait_zero ----------------------- */
413 /* A cut-down version of POSIX sigtimedwait: poll for pending signals
414 mentioned in the sigset_t, and if any are present, select one
415 arbitrarily, return its number (which must be > 0), and put
416 auxiliary info about it in the siginfo_t, and make it
417 not-pending-any-more. If none are pending, return zero. The _zero
418 refers to the fact that there is zero timeout, so if no signals are
419 pending it returns immediately. Perhaps a better name would be
420 'sigpoll'. Returns -1 on error, 0 if no signals pending, and n > 0
421 if signal n was selected.
423 The Linux implementation is trivial: do the corresponding syscall.
425 The Darwin implementation is horrible and probably broken in a dozen
426 obscure ways. I suspect it's only thread-safe because V forces
427 single-threadedness. */
429 /* ---------- sigtimedwait_zero: Linux ----------- */
431 #if defined(VGO_linux)
432 Int
VG_(sigtimedwait_zero
)( const vki_sigset_t
*set
,
433 vki_siginfo_t
*info
)
435 static const struct vki_timespec zero
= { 0, 0 };
436 SysRes res
= VG_(do_syscall4
)(__NR_rt_sigtimedwait
, (UWord
)set
, (UWord
)info
,
437 (UWord
)&zero
, sizeof(*set
));
438 return sr_isError(res
) ? -1 : sr_Res(res
);
441 /* ---------- sigtimedwait_zero: Darwin ----------- */
443 #elif defined(VGO_darwin)
445 //static void show_set ( HChar* str, const vki_sigset_t* set ) {
447 // VG_(printf)("%s { ", str);
448 // for (i = 1; i <= _VKI_NSIG; i++) {
449 // if (VG_(sigismember)(set, i))
450 // VG_(printf)("%u ", i);
452 // VG_(printf)("}\n");
455 /* The general idea is:
456 - use sigpending to find out which signals are pending
458 - temporarily set its handler to sigtimedwait_zero_handler
459 - use sigsuspend atomically unblock it and wait for the signal.
460 Upon return, sigsuspend restores the signal mask to what it
462 - Restore the handler for the signal to whatever it was before.
465 /* A signal handler which does nothing (it doesn't need to). It does
466 however check that it's not handing a sync signal for which
467 returning is meaningless. */
468 static void sigtimedwait_zero_handler ( Int sig
)
470 /* XXX this is wrong -- get rid of these. We could
471 get _any_ signal here */
472 vg_assert(sig
!= VKI_SIGILL
);
473 vg_assert(sig
!= VKI_SIGSEGV
);
474 vg_assert(sig
!= VKI_SIGBUS
);
475 vg_assert(sig
!= VKI_SIGTRAP
);
479 Int
VG_(sigtimedwait_zero
)( const vki_sigset_t
*set
,
480 vki_siginfo_t
*info
)
482 const Bool debug
= False
;
485 vki_sigset_t pending
, blocked
, allbutone
;
486 vki_sigaction_toK_t sa
, saved_sa2
;
487 vki_sigaction_fromK_t saved_sa
;
489 //show_set("STWZ: looking for", set);
491 /* Find out what's pending: Darwin sigpending */
492 sr
= VG_(do_syscall1
)(__NR_sigpending
, (UWord
)&pending
);
493 vg_assert(!sr_isError(sr
));
495 /* don't try for signals not in 'set' */
496 /* pending = pending `intersect` set */
497 VG_(sigintersectset
)(&pending
, (const vki_sigset_t
*)set
);
499 /* don't try for signals not blocked at the moment */
500 ir
= VG_(sigprocmask
)(VKI_SIG_SETMASK
, NULL
, &blocked
);
503 /* pending = pending `intersect` blocked */
504 VG_(sigintersectset
)(&pending
, &blocked
);
506 /* decide which signal we're going to snarf */
507 for (i
= 1; i
< _VKI_NSIG
; i
++)
508 if (VG_(sigismember
)(&pending
,i
))
515 VG_(debugLog
)(0, "libcsignal",
516 "sigtimedwait_zero: snarfing signal %d\n", i
);
519 pre: i is blocked and pending
520 pre: we are the only thread running
522 /* Set up alternative signal handler */
523 VG_(sigfillset
)(&sa
.sa_mask
);
524 sa
.ksa_handler
= &sigtimedwait_zero_handler
;
526 ir
= VG_(sigaction
)(i
, &sa
, &saved_sa
);
529 /* Switch signal masks and wait for the signal. This should happen
530 immediately, since we've already established it is pending and
532 VG_(sigfillset
)(&allbutone
);
533 VG_(sigdelset
)(&allbutone
, i
);
534 /* Note: pass the sig mask by value here, not reference (!) */
535 vg_assert(_VKI_NSIG_WORDS
== 1);
536 sr
= VG_(do_syscall3
)(__NR_sigsuspend_nocancel
,
537 (UWord
)allbutone
.sig
[0], 0,0);
539 VG_(debugLog
)(0, "libcsignal",
540 "sigtimedwait_zero: sigsuspend got "
542 sr_isError(sr
) ? "FAIL" : "SUCCESS",
543 sr_isError(sr
) ? sr_Err(sr
) : sr_Res(sr
));
544 vg_assert(sr_isError(sr
));
545 vg_assert(sr_Err(sr
) == VKI_EINTR
);
547 /* Restore signal's handler to whatever it was before */
548 VG_(convert_sigaction_fromK_to_toK
)( &saved_sa
, &saved_sa2
);
549 ir
= VG_(sigaction
)(i
, &saved_sa2
, NULL
);
552 /* This is bogus - we could get more info from the sighandler. */
553 VG_(memset
)( info
, 0, sizeof(*info
) );
559 #elif defined(VGO_solaris)
560 Int
VG_(sigtimedwait_zero
)( const vki_sigset_t
*set
, vki_siginfo_t
*info
)
562 /* Trivial as on Linux. */
563 static const struct vki_timespec zero
= { 0, 0 };
564 SysRes res
= VG_(do_syscall3
)(__NR_sigtimedwait
, (UWord
)set
, (UWord
)info
,
566 return sr_isError(res
) ? -1 : sr_Res(res
);
569 #elif defined(VGO_freebsd)
572 Int
VG_(sigtimedwait_zero
)( const vki_sigset_t
*set
,
573 vki_siginfo_t
*info
)
575 static const struct vki_timespec zero
= { 0, 0 };
577 SysRes res
= VG_(do_syscall3
)(__NR_sigtimedwait
, (UWord
)set
, (UWord
)info
,
579 return sr_isError(res
) ? -1 : sr_Res(res
);
586 /*--------------------------------------------------------------------*/
588 /*--------------------------------------------------------------------*/