Home | History | Annotate | Download | only in strace
      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