Home | History | Annotate | Download | only in arch-mips
      1 /*
      2  * Copyright 2012, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <portability.h>
     18 #include <unistd.h>
     19 #include <stdarg.h>
     20 #include <stdlib.h>
     21 #include <signal.h>
     22 #include <signal_portable.h>
     23 #include <portability.h>
     24 #include <stdio.h>
     25 #include <errno.h>
     26 #include <errno_portable.h>
     27 #include <asm/unistd-portable.h>
     28 #include <asm/unistd.h>
     29 #include <signalfd_portable.h>
     30 #include <filefd_portable.h>
     31 
     32 #define PORTABLE_TAG "signal_portable"
     33 #include <log_portable.h>
     34 
     35 
     36 #if SIGBUS_PORTABLE == SIGBUS
     37 #error Bad build environment
     38 #endif
     39 
     40 typedef void  (*sig3handler_t)(int, siginfo_t *, void *);
     41 
     42 static volatile int signal_handler_mapping_enabled = 1;
     43 
     44 extern int syscall(int, ...);
     45 
     46 
     47 __hidden void signal_disable_mapping()
     48 {
     49     ALOGV("%s(): signal_handler_mapping_enabled:%d = 0;", __func__,
     50                  signal_handler_mapping_enabled);
     51 
     52     signal_handler_mapping_enabled = 0;
     53 }
     54 
     55 
     56 /*
     57  * The next five hidden functions are not exposed in the
     58  * libportable shared object. They are used here and other
     59  * functions, like waitpid(), which need to map signal numbers.
     60  */
     61 __hidden char *map_portable_signum_to_name(int portable_signum)
     62 {
     63     char *name;
     64 
     65     switch(portable_signum) {
     66     case 0:                     name = "SIG_0_PORTABLE:0";              break;
     67     case SIGHUP_PORTABLE:       name = "SIGHUP_PORTABLE:1";             break;
     68     case SIGINT_PORTABLE:       name = "SIGINT_PORTABLE:2";             break;
     69     case SIGQUIT_PORTABLE:      name = "SIGQUIT_PORTABLE:3";            break;
     70     case SIGILL_PORTABLE:       name = "SIGILL_PORTABLE:4";             break;
     71     case SIGTRAP_PORTABLE:      name = "SIGTRAP_PORTABLE:5";            break;
     72     case SIGABRT_PORTABLE:      name = "SIGABRT_PORTABLE:6";            break;
     73     case SIGBUS_PORTABLE:       name = "SIGBUS_PORTABLE:7";             break;
     74     case SIGFPE_PORTABLE:       name = "SIGFPE_PORTABLE:8";             break;
     75     case SIGKILL_PORTABLE:      name = "SIGKILL_PORTABLE:9";            break;
     76     case SIGUSR1_PORTABLE:      name = "SIGUSR1_PORTABLE:10";           break;
     77     case SIGSEGV_PORTABLE:      name = "SIGSEGV_PORTABLE:11";           break;
     78     case SIGUSR2_PORTABLE:      name = "SIGUSR2_PORTABLE:12";           break;
     79     case SIGPIPE_PORTABLE:      name = "SIGPIPE_PORTABLE:13";           break;
     80     case SIGALRM_PORTABLE:      name = "SIGALRM_PORTABLE:14";           break;
     81     case SIGTERM_PORTABLE:      name = "SIGTERM_PORTABLE:15";           break;
     82     case SIGSTKFLT_PORTABLE:    name = "SIGSTKFLT_PORTABLE:16";         break;
     83     case SIGCHLD_PORTABLE:      name = "SIGCHLD_PORTABLE:17";           break;
     84     case SIGCONT_PORTABLE:      name = "SIGCONT_PORTABLE:18";           break;
     85     case SIGSTOP_PORTABLE:      name = "SIGSTOP_PORTABLE:19";           break;
     86     case SIGTSTP_PORTABLE:      name = "SIGTSTP_PORTABLE:20";           break;
     87     case SIGTTIN_PORTABLE:      name = "SIGTTIN_PORTABLE:21";           break;
     88     case SIGTTOU_PORTABLE:      name = "SIGTTOU_PORTABLE:22";           break;
     89     case SIGURG_PORTABLE:       name = "SIGURG_PORTABLE:23";            break;
     90     case SIGXCPU_PORTABLE:      name = "SIGXCPU_PORTABLE:24";           break;
     91     case SIGXFSZ_PORTABLE:      name = "SIGXFSZ_PORTABLE:25";           break;
     92     case SIGVTALRM_PORTABLE:    name = "SIGVTALRM_PORTABLE:26";         break;
     93     case SIGPROF_PORTABLE:      name = "SIGPROF_PORTABLE:27";           break;
     94     case SIGWINCH_PORTABLE:     name = "SIGWINCH_PORTABLE:28";          break;
     95     case SIGIO_PORTABLE:        name = "SIGIO_PORTABLE:29";             break;
     96     case SIGPWR_PORTABLE:       name = "SIGPWR_PORTABLE:30";            break;
     97     case SIGSYS_PORTABLE:       name = "SIGSYS_PORTABLE:31";            break;
     98     case SIGRTMIN_PORTABLE:     name = "SIGRTMIN_PORTABLE:32";          break;
     99 
    100     case SIGRT_1_PORTABLE:      name = "SIGRT_1_PORTABLE:33";           break;
    101     case SIGRT_2_PORTABLE:      name = "SIGRT_2_PORTABLE:34";           break;
    102     case SIGRT_3_PORTABLE:      name = "SIGRT_3_PORTABLE:35";           break;
    103     case SIGRT_4_PORTABLE:      name = "SIGRT_4_PORTABLE:36";           break;
    104     case SIGRT_5_PORTABLE:      name = "SIGRT_5_PORTABLE:37";           break;
    105     case SIGRT_6_PORTABLE:      name = "SIGRT_6_PORTABLE:38";           break;
    106     case SIGRT_7_PORTABLE:      name = "SIGRT_7_PORTABLE:39";           break;
    107     case SIGRT_8_PORTABLE:      name = "SIGRT_8_PORTABLE:40";           break;
    108     case SIGRT_9_PORTABLE:      name = "SIGRT_9_PORTABLE:41";           break;
    109     case SIGRT_10_PORTABLE:     name = "SIGRT_10_PORTABLE:42";          break;
    110     case SIGRT_11_PORTABLE:     name = "SIGRT_11_PORTABLE:43";          break;
    111     case SIGRT_12_PORTABLE:     name = "SIGRT_12_PORTABLE:44";          break;
    112     case SIGRT_13_PORTABLE:     name = "SIGRT_13_PORTABLE:45";          break;
    113     case SIGRT_14_PORTABLE:     name = "SIGRT_14_PORTABLE:46";          break;
    114     case SIGRT_15_PORTABLE:     name = "SIGRT_15_PORTABLE:47";          break;
    115     case SIGRT_16_PORTABLE:     name = "SIGRT_16_PORTABLE:48";          break;
    116     case SIGRT_17_PORTABLE:     name = "SIGRT_17_PORTABLE:49";          break;
    117     case SIGRT_18_PORTABLE:     name = "SIGRT_18_PORTABLE:50";          break;
    118     case SIGRT_19_PORTABLE:     name = "SIGRT_19_PORTABLE:51";          break;
    119     case SIGRT_20_PORTABLE:     name = "SIGRT_20_PORTABLE:52";          break;
    120     case SIGRT_21_PORTABLE:     name = "SIGRT_21_PORTABLE:53";          break;
    121     case SIGRT_22_PORTABLE:     name = "SIGRT_22_PORTABLE:54";          break;
    122     case SIGRT_23_PORTABLE:     name = "SIGRT_23_PORTABLE:55";          break;
    123     case SIGRT_24_PORTABLE:     name = "SIGRT_24_PORTABLE:56";          break;
    124     case SIGRT_25_PORTABLE:     name = "SIGRT_25_PORTABLE:57";          break;
    125     case SIGRT_26_PORTABLE:     name = "SIGRT_26_PORTABLE:58";          break;
    126     case SIGRT_27_PORTABLE:     name = "SIGRT_27_PORTABLE:59";          break;
    127     case SIGRT_28_PORTABLE:     name = "SIGRT_28_PORTABLE:60";          break;
    128     case SIGRT_29_PORTABLE:     name = "SIGRT_29_PORTABLE:61";          break;
    129     case SIGRT_30_PORTABLE:     name = "SIGRT_30_PORTABLE:62";          break;
    130     case SIGRT_31_PORTABLE:     name = "SIGRT_31_PORTABLE:63";          break;
    131     case SIGRTMAX_PORTABLE:     name = "SIGRTMAX_PORTABLE:64";          break;
    132 
    133     default:                    name = "<<UNKNOWN>>";                   break;
    134     }
    135     return name;
    136 }
    137 
    138 
    139 __hidden char *map_mips_signum_to_name(int mips_signum)
    140 {
    141     char *name;
    142 
    143     switch(mips_signum) {
    144     case 0:             name = "SIG_0:0";       break;
    145     case SIGHUP:        name = "SIGHUP:1";      break;
    146     case SIGINT:        name = "SIGINT:2";      break;
    147     case SIGQUIT:       name = "SIGQUIT:3";     break;
    148     case SIGILL:        name = "SIGILL:4";      break;
    149     case SIGTRAP:       name = "SIGTRAP:5";     break;
    150     case SIGIOT:        name = "SIGIOT:6";      break;
    151     case SIGEMT:        name = "SIGEMT:7";      break;
    152     case SIGFPE:        name = "SIGFPE:8";      break;
    153     case SIGKILL:       name = "SIGKILL:9";     break;
    154     case SIGBUS:        name = "SIGBUS:10";     break;
    155     case SIGSEGV:       name = "SIGSEGV:11";    break;
    156     case SIGSYS:        name = "SIGSYS:12";     break;
    157     case SIGPIPE:       name = "SIGPIPE:13";    break;
    158     case SIGALRM:       name = "SIGALRM:14";    break;
    159     case SIGTERM:       name = "SIGTERM:15";    break;
    160     case SIGUSR1:       name = "SIGUSR1:16";    break;
    161     case SIGUSR2:       name = "SIGUSR2:17";    break;
    162     case SIGCHLD:       name = "SIGCHLD:18";    break;
    163     case SIGPWR:        name = "SIGPWR:19";     break;
    164     case SIGWINCH:      name = "SIGWINCH:20";   break;
    165     case SIGURG:        name = "SIGURG:21";     break;
    166     case SIGIO:         name = "SIGIO:22";      break;
    167     case SIGSTOP:       name = "SIGSTOP:23";    break;
    168     case SIGTSTP:       name = "SIGTSTP:24";    break;
    169     case SIGCONT:       name = "SIGCONT:25";    break;
    170     case SIGTTIN:       name = "SIGTTIN:26";    break;
    171     case SIGTTOU:       name = "SIGTTOU:27";    break;
    172     case SIGVTALRM:     name = "SIGVTALRM:28";  break;
    173     case SIGPROF:       name = "SIGPROF:29";    break;
    174     case SIGXCPU:       name = "SIGXCPU:30";    break;
    175     case SIGXFSZ:       name = "SIGXFSZ:31";    break;
    176 
    177     case SIGRTMIN:      name = "SIGRTMIN:32";   break;
    178     case SIGRT_1:       name = "SIGRT_1:33";    break;
    179     case SIGRT_2:       name = "SIGRT_2:34";    break;
    180     case SIGRT_3:       name = "SIGRT_3:35";    break;
    181     case SIGRT_4:       name = "SIGRT_4:36";    break;
    182     case SIGRT_5:       name = "SIGRT_5:37";    break;
    183     case SIGRT_6:       name = "SIGRT_6:38";    break;
    184     case SIGRT_7:       name = "SIGRT_7:39";    break;
    185     case SIGRT_8:       name = "SIGRT_8:40";    break;
    186     case SIGRT_9:       name = "SIGRT_9:41";    break;
    187     case SIGRT_10:      name = "SIGRT_10:42";   break;
    188     case SIGRT_11:      name = "SIGRT_11:43";   break;
    189     case SIGRT_12:      name = "SIGRT_12:44";   break;
    190     case SIGRT_13:      name = "SIGRT_13:45";   break;
    191     case SIGRT_14:      name = "SIGRT_14:46";   break;
    192     case SIGRT_15:      name = "SIGRT_15:47";   break;
    193     case SIGRT_16:      name = "SIGRT_16:48";   break;
    194     case SIGRT_17:      name = "SIGRT_17:49";   break;
    195     case SIGRT_18:      name = "SIGRT_18:50";   break;
    196     case SIGRT_19:      name = "SIGRT_19:51";   break;
    197     case SIGRT_20:      name = "SIGRT_20:52";   break;
    198     case SIGRT_21:      name = "SIGRT_21:53";   break;
    199     case SIGRT_22:      name = "SIGRT_22:54";   break;
    200     case SIGRT_23:      name = "SIGRT_23:55";   break;
    201     case SIGRT_24:      name = "SIGRT_24:56";   break;
    202     case SIGRT_25:      name = "SIGRT_25:57";   break;
    203     case SIGRT_26:      name = "SIGRT_26:58";   break;
    204     case SIGRT_27:      name = "SIGRT_27:59";   break;
    205     case SIGRT_28:      name = "SIGRT_28:60";   break;
    206     case SIGRT_29:      name = "SIGRT_29:61";   break;
    207     case SIGRT_30:      name = "SIGRT_30:62";   break;
    208     case SIGRT_31:      name = "SIGRT_31:63";   break;
    209     case SIGRT_32:      name = "SIGRT_32:64";   break;
    210 
    211     /* NOTE: SIGRT_33...SIGRTMAX-1 Not printed */
    212 
    213     case SIGRTMAX:      name = "SIGRTMAX:128";  break;
    214     default:            name = "<<UNKNOWN>>";   break;
    215     }
    216     return name;
    217 }
    218 
    219 
    220 /*
    221  * Maps a signal number from portable to native.
    222  */
    223 __hidden int signum_pton(int portable_signum)
    224 {
    225     int mips_signum = -1;
    226 
    227     switch(portable_signum) {
    228 
    229     case 0:                             /* 0 */
    230         return 0;
    231 
    232     case SIGHUP_PORTABLE:               /* 1 */
    233         return SIGHUP;
    234 
    235     case SIGINT_PORTABLE:               /* 2 */
    236         return SIGINT;
    237 
    238     case SIGQUIT_PORTABLE:              /* 3 */
    239         return SIGQUIT;
    240 
    241     case SIGILL_PORTABLE:               /* 4 */
    242         return SIGILL;
    243 
    244     case SIGTRAP_PORTABLE:              /* 5 */
    245         return SIGTRAP;
    246 
    247     case SIGABRT_PORTABLE:              /* 6 */
    248         return SIGABRT;
    249 
    250     case SIGBUS_PORTABLE:               /* 7 --> 10 */
    251         return SIGBUS;
    252 
    253     case SIGFPE_PORTABLE:               /* 8 */
    254         return SIGFPE;
    255 
    256     case SIGKILL_PORTABLE:              /* 9 */
    257         return SIGKILL;
    258 
    259     case SIGUSR1_PORTABLE:              /* 10 --> 16 */
    260         return SIGUSR1;
    261 
    262     case SIGSEGV_PORTABLE:              /* 11 */
    263         return SIGSEGV;
    264 
    265     case SIGUSR2_PORTABLE:              /* 12 --> 17 */
    266         return SIGUSR2;
    267 
    268     case SIGPIPE_PORTABLE:              /* 13 */
    269         return SIGPIPE;
    270 
    271     case SIGALRM_PORTABLE:              /* 14 */
    272         return SIGALRM;
    273 
    274     case SIGTERM_PORTABLE:              /* 15 */
    275         return SIGTERM;
    276 
    277     case SIGSTKFLT_PORTABLE:            /* 16 --> 7 */
    278         return SIGEMT;                  /* No native SIGSTKFLT exist  ...
    279                                            ... mapping it to SIGEMT. */
    280 
    281     case SIGCHLD_PORTABLE:              /* 17 --> 18 */
    282         return SIGCHLD;
    283 
    284     case SIGCONT_PORTABLE:              /* 18 --> 25 */
    285         return SIGCONT;
    286 
    287     case SIGSTOP_PORTABLE:              /* 19 --> 23 */
    288         return SIGSTOP;
    289 
    290     case SIGTSTP_PORTABLE:              /* 20 --> 24 */
    291         return SIGTSTP;
    292 
    293     case SIGTTIN_PORTABLE:              /* 21 --> 26 */
    294         return SIGTTIN;
    295 
    296     case SIGTTOU_PORTABLE:              /* 22 --> 27 */
    297         return SIGTTOU;
    298 
    299     case SIGURG_PORTABLE:               /* 23 --> 21 */
    300         return SIGURG;
    301 
    302     case SIGXCPU_PORTABLE:              /* 24 --> 30 */
    303         return SIGXCPU;
    304 
    305     case SIGXFSZ_PORTABLE:              /* 25 --> 31 */
    306         return SIGXFSZ;
    307 
    308     case SIGVTALRM_PORTABLE:            /* 26 --> 28 */
    309         return SIGVTALRM;
    310 
    311     case SIGPROF_PORTABLE:              /* 27 --> 29 */
    312         return SIGPROF;
    313 
    314     case SIGWINCH_PORTABLE:             /* 28 --> 20 */
    315         return SIGWINCH;
    316 
    317     case SIGIO_PORTABLE:                /* 29 --> 22 */
    318         return SIGIO;
    319 
    320     case SIGPWR_PORTABLE:               /* 30 --> 19 */
    321         return SIGPWR;
    322 
    323     case SIGSYS_PORTABLE:               /* 31 --> 12 */
    324         return SIGSYS;
    325     /*
    326      * Mapping lower 32 Real Time signals to identical Native signal numbers.
    327      * NOTE: SIGRTMAX_PORTABLE == 64 but SIGRTMAX == 128.
    328      */
    329     case SIGRTMIN_PORTABLE...SIGRTMAX_PORTABLE:         /* 32 ... 64 */
    330         ASSERT(SIGRTMIN_PORTABLE == SIGRTMIN);
    331         ASSERT(SIGRTMAX_PORTABLE <= SIGRTMAX);
    332         return portable_signum;
    333 
    334     default:
    335         ALOGE("%s: switch default: NOTE portable_signum:%d Not supported. Just a Test?",
    336               __func__,                 portable_signum);
    337         /*
    338          * User could be LTP testing with bogus signal numbers,
    339          * if so we mimic the test.
    340          *
    341          * If the signal is just outside the PORTABLE range
    342          * we use a signal just outside the Native/MIPS range.
    343          */
    344         if (portable_signum < 0) {
    345             mips_signum = portable_signum;
    346         } else if (portable_signum > NSIG_PORTABLE) {
    347             mips_signum = (portable_signum - NSIG_PORTABLE) +  NSIG;
    348         } else {
    349             ALOGE("%s: 0 < portable_signum:%d <= NSIG_PORTABLE:%d; Not supported, return(0);",
    350                  __func__, portable_signum,      NSIG_PORTABLE);
    351 
    352             mips_signum = 0;
    353         }
    354         break;
    355     }
    356     ALOGV("%s(portable_signum:%d): return(mips_signum:%d);", __func__,
    357               portable_signum,            mips_signum);
    358 
    359     return mips_signum;
    360 }
    361 
    362 
    363 /*
    364  * Maps a signal number from native to portable.
    365  */
    366 __hidden int signum_ntop(int mips_signum)
    367 {
    368     int portable_ssignum = -1;
    369 
    370     switch(mips_signum) {
    371     case 0:                             /* 0 */
    372         return 0;
    373 
    374     case SIGHUP:                        /* 1 */
    375         return SIGHUP_PORTABLE;
    376 
    377     case SIGINT:                        /* 2 */
    378         return SIGINT_PORTABLE;
    379 
    380     case SIGQUIT:                       /* 3 */
    381         return SIGQUIT_PORTABLE;
    382 
    383     case SIGILL:                        /* 4 */
    384         return SIGILL_PORTABLE;
    385 
    386     case SIGTRAP:                       /* 5 */
    387         return SIGTRAP_PORTABLE;
    388 
    389     case SIGABRT:                       /* 6 */
    390         return SIGABRT_PORTABLE;
    391 
    392     case SIGBUS:                        /* 7 <-- 10 */
    393         return SIGBUS_PORTABLE;
    394 
    395     case SIGFPE:                        /* 8 */
    396         return SIGFPE_PORTABLE;
    397 
    398     case SIGKILL:                       /* 9 */
    399         return SIGKILL_PORTABLE;
    400 
    401     case SIGUSR1:                       /* 10 <-- 16 */
    402         return SIGUSR1_PORTABLE;
    403 
    404     case SIGSEGV:                       /* 11 */
    405         return SIGSEGV_PORTABLE;
    406 
    407     case SIGUSR2:                       /* 12 <-- 17 */
    408         return SIGUSR2_PORTABLE;
    409 
    410     case SIGPIPE:                       /* 13 */
    411         return SIGPIPE_PORTABLE;
    412 
    413     case SIGALRM:                       /* 14 */
    414         return SIGALRM_PORTABLE;
    415 
    416     case SIGTERM:                       /* 15 */
    417         return SIGTERM_PORTABLE;
    418 
    419     case SIGEMT:                        /* 16 <--- 7 */
    420         return SIGSTKFLT_PORTABLE;      /* No native SIGSTKFLT exist ...
    421                                            ... reverse mapping SIGEMT ...
    422                                            ...  back to SIGSTKFLT. */
    423 
    424     case SIGCHLD:                       /* 17 <-- 18 */
    425         return SIGCHLD_PORTABLE;
    426 
    427     case SIGCONT:                       /* 18 <-- 15 */
    428         return SIGCONT_PORTABLE;
    429 
    430     case SIGSTOP:                       /* 19 <-- 23 */
    431         return SIGSTOP_PORTABLE;
    432 
    433     case SIGTSTP:                       /* 20 <-- 24 */
    434         return SIGTSTP_PORTABLE;
    435 
    436     case SIGTTIN:                       /* 21 <-- 26 */
    437         return SIGTTIN_PORTABLE;
    438 
    439     case SIGTTOU:                       /* 22 <-- 27 */
    440         return SIGTTOU_PORTABLE;
    441 
    442     case SIGURG:                        /* 23 <-- 21 */
    443         return SIGURG_PORTABLE;
    444 
    445     case SIGXCPU:                       /* 24 <-- 30 */
    446         return SIGXCPU_PORTABLE;
    447 
    448     case SIGXFSZ:                       /* 25 <-- 31 */
    449         return SIGXFSZ_PORTABLE;
    450 
    451     case SIGVTALRM:                     /* 26 <-- 28 */
    452         return SIGVTALRM_PORTABLE;
    453 
    454     case SIGPROF:                       /* 27 <-- 29 */
    455         return SIGPROF_PORTABLE;
    456 
    457     case SIGWINCH:                      /* 28 <-- 20 */
    458         return SIGWINCH_PORTABLE;
    459 
    460     case SIGIO:                         /* 29 <-- 22 */
    461         return SIGIO_PORTABLE;
    462 
    463     case SIGPWR:                        /* 30 <-- 19 */
    464         return SIGPWR_PORTABLE;
    465 
    466     case SIGSYS:                        /* 31 <-- 12 */
    467         return SIGSYS_PORTABLE;
    468 
    469     /*
    470      * Mapping lower 32 Real Time signals to identical Portable signal numbers.
    471      * NOTE: SIGRTMAX_PORTABLE == 64 but SIGRTMAX == 128.
    472      */
    473     case SIGRTMIN...SIGRTMAX_PORTABLE:              /* 32 ... 64 */
    474         ASSERT(SIGRTMIN == SIGRTMIN_PORTABLE);
    475         ASSERT(SIGRTMAX >= SIGRTMAX_PORTABLE);
    476         return mips_signum;
    477 
    478    /*
    479     * Mapping upper 63 Native Real Time signals to the last Portable signal number.
    480     * Shouldn't even be possible to be using these signals.
    481     */
    482     case (SIGRTMAX_PORTABLE+1)...SIGRTMAX:          /* 65 ... 128 */
    483         ASSERT(SIGRTMIN == SIGRTMIN_PORTABLE);
    484         ASSERT(SIGRTMAX >= SIGRTMAX_PORTABLE);
    485 
    486         ALOGE("%s: mips_signum:%d Can't be mapped to a unique portable signal;", __func__,
    487                    mips_signum);
    488 
    489         ALOGE("%s: Mapping highest 63 Real Time Signals to the largest RT Portable SigNo.",
    490                 __func__);
    491 
    492         return SIGRTMAX_PORTABLE;
    493 
    494 
    495     default:
    496         ALOGE("%s: switch default: mips_signum:%d Not supported! return(0);", __func__,
    497                                    mips_signum);
    498 #if 0
    499         LOG_FATAL("%s: mips_signum:%d is not portable;", __func__, mips_signum);
    500 #endif
    501         return 0;
    502     }
    503     return portable_ssignum;
    504 }
    505 
    506 
    507 /*
    508  * Deal with siginfo structure being a bit different.
    509  * Need to swap errno and code fields.
    510  */
    511 static void siginfo_pton(siginfo_portable_t *portable_sip, siginfo_t *native_sip)
    512 {
    513 
    514     ALOGV("%s(portable_sip:%p, native_sip:%p) {", __func__,
    515               portable_sip,    native_sip);
    516 
    517     ASSERT(sizeof(siginfo_portable_t) == sizeof(siginfo_t));
    518 
    519     /*
    520      * Default to the same structure members,
    521      * code and errno are swapped between ARM and MIPS,
    522      * and errno needs to be translated.
    523      *
    524      * The signal number isn't translated, as the kernel
    525      * will fill it it when it delivers the signal.
    526      */
    527 
    528     *native_sip = *((siginfo_t *)portable_sip);
    529     native_sip->si_signo = 0;
    530     native_sip->si_code = portable_sip->si_code;
    531     native_sip->si_errno = errno_pton(portable_sip->si_errno);
    532 
    533     ALOGV("%s: return; }", __func__);
    534 }
    535 
    536 
    537 static void siginfo_ntop(siginfo_t *native_sip, siginfo_portable_t *portable_sip)
    538 {
    539 
    540     ALOGV("%s(native_sip,:%p, portable_sip:%p) {", __func__,
    541               native_sip,     portable_sip);
    542 
    543     ASSERT(sizeof(siginfo_portable_t) == sizeof(siginfo_t));
    544 
    545     /*
    546      * Structure assignment to default to the same structure members,
    547      * as only the code and errno are swapped in position between
    548      * ARM and MIPS; errno and signal number also need to be translated.
    549      */
    550     *portable_sip = *((siginfo_portable_t *)native_sip);
    551 
    552     portable_sip->si_signo = signum_ntop(native_sip->si_signo);
    553     portable_sip->si_code = native_sip->si_code;
    554     portable_sip->si_errno = errno_ntop(native_sip->si_errno);
    555 
    556     ALOGV("%s: return; }", __func__);
    557 }
    558 
    559 
    560 /*
    561  * Array of signal handlers as the portable users expects they
    562  * they have been registered in the kernel. Problem is we need
    563  * to have our own handler to map the MIPS signal number to a
    564  * portable signal number.
    565  */
    566 static sig3handler_portable_t mips_portable_sighandler[NSIG_PORTABLE + 1] = { NULL };
    567 
    568 static void mips_sigaction_handler(int mips_signum, siginfo_t *sip, void *ucp)
    569 {
    570     int portable_signum;
    571     char *portable_signame;
    572     char *mips_signame = map_mips_signum_to_name(mips_signum);
    573     sig3handler_portable_t portable_sighandler;
    574     siginfo_portable_t portable_si;
    575     siginfo_portable_t *portable_sip;
    576 
    577     ALOGV(" ");
    578     ALOGV("%s(mips_signum:%d:'%s', sip:%p, ucp:%p) {", __func__,
    579               mips_signum,
    580               mips_signame,        sip,    ucp);
    581 
    582     portable_signum = signum_ntop(mips_signum);
    583     portable_signame = map_portable_signum_to_name(portable_signum);
    584     portable_sighandler = mips_portable_sighandler[portable_signum];
    585 
    586     if (invalid_pointer(portable_sighandler)) {
    587         /*
    588          * If a portable/ARM application tries to set signals in the signal mask > 32
    589          * it results in a signal_handler being set to -1:SIG_ERR. Calling a function
    590          * at location -1 doesn't produce very informative Android backtraces on MIPS.
    591          */
    592         ALOGE("%s: invalid_pointer(portable_sighandler:%p); Likely about to Trap or Bus Error!",
    593                 __func__,          portable_sighandler);
    594 
    595         ALOGE("%s: HINT: Likely best to use gdbserver and look at sigaction arguments.", __func__);
    596     }
    597     ASSERT(portable_sighandler != NULL);
    598     ASSERT(portable_sighandler != (sig3handler_portable_t) SIG_DFL);
    599     ASSERT(portable_sighandler != (sig3handler_portable_t) SIG_IGN);
    600 
    601     if (sip == NULL) {
    602         portable_sip = NULL;
    603     } else {
    604         /* Map signinfo from native to portable format */
    605         portable_sip = &portable_si;
    606         siginfo_ntop(sip, portable_sip);
    607     }
    608 
    609 
    610     ALOGV("%s: Calling portable_sighandler:%p(portable_signum:%d, portable_sip:%p, ucp:%p);",
    611           __func__,    portable_sighandler,   portable_signum,    portable_sip,    ucp);
    612 
    613     portable_sighandler(portable_signum, portable_sip, ucp);
    614 
    615     ALOGV("%s: return; }", __func__);
    616 }
    617 
    618 
    619 static void mips_sighandler(int mips_signum)
    620 {
    621     int portable_signum;
    622     char *portable_signame;
    623     char *mips_signame = map_mips_signum_to_name(mips_signum);
    624     sig3handler_portable_t portable_sighandler;
    625 
    626     ALOGV(" ");
    627     ALOGV("%s(mips_signum:%d:'%s') {", __func__, mips_signum, mips_signame);
    628 
    629     mips_sigaction_handler(mips_signum, NULL, NULL);
    630 
    631     ALOGV("%s: return; }", __func__);
    632 }
    633 
    634 
    635 static sighandler_t sighandler_pton(sighandler_portable_t portable_handler, int sigaction)
    636 {
    637     sighandler_t mips_handler;
    638 
    639     ALOGV("%s(portable_handler:%p, sigaction:%d) {", __func__,
    640               portable_handler,    sigaction);
    641 
    642     switch((int) portable_handler) {
    643     case (int) SIG_DFL:
    644     case (int) SIG_IGN:
    645         mips_handler = portable_handler;
    646         break;
    647 
    648     default:    /* NOTE: Includes SIG_ERR:-1 */
    649         if (invalid_pointer(portable_handler)) {
    650             /*
    651              * Calling sigaction() with a bogus signal handler doesn't fail,
    652              * so we let the portable cases fail later as the native case would.
    653              */
    654             ALOGE("%s: invalid_pointer(portable_handler:%p)!", __func__, portable_handler);
    655             ALOGE("%s: HINT: Likely to cause a BUS Error ....", __func__);
    656             ALOGE("%s: HINT: ... when the signal handler is called!", __func__);
    657         }
    658 
    659         /*
    660          * Signal Mapping can be disabled in the rare case of the clone
    661          * flags not being compatble for VM and file descriptors.
    662          */
    663         if (signal_handler_mapping_enabled) {
    664             if (sigaction)
    665                 mips_handler = (sighandler_t) mips_sigaction_handler;
    666             else
    667                 mips_handler = (sighandler_t) mips_sighandler;
    668         } else {
    669             mips_handler = portable_handler;        /* Don't MAP */
    670         }
    671         break;
    672     }
    673 
    674     ALOGV("%s: return(mips_handler:%p); }", __func__, mips_handler);
    675     return mips_handler;
    676 }
    677 
    678 
    679 /*
    680  * This function maps the signal number and calls one of the low level mips signal()
    681  * functions implemented in libc/unistd/signal.c:
    682  *              sysv_signal()
    683  *              bsd_signal()
    684  *
    685  * The last 2 parameters to this static function, mips_signal_fn*, specify which of
    686  * these functions to call.  We intercept the above to functions, as well as signal(),
    687  * and call the associated *_portable() functions below.
    688  *
    689  * In addition, we intercept the signal_handler with our own handlers that map the
    690  * signal number from the MIPS convention to the PORTABLE/ARM convention.
    691  */
    692 static sighandler_portable_t
    693 do_signal_portable(int portable_signum, sighandler_portable_t portable_handler,
    694                    __sighandler_t (mips_signal_fn)(int, __sighandler_t))
    695 {
    696     char *portable_signame = map_portable_signum_to_name(portable_signum);
    697     int mips_signum;
    698     sighandler_t mips_handler;
    699     sighandler_portable_t rv;
    700     sighandler_portable_t prev_portable_handler;
    701 
    702     ALOGV("%s(portable_signum:%d:%s, portable_handler:%p,  mips_signal_fn:%p) {", __func__,
    703               portable_signum,
    704               portable_signame,      portable_handler,     mips_signal_fn);
    705 
    706     mips_signum = signum_pton(portable_signum);
    707 
    708     if ((mips_signum <= 0) || (mips_signum > NSIG)) {
    709         /*
    710          * Invalid signal number, perhaps zero. Let the kernel generate the
    711          * proper return value and set errno.
    712          */
    713         mips_handler = sighandler_pton(portable_handler, 0);
    714         rv = mips_signal_fn(mips_signum, mips_handler);
    715     } else {
    716         /*
    717          * We have a usable signal number, redirect it to our signal handler
    718          * if a portable handler was provided so we can convert the signal number.
    719          * Save our current mapped signal handler for likely return.
    720          */
    721         prev_portable_handler = (sighandler_portable_t) mips_portable_sighandler[portable_signum];
    722 
    723         mips_handler = sighandler_pton(portable_handler, 0);
    724         if (mips_handler != portable_handler) {
    725             mips_portable_sighandler[portable_signum] = (sig3handler_portable_t) portable_handler;
    726         }
    727         rv = mips_signal_fn(mips_signum, mips_handler);
    728 
    729         if ((rv == (sighandler_portable_t) mips_sighandler) ||
    730             (rv == (sighandler_portable_t) mips_sigaction_handler)) {
    731 
    732             rv = (sighandler_t) prev_portable_handler;
    733         }
    734     }
    735 
    736     ALOGV("%s: return(rv:%p); }", __func__, rv);
    737     return rv;
    738 }
    739 
    740 
    741 /*
    742  * signal() can't be called directly, due to an in-line function in signal.h which
    743  * redirects the call to bsd_signal(). _signal() is a static function; not to be called
    744  * directly. This function isn't actually needed.
    745  */
    746 sighandler_portable_t WRAP(signal)(int portable_signum, sighandler_portable_t handler)
    747 {
    748     extern __sighandler_t REAL(bsd_signal)(int, __sighandler_t);
    749     sighandler_portable_t rv;
    750 
    751     ALOGV(" ");
    752     ALOGV("%s(portable_signum:%d, handler:%p) {", __func__,
    753               portable_signum,    handler);
    754 
    755     /* bsd does a SA_RESTART */
    756     rv = do_signal_portable(portable_signum, handler, REAL(bsd_signal));
    757 
    758     ALOGV("%s: return(ret:%p); }", __func__, rv);
    759     return rv;
    760 }
    761 
    762 
    763 sighandler_portable_t WRAP(sysv_signal)(int portable_signum, sighandler_portable_t handler)
    764 {
    765     extern __sighandler_t REAL(sysv_signal)(int, __sighandler_t);
    766     sighandler_portable_t rv;
    767 
    768     ALOGV(" ");
    769     ALOGV("%s(portable_signum:%d, handler:%p) {", __func__,
    770               portable_signum,    handler);
    771 
    772     /* sysv does a SA_RESETHAND */
    773     rv = do_signal_portable(portable_signum, handler, REAL(sysv_signal));
    774 
    775     ALOGV("%s: return(ret:%p); }", __func__, rv);
    776     return rv;
    777 }
    778 
    779 
    780 /*
    781  * NOTE:
    782  *    handler is either the Bionic
    783  *      bsd_signal() signal handler
    784  * or
    785  *      the sysv_signal() signal handler.
    786  */
    787 
    788 sighandler_portable_t WRAP(bsd_signal)(int portable_signum, sighandler_portable_t handler)
    789 {
    790     extern __sighandler_t REAL(bsd_signal)(int, __sighandler_t);
    791     sighandler_portable_t rv;
    792 
    793     ALOGV(" ");
    794     ALOGV("%s(portable_signum:%d, handler:%p) {", __func__,
    795               portable_signum,    handler);
    796 
    797     /* bsd does a SA_RESTART */
    798     rv = do_signal_portable(portable_signum, handler, REAL(bsd_signal));
    799 
    800     ALOGV("%s: return(ret:%p); }", __func__, rv);
    801     return rv;
    802 }
    803 
    804 
    805 static int do_kill(int id, int portable_signum, int (*fn)(int, int))
    806 {
    807     char *portable_signame = map_portable_signum_to_name(portable_signum);
    808     int mips_signum;
    809     int rv;
    810 
    811     ALOGV("%s(id:%d, portable_signum:%d:'%s', fn:%p) {", __func__,
    812               id,    portable_signum,
    813                      portable_signame,        fn);
    814 
    815     mips_signum = signum_pton(portable_signum);
    816 
    817     /*
    818      * SIG_0 gets passed down to the kernel to test for the existence of a process.
    819      * If a non-zero portable_signum has been mapped to 0,
    820      * it's unsupported and will be ignored.
    821      */
    822     if ((portable_signum != 0) && (mips_signum == 0)) {
    823         rv = 0;
    824     } else {
    825         ALOGV("%s: Calling fn:%p(id:%d, mips_signum:%d);", __func__,
    826                            fn,   id,    mips_signum);
    827 
    828         rv =  fn(id, mips_signum);
    829     }
    830     ALOGV("%s: return(rv:%d); }", __func__, rv);
    831     return rv;
    832 }
    833 
    834 
    835 int WRAP(killpg)(int pgrp, int portable_signum)
    836 {
    837     extern int REAL(killpg)(int pgrp, int sig);
    838     int rv;
    839 
    840     ALOGV(" ");
    841     ALOGV("%s(pgrp:%d, portable_signum:%d) {", __func__,
    842               pgrp,    portable_signum);
    843 
    844     rv = do_kill(pgrp, portable_signum, REAL(killpg));
    845 
    846     ALOGV("%s: return(rv:%d); }", __func__, rv);
    847     return rv;
    848 }
    849 
    850 
    851 int WRAP(kill)(pid_t pid, int portable_signum)
    852 {
    853     extern int REAL(kill)(pid_t, int);
    854     int rv;
    855 
    856     ALOGV(" ");
    857     ALOGV("%s(pid:%d, portable_signum:%d) {", __func__,
    858               pid,    portable_signum);
    859 
    860     rv = do_kill(pid, portable_signum, REAL(kill));
    861 
    862     ALOGV("%s: return(rv:%d); }", __func__, rv);
    863     return rv;
    864 }
    865 
    866 
    867 int WRAP(tkill)(int tid, int portable_signum)
    868 {
    869     extern int REAL(tkill)(int, int);
    870     int rv;
    871 
    872     ALOGV(" ");
    873     ALOGV("%s(tid:%d, portable_signum:%d) {", __func__,
    874               tid,    portable_signum);
    875 
    876     rv = do_kill(tid, portable_signum, REAL(tkill));
    877 
    878     ALOGV("%s: return(rv:%d); }", __func__, rv);
    879     return rv;
    880 }
    881 
    882 
    883 /* tgkill is not exported from android-14 libc.so */
    884 #if 0
    885 int WRAP(tgkill)(int tgid, int tid, int portable_signum)
    886 {
    887     extern int tgkill(int, int, int);
    888     char *portable_signame = map_portable_signum_to_name(portable_signum);
    889     int mips_signum;
    890     int rv;
    891 
    892     ALOGV("%s(tgid:%d, tid:%d, portable_signum:%d:'%s') {", __func__,
    893               tgid,    tid,    portable_signum, portable_signame);
    894 
    895     mips_signum = signum_pton(portable_signum);
    896 
    897     /*
    898      * If a non-zero portable_signum has been mapped to 0,
    899      * it is unsupported and will be ignored.
    900      */
    901     if ((portable_signum != 0) && (mips_signum == 0))
    902         rv = 0;
    903     else
    904         rv = REAL(tgkill)(tgid, tid, mips_signum);
    905 
    906     ALOGV("%s: return rv:%d; }", __func__, rv);
    907     return rv;
    908 }
    909 #endif
    910 
    911 
    912 int WRAP(raise)(int portable_signum)
    913 {
    914     char *portable_signame = map_portable_signum_to_name(portable_signum);
    915     int mips_signum = signum_pton(portable_signum);
    916     int rv;
    917 
    918     ALOGV("%s(portable_signum:%d:'%s') {", __func__, portable_signum, portable_signame);
    919 
    920     /*
    921      * SIG_0 gets passed down to the kernel to test for the existence of a process.
    922      * If a non-zero portable_signum has been mapped to 0,
    923      * it's unsupported and will be ignored.
    924      */
    925     if ((portable_signum != 0) && (mips_signum == 0))
    926         rv = 0;
    927     else
    928         rv = REAL(raise)(mips_signum);
    929 
    930     ALOGV("%s: return(rv:%d); }", __func__, rv);
    931     return rv;
    932 }
    933 
    934 
    935 void sigset_pton(sigset_portable_t *portable_sigset, sigset_t *mips_sigset)
    936 {
    937     int portable_signum;
    938 
    939     ASSERT(mips_sigset != NULL);
    940 
    941     ALOGV("%s(portable_sigset:%p, mips_sigset:%p) {", __func__,
    942               portable_sigset,    mips_sigset);
    943 
    944     sigemptyset(mips_sigset);
    945     if (invalid_pointer((void *)portable_sigset)) {
    946         ALOGE("%s: portable_sigset:%p is not valid; returning empty set.", __func__,
    947                    portable_sigset);
    948         goto done;
    949     }
    950 
    951     for(portable_signum = 1; portable_signum <= NSIG_PORTABLE; portable_signum++) {
    952 
    953         if (WRAP(sigismember)(portable_sigset, portable_signum)) {
    954             char *portable_signame = map_portable_signum_to_name(portable_signum);
    955             int mips_signum = signum_pton(portable_signum);
    956             char *mips_signame;
    957 
    958             if (mips_signum != 0) {
    959                 int err;
    960 
    961                 mips_signame = map_mips_signum_to_name(mips_signum);
    962                 ALOGV("%s: sigaddset(mips_sigset:%p, mips_signum:%d:'%s');", __func__,
    963                                      mips_sigset,    mips_signum,
    964                                                      mips_signame);
    965 
    966                 err = sigaddset(mips_sigset, mips_signum);
    967                 if (err == -1) {
    968                     PERROR("sigaddset");
    969                 }
    970             }
    971         }
    972     }
    973 
    974 done:
    975     ALOGV("%s: return; }", __func__);
    976     return;
    977 }
    978 
    979 
    980 void
    981 sigset_ntop(const sigset_t *const_mips_sigset, sigset_portable_t *portable_sigset)
    982 {
    983     int mips_signum;
    984     sigset_t *mips_sigset = (sigset_t *) const_mips_sigset;
    985 
    986     ALOGV("%s(const_mips_sigset:%p, portable_sigset:%p) {", __func__,
    987               const_mips_sigset,    portable_sigset);
    988 
    989     ASSERT(mips_sigset != NULL);
    990 
    991     if (invalid_pointer((void *)portable_sigset)) {
    992         ALOGE("%s: portable_sigset:%p is not Valid; can't return sigset", __func__,
    993                    portable_sigset);
    994         goto done;
    995     }
    996     WRAP(sigemptyset)(portable_sigset);
    997 
    998     for(mips_signum = 1; mips_signum <= NSIG; mips_signum++) {
    999         if (sigismember(mips_sigset, mips_signum)) {
   1000             int portable_signum = signum_ntop(mips_signum);
   1001 
   1002             if (portable_signum != 0)
   1003                 WRAP(sigaddset)(portable_sigset, portable_signum);
   1004         }
   1005     }
   1006 
   1007 done:
   1008     ALOGV("%s: return; }", __func__);
   1009     return;
   1010 }
   1011 
   1012 
   1013 static int sigaction_flags_pton(int portable_flags)
   1014 {
   1015     int mips_flags = 0;
   1016 
   1017     if (portable_flags & SA_NOCLDSTOP_PORTABLE) {
   1018         mips_flags |= SA_NOCLDSTOP;
   1019     }
   1020     if (portable_flags & SA_NOCLDWAIT_PORTABLE) {
   1021         mips_flags |= SA_NOCLDWAIT;
   1022     }
   1023     if (portable_flags & SA_SIGINFO_PORTABLE) {
   1024         mips_flags |= SA_SIGINFO;
   1025     }
   1026     if (portable_flags & SA_THIRTYTWO_PORTABLE) {
   1027         ALOGV("%s: SA_THIRTYTWO_PORTABLE isn't SUPPORTED.", __func__);
   1028     }
   1029     if (portable_flags & SA_RESTORER_PORTABLE) {
   1030         mips_flags |= SA_RESTORER;
   1031     }
   1032     if (portable_flags & SA_ONSTACK_PORTABLE) {
   1033         mips_flags |= SA_ONSTACK;
   1034     }
   1035     if (portable_flags & SA_RESTART_PORTABLE) {
   1036         mips_flags |= SA_RESTART;
   1037     }
   1038     if (portable_flags & SA_NODEFER_PORTABLE) {
   1039         mips_flags |= SA_NODEFER;
   1040     }
   1041     if (portable_flags & SA_RESETHAND_PORTABLE) {
   1042         mips_flags |= SA_RESETHAND;
   1043     }
   1044 
   1045     ALOGV("%s(portable_flags:0x%x) return(mips_flags:0x%x);", __func__,
   1046               portable_flags,             mips_flags);
   1047 
   1048     return mips_flags;
   1049 }
   1050 
   1051 
   1052 int sigaction_flags_ntop(int mips_flags)
   1053 {
   1054     int portable_flags = 0;
   1055 
   1056     if (mips_flags & SA_NOCLDSTOP)      portable_flags |= SA_NOCLDSTOP_PORTABLE;
   1057     if (mips_flags & SA_NOCLDWAIT)      portable_flags |= SA_NOCLDWAIT_PORTABLE;
   1058     if (mips_flags & SA_SIGINFO)        portable_flags |= SA_SIGINFO_PORTABLE;
   1059 #ifdef SA_THIRTYTWO
   1060     if (mips_flags & SA_THIRTYTWO)      portable_flags |= SA_THIRTYTWO_PORTABLE;
   1061 #endif
   1062     if (mips_flags & SA_RESTORER)       portable_flags |= SA_RESTORER_PORTABLE;
   1063     if (mips_flags & SA_ONSTACK)        portable_flags |= SA_ONSTACK_PORTABLE;
   1064     if (mips_flags & SA_RESTART)        portable_flags |= SA_RESTART_PORTABLE;
   1065     if (mips_flags & SA_NODEFER)        portable_flags |= SA_NODEFER_PORTABLE;
   1066     if (mips_flags & SA_RESETHAND)      portable_flags |= SA_RESETHAND_PORTABLE;
   1067 
   1068     ALOGV("%s(mips_flags:0x%x) return(portable_flags:0x%x);", __func__,
   1069               mips_flags,             portable_flags);
   1070 
   1071     return portable_flags;
   1072 }
   1073 
   1074 
   1075 /*
   1076  * Called by portable/ARM code, which we map and do MIPS system calls.
   1077  *
   1078  * The incoming system call used a Portable/ARM sigaction structure:
   1079  * ------------------------------------------------------------------
   1080  *   struct sigaction_portable {
   1081  *     union {
   1082  *       __sighandler_portable_t        _sa_handler;
   1083  *       __sigaction_handler_portable_t _sa_sigaction;
   1084  *     } _u;
   1085  *     sigset_portable_t sa_mask;
   1086  *     unsigned long sa_flags;
   1087  *     void (*sa_restorer)(void);
   1088  * };
   1089  *
   1090  * A similar, but different, structure is used in the MIPS/Native system call:
   1091  * ---------------------------------------------------------------------------
   1092  *    struct sigaction {
   1093  *      unsigned int sa_flags;
   1094  *      union {
   1095  *        __sighandler_t                  sa_handler;
   1096  *        __sigaction_handler_portable_t _sa_sigaction;
   1097  *      } __u;
   1098  *      sigset_t sa_mask;
   1099  *  };
   1100  *
   1101  * This sigaction structure needs to be mapped before the MIPS systems call as well as after for
   1102  * returning the old/previous sigaction. Also, like signal_portable() above, we need to maintain
   1103  * a table of signal handlers that our intercepting handler can call after it converts the signal
   1104  * numbers.
   1105  */
   1106 static int do_sigaction_portable(int portable_signum, const struct sigaction_portable *act,
   1107                                  struct sigaction_portable *oldact, sigaction_fn fn,
   1108                                  rt_sigaction_fn rt_fn)
   1109 {
   1110     int mips_signum;
   1111     char *mips_signame;
   1112     struct sigaction mips_act;
   1113     struct sigaction *mips_act_ptr;
   1114     struct sigaction mips_oldact;
   1115     sighandler_t mips_handler;
   1116     sighandler_portable_t portable_handler;
   1117     sig3handler_portable_t prev_portable_handler;
   1118     char *portable_signame = map_portable_signum_to_name(portable_signum);
   1119     int rv;
   1120 
   1121     ALOGV("%s(portable_signum:%d:'%s', act:%p, oldact:%p, fn:%p, rt_fn:%p) {", __func__,
   1122               portable_signum,
   1123               portable_signame,        act,    oldact,    fn,    rt_fn);
   1124 
   1125     mips_signum = signum_pton(portable_signum);
   1126     mips_signame = map_mips_signum_to_name(mips_signum);
   1127 
   1128     /*
   1129      * If a non-zero portable_signum has been mapped to 0,
   1130      * it's unsupported and will be ignored.
   1131      */
   1132     if ((portable_signum != 0) && (mips_signum == 0)) {
   1133         rv = 0;
   1134         goto done;
   1135     }
   1136     if (portable_signum > 0 && portable_signum <= NSIG_PORTABLE)
   1137         prev_portable_handler = mips_portable_sighandler[portable_signum];
   1138     else
   1139         prev_portable_handler = NULL;
   1140 
   1141     memset(&mips_act, 0, sizeof(mips_act));
   1142 
   1143     if (invalid_pointer((void *)act)) {
   1144         mips_act_ptr = (struct sigaction *)act;
   1145     } else {
   1146         /*
   1147          * Make the MIPS version of sigaction, which has no sa_restorer function pointer.
   1148          * Also the handler will be called with a pointer to a to a sigcontext structure
   1149          * which is totally non-portable.
   1150          */
   1151         sigset_pton(((sigset_portable_t *)&act->sa_mask),
   1152                                     ((sigset_t *) &mips_act.sa_mask));
   1153 
   1154         mips_act.sa_flags = sigaction_flags_pton(act->sa_flags);
   1155 
   1156         if (mips_act.sa_flags & SA_SIGINFO) {
   1157             /*
   1158              * Providing the three argument version of a signal handler.
   1159              */
   1160             portable_handler = (sighandler_portable_t) act->sa_sigaction_portable;
   1161             if ((portable_signum <= 0) || (portable_signum > NSIG_PORTABLE)) {
   1162                 /*
   1163                  * Let the kernel generate the proper return value and set errno.
   1164                  */
   1165                 mips_act.sa_sigaction = (sig3handler_t) portable_handler;
   1166             } else {
   1167                 mips_handler = sighandler_pton(portable_handler, 1);
   1168                 if (mips_handler != portable_handler) {
   1169                     mips_portable_sighandler[portable_signum] =
   1170                                                        (sig3handler_portable_t) portable_handler;
   1171                 }
   1172                 mips_act.sa_sigaction = (sig3handler_t) mips_handler;
   1173             }
   1174         } else {
   1175             /*
   1176              * Providing the classic single argument version of a signal handler.
   1177              */
   1178             portable_handler = act->sa_handler_portable;
   1179             if ((portable_signum <= 0) || (portable_signum > NSIG_PORTABLE)) {
   1180                 /*
   1181                  * Let the kernel generate the proper return value and set errno.
   1182                  */
   1183                 mips_act.sa_handler = (sighandler_t) portable_handler;
   1184             } else {
   1185                 mips_handler = sighandler_pton(portable_handler, 1);
   1186                 if (mips_handler != portable_handler) {
   1187                     mips_portable_sighandler[portable_signum] =
   1188                                                        (sig3handler_portable_t) portable_handler;
   1189                 }
   1190                 mips_act.sa_handler = mips_handler;
   1191             }
   1192         }
   1193         mips_act_ptr = &mips_act;
   1194     }
   1195 
   1196     if (fn != NULL) {
   1197         ASSERT(rt_fn == NULL);
   1198         rv = fn(mips_signum, mips_act_ptr, &mips_oldact);
   1199     } else {
   1200         ASSERT(rt_fn != NULL);
   1201         rv = rt_fn(mips_signum, mips_act_ptr, &mips_oldact, sizeof(sigset_t));
   1202     }
   1203 
   1204     if (rv == 0 && oldact) {
   1205         if (mips_oldact.sa_sigaction == (__sigaction_handler_portable_t) mips_sigaction_handler ||
   1206             mips_oldact.sa_sigaction == (__sigaction_handler_portable_t) mips_sighandler) {
   1207 
   1208             oldact->sa_sigaction_portable =
   1209                                         (__sigaction_handler_portable_t) prev_portable_handler;
   1210         } else {
   1211             oldact->sa_sigaction_portable =
   1212                                         (__sigaction_handler_portable_t) mips_oldact.sa_sigaction;
   1213         }
   1214         sigset_ntop((sigset_t *) &(mips_oldact.sa_mask),
   1215                                     (sigset_portable_t *) &(oldact->sa_mask));
   1216 
   1217         oldact->sa_flags = sigaction_flags_ntop(mips_oldact.sa_flags);
   1218         oldact->sa_restorer = NULL;
   1219     }
   1220 
   1221 done:
   1222     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1223     return rv;
   1224 }
   1225 
   1226 
   1227 int WRAP(sigaction)(int portable_signum, const struct sigaction_portable *act,
   1228                        struct sigaction_portable *oldact)
   1229 {
   1230     extern int REAL(sigaction)(int, const struct sigaction *, struct sigaction *);
   1231     int rv;
   1232 
   1233     ALOGV(" ");
   1234     ALOGV("%s(portable_signum:%d, act:%p, oldact:%p) {", __func__,
   1235               portable_signum,    act,    oldact);
   1236 
   1237     rv = do_sigaction_portable(portable_signum, act, oldact, REAL(sigaction), NULL);
   1238 
   1239     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1240     return rv;
   1241 }
   1242 
   1243 
   1244 /*
   1245  * Currently signalfd() isn't supported by bionic with
   1246  * only the portable syscall.c code using this code by
   1247  * intercepting the syscall(__NR_signalfd4, ...) in bionic.
   1248  */
   1249 __hidden int do_signalfd4_portable(int fd, const sigset_portable_t *portable_sigmask,
   1250                                    int portable_sigsetsize, int portable_flags)
   1251 {
   1252     sigset_t native_sigmask;
   1253     int native_sigsetsize = sizeof(native_sigmask);
   1254     int native_flags = 0;
   1255     int rv;
   1256 
   1257     ALOGV("%s(fd:%d, portable_sigmask:%p, portable_sigsetsize:%d, portable_flags:0x%x) {",
   1258     __func__, fd,    portable_sigmask,    portable_sigsetsize,    portable_flags);
   1259 
   1260     sigset_pton((sigset_portable_t *)portable_sigmask, &native_sigmask);
   1261 
   1262     if (portable_flags & SFD_NONBLOCK_PORTABLE) {
   1263         native_flags |= SFD_NONBLOCK;
   1264     }
   1265     if (portable_flags & SFD_CLOEXEC_PORTABLE) {
   1266         native_flags |= SFD_CLOEXEC;
   1267     }
   1268     rv = syscall(__NR_signalfd4, fd, &native_sigmask, native_sigsetsize, native_flags);
   1269 
   1270     if (rv >= 0) {
   1271         if (native_flags & SFD_CLOEXEC) {
   1272             filefd_CLOEXEC_enabled(rv);
   1273         }
   1274 
   1275         /*
   1276          * Reads on this file descriptor must be mapped to be portable.
   1277          * The mapping should survive a fork and most clones naturally.
   1278          * For the system call to be completely portable it has to propagate
   1279          * these mapped files after an execve(). Environment variables have
   1280          * been added to do that. See filefd.c for details.
   1281          */
   1282         filefd_opened(rv, SIGNAL_FD_TYPE);
   1283     }
   1284 
   1285     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1286     return rv;
   1287 }
   1288 
   1289 
   1290 #if 0
   1291 /*
   1292  * signalfd() isn't available in Bionic yet. When it is, it will be implemented like
   1293  * the glibc version where the sigsetsize is computed in the bionic code and passed
   1294  * down to the kernel with __NR_signalfd4.
   1295  *
   1296  * This function can't be called from bionic, so there isn't an entry in the experimental
   1297  * linker.cpp table for testing and this function.
   1298  */
   1299 int WRAP(signalfd)(int fd, const sigset_portable_t *portable_sigmask, int portable_flags)
   1300 {
   1301     int portable_sigsetsize = sizeof(sigset_portable_t);
   1302     int rv;
   1303 
   1304     ALOGV("%s(fd:%d, portable_sigmask:%p, portable_flags:0x%x) {", __func__,
   1305               fd,    portable_sigmask,    portable_flags);
   1306 
   1307     rv = do_signalfd4_portable(fd, portable_sigsetsize, portable_sigmask, portable_flags);
   1308 
   1309     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1310     return rv;
   1311 }
   1312 #endif
   1313 
   1314 
   1315 /*
   1316  * Called by read_portable() to do signalfd read() mapping.
   1317  */
   1318 __hidden int read_signalfd_mapper(int fd, void *buf, size_t count)
   1319 {
   1320     int rv;
   1321 
   1322     ALOGV("%s(fd:%d, buf:0x%p, count:%d) {", __func__,
   1323               fd,    buf,      count);
   1324 
   1325     rv = read(fd, buf, count);
   1326     if (rv > 0) {
   1327         int siginfos = rv/sizeof(struct signalfd_siginfo);
   1328         struct signalfd_siginfo *si = (struct signalfd_siginfo *) buf;
   1329         int i;
   1330 
   1331         /* Read signalfd_siginfo structure(s) if read is large enough */
   1332         for (i = 0; i < siginfos; i++, si++) {
   1333             int ssi_signo;
   1334 
   1335             ssi_signo = si->ssi_signo;
   1336             si->ssi_signo = signum_ntop(si->ssi_signo);
   1337             ALOGV("%s: si->ssi_signo:%d = signum_ntop(si->ssi_signo:%d); i:%d", __func__,
   1338                        si->ssi_signo,                     ssi_signo,     i);
   1339 
   1340             si->ssi_errno = errno_ntop(si->ssi_errno);
   1341 
   1342             /*
   1343              * The ssi_codes appear to be generic; defined in
   1344              * the kernel in include/asm-generic/siginfo.h
   1345              */
   1346             if (si->ssi_status > 0 && si->ssi_status <= NSIG) {
   1347                 si->ssi_status = signum_ntop(si->ssi_status);
   1348             }
   1349 
   1350             /*
   1351              * The rest of the struct members, like
   1352              *  ssi_trapno, ssi_int, ssi_ptr
   1353              * are not likely worth dealing with.
   1354              */
   1355         }
   1356     }
   1357 
   1358     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1359     return rv;
   1360 }
   1361 
   1362 int WRAP(sigsuspend)(const sigset_portable_t *portable_sigmask)
   1363 {
   1364     int rv;
   1365     sigset_t mips_sigmask;
   1366 
   1367     ALOGV("%s(portable_sigmask:%p) {", __func__, portable_sigmask);
   1368 
   1369     if (invalid_pointer((void *)portable_sigmask)) {
   1370         *REAL(__errno)() = EFAULT;
   1371         rv = -1;
   1372     } else {
   1373         sigset_pton((sigset_portable_t *)portable_sigmask, &mips_sigmask);
   1374         rv = REAL(sigsuspend)(&mips_sigmask);
   1375     }
   1376 
   1377     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1378     return rv;
   1379 }
   1380 
   1381 
   1382 int WRAP(sigpending)(sigset_portable_t *portable_sigset)
   1383 {
   1384     int rv;
   1385     sigset_t mips_sigset;
   1386 
   1387     ALOGV("%s(portable_sigset:%p) {", __func__,
   1388               portable_sigset);
   1389 
   1390     if (invalid_pointer((void *)portable_sigset)) {
   1391         *REAL(__errno)() = EFAULT;
   1392         rv = -1;
   1393     } else {
   1394         rv = REAL(sigpending)(&mips_sigset);
   1395         sigset_ntop(&mips_sigset, portable_sigset);
   1396     }
   1397 
   1398     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1399     return rv;
   1400 }
   1401 
   1402 
   1403 int WRAP(sigwait)(const sigset_portable_t *portable_sigset, int *ptr_to_portable_sig)
   1404 {
   1405     int rv;
   1406     sigset_t mips_sigset;
   1407     int mips_sig;
   1408     int portable_sig;
   1409 
   1410     ALOGV("%s(portable_sigset:%p, ptr_to_portable_sig:%p) {", __func__,
   1411               portable_sigset,    ptr_to_portable_sig);
   1412 
   1413     if (invalid_pointer((void *)portable_sigset)) {
   1414         *REAL(__errno)() = EFAULT;
   1415         rv = -1;
   1416     } else {
   1417         sigset_pton((sigset_portable_t *)portable_sigset, &mips_sigset);
   1418 
   1419         rv = REAL(sigwait)(&mips_sigset, &mips_sig);
   1420 
   1421         portable_sig = signum_ntop(mips_sig);
   1422         *ptr_to_portable_sig = portable_sig;
   1423     }
   1424     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1425     return rv;
   1426 }
   1427 
   1428 
   1429 int WRAP(siginterrupt)(int portable_signum, int flag)
   1430 
   1431 {
   1432     int rv;
   1433     int mips_signum;
   1434 
   1435     ALOGV("%s(portable_signum:%d, flag:0x%x) {", __func__,
   1436               portable_signum,    flag);
   1437 
   1438     mips_signum = signum_pton(portable_signum);
   1439 
   1440     /*
   1441      * If a non-zero portable_signum has been mapped to 0,
   1442      * it's unsupported and will be ignored.
   1443      */
   1444     if ((portable_signum != 0) && (mips_signum == 0)) {
   1445         rv = 0;
   1446     } else {
   1447         rv = REAL(siginterrupt)(mips_signum, flag);
   1448     }
   1449     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1450     return rv;
   1451 }
   1452 
   1453 
   1454 __hidden int do_sigmask(int portable_how, const sigset_portable_t *portable_sigset,
   1455                         sigset_portable_t *portable_oldset, sigmask_fn fn,
   1456                         rt_sigmask_fn rt_fn)
   1457 {
   1458     int rv;
   1459     int how;
   1460     char *how_name;
   1461     sigset_t mips_sigset, *mips_sigset_p;
   1462     sigset_t mips_oldset, *mips_oldset_p;
   1463 
   1464     ALOGV("%s(portable_how:%d, portable_sigset:%p, portable_oldset:%p, fn:%p, rt_fn:%p) {",
   1465     __func__, portable_how,    portable_sigset,    portable_oldset,    fn,    rt_fn);
   1466 
   1467     switch(portable_how) {
   1468     case SIG_BLOCK_PORTABLE:    how = SIG_BLOCK;        how_name = "SIG_BLOCK";         break;
   1469     case SIG_UNBLOCK_PORTABLE:  how = SIG_UNBLOCK;      how_name = "SIG_UNBLOCK";       break;
   1470     case SIG_SETMASK_PORTABLE:  how = SIG_SETMASK;      how_name = "SIG_SETMASK";       break;
   1471 
   1472     default:
   1473         ALOGE("%s: portable_how:%d NOT SUPPORTED!", __func__, portable_how);
   1474         how = -1;
   1475         break;
   1476     }
   1477 
   1478     if (invalid_pointer((void *)portable_sigset)) {
   1479         mips_sigset_p = (sigset_t *) portable_sigset;
   1480     } else {
   1481         mips_sigset_p = &mips_sigset;
   1482         memset(mips_sigset_p, 0, sizeof(mips_sigset));
   1483         sigemptyset(mips_sigset_p);
   1484         sigset_pton((sigset_portable_t *)portable_sigset, &mips_sigset);
   1485     }
   1486 
   1487     if (invalid_pointer((void *)portable_oldset)) {
   1488         mips_oldset_p = (sigset_t *) portable_oldset;
   1489     } else {
   1490         mips_oldset_p = &mips_oldset;
   1491         memset(mips_oldset_p, 0, sizeof(mips_oldset));
   1492         sigemptyset(mips_oldset_p);
   1493     }
   1494 
   1495     if (fn != NULL) {
   1496         ASSERT(rt_fn == NULL);
   1497         rv = fn(how, mips_sigset_p, mips_oldset_p);
   1498     } else {
   1499         ASSERT(rt_fn != NULL);
   1500         rv = rt_fn(how, mips_sigset_p, mips_oldset_p, sizeof(sigset_t));
   1501     }
   1502 
   1503     if (rv == 0 && !invalid_pointer(portable_oldset)) {
   1504         /* Map returned mips_oldset to portable_oldset for return to caller */
   1505         sigset_ntop(mips_oldset_p, portable_oldset);
   1506     }
   1507 
   1508     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1509     return rv;
   1510 }
   1511 
   1512 
   1513 int WRAP(sigprocmask)(int portable_how, const sigset_portable_t *portable_sigset,
   1514                          sigset_portable_t *portable_oldset)
   1515 {
   1516     extern int REAL(sigprocmask)(int, const sigset_t *, sigset_t *);
   1517     int rv;
   1518 
   1519     ALOGV(" ");
   1520     ALOGV("%s(portable_how:%d, portable_sigset:%p, portable_oldset:%p) {", __func__,
   1521               portable_how,    portable_sigset,    portable_oldset);
   1522 
   1523     rv = do_sigmask(portable_how, portable_sigset, portable_oldset, REAL(sigprocmask), NULL);
   1524 
   1525     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1526     return rv;
   1527 }
   1528 
   1529 
   1530 int WRAP(__rt_sigaction)(int portable_signum, const struct sigaction_portable *act,
   1531                             struct sigaction_portable *oldact, size_t sigsetsize)
   1532 {
   1533     extern int REAL(__rt_sigaction)(int , const struct sigaction *, struct sigaction *, size_t);
   1534     int rv;
   1535 
   1536     ALOGV(" ");
   1537     ALOGV("%s(portable_signum:%d, act:%p, oldset:%p, sigsetsize:%d) {", __func__,
   1538               portable_signum,    act,    oldact,    sigsetsize);
   1539 
   1540     /* NOTE: ARM kernel is expecting sizeof(sigset_t) to be 8 bytes */
   1541     if (sigsetsize != (2* sizeof(long))) {
   1542         *REAL(__errno)() = EINVAL;
   1543         rv = -1;
   1544         goto done;
   1545     }
   1546     rv = do_sigaction_portable(portable_signum, act, oldact, NULL, REAL(__rt_sigaction));
   1547 
   1548 done:
   1549     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1550     return rv;
   1551 }
   1552 
   1553 int WRAP(__rt_sigprocmask)(int portable_how,
   1554                               const sigset_portable_t *portable_sigset,
   1555                               sigset_portable_t *portable_oldset,
   1556                               size_t sigsetsize)
   1557 {
   1558     extern int REAL(__rt_sigprocmask)(int, const sigset_t *, sigset_t *, size_t);
   1559     int rv;
   1560 
   1561     ALOGV(" ");
   1562     ALOGV("%s(portable_how:%d, portable_sigset:%p, portable_oldset:%p, sigsetsize:%d) {",
   1563     __func__, portable_how,    portable_sigset,    portable_oldset,    sigsetsize);
   1564 
   1565     /* NOTE: ARM kernel is expecting sizeof(sigset_t) to be 8 bytes */
   1566     if (sigsetsize != (2* sizeof(long))) {
   1567         *REAL(__errno)() = EINVAL;
   1568         rv = -1;
   1569         goto done;
   1570     }
   1571     rv = do_sigmask(portable_how, portable_sigset, portable_oldset, NULL, REAL(__rt_sigprocmask));
   1572 
   1573  done:
   1574     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1575 
   1576     return rv;
   1577 }
   1578 
   1579 
   1580 int WRAP(__rt_sigtimedwait)(const sigset_portable_t *portable_sigset,
   1581                                siginfo_portable_t *portable_siginfo,
   1582                                const struct timespec *timeout,
   1583                                size_t portable_sigsetsize)
   1584 {
   1585     extern int REAL(__rt_sigtimedwait)(const sigset_t *, siginfo_t *, const struct timespec *, size_t);
   1586 
   1587     sigset_t native_sigset_struct;
   1588     sigset_t *native_sigset = &native_sigset_struct;
   1589     siginfo_t native_siginfo_struct;
   1590     siginfo_t *native_siginfo;
   1591     int rv;
   1592 
   1593     ALOGV(" ");
   1594     ALOGV("%s(portable_sigset:%p, portable_siginfo:%p, timeout:%p, portable_sigsetsize:%d) {",
   1595     __func__, portable_sigset,    portable_siginfo,    timeout,    portable_sigsetsize);
   1596 
   1597     /* NOTE: ARM kernel is expecting sizeof(sigset_t) to be 8 bytes */
   1598     if (portable_sigsetsize != (2* sizeof(long))) {
   1599         *REAL(__errno)() = EINVAL;
   1600         rv = -1;
   1601         goto done;
   1602     }
   1603     if (portable_sigset == NULL) {
   1604         native_sigset = NULL;
   1605     } else {
   1606         sigset_pton((sigset_portable_t *)portable_sigset, native_sigset);
   1607     }
   1608     if (portable_siginfo == NULL) {
   1609         native_siginfo = NULL;
   1610     } else {
   1611         native_siginfo = &native_siginfo_struct;
   1612     }
   1613     rv = REAL(__rt_sigtimedwait)(native_sigset, native_siginfo, timeout, sizeof(sigset_t));
   1614     if (rv == 0 && native_siginfo != NULL) {
   1615         /* Map siginfo struct from native to portable format. */
   1616         siginfo_ntop(native_siginfo, portable_siginfo);
   1617     }
   1618 
   1619 done:
   1620     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1621     return rv;
   1622 }
   1623 
   1624 
   1625 #ifdef  __NR_rt_sigqueueinfo
   1626 
   1627 #if 0
   1628 /*
   1629  * sigqueue():
   1630  *    This function became available in UNIX GLIBC after 1993.
   1631  *    It's not available in any versions of Android yet, and
   1632  *    it can't be called via syscall(). It's been useful for
   1633  *    testing with the LTP by the posix testsuite, and tests
   1634  *    show that it works fine.
   1635  *
   1636  * NOTE:
   1637  *    Android has in incorrect limit on the number of queueable signals
   1638  *    defined in libc/unistd/sysconf.c:
   1639  *
   1640  *        #define  SYSTEM_SIGQUEUE_MAX    32
   1641  *
   1642  *    sigqueue() must return EAGAIN if exceeded and we don't on Android.
   1643  */
   1644 int WRAP(sigqueue)(pid_t pid, int portable_sig, const union sigval value)
   1645 {
   1646     siginfo_t native_siginfo;
   1647     siginfo_t *native_sip;
   1648     siginfo_portable_t portable_siginfo;
   1649     siginfo_portable_t *portable_sip;
   1650     int native_sig;
   1651     int rv;
   1652 
   1653     ALOGV(" ");
   1654     ALOGV("%s(pid:%d, portable_sig:%d, value:%p) {", __func__,
   1655               pid,    portable_sig,    value.sival_ptr);
   1656 
   1657     native_sig = signum_pton(portable_sig);
   1658     native_sip = &native_siginfo;
   1659 
   1660     portable_sip = &portable_siginfo;
   1661     portable_sip->si_signo = 0;                 /* Filled in by the kernel */
   1662     portable_sip->si_code = SI_QUEUE;
   1663     portable_sip->si_pid = getpid();            /* Process ID of sender */
   1664     portable_sip->si_uid = getuid();            /* Real UID of sender */
   1665     portable_sip->si_value = value;             /* Last arg supplied */
   1666 
   1667     siginfo_pton(portable_sip, native_sip);
   1668 
   1669     /*
   1670      * man page says sigqueue() is implemented via rt_sigqueueinfo().
   1671      */
   1672     ALOGV("%s: calling syscall(__NR_rt_sigqueueinfo:%d, pid:%d, native_sig:%d, native_sip:%p);",
   1673            __func__,           __NR_rt_sigqueueinfo,    pid,    native_sig,    native_sip);
   1674 
   1675     rv = syscall(__NR_rt_sigqueueinfo, pid, native_sig, native_sip);
   1676 
   1677     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1678     return rv;
   1679 }
   1680 #endif
   1681 
   1682 
   1683 /*
   1684  * Real Time version of sigqueueinfo().
   1685  */
   1686 int WRAP(rt_sigqueueinfo)(pid_t pid, int portable_sig, siginfo_portable_t *portable_sip)
   1687 {
   1688     int native_sig;
   1689     siginfo_t native_siginfo, *native_sip;
   1690     int rv;
   1691 
   1692     ALOGV(" ");
   1693     ALOGV("%s(pid:%d, portable_sig:%d, portable_sip:%p) {", __func__,
   1694               pid,    portable_sig,    portable_sip);
   1695 
   1696     native_sig = signum_pton(portable_sig);
   1697 
   1698     /*
   1699      * If a non-zero portable_signum has been mapped to 0,
   1700      * it's unsupported and will be ignored.
   1701      */
   1702     if ((portable_sig != 0) && (native_sig == 0)) {
   1703         rv = 0;
   1704         goto done;
   1705     }
   1706 
   1707     if (portable_sip != NULL) {
   1708         native_sip = &native_siginfo;
   1709         siginfo_pton(portable_sip, native_sip);
   1710     } else {
   1711         native_sip = NULL;
   1712     }
   1713     rv = syscall(__NR_rt_sigqueueinfo, pid, native_sig, native_sip);
   1714 
   1715 done:
   1716     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1717     return rv;
   1718 }
   1719 #endif /* __NR_rt_sigqueueinfo */
   1720 
   1721 
   1722 #ifdef __NR_rt_tgsigqueueinfo
   1723 /*
   1724  * Thread Group flavor of the real time version of sigqueueinfo().
   1725  */
   1726 int WRAP(rt_tgsigqueueinfo)(pid_t tgid, pid_t pid, int portable_sig,
   1727                                siginfo_portable_t *portable_sip)
   1728 {
   1729     siginfo_t native_siginfo, *native_sip;
   1730     int native_sig;
   1731     int rv;
   1732 
   1733     ALOGV(" ");
   1734     ALOGV("%s(tgid:%d, pid:%d, portable_sig:%d, portable_sip:%p) {", __func__,
   1735               tgid,    pid,    portable_sig,    portable_sip);
   1736 
   1737     native_sig = signum_pton(portable_sig);
   1738 
   1739     /*
   1740      * If a non-zero portable_signum has been mapped to 0,
   1741      * it's unsupported and will be ignored.
   1742      */
   1743     if ((portable_sig != 0) && (native_sig == 0)) {
   1744         rv = 0;
   1745         goto done;
   1746     }
   1747     if (portable_sip != NULL) {
   1748         native_sip = &native_siginfo;
   1749         siginfo_pton(portable_sip, native_sip);
   1750     } else {
   1751         native_sip = NULL;
   1752     }
   1753     rv = syscall(__NR_rt_tgsigqueueinfo, pid, native_sig, native_sip);
   1754 
   1755 done:
   1756     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1757     return rv;
   1758 }
   1759 #endif /* __NR_rt_tgsigqueueinfo */
   1760 
   1761 
   1762 /*
   1763  * ss_flags and ss_size are located in different locations in stack_t structure:
   1764  *
   1765  * Incomming ARM/Portable stack_t:                  Outgoing MIPS stack_t:
   1766  * -------------------------------              ----------------------------
   1767  *    typedef struct sigaltstack {              typedef struct sigaltstack {
   1768  *        void __user *ss_sp;                       void *ss_sp;
   1769  *        int ss_flags;                             size_t ss_size;
   1770  *        size_t ss_size;                           int ss_flags;
   1771  *    } stack_t;
   1772  *
   1773  */
   1774 int WRAP(sigaltstack)(const portable_stack_t *ss, portable_stack_t *oss)
   1775 {
   1776     int rv;
   1777     stack_t new_stack, *mips_ss;
   1778     stack_t old_stack, *mips_oss;
   1779 
   1780     ALOGV(" ");
   1781     ALOGV("%s(ss:%p, oss:%p) {", __func__, ss, oss);
   1782 
   1783     if (ss == NULL) {
   1784         mips_ss = NULL;
   1785     } else {
   1786         if (invalid_pointer((void *)ss)) {
   1787             ALOGE("%s: invalid_pointer(ss:%p): Let kernel set proper errno and set return value.",
   1788                    __func__,           ss);
   1789 
   1790             mips_ss = (stack_t *) ss;
   1791         } else {
   1792             memset(&new_stack, 0, sizeof(stack_t));
   1793             new_stack.ss_sp = ss->ss_sp;
   1794             new_stack.ss_flags = ss->ss_flags;
   1795             new_stack.ss_size = ss->ss_size;
   1796             mips_ss = &new_stack;
   1797         }
   1798     }
   1799     if (oss == NULL) {
   1800         mips_oss = NULL;
   1801     } else {
   1802         if (invalid_pointer((void *)oss)) {
   1803             ALOGE("%s: invalid_pointer(oss:%p): Let kernel set proper errno and return value.",
   1804                    __func__,           oss);
   1805 
   1806             mips_oss = (stack_t *)oss;
   1807         } else {
   1808             memset(&old_stack, 0, sizeof(stack_t));
   1809             mips_oss = &old_stack;
   1810         }
   1811     }
   1812 
   1813     rv = REAL(sigaltstack)(mips_ss, mips_oss);
   1814 
   1815     if (!invalid_pointer(oss)) {
   1816         oss->ss_sp = old_stack.ss_sp;
   1817         oss->ss_flags = old_stack.ss_flags;
   1818         oss->ss_size = old_stack.ss_size;
   1819     }
   1820     ALOGV("%s: return(rv:%d); }", __func__, rv);
   1821 
   1822     return rv;
   1823 }
   1824