Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/common/brand/lx/lx_signum.c
          +++ new/usr/src/common/brand/lx/lx_signum.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   * Copyright 2015 Joyent, Inc.
  26   26   */
  27   27  
  28   28  #include <sys/signal.h>
  29   29  #include <sys/lx_siginfo.h>
  30   30  #include <lx_signum.h>
  31   31  #include <sys/debug.h>
  32   32  
  33   33  /*
  34   34   * Delivering signals to a Linux process is complicated by differences in
  35   35   * signal numbering, stack structure and contents, and the action taken when a
  36   36   * signal handler exits.  In addition, many signal-related structures, such as
  37   37   * sigset_ts, vary between Solaris and Linux.
  38   38   *
  39   39   * The simplest transformation that must be done when sending signals is to
  40   40   * translate between Linux and Solaris signal numbers.
  41   41   *
  42   42   * These are the major signal number differences between Linux and Solaris:
  43   43   *
  44   44   *      ====================================
  45   45   *      | Number |   Linux    |  Solaris   |
  46   46   *      | ====== | =========  | ========== |
  47   47   *      |    7   | SIGBUS     | SIGEMT     |
  48   48   *      |   10   | SIGUSR1    | SIGBUS     |
  49   49   *      |   12   | SIGUSR2    | SIGSYS     |
  50   50   *      |   16   | SIGSTKFLT  | SIGUSR1    |
  51   51   *      |   17   | SIGCHLD    | SIGUSR2    |
  52   52   *      |   18   | SIGCONT    | SIGCHLD    |
  53   53   *      |   19   | SIGSTOP    | SIGPWR     |
  54   54   *      |   20   | SIGTSTP    | SIGWINCH   |
  55   55   *      |   21   | SIGTTIN    | SIGURG     |
  56   56   *      |   22   | SIGTTOU    | SIGPOLL    |
  57   57   *      |   23   | SIGURG     | SIGSTOP    |
  58   58   *      |   24   | SIGXCPU    | SIGTSTP    |
  59   59   *      |   25   | SIGXFSZ    | SIGCONT    |
  60   60   *      |   26   | SIGVTALARM | SIGTTIN    |
  61   61   *      |   27   | SIGPROF    | SIGTTOU    |
  62   62   *      |   28   | SIGWINCH   | SIGVTALARM |
  63   63   *      |   29   | SIGPOLL    | SIGPROF    |
  64   64   *      |   30   | SIGPWR     | SIGXCPU    |
  65   65   *      |   31   | SIGSYS     | SIGXFSZ    |
  66   66   *      ====================================
  67   67   *
  68   68   * Not every Linux signal maps to a Solaris signal, nor does every Solaris
  69   69   * signal map to a Linux counterpart. However, when signals do map, the
  70   70   * mapping is unique.
  71   71   *
  72   72   * One mapping issue is that Linux supports 33 real time signals, with SIGRTMIN
  73   73   * typically starting at or near 32 (SIGRTMIN) and proceeding to 64 (SIGRTMAX)
  74   74   * (SIGRTMIN is "at or near" 32 because glibc usually "steals" one ore more of
  75   75   * these signals for its own internal use, adjusting SIGRTMIN and SIGRTMAX as
  76   76   * needed.)  Conversely, Solaris actively uses signals 32-40 for other purposes
  77   77   * and supports exactly 32 real time signals, in the range 41 (SIGRTMIN)
  78   78   * to 72 (SIGRTMAX).
  79   79   *
  80   80   * At present, attempting to translate a Linux signal equal to 63
  81   81   * will generate an error (we allow SIGRTMAX because a program
  82   82   * should be able to send SIGRTMAX without getting an EINVAL, though obviously
  83   83   * anything that loops through the signals from SIGRTMIN to SIGRTMAX will
  84   84   * fail.)
  85   85   *
  86   86   * Similarly, attempting to translate a native Solaris signal in the range
  87   87   * 32-40 will also generate an error as we don't want to support the receipt of
  88   88   * those signals from the Solaris global zone.
  89   89   */
  90   90  
  91   91  /*
  92   92   * Linux to Solaris signal map
  93   93   *
  94   94   * Usage:  solaris_signal = ltos_signum[lx_signal];
  95   95   */
  96   96  const int
  97   97  ltos_signo[LX_NSIG + 1] = {
  98   98          0,
  99   99          SIGHUP,
 100  100          SIGINT,
 101  101          SIGQUIT,
 102  102          SIGILL,
 103  103          SIGTRAP,
 104  104          SIGABRT,
 105  105          SIGBUS,
 106  106          SIGFPE,
 107  107          SIGKILL,
 108  108          SIGUSR1,
 109  109          SIGSEGV,
 110  110          SIGUSR2,
 111  111          SIGPIPE,
 112  112          SIGALRM,
 113  113          SIGTERM,
 114  114          SIGEMT,                 /* 16:  Linux SIGSTKFLT; use Solaris SIGEMT */
 115  115          SIGCHLD,
 116  116          SIGCONT,
 117  117          SIGSTOP,
 118  118          SIGTSTP,
 119  119          SIGTTIN,
 120  120          SIGTTOU,
 121  121          SIGURG,
 122  122          SIGXCPU,
 123  123          SIGXFSZ,
 124  124          SIGVTALRM,
 125  125          SIGPROF,
 126  126          SIGWINCH,
 127  127          SIGPOLL,
 128  128          SIGPWR,
 129  129          SIGSYS,
 130  130          _SIGRTMIN,              /* 32:  Linux SIGRTMIN */
 131  131          _SIGRTMIN + 1,
 132  132          _SIGRTMIN + 2,
 133  133          _SIGRTMIN + 3,
 134  134          _SIGRTMIN + 4,
 135  135          _SIGRTMIN + 5,
 136  136          _SIGRTMIN + 6,
 137  137          _SIGRTMIN + 7,
 138  138          _SIGRTMIN + 8,
 139  139          _SIGRTMIN + 9,
 140  140          _SIGRTMIN + 10,
 141  141          _SIGRTMIN + 11,
 142  142          _SIGRTMIN + 12,
 143  143          _SIGRTMIN + 13,
 144  144          _SIGRTMIN + 14,
 145  145          _SIGRTMIN + 15,
 146  146          _SIGRTMIN + 16,
 147  147          _SIGRTMIN + 17,
 148  148          _SIGRTMIN + 18,
 149  149          _SIGRTMIN + 19,
 150  150          _SIGRTMIN + 20,
 151  151          _SIGRTMIN + 21,
 152  152          _SIGRTMIN + 22,
 153  153          _SIGRTMIN + 23,
 154  154          _SIGRTMIN + 24,
 155  155          _SIGRTMIN + 25,
 156  156          _SIGRTMIN + 26,
 157  157          _SIGRTMIN + 27,
 158  158          _SIGRTMIN + 28,
 159  159          _SIGRTMIN + 29,
 160  160          _SIGRTMIN + 30,
 161  161          _SIGRTMIN + 31,
 162  162          _SIGRTMAX,              /* 64:  Linux SIGRTMAX */
 163  163  };
 164  164  
 165  165  /*
 166  166   * Solaris to Linux signal map
 167  167   *
 168  168   * Usage:  lx_signal = stol_signo[solaris_signal];
 169  169   */
 170  170  const int
 171  171  stol_signo[NSIG] = {
 172  172          0,
 173  173          LX_SIGHUP,
 174  174          LX_SIGINT,
 175  175          LX_SIGQUIT,
 176  176          LX_SIGILL,
 177  177          LX_SIGTRAP,
 178  178          LX_SIGABRT,
 179  179          LX_SIGSTKFLT,           /* 7:  Solaris SIGEMT; use for LX_SIGSTKFLT */
 180  180          LX_SIGFPE,
 181  181          LX_SIGKILL,
 182  182          LX_SIGBUS,
 183  183          LX_SIGSEGV,
 184  184          LX_SIGSYS,
 185  185          LX_SIGPIPE,
 186  186          LX_SIGALRM,
 187  187          LX_SIGTERM,
 188  188          LX_SIGUSR1,
 189  189          LX_SIGUSR2,
 190  190          LX_SIGCHLD,
 191  191          LX_SIGPWR,
 192  192          LX_SIGWINCH,
 193  193          LX_SIGURG,
 194  194          LX_SIGPOLL,
 195  195          LX_SIGSTOP,
 196  196          LX_SIGTSTP,
 197  197          LX_SIGCONT,
 198  198          LX_SIGTTIN,
 199  199          LX_SIGTTOU,
 200  200          LX_SIGVTALRM,
 201  201          LX_SIGPROF,
 202  202          LX_SIGXCPU,
 203  203          LX_SIGXFSZ,
 204  204          -1,                     /* 32:  Solaris SIGWAITING */
 205  205          -1,                     /* 33:  Solaris SIGLWP */
 206  206          -1,                     /* 34:  Solaris SIGFREEZE */
 207  207          -1,                     /* 35:  Solaris SIGTHAW */
 208  208          -1,                     /* 36:  Solaris SIGCANCEL */
 209  209          -1,                     /* 37:  Solaris SIGLOST */
 210  210          -1,                     /* 38:  Solaris SIGXRES */
 211  211          -1,                     /* 39:  Solaris SIGJVM1 */
 212  212          -1,                     /* 40:  Solaris SIGJVM2 */
 213  213          -1,                     /* 41:  Solaris SIGINFO */
 214  214          LX_SIGRTMIN,            /* 42:  Solaris _SIGRTMIN */
 215  215          LX_SIGRTMIN + 1,
 216  216          LX_SIGRTMIN + 2,
 217  217          LX_SIGRTMIN + 3,
 218  218          LX_SIGRTMIN + 4,
 219  219          LX_SIGRTMIN + 5,
 220  220          LX_SIGRTMIN + 6,
 221  221          LX_SIGRTMIN + 7,
 222  222          LX_SIGRTMIN + 8,
 223  223          LX_SIGRTMIN + 9,
 224  224          LX_SIGRTMIN + 10,
 225  225          LX_SIGRTMIN + 11,
 226  226          LX_SIGRTMIN + 12,
 227  227          LX_SIGRTMIN + 13,
 228  228          LX_SIGRTMIN + 14,
 229  229          LX_SIGRTMIN + 15,
 230  230          LX_SIGRTMIN + 16,
 231  231          LX_SIGRTMIN + 17,
 232  232          LX_SIGRTMIN + 18,
 233  233          LX_SIGRTMIN + 19,
 234  234          LX_SIGRTMIN + 20,
 235  235          LX_SIGRTMIN + 21,
 236  236          LX_SIGRTMIN + 22,
 237  237          LX_SIGRTMIN + 23,
 238  238          LX_SIGRTMIN + 24,
 239  239          LX_SIGRTMIN + 25,
 240  240          LX_SIGRTMIN + 26,
 241  241          LX_SIGRTMIN + 27,
 242  242          LX_SIGRTMIN + 28,
 243  243          LX_SIGRTMIN + 29,
 244  244          LX_SIGRTMIN + 30,
 245  245          LX_SIGRTMIN + 31,
 246  246          LX_SIGRTMAX,            /* 74: Solaris _SIGRTMAX */
 247  247  };
 248  248  
 249  249  /*
 250  250   * Convert an illumos native signal number to a Linux signal number and return
 251  251   * it.  If no valid conversion is possible, the function fails back to the
 252  252   * value of "defsig".  In userland, passing a default signal number of "-1"
 253  253   * will abort the program if the signal number could not be converted.
 254  254   */
 255  255  int
 256  256  lx_stol_signo(int signo, int defsig)
 257  257  {
 258  258          int rval;
 259  259  
 260  260  #ifdef  _KERNEL
 261  261          VERIFY3S(defsig, >=, 0);
 262  262  #endif
 263  263  
 264  264          if (signo < 0 || signo >= NSIG || (rval = stol_signo[signo]) < 1) {
 265  265  #ifndef _KERNEL
 266  266                  VERIFY3S(defsig, >=, 0);
 267  267  #endif
 268  268                  return (defsig);
 269  269          }
 270  270  
 271  271          return (rval);
 272  272  }
 273  273  
 274  274  
 275  275  /*
 276  276   * Convert a Linux signal number to an illumos signal number and return it.
 277  277   * Error behavior is identical to lx_stol_signo.
 278  278   */
 279  279  int
 280  280  lx_ltos_signo(int signo, int defsig)
 281  281  {
 282  282  #ifdef  _KERNEL
 283  283          VERIFY3S(defsig, >=, 0);
 284  284  #endif
 285  285  
 286  286          if (signo < 1 || signo >= NSIG) {
 287  287  #ifndef _KERNEL
 288  288                  VERIFY3S(defsig, >=, 0);
 289  289  #endif
 290  290                  return (defsig);
 291  291          }
 292  292  
 293  293          return (ltos_signo[signo]);
 294  294  }
 295  295  
 296  296  /*
 297  297   * Convert the "status" field of a SIGCLD siginfo_t.  We need to extract the
 298  298   * illumos signal number and convert it to a Linux signal number while leaving
 299  299   * the ptrace(2) event bits intact.  In userland, passing a default signal
 300  300   * number of "-1" will abort the program if the signal number could not be
 301  301   * converted, as for lx_stol_signo().
 302  302   */
 303  303  int
 304  304  lx_stol_status(int s, int defsig)
 305  305  {
 306  306          /*
 307  307           * We mask out the top bit here in case PTRACE_O_TRACESYSGOOD
 308  308           * is in use and 0x80 has been ORed with the signal number.
 309  309           */
 310  310          int stat = lx_stol_signo(s & 0x7f, defsig);
 311  311  
 312  312          /*
 313  313           * We must mix in the ptrace(2) event which may be stored in
 314  314           * the second byte of the status code.  We also re-include the
 315  315           * PTRACE_O_TRACESYSGOOD bit.
 316  316           */
 317  317          return ((s & 0xff80) | stat);
 318  318  }
 319  319  
 320  320  int
 321  321  lx_stol_sigcode(int code)
 322  322  {
 323  323          switch (code) {
 324  324          case SI_USER:
 325  325                  return (LX_SI_USER);
 326  326          case SI_LWP:
 327  327                  return (LX_SI_TKILL);
 328  328          case SI_QUEUE:
 329  329                  return (LX_SI_QUEUE);
 330  330          case SI_TIMER:
 331  331                  return (LX_SI_TIMER);
 332  332          case SI_ASYNCIO:
 333  333                  return (LX_SI_ASYNCIO);
 334  334          case SI_MESGQ:
 335  335                  return (LX_SI_MESGQ);
 336  336          default:
 337  337                  return (code);
 338  338          }
 339  339  }
  
    | 
      ↓ open down ↓ | 
    339 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX