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