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