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