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