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