• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@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
tprint_timeval32(struct tcb * tcp,const struct timeval32 * tv)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
tprint_timeval(struct tcb * tcp,const struct timeval * tv)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
printtv_bitness(struct tcb * tcp,long addr,enum bitness_t bitness,int special)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
sprinttv(struct tcb * tcp,long addr,enum bitness_t bitness,char * buf)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 
print_timespec(struct tcb * tcp,long addr)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 
sprint_timespec(char * buf,struct tcb * tcp,long addr)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
sys_time(tcp)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
sys_stime(tcp)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
sys_gettimeofday(tcp)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
sys_osf_gettimeofday(tcp)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
sys_settimeofday(tcp)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
sys_osf_settimeofday(tcp)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
sys_adjtime(tcp)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
sys_nanosleep(struct tcb * tcp)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
printitv_bitness(struct tcb * tcp,long addr,enum bitness_t bitness)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
sys_getitimer(tcp)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
sys_osf_getitimer(tcp)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
sys_setitimer(tcp)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
sys_osf_setitimer(tcp)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
tprint_timex32(struct tcb * tcp,long addr)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
tprint_timex(struct tcb * tcp,long addr)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
sys_adjtimex(struct tcb * tcp)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
sys_clock_settime(tcp)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
sys_clock_gettime(tcp)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
sys_clock_nanosleep(tcp)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
printsigevent32(struct tcb * tcp,long arg)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
printsigevent(struct tcb * tcp,long arg)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
sys_timer_create(tcp)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
sys_timer_settime(tcp)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
sys_timer_gettime(tcp)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
print_rtc(tcp,rt)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
rtc_ioctl(tcp,code,arg)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
sys_timerfd(tcp)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
sys_timerfd_create(struct tcb * tcp)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
sys_timerfd_settime(struct tcb * tcp)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
sys_timerfd_gettime(struct tcb * tcp)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