1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $Id$ 30 */ 31 32 #include "defs.h" 33 34 #ifdef LINUX 35 #include <linux/version.h> 36 #ifdef HAVE_ANDROID_OS 37 #include <linux/timex.h> 38 #else 39 #include <sys/timex.h> 40 #endif 41 #include <linux/ioctl.h> 42 #include <linux/rtc.h> 43 44 #ifndef UTIME_NOW 45 #define UTIME_NOW ((1l << 30) - 1l) 46 #endif 47 #ifndef UTIME_OMIT 48 #define UTIME_OMIT ((1l << 30) - 2l) 49 #endif 50 #endif /* LINUX */ 51 52 struct timeval32 53 { 54 u_int32_t tv_sec, tv_usec; 55 }; 56 57 static void 58 tprint_timeval32(struct tcb *tcp, const struct timeval32 *tv) 59 { 60 tprintf("{%u, %u}", tv->tv_sec, tv->tv_usec); 61 } 62 63 static void 64 tprint_timeval(struct tcb *tcp, const struct timeval *tv) 65 { 66 tprintf("{%lu, %lu}", 67 (unsigned long) tv->tv_sec, (unsigned long) tv->tv_usec); 68 } 69 70 void 71 printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special) 72 { 73 if (addr == 0) 74 tprintf("NULL"); 75 else if (!verbose(tcp)) 76 tprintf("%#lx", addr); 77 else { 78 int rc; 79 80 if (bitness == BITNESS_32 81 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 82 || personality_wordsize[current_personality] == 4 83 #endif 84 ) 85 { 86 struct timeval32 tv; 87 88 if ((rc = umove(tcp, addr, &tv)) >= 0) { 89 if (special && tv.tv_sec == 0 && 90 tv.tv_usec == UTIME_NOW) 91 tprintf("UTIME_NOW"); 92 else if (special && tv.tv_sec == 0 && 93 tv.tv_usec == UTIME_OMIT) 94 tprintf("UTIME_OMIT"); 95 else 96 tprint_timeval32(tcp, &tv); 97 } 98 } else { 99 struct timeval tv; 100 101 if ((rc = umove(tcp, addr, &tv)) >= 0) { 102 if (special && tv.tv_sec == 0 && 103 tv.tv_usec == UTIME_NOW) 104 tprintf("UTIME_NOW"); 105 else if (special && tv.tv_sec == 0 && 106 tv.tv_usec == UTIME_OMIT) 107 tprintf("UTIME_OMIT"); 108 else 109 tprint_timeval(tcp, &tv); 110 } 111 } 112 if (rc < 0) 113 tprintf("{...}"); 114 } 115 } 116 117 void 118 sprinttv(struct tcb *tcp, long addr, enum bitness_t bitness, char *buf) 119 { 120 if (addr == 0) 121 strcpy(buf, "NULL"); 122 else if (!verbose(tcp)) 123 sprintf(buf, "%#lx", addr); 124 else { 125 int rc; 126 127 if (bitness == BITNESS_32 128 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 129 || personality_wordsize[current_personality] == 4 130 #endif 131 ) 132 { 133 struct timeval32 tv; 134 135 if ((rc = umove(tcp, addr, &tv)) >= 0) 136 sprintf(buf, "{%u, %u}", 137 tv.tv_sec, tv.tv_usec); 138 } else { 139 struct timeval tv; 140 141 if ((rc = umove(tcp, addr, &tv)) >= 0) 142 sprintf(buf, "{%lu, %lu}", 143 (unsigned long) tv.tv_sec, 144 (unsigned long) tv.tv_usec); 145 } 146 if (rc < 0) 147 strcpy(buf, "{...}"); 148 } 149 } 150 151 void print_timespec(struct tcb *tcp, long addr) 152 { 153 if (addr == 0) 154 tprintf("NULL"); 155 else if (!verbose(tcp)) 156 tprintf("%#lx", addr); 157 else { 158 int rc; 159 160 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 161 if (personality_wordsize[current_personality] == 4) { 162 struct timeval32 tv; 163 164 if ((rc = umove(tcp, addr, &tv)) >= 0) 165 tprintf("{%u, %u}", 166 tv.tv_sec, tv.tv_usec); 167 } else 168 #endif 169 { 170 struct timespec ts; 171 172 if ((rc = umove(tcp, addr, &ts)) >= 0) 173 tprintf("{%lu, %lu}", 174 (unsigned long) ts.tv_sec, 175 (unsigned long) ts.tv_nsec); 176 } 177 if (rc < 0) 178 tprintf("{...}"); 179 } 180 } 181 182 void sprint_timespec(char *buf, struct tcb *tcp, long addr) 183 { 184 if (addr == 0) 185 strcpy(buf, "NULL"); 186 else if (!verbose(tcp)) 187 sprintf(buf, "%#lx", addr); 188 else { 189 int rc; 190 191 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 192 if (personality_wordsize[current_personality] == 4) { 193 struct timeval32 tv; 194 195 if ((rc = umove(tcp, addr, &tv)) >= 0) 196 sprintf(buf, "{%u, %u}", 197 tv.tv_sec, tv.tv_usec); 198 } else 199 #endif 200 { 201 struct timespec ts; 202 203 if ((rc = umove(tcp, addr, &ts)) >= 0) 204 sprintf(buf, "{%lu, %lu}", 205 (unsigned long) ts.tv_sec, 206 (unsigned long) ts.tv_nsec); 207 } 208 if (rc < 0) 209 strcpy(buf, "{...}"); 210 } 211 } 212 213 int 214 sys_time(tcp) 215 struct tcb *tcp; 216 { 217 if (exiting(tcp)) { 218 #ifndef SVR4 219 printnum(tcp, tcp->u_arg[0], "%ld"); 220 #endif /* SVR4 */ 221 } 222 return 0; 223 } 224 225 int 226 sys_stime(tcp) 227 struct tcb *tcp; 228 { 229 if (exiting(tcp)) { 230 printnum(tcp, tcp->u_arg[0], "%ld"); 231 } 232 return 0; 233 } 234 235 int 236 sys_gettimeofday(tcp) 237 struct tcb *tcp; 238 { 239 if (exiting(tcp)) { 240 if (syserror(tcp)) { 241 tprintf("%#lx, %#lx", 242 tcp->u_arg[0], tcp->u_arg[1]); 243 return 0; 244 } 245 printtv(tcp, tcp->u_arg[0]); 246 #ifndef SVR4 247 tprintf(", "); 248 printtv(tcp, tcp->u_arg[1]); 249 #endif /* !SVR4 */ 250 } 251 return 0; 252 } 253 254 255 #ifdef ALPHA 256 int 257 sys_osf_gettimeofday(tcp) 258 struct tcb *tcp; 259 { 260 if (exiting(tcp)) { 261 if (syserror(tcp)) { 262 tprintf("%#lx, %#lx", tcp->u_arg[0], tcp->u_arg[1]); 263 return 0; 264 } 265 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0); 266 #ifndef SVR4 267 tprintf(", "); 268 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0); 269 #endif /* !SVR4 */ 270 } 271 return 0; 272 } 273 #endif 274 275 int 276 sys_settimeofday(tcp) 277 struct tcb *tcp; 278 { 279 if (entering(tcp)) { 280 printtv(tcp, tcp->u_arg[0]); 281 #ifndef SVR4 282 tprintf(", "); 283 printtv(tcp, tcp->u_arg[1]); 284 #endif /* !SVR4 */ 285 } 286 return 0; 287 } 288 289 #ifdef ALPHA 290 int 291 sys_osf_settimeofday(tcp) 292 struct tcb *tcp; 293 { 294 if (entering(tcp)) { 295 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0); 296 #ifndef SVR4 297 tprintf(", "); 298 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0); 299 #endif /* !SVR4 */ 300 } 301 return 0; 302 } 303 #endif 304 305 int 306 sys_adjtime(tcp) 307 struct tcb *tcp; 308 { 309 if (entering(tcp)) { 310 printtv(tcp, tcp->u_arg[0]); 311 tprintf(", "); 312 } else { 313 if (syserror(tcp)) 314 tprintf("%#lx", tcp->u_arg[1]); 315 else 316 printtv(tcp, tcp->u_arg[1]); 317 } 318 return 0; 319 } 320 321 int 322 sys_nanosleep(struct tcb *tcp) 323 { 324 if (entering(tcp)) { 325 print_timespec(tcp, tcp->u_arg[0]); 326 tprintf(", "); 327 } else { 328 if (!tcp->u_arg[1] || is_restart_error(tcp)) 329 print_timespec(tcp, tcp->u_arg[1]); 330 else 331 tprintf("%#lx", tcp->u_arg[1]); 332 } 333 return 0; 334 } 335 336 static const struct xlat which[] = { 337 { ITIMER_REAL, "ITIMER_REAL" }, 338 { ITIMER_VIRTUAL,"ITIMER_VIRTUAL"}, 339 { ITIMER_PROF, "ITIMER_PROF" }, 340 { 0, NULL }, 341 }; 342 343 static void 344 printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness) 345 { 346 if (addr == 0) 347 tprintf("NULL"); 348 else if (!verbose(tcp)) 349 tprintf("%#lx", addr); 350 else { 351 int rc; 352 353 if (bitness == BITNESS_32 354 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 355 || personality_wordsize[current_personality] == 4 356 #endif 357 ) 358 { 359 struct { 360 struct timeval32 it_interval, it_value; 361 } itv; 362 363 if ((rc = umove(tcp, addr, &itv)) >= 0) { 364 tprintf("{it_interval="); 365 tprint_timeval32(tcp, &itv.it_interval); 366 tprintf(", it_value="); 367 tprint_timeval32(tcp, &itv.it_value); 368 tprintf("}"); 369 } 370 } else { 371 struct itimerval itv; 372 373 if ((rc = umove(tcp, addr, &itv)) >= 0) { 374 tprintf("{it_interval="); 375 tprint_timeval(tcp, &itv.it_interval); 376 tprintf(", it_value="); 377 tprint_timeval(tcp, &itv.it_value); 378 tprintf("}"); 379 } 380 } 381 if (rc < 0) 382 tprintf("{...}"); 383 } 384 } 385 386 #define printitv(tcp, addr) \ 387 printitv_bitness((tcp), (addr), BITNESS_CURRENT) 388 389 int 390 sys_getitimer(tcp) 391 struct tcb *tcp; 392 { 393 if (entering(tcp)) { 394 printxval(which, tcp->u_arg[0], "ITIMER_???"); 395 tprintf(", "); 396 } else { 397 if (syserror(tcp)) 398 tprintf("%#lx", tcp->u_arg[1]); 399 else 400 printitv(tcp, tcp->u_arg[1]); 401 } 402 return 0; 403 } 404 405 406 #ifdef ALPHA 407 int 408 sys_osf_getitimer(tcp) 409 struct tcb *tcp; 410 { 411 if (entering(tcp)) { 412 printxval(which, tcp->u_arg[0], "ITIMER_???"); 413 tprintf(", "); 414 } else { 415 if (syserror(tcp)) 416 tprintf("%#lx", tcp->u_arg[1]); 417 else 418 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32); 419 } 420 return 0; 421 } 422 #endif 423 424 int 425 sys_setitimer(tcp) 426 struct tcb *tcp; 427 { 428 if (entering(tcp)) { 429 printxval(which, tcp->u_arg[0], "ITIMER_???"); 430 tprintf(", "); 431 printitv(tcp, tcp->u_arg[1]); 432 tprintf(", "); 433 } else { 434 if (syserror(tcp)) 435 tprintf("%#lx", tcp->u_arg[2]); 436 else 437 printitv(tcp, tcp->u_arg[2]); 438 } 439 return 0; 440 } 441 442 #ifdef ALPHA 443 int 444 sys_osf_setitimer(tcp) 445 struct tcb *tcp; 446 { 447 if (entering(tcp)) { 448 printxval(which, tcp->u_arg[0], "ITIMER_???"); 449 tprintf(", "); 450 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32); 451 tprintf(", "); 452 } else { 453 if (syserror(tcp)) 454 tprintf("%#lx", tcp->u_arg[2]); 455 else 456 printitv_bitness(tcp, tcp->u_arg[2], BITNESS_32); 457 } 458 return 0; 459 } 460 #endif 461 462 #ifdef LINUX 463 464 static const struct xlat adjtimex_modes[] = { 465 { 0, "0" }, 466 #ifdef ADJ_OFFSET 467 { ADJ_OFFSET, "ADJ_OFFSET" }, 468 #endif 469 #ifdef ADJ_FREQUENCY 470 { ADJ_FREQUENCY, "ADJ_FREQUENCY" }, 471 #endif 472 #ifdef ADJ_MAXERROR 473 { ADJ_MAXERROR, "ADJ_MAXERROR" }, 474 #endif 475 #ifdef ADJ_ESTERROR 476 { ADJ_ESTERROR, "ADJ_ESTERROR" }, 477 #endif 478 #ifdef ADJ_STATUS 479 { ADJ_STATUS, "ADJ_STATUS" }, 480 #endif 481 #ifdef ADJ_TIMECONST 482 { ADJ_TIMECONST, "ADJ_TIMECONST" }, 483 #endif 484 #ifdef ADJ_TICK 485 { ADJ_TICK, "ADJ_TICK" }, 486 #endif 487 #ifdef ADJ_OFFSET_SINGLESHOT 488 { ADJ_OFFSET_SINGLESHOT, "ADJ_OFFSET_SINGLESHOT" }, 489 #endif 490 { 0, NULL } 491 }; 492 493 static const struct xlat adjtimex_status[] = { 494 #ifdef STA_PLL 495 { STA_PLL, "STA_PLL" }, 496 #endif 497 #ifdef STA_PPSFREQ 498 { STA_PPSFREQ, "STA_PPSFREQ" }, 499 #endif 500 #ifdef STA_PPSTIME 501 { STA_PPSTIME, "STA_PPSTIME" }, 502 #endif 503 #ifdef STA_FLL 504 { STA_FLL, "STA_FLL" }, 505 #endif 506 #ifdef STA_INS 507 { STA_INS, "STA_INS" }, 508 #endif 509 #ifdef STA_DEL 510 { STA_DEL, "STA_DEL" }, 511 #endif 512 #ifdef STA_UNSYNC 513 { STA_UNSYNC, "STA_UNSYNC" }, 514 #endif 515 #ifdef STA_FREQHOLD 516 { STA_FREQHOLD, "STA_FREQHOLD" }, 517 #endif 518 #ifdef STA_PPSSIGNAL 519 { STA_PPSSIGNAL, "STA_PPSSIGNAL" }, 520 #endif 521 #ifdef STA_PPSJITTER 522 { STA_PPSJITTER, "STA_PPSJITTER" }, 523 #endif 524 #ifdef STA_PPSWANDER 525 { STA_PPSWANDER, "STA_PPSWANDER" }, 526 #endif 527 #ifdef STA_PPSERROR 528 { STA_PPSERROR, "STA_PPSERROR" }, 529 #endif 530 #ifdef STA_CLOCKERR 531 { STA_CLOCKERR, "STA_CLOCKERR" }, 532 #endif 533 { 0, NULL } 534 }; 535 536 static const struct xlat adjtimex_state[] = { 537 #ifdef TIME_OK 538 { TIME_OK, "TIME_OK" }, 539 #endif 540 #ifdef TIME_INS 541 { TIME_INS, "TIME_INS" }, 542 #endif 543 #ifdef TIME_DEL 544 { TIME_DEL, "TIME_DEL" }, 545 #endif 546 #ifdef TIME_OOP 547 { TIME_OOP, "TIME_OOP" }, 548 #endif 549 #ifdef TIME_WAIT 550 { TIME_WAIT, "TIME_WAIT" }, 551 #endif 552 #ifdef TIME_ERROR 553 { TIME_ERROR, "TIME_ERROR" }, 554 #endif 555 { 0, NULL } 556 }; 557 558 #if SUPPORTED_PERSONALITIES > 1 559 static int 560 tprint_timex32(struct tcb *tcp, long addr) 561 { 562 struct { 563 unsigned int modes; 564 int offset; 565 int freq; 566 int maxerror; 567 int esterror; 568 int status; 569 int constant; 570 int precision; 571 int tolerance; 572 struct timeval32 time; 573 int tick; 574 int ppsfreq; 575 int jitter; 576 int shift; 577 int stabil; 578 int jitcnt; 579 int calcnt; 580 int errcnt; 581 int stbcnt; 582 } tx; 583 584 if (umove(tcp, addr, &tx) < 0) 585 return -1; 586 587 tprintf("{modes="); 588 printflags(adjtimex_modes, tx.modes, "ADJ_???"); 589 tprintf(", offset=%d, freq=%d, maxerror=%d, ", 590 tx.offset, tx.freq, tx.maxerror); 591 tprintf("esterror=%u, status=", tx.esterror); 592 printflags(adjtimex_status, tx.status, "STA_???"); 593 tprintf(", constant=%d, precision=%u, ", 594 tx.constant, tx.precision); 595 tprintf("tolerance=%d, time=", tx.tolerance); 596 tprint_timeval32(tcp, &tx.time); 597 tprintf(", tick=%d, ppsfreq=%d, jitter=%d", 598 tx.tick, tx.ppsfreq, tx.jitter); 599 tprintf(", shift=%d, stabil=%d, jitcnt=%d", 600 tx.shift, tx.stabil, tx.jitcnt); 601 tprintf(", calcnt=%d, errcnt=%d, stbcnt=%d", 602 tx.calcnt, tx.errcnt, tx.stbcnt); 603 tprintf("}"); 604 return 0; 605 } 606 #endif /* SUPPORTED_PERSONALITIES > 1 */ 607 608 static int 609 tprint_timex(struct tcb *tcp, long addr) 610 { 611 struct timex tx; 612 613 #if SUPPORTED_PERSONALITIES > 1 614 if (personality_wordsize[current_personality] == 4) 615 return tprint_timex32(tcp, addr); 616 #endif 617 if (umove(tcp, addr, &tx) < 0) 618 return -1; 619 620 #if LINUX_VERSION_CODE < 66332 621 tprintf("{mode=%d, offset=%ld, frequency=%ld, ", 622 tx.mode, tx.offset, tx.frequency); 623 tprintf("maxerror=%ld, esterror=%lu, status=%u, ", 624 tx.maxerror, tx.esterror, tx.status); 625 tprintf("time_constant=%ld, precision=%lu, ", 626 tx.time_constant, tx.precision); 627 tprintf("tolerance=%ld, time=", tx.tolerance); 628 tprint_timeval(tcp, &tx.time); 629 #else 630 tprintf("{modes="); 631 printflags(adjtimex_modes, tx.modes, "ADJ_???"); 632 tprintf(", offset=%ld, freq=%ld, maxerror=%ld, ", 633 tx.offset, tx.freq, tx.maxerror); 634 tprintf("esterror=%lu, status=", tx.esterror); 635 printflags(adjtimex_status, tx.status, "STA_???"); 636 tprintf(", constant=%ld, precision=%lu, ", 637 tx.constant, tx.precision); 638 tprintf("tolerance=%ld, time=", tx.tolerance); 639 tprint_timeval(tcp, &tx.time); 640 tprintf(", tick=%ld, ppsfreq=%ld, jitter=%ld", 641 tx.tick, tx.ppsfreq, tx.jitter); 642 tprintf(", shift=%d, stabil=%ld, jitcnt=%ld", 643 tx.shift, tx.stabil, tx.jitcnt); 644 tprintf(", calcnt=%ld, errcnt=%ld, stbcnt=%ld", 645 tx.calcnt, tx.errcnt, tx.stbcnt); 646 #endif 647 tprintf("}"); 648 return 0; 649 } 650 651 int 652 sys_adjtimex(struct tcb *tcp) 653 { 654 if (exiting(tcp)) { 655 if (tcp->u_arg[0] == 0) 656 tprintf("NULL"); 657 else if (syserror(tcp) || !verbose(tcp)) 658 tprintf("%#lx", tcp->u_arg[0]); 659 else if (tprint_timex(tcp, tcp->u_arg[0]) < 0) 660 tprintf("{...}"); 661 if (syserror(tcp)) 662 return 0; 663 tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval); 664 if (tcp->auxstr) 665 return RVAL_STR; 666 } 667 return 0; 668 } 669 670 static const struct xlat clockflags[] = { 671 { TIMER_ABSTIME, "TIMER_ABSTIME" }, 672 { 0, NULL } 673 }; 674 675 static const struct xlat clocknames[] = { 676 #ifdef CLOCK_REALTIME 677 { CLOCK_REALTIME, "CLOCK_REALTIME" }, 678 #endif 679 #ifdef CLOCK_MONOTONIC 680 { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" }, 681 #endif 682 #ifdef CLOCK_PROCESS_CPUTIME_ID 683 { CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID" }, 684 #endif 685 #ifdef CLOCK_THREAD_CPUTIME_ID 686 { CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID" }, 687 #endif 688 #ifdef CLOCK_MONOTONIC_RAW 689 { CLOCK_MONOTONIC_RAW, "CLOCK_MONOTONIC_RAW" }, 690 #endif 691 #ifdef CLOCK_REALTIME_COARSE 692 { CLOCK_REALTIME_COARSE, "CLOCK_REALTIME_COARSE" }, 693 #endif 694 #ifdef CLOCK_MONOTONIC_COARSE 695 { CLOCK_MONOTONIC_COARSE, "CLOCK_MONOTONIC_COARSE" }, 696 #endif 697 { 0, NULL } 698 }; 699 700 int 701 sys_clock_settime(tcp) 702 struct tcb *tcp; 703 { 704 if (entering(tcp)) { 705 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 706 tprintf(", "); 707 printtv(tcp, tcp->u_arg[1]); 708 } 709 return 0; 710 } 711 712 int 713 sys_clock_gettime(tcp) 714 struct tcb *tcp; 715 { 716 if (entering(tcp)) { 717 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 718 tprintf(", "); 719 } else { 720 if (syserror(tcp)) 721 tprintf("%#lx", tcp->u_arg[1]); 722 else 723 printtv(tcp, tcp->u_arg[1]); 724 } 725 return 0; 726 } 727 728 int 729 sys_clock_nanosleep(tcp) 730 struct tcb *tcp; 731 { 732 if (entering(tcp)) { 733 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 734 tprintf(", "); 735 printflags(clockflags, tcp->u_arg[1], "TIMER_???"); 736 tprintf(", "); 737 printtv(tcp, tcp->u_arg[2]); 738 tprintf(", "); 739 } else { 740 if (syserror(tcp)) 741 tprintf("%#lx", tcp->u_arg[3]); 742 else 743 printtv(tcp, tcp->u_arg[3]); 744 } 745 return 0; 746 } 747 748 #ifndef SIGEV_THREAD_ID 749 # define SIGEV_THREAD_ID 4 750 #endif 751 static const struct xlat sigev_value[] = { 752 { SIGEV_SIGNAL+1, "SIGEV_SIGNAL" }, 753 { SIGEV_NONE+1, "SIGEV_NONE" }, 754 { SIGEV_THREAD+1, "SIGEV_THREAD" }, 755 { SIGEV_THREAD_ID+1, "SIGEV_THREAD_ID" }, 756 { 0, NULL } 757 }; 758 759 #if SUPPORTED_PERSONALITIES > 1 760 static void 761 printsigevent32(struct tcb *tcp, long arg) 762 { 763 struct { 764 int sigev_value; 765 int sigev_signo; 766 int sigev_notify; 767 768 union { 769 int tid; 770 struct { 771 int function, attribute; 772 } thread; 773 } un; 774 } sev; 775 776 if (umove(tcp, arg, &sev) < 0) 777 tprintf("{...}"); 778 else { 779 tprintf("{%#x, ", sev.sigev_value); 780 if (sev.sigev_notify == SIGEV_SIGNAL) 781 tprintf("%s, ", signame(sev.sigev_signo)); 782 else 783 tprintf("%u, ", sev.sigev_signo); 784 printxval(sigev_value, sev.sigev_notify + 1, "SIGEV_???"); 785 tprintf(", "); 786 if (sev.sigev_notify == SIGEV_THREAD_ID) 787 tprintf("{%d}", sev.un.tid); 788 else if (sev.sigev_notify == SIGEV_THREAD) 789 tprintf("{%#x, %#x}", 790 sev.un.thread.function, 791 sev.un.thread.attribute); 792 else 793 tprintf("{...}"); 794 tprintf("}"); 795 } 796 } 797 #endif 798 799 void 800 printsigevent(struct tcb *tcp, long arg) 801 { 802 struct sigevent sev; 803 804 #if SUPPORTED_PERSONALITIES > 1 805 if (personality_wordsize[current_personality] == 4) 806 { 807 printsigevent32(tcp, arg); 808 return; 809 } 810 #endif 811 if (umove (tcp, arg, &sev) < 0) 812 tprintf("{...}"); 813 else { 814 tprintf("{%p, ", sev.sigev_value.sival_ptr); 815 if (sev.sigev_notify == SIGEV_SIGNAL) 816 tprintf("%s, ", signame(sev.sigev_signo)); 817 else 818 tprintf("%u, ", sev.sigev_signo); 819 printxval(sigev_value, sev.sigev_notify+1, "SIGEV_???"); 820 tprintf(", "); 821 if (sev.sigev_notify == SIGEV_THREAD_ID) 822 /* _pad[0] is the _tid field which might not be 823 present in the userlevel definition of the 824 struct. */ 825 tprintf("{%d}", sev._sigev_un._pad[0]); 826 else if (sev.sigev_notify == SIGEV_THREAD) 827 tprintf("{%p, %p}", sev.sigev_notify_function, 828 sev.sigev_notify_attributes); 829 else 830 tprintf("{...}"); 831 tprintf("}"); 832 } 833 } 834 835 int 836 sys_timer_create(tcp) 837 struct tcb *tcp; 838 { 839 if (entering(tcp)) { 840 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 841 tprintf(", "); 842 printsigevent(tcp, tcp->u_arg[1]); 843 tprintf(", "); 844 } else { 845 void *p; 846 847 if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &p) < 0) 848 tprintf("%#lx", tcp->u_arg[2]); 849 else 850 tprintf("{%p}", p); 851 } 852 return 0; 853 } 854 855 int 856 sys_timer_settime(tcp) 857 struct tcb *tcp; 858 { 859 if (entering(tcp)) { 860 tprintf("%#lx, ", tcp->u_arg[0]); 861 printflags(clockflags, tcp->u_arg[1], "TIMER_???"); 862 tprintf(", "); 863 printitv(tcp, tcp->u_arg[2]); 864 tprintf(", "); 865 } else { 866 if (syserror(tcp)) 867 tprintf("%#lx", tcp->u_arg[3]); 868 else 869 printitv(tcp, tcp->u_arg[3]); 870 } 871 return 0; 872 } 873 874 int 875 sys_timer_gettime(tcp) 876 struct tcb *tcp; 877 { 878 if (entering(tcp)) { 879 tprintf("%#lx, ", tcp->u_arg[0]); 880 } else { 881 if (syserror(tcp)) 882 tprintf("%#lx", tcp->u_arg[1]); 883 else 884 printitv(tcp, tcp->u_arg[1]); 885 } 886 return 0; 887 } 888 889 static void 890 print_rtc(tcp, rt) 891 struct tcb *tcp; 892 const struct rtc_time *rt; 893 { 894 tprintf("{tm_sec=%d, tm_min=%d, tm_hour=%d, " 895 "tm_mday=%d, tm_mon=%d, tm_year=%d, ", 896 rt->tm_sec, rt->tm_min, rt->tm_hour, 897 rt->tm_mday, rt->tm_mon, rt->tm_year); 898 if (!abbrev(tcp)) 899 tprintf("tm_wday=%d, tm_yday=%d, tm_isdst=%d}", 900 rt->tm_wday, rt->tm_yday, rt->tm_isdst); 901 else 902 tprintf("...}"); 903 } 904 905 int 906 rtc_ioctl(tcp, code, arg) 907 struct tcb *tcp; 908 long code; 909 long arg; 910 { 911 switch (code) { 912 case RTC_ALM_SET: 913 case RTC_SET_TIME: 914 if (entering(tcp)) { 915 struct rtc_time rt; 916 if (umove(tcp, arg, &rt) < 0) 917 tprintf(", %#lx", arg); 918 else { 919 tprintf(", "); 920 print_rtc(tcp, &rt); 921 } 922 } 923 break; 924 case RTC_ALM_READ: 925 case RTC_RD_TIME: 926 if (exiting(tcp)) { 927 struct rtc_time rt; 928 if (syserror(tcp) || umove(tcp, arg, &rt) < 0) 929 tprintf(", %#lx", arg); 930 else { 931 tprintf(", "); 932 print_rtc(tcp, &rt); 933 } 934 } 935 break; 936 case RTC_IRQP_SET: 937 case RTC_EPOCH_SET: 938 if (entering(tcp)) 939 tprintf(", %lu", arg); 940 break; 941 case RTC_IRQP_READ: 942 case RTC_EPOCH_READ: 943 if (exiting(tcp)) 944 tprintf(", %lu", arg); 945 break; 946 case RTC_WKALM_SET: 947 if (entering(tcp)) { 948 struct rtc_wkalrm wk; 949 if (umove(tcp, arg, &wk) < 0) 950 tprintf(", %#lx", arg); 951 else { 952 tprintf(", {enabled=%d, pending=%d, ", 953 wk.enabled, wk.pending); 954 print_rtc(tcp, &wk.time); 955 tprintf("}"); 956 } 957 } 958 break; 959 case RTC_WKALM_RD: 960 if (exiting(tcp)) { 961 struct rtc_wkalrm wk; 962 if (syserror(tcp) || umove(tcp, arg, &wk) < 0) 963 tprintf(", %#lx", arg); 964 else { 965 tprintf(", {enabled=%d, pending=%d, ", 966 wk.enabled, wk.pending); 967 print_rtc(tcp, &wk.time); 968 tprintf("}"); 969 } 970 } 971 break; 972 default: 973 if (entering(tcp)) 974 tprintf(", %#lx", arg); 975 break; 976 } 977 return 1; 978 } 979 980 #ifndef TFD_TIMER_ABSTIME 981 #define TFD_TIMER_ABSTIME (1 << 0) 982 #endif 983 984 static const struct xlat timerfdflags[] = { 985 { TFD_TIMER_ABSTIME, "TFD_TIMER_ABSTIME" }, 986 { 0, NULL } 987 }; 988 989 int 990 sys_timerfd(tcp) 991 struct tcb *tcp; 992 { 993 if (entering(tcp)) { 994 /* It does not matter that the kernel uses itimerspec. */ 995 tprintf("%ld, ", tcp->u_arg[0]); 996 printxval(clocknames, tcp->u_arg[1], "CLOCK_???"); 997 tprintf(", "); 998 printflags(timerfdflags, tcp->u_arg[2], "TFD_???"); 999 tprintf(", "); 1000 printitv(tcp, tcp->u_arg[3]); 1001 } 1002 return 0; 1003 } 1004 1005 int 1006 sys_timerfd_create(struct tcb *tcp) 1007 { 1008 if (entering(tcp)) { 1009 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 1010 tprintf(", "); 1011 printflags(timerfdflags, tcp->u_arg[1], "TFD_???"); 1012 } 1013 return 0; 1014 } 1015 1016 int 1017 sys_timerfd_settime(struct tcb *tcp) 1018 { 1019 if (entering(tcp)) { 1020 printfd(tcp, tcp->u_arg[0]); 1021 tprintf(", "); 1022 printflags(timerfdflags, tcp->u_arg[1], "TFD_???"); 1023 tprintf(", "); 1024 printitv(tcp, tcp->u_arg[2]); 1025 tprintf(", "); 1026 printitv(tcp, tcp->u_arg[3]); 1027 } 1028 return 0; 1029 } 1030 1031 int 1032 sys_timerfd_gettime(struct tcb *tcp) 1033 { 1034 if (entering(tcp)) { 1035 printfd(tcp, tcp->u_arg[0]); 1036 tprintf(", "); 1037 printitv(tcp, tcp->u_arg[1]); 1038 } 1039 return 0; 1040 } 1041 1042 #endif /* LINUX */ 1043