1
2/*--------------------------------------------------------------------*/
3/*--- Signal-related libc stuff.                    m_libcsignal.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2013 Julian Seward
11      jseward@acm.org
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
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 */
39
40/* IMPORTANT: on Darwin it is essential to use the _nocancel versions
41   of syscalls rather than the vanilla version, if a _nocancel version
42   is available.  See docs/internals/Darwin-notes.txt for the reason
43   why. */
44
45/* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
46   success and -1 on error.  */
47/* In the sigset routines below, be aware that _VKI_NSIG_BPW can be
48   either 32 or 64, and hence the sig[] words can either be 32- or
49   64-bits.  And which they are it doesn't necessarily follow from the
50   host word size. */
51
52Int VG_(sigfillset)( vki_sigset_t* set )
53{
54   Int i;
55   if (set == NULL)
56      return -1;
57   for (i = 0; i < _VKI_NSIG_WORDS; i++)
58      set->sig[i] = ~0;
59   return 0;
60}
61
62Int VG_(sigemptyset)( vki_sigset_t* set )
63{
64   Int i;
65   if (set == NULL)
66      return -1;
67   for (i = 0; i < _VKI_NSIG_WORDS; i++)
68      set->sig[i] = 0;
69   return 0;
70}
71
72Bool VG_(isemptysigset)( const vki_sigset_t* set )
73{
74   Int i;
75   vg_assert(set != NULL);
76   for (i = 0; i < _VKI_NSIG_WORDS; i++)
77      if (set->sig[i] != 0) return False;
78   return True;
79}
80
81Bool VG_(isfullsigset)( const vki_sigset_t* set )
82{
83   Int i;
84   vg_assert(set != NULL);
85   for (i = 0; i < _VKI_NSIG_WORDS; i++)
86      if (set->sig[i] != ~0) return False;
87   return True;
88}
89
90Bool VG_(iseqsigset)( const vki_sigset_t* set1, const vki_sigset_t* set2 )
91{
92   Int i;
93   vg_assert(set1 != NULL && set2 != NULL);
94   for (i = 0; i < _VKI_NSIG_WORDS; i++)
95      if (set1->sig[i] != set2->sig[i]) return False;
96   return True;
97}
98
99
100Int VG_(sigaddset)( vki_sigset_t* set, Int signum )
101{
102   if (set == NULL)
103      return -1;
104   if (signum < 1 || signum > _VKI_NSIG)
105      return -1;
106   signum--;
107   set->sig[signum / _VKI_NSIG_BPW] |= (1ULL << (signum % _VKI_NSIG_BPW));
108   return 0;
109}
110
111Int VG_(sigdelset)( vki_sigset_t* set, Int signum )
112{
113   if (set == NULL)
114      return -1;
115   if (signum < 1 || signum > _VKI_NSIG)
116      return -1;
117   signum--;
118   set->sig[signum / _VKI_NSIG_BPW] &= ~(1ULL << (signum % _VKI_NSIG_BPW));
119   return 0;
120}
121
122Int VG_(sigismember) ( const vki_sigset_t* set, Int signum )
123{
124   if (set == NULL)
125      return 0;
126   if (signum < 1 || signum > _VKI_NSIG)
127      return 0;
128   signum--;
129   if (1 & ((set->sig[signum / _VKI_NSIG_BPW]) >> (signum % _VKI_NSIG_BPW)))
130      return 1;
131   else
132      return 0;
133}
134
135/* Add all signals in src to dst. */
136void VG_(sigaddset_from_set)( vki_sigset_t* dst, vki_sigset_t* src )
137{
138   Int i;
139   vg_assert(dst != NULL && src != NULL);
140   for (i = 0; i < _VKI_NSIG_WORDS; i++)
141      dst->sig[i] |= src->sig[i];
142}
143
144/* Remove all signals in src from dst. */
145void VG_(sigdelset_from_set)( vki_sigset_t* dst, vki_sigset_t* src )
146{
147   Int i;
148   vg_assert(dst != NULL && src != NULL);
149   for (i = 0; i < _VKI_NSIG_WORDS; i++)
150      dst->sig[i] &= ~(src->sig[i]);
151}
152
153/* dst = dst `intersect` src. */
154void VG_(sigintersectset)( vki_sigset_t* dst, vki_sigset_t* src )
155{
156   Int i;
157   vg_assert(dst != NULL && src != NULL);
158   for (i = 0; i < _VKI_NSIG_WORDS; i++)
159      dst->sig[i] &= src->sig[i];
160}
161
162/* dst = ~src */
163void VG_(sigcomplementset)( vki_sigset_t* dst, vki_sigset_t* src )
164{
165   Int i;
166   vg_assert(dst != NULL && src != NULL);
167   for (i = 0; i < _VKI_NSIG_WORDS; i++)
168      dst->sig[i] = ~ src->sig[i];
169}
170
171
172/* The functions sigaction, sigprocmask, sigpending and sigsuspend
173   return 0 on success and -1 on error.
174*/
175Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset)
176{
177#  if defined(VGO_linux)
178#  if defined(__NR_rt_sigprocmask)
179   SysRes res = VG_(do_syscall4)(__NR_rt_sigprocmask,
180                                 how, (UWord)set, (UWord)oldset,
181                                 _VKI_NSIG_WORDS * sizeof(UWord));
182#  else
183   SysRes res = VG_(do_syscall3)(__NR_sigprocmask,
184                                 how, (UWord)set, (UWord)oldset);
185#  endif
186
187#  elif defined(VGO_darwin)
188   /* On Darwin, __NR_sigprocmask appears to affect the entire
189      process, not just this thread.  Hence need to use
190      __NR___pthread_sigmask instead. */
191   SysRes res =  VG_(do_syscall3)(__NR___pthread_sigmask,
192                                  how, (UWord)set, (UWord)oldset);
193#  else
194#    error "Unknown OS"
195#  endif
196   return sr_isError(res) ? -1 : 0;
197}
198
199
200#if defined(VGO_darwin)
201/* A helper function for sigaction on Darwin. */
202static
203void darwin_signal_demux(void* a1, UWord a2, UWord a3, void* a4, void* a5) {
204   VG_(debugLog)(2, "libcsignal",
205                    "PRE  demux sig, a2 = %lu, signo = %lu\n", a2, a3);
206   if (a2 == 1)
207      ((void(*)(int))a1) (a3);
208   else
209      ((void(*)(int,void*,void*))a1) (a3,a4,a5);
210   VG_(debugLog)(2, "libcsignal",
211                    "POST demux sig, a2 = %lu, signo = %lu\n", a2, a3);
212   VG_(do_syscall2)(__NR_sigreturn, (UWord)a5, 0x1E);
213   /* NOTREACHED */
214   __asm__ __volatile__("ud2");
215}
216#endif
217
218Int VG_(sigaction) ( Int signum,
219                     const vki_sigaction_toK_t* act,
220                     vki_sigaction_fromK_t* oldact)
221{
222#  if defined(VGO_linux)
223   /* Normal case: vki_sigaction_toK_t and vki_sigaction_fromK_t are
224      identical types. */
225   SysRes res = VG_(do_syscall4)(__NR_rt_sigaction,
226                                 signum, (UWord)act, (UWord)oldact,
227                                 _VKI_NSIG_WORDS * sizeof(UWord));
228   return sr_isError(res) ? -1 : 0;
229
230#  elif defined(VGO_darwin)
231   /* If we're passing a new action to the kernel, make a copy of the
232      new action, install our own sa_tramp field in it, and ignore
233      whatever we were provided with.  This is OK because all the
234      sigaction requests come from m_signals, and are not directly
235      what the client program requested, so there is no chance that we
236      will inadvertantly ignore the sa_tramp field requested by the
237      client.  (In fact m_signals does ignore it when building signal
238      frames for the client, but that's a completely different
239      matter).
240
241      If we're receiving an old action from the kernel, be very
242      paranoid and make sure the kernel doesn't trash bits of memory
243      that we don't expect it to. */
244   SysRes res;
245
246   vki_sigaction_toK_t actCopy;
247   struct {
248     ULong before[2];
249     vki_sigaction_fromK_t oa;
250     ULong after[2];
251   }
252   oldactCopy;
253
254   vki_sigaction_toK_t*   real_act;
255   vki_sigaction_fromK_t* real_oldact;
256
257   real_act    = act    ? &actCopy       : NULL;
258   real_oldact = oldact ? &oldactCopy.oa : NULL;
259   VG_(memset)(&oldactCopy, 0x55, sizeof(oldactCopy));
260   if (real_act) {
261      *real_act = *act;
262      real_act->sa_tramp = (void*)&darwin_signal_demux;
263   }
264   res = VG_(do_syscall3)(__NR_sigaction,
265                          signum, (UWord)real_act, (UWord)real_oldact);
266   if (real_oldact) {
267      vg_assert(oldactCopy.before[0] == 0x5555555555555555ULL);
268      vg_assert(oldactCopy.before[1] == 0x5555555555555555ULL);
269      vg_assert(oldactCopy.after[0]  == 0x5555555555555555ULL);
270      vg_assert(oldactCopy.after[1]  == 0x5555555555555555ULL);
271      *oldact = *real_oldact;
272   }
273   return sr_isError(res) ? -1 : 0;
274
275#  else
276#    error "Unsupported OS"
277#  endif
278}
279
280
281/* See explanation in pub_core_libcsignal.h. */
282void
283VG_(convert_sigaction_fromK_to_toK)( vki_sigaction_fromK_t* fromK,
284                                     /*OUT*/vki_sigaction_toK_t* toK )
285{
286#  if defined(VGO_linux)
287   *toK = *fromK;
288#  elif defined(VGO_darwin)
289   toK->ksa_handler = fromK->ksa_handler;
290   toK->sa_tramp    = NULL; /* the cause of all the difficulty */
291   toK->sa_mask     = fromK->sa_mask;
292   toK->sa_flags    = fromK->sa_flags;
293#  else
294#    error "Unsupported OS"
295#  endif
296}
297
298
299Int VG_(kill)( Int pid, Int signo )
300{
301#  if defined(VGO_linux)
302   SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo);
303#  elif defined(VGO_darwin)
304   SysRes res = VG_(do_syscall3)(__NR_kill,
305                                 pid, signo, 1/*posix-compliant*/);
306#  else
307#    error "Unsupported OS"
308#  endif
309   return sr_isError(res) ? -1 : 0;
310}
311
312Int VG_(tkill)( Int lwpid, Int signo )
313{
314#  if defined(__NR_tkill)
315   SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
316   res = VG_(do_syscall2)(__NR_tkill, lwpid, signo);
317   if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
318      res = VG_(do_syscall2)(__NR_kill, lwpid, signo);
319   return sr_isError(res) ? -1 : 0;
320
321#  elif defined(VGO_darwin)
322   // Note that the __pthread_kill syscall takes a Mach thread, not a pthread.
323   SysRes res;
324   res = VG_(do_syscall2)(__NR___pthread_kill, lwpid, signo);
325   return sr_isError(res) ? -1 : 0;
326
327#  else
328#    error "Unsupported plat"
329#  endif
330}
331
332/* ---------------------- sigtimedwait_zero ----------------------- */
333
334/* A cut-down version of POSIX sigtimedwait: poll for pending signals
335   mentioned in the sigset_t, and if any are present, select one
336   arbitrarily, return its number (which must be > 0), and put
337   auxiliary info about it in the siginfo_t, and make it
338   not-pending-any-more.  If none are pending, return zero.  The _zero
339   refers to the fact that there is zero timeout, so if no signals are
340   pending it returns immediately.  Perhaps a better name would be
341   'sigpoll'.  Returns -1 on error, 0 if no signals pending, and n > 0
342   if signal n was selected.
343
344   The Linux implementation is trivial: do the corresponding syscall.
345
346   The Darwin implementation is horrible and probably broken in a dozen
347   obscure ways.  I suspect it's only thread-safe because V forces
348   single-threadedness. */
349
350/* ---------- sigtimedwait_zero: Linux ----------- */
351
352#if defined(VGO_linux)
353Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
354                            vki_siginfo_t *info )
355{
356   static const struct vki_timespec zero = { 0, 0 };
357   SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info,
358                                 (UWord)&zero, sizeof(*set));
359   return sr_isError(res) ? -1 : sr_Res(res);
360}
361
362/* ---------- sigtimedwait_zero: Darwin ----------- */
363
364#elif defined(VGO_darwin)
365
366//static void show_set ( HChar* str, const vki_sigset_t* set ) {
367//   Int i;
368//   VG_(printf)("%s { ", str);
369//   for (i = 1; i <= _VKI_NSIG; i++) {
370//     if (VG_(sigismember)(set, i))
371//         VG_(printf)("%u ", i);
372//   }
373//   VG_(printf)("}\n");
374//}
375
376/* The general idea is:
377   - use sigpending to find out which signals are pending
378   - choose one
379   - temporarily set its handler to sigtimedwait_zero_handler
380   - use sigsuspend atomically unblock it and wait for the signal.
381     Upon return, sigsuspend restores the signal mask to what it
382     was to start with.
383   - Restore the handler for the signal to whatever it was before.
384*/
385
386/* A signal handler which does nothing (it doesn't need to).  It does
387   however check that it's not handing a sync signal for which
388   returning is meaningless. */
389static void sigtimedwait_zero_handler ( Int sig )
390{
391   /* XXX this is wrong -- get rid of these.  We could
392      get _any_ signal here */
393   vg_assert(sig != VKI_SIGILL);
394   vg_assert(sig != VKI_SIGSEGV);
395   vg_assert(sig != VKI_SIGBUS);
396   vg_assert(sig != VKI_SIGTRAP);
397   /* do nothing */
398}
399
400Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
401                            vki_siginfo_t *info )
402{
403  const Bool debug = False;
404  Int    i, ir;
405  SysRes sr;
406  vki_sigset_t pending, blocked, allbutone;
407  vki_sigaction_toK_t   sa, saved_sa2;
408  vki_sigaction_fromK_t saved_sa;
409
410  //show_set("STWZ: looking for", set);
411
412  /* Find out what's pending: Darwin sigpending */
413  sr = VG_(do_syscall1)(__NR_sigpending, (UWord)&pending);
414  vg_assert(!sr_isError(sr));
415
416  /* don't try for signals not in 'set' */
417  /* pending = pending `intersect` set */
418  VG_(sigintersectset)(&pending, (vki_sigset_t*)set);
419
420  /* don't try for signals not blocked at the moment */
421  ir = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &blocked);
422  vg_assert(ir == 0);
423
424  /* pending = pending `intersect` blocked */
425  VG_(sigintersectset)(&pending, &blocked);
426
427  /* decide which signal we're going to snarf */
428  for (i = 1; i < _VKI_NSIG; i++)
429     if (VG_(sigismember)(&pending,i))
430        break;
431
432  if (i == _VKI_NSIG)
433     return 0;
434
435  if (debug)
436     VG_(debugLog)(0, "libcsignal",
437                      "sigtimedwait_zero: snarfing signal %d\n", i );
438
439  /* fetch signal i.
440     pre: i is blocked and pending
441     pre: we are the only thread running
442  */
443  /* Set up alternative signal handler */
444  VG_(sigfillset)(&sa.sa_mask);
445  sa.ksa_handler = &sigtimedwait_zero_handler;
446  sa.sa_flags    = 0;
447  ir = VG_(sigaction)(i, &sa, &saved_sa);
448  vg_assert(ir == 0);
449
450  /* Switch signal masks and wait for the signal.  This should happen
451     immediately, since we've already established it is pending and
452     blocked. */
453  VG_(sigfillset)(&allbutone);
454  VG_(sigdelset)(&allbutone, i);
455  /* Note: pass the sig mask by value here, not reference (!) */
456  vg_assert(_VKI_NSIG_WORDS == 1);
457  sr = VG_(do_syscall3)(__NR_sigsuspend_nocancel,
458                        (UWord)allbutone.sig[0], 0,0);
459  if (debug)
460     VG_(debugLog)(0, "libcsignal",
461                      "sigtimedwait_zero: sigsuspend got "
462                      "res: %s %#lx\n",
463                      sr_isError(sr) ? "FAIL" : "SUCCESS",
464                      sr_isError(sr) ? sr_Err(sr) : sr_Res(sr));
465  vg_assert(sr_isError(sr));
466  vg_assert(sr_Err(sr) == VKI_EINTR);
467
468  /* Restore signal's handler to whatever it was before */
469  VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &saved_sa2 );
470  ir = VG_(sigaction)(i, &saved_sa2, NULL);
471  vg_assert(ir == 0);
472
473  /* This is bogus - we could get more info from the sighandler. */
474  VG_(memset)( info, 0, sizeof(*info) );
475  info->si_signo = i;
476
477  return i;
478}
479
480#else
481#  error "Unknown OS"
482#endif
483
484/*--------------------------------------------------------------------*/
485/*--- end                                                          ---*/
486/*--------------------------------------------------------------------*/
487