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