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>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
33 #include <linux/version.h>
34 #include <sys/timex.h>
37 #define UTIME_NOW ((1l << 30) - 1l)
40 #define UTIME_OMIT ((1l << 30) - 2l)
43 #if SUPPORTED_PERSONALITIES > 1
44 # if defined X86_64 || defined X32
45 # define current_time_t_is_compat (current_personality == 1)
47 # define current_time_t_is_compat (current_wordsize == 4)
49 # define current_time_t_is_int32 current_time_t_is_compat
51 # define current_time_t_is_compat 0
52 # define current_time_t_is_int32 (sizeof(time_t) == 4)
57 u_int32_t tv_sec, tv_usec;
61 tprint_timeval32(struct tcb *tcp, const struct timeval32 *tv)
63 tprintf("{%u, %u}", tv->tv_sec, tv->tv_usec);
67 tprint_timeval(struct tcb *tcp, const struct timeval *tv)
69 tprintf("{%ju, %ju}", (uintmax_t) tv->tv_sec, (uintmax_t) tv->tv_usec);
73 printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special)
75 char buf[TIMEVAL_TEXT_BUFSIZE];
76 sprinttv(buf, tcp, addr, bitness, special);
81 do_sprinttv(char *buf, const uintmax_t sec, const uintmax_t usec,
87 return stpcpy(buf, "UTIME_NOW");
89 return stpcpy(buf, "UTIME_OMIT");
92 return buf + sprintf(buf, "{%ju, %ju}", sec, usec);
96 sprinttv(char *buf, struct tcb *tcp, long addr, enum bitness_t bitness, int special)
99 return stpcpy(buf, "NULL");
101 if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)))
102 return buf + sprintf(buf, "%#lx", addr);
104 if (bitness == BITNESS_32 || current_time_t_is_compat)
108 if (umove(tcp, addr, &tv) >= 0)
109 return do_sprinttv(buf, tv.tv_sec, tv.tv_usec, special);
113 if (umove(tcp, addr, &tv) >= 0)
114 return do_sprinttv(buf, tv.tv_sec, tv.tv_usec, special);
117 return buf + sprintf(buf, "%#lx", addr);
121 print_timespec(struct tcb *tcp, long addr)
123 char buf[TIMESPEC_TEXT_BUFSIZE];
124 sprint_timespec(buf, tcp, addr);
129 sprint_timespec(char *buf, struct tcb *tcp, long addr)
133 else if (!verbose(tcp))
134 sprintf(buf, "%#lx", addr);
138 #if SUPPORTED_PERSONALITIES > 1
139 if (current_time_t_is_compat) {
142 rc = umove(tcp, addr, &tv);
144 sprintf(buf, "{%u, %u}",
145 tv.tv_sec, tv.tv_usec);
151 rc = umove(tcp, addr, &ts);
153 sprintf(buf, "{%ju, %ju}",
154 (uintmax_t) ts.tv_sec,
155 (uintmax_t) ts.tv_nsec);
158 strcpy(buf, "{...}");
165 if (current_time_t_is_int32)
166 printnum_int(tcp, tcp->u_arg[0], "%d");
168 printnum_int64(tcp, tcp->u_arg[0], "%" PRId64);
173 SYS_FUNC(gettimeofday)
176 printtv(tcp, tcp->u_arg[0]);
178 printtv(tcp, tcp->u_arg[1]);
184 SYS_FUNC(osf_gettimeofday)
187 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
189 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
195 SYS_FUNC(settimeofday)
197 printtv(tcp, tcp->u_arg[0]);
199 printtv(tcp, tcp->u_arg[1]);
205 SYS_FUNC(osf_settimeofday)
207 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
209 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
218 printtv(tcp, tcp->u_arg[0]);
221 printtv(tcp, tcp->u_arg[1]);
229 print_timespec(tcp, tcp->u_arg[0]);
232 /* Second (returned) timespec is only significant
233 * if syscall was interrupted. On success, we print
234 * only its address, since kernel doesn't modify it,
235 * and printing the value may show uninitialized data.
237 switch (tcp->u_error) {
239 /* Not interrupted (slept entire interval) */
240 printaddr(tcp->u_arg[1]);
245 case ERESTART_RESTARTBLOCK:
247 print_timespec(tcp, tcp->u_arg[1]);
253 #include "xlat/itimer_which.h"
256 printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness)
258 if (bitness == BITNESS_32 || current_time_t_is_compat) {
260 struct timeval32 it_interval, it_value;
263 if (!umove_or_printaddr(tcp, addr, &itv)) {
264 tprints("{it_interval=");
265 tprint_timeval32(tcp, &itv.it_interval);
266 tprints(", it_value=");
267 tprint_timeval32(tcp, &itv.it_value);
271 struct itimerval itv;
273 if (!umove_or_printaddr(tcp, addr, &itv)) {
274 tprints("{it_interval=");
275 tprint_timeval(tcp, &itv.it_interval);
276 tprints(", it_value=");
277 tprint_timeval(tcp, &itv.it_value);
283 #define printitv(tcp, addr) \
284 printitv_bitness((tcp), (addr), BITNESS_CURRENT)
289 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
292 printitv(tcp, tcp->u_arg[1]);
298 SYS_FUNC(osf_getitimer)
301 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
304 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
313 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
315 printitv(tcp, tcp->u_arg[1]);
318 printitv(tcp, tcp->u_arg[2]);
324 SYS_FUNC(osf_setitimer)
327 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
329 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
332 printitv_bitness(tcp, tcp->u_arg[2], BITNESS_32);
338 #include "xlat/adjtimex_modes.h"
339 #include "xlat/adjtimex_status.h"
340 #include "xlat/adjtimex_state.h"
342 #if SUPPORTED_PERSONALITIES > 1
344 tprint_timex32(struct tcb *tcp, long addr)
356 struct timeval32 time;
368 if (umove_or_printaddr(tcp, addr, &tx))
372 printflags(adjtimex_modes, tx.modes, "ADJ_???");
373 tprintf(", offset=%d, freq=%d, maxerror=%d, ",
374 tx.offset, tx.freq, tx.maxerror);
375 tprintf("esterror=%u, status=", tx.esterror);
376 printflags(adjtimex_status, tx.status, "STA_???");
377 tprintf(", constant=%d, precision=%u, ",
378 tx.constant, tx.precision);
379 tprintf("tolerance=%d, time=", tx.tolerance);
380 tprint_timeval32(tcp, &tx.time);
381 tprintf(", tick=%d, ppsfreq=%d, jitter=%d",
382 tx.tick, tx.ppsfreq, tx.jitter);
383 tprintf(", shift=%d, stabil=%d, jitcnt=%d",
384 tx.shift, tx.stabil, tx.jitcnt);
385 tprintf(", calcnt=%d, errcnt=%d, stbcnt=%d",
386 tx.calcnt, tx.errcnt, tx.stbcnt);
390 #endif /* SUPPORTED_PERSONALITIES > 1 */
393 tprint_timex(struct tcb *tcp, long addr)
397 #if SUPPORTED_PERSONALITIES > 1
398 if (current_time_t_is_compat)
399 return tprint_timex32(tcp, addr);
401 if (umove_or_printaddr(tcp, addr, &tx))
405 printflags(adjtimex_modes, tx.modes, "ADJ_???");
406 tprintf(", offset=%jd, freq=%jd, maxerror=%ju, esterror=%ju, status=",
407 (intmax_t) tx.offset, (intmax_t) tx.freq,
408 (uintmax_t) tx.maxerror, (uintmax_t) tx.esterror);
409 printflags(adjtimex_status, tx.status, "STA_???");
410 tprintf(", constant=%jd, precision=%ju, tolerance=%jd, time=",
411 (intmax_t) tx.constant, (uintmax_t) tx.precision,
412 (intmax_t) tx.tolerance);
413 tprint_timeval(tcp, &tx.time);
414 tprintf(", tick=%jd, ppsfreq=%jd, jitter=%jd",
415 (intmax_t) tx.tick, (intmax_t) tx.ppsfreq, (intmax_t) tx.jitter);
416 tprintf(", shift=%d, stabil=%jd, jitcnt=%jd",
417 tx.shift, (intmax_t) tx.stabil, (intmax_t) tx.jitcnt);
418 tprintf(", calcnt=%jd, errcnt=%jd, stbcnt=%jd",
419 (intmax_t) tx.calcnt, (intmax_t) tx.errcnt, (intmax_t) tx.stbcnt);
425 do_adjtimex(struct tcb *tcp, long addr)
427 if (tprint_timex(tcp, addr))
429 tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
438 return do_adjtimex(tcp, tcp->u_arg[0]);
442 #include "xlat/clockflags.h"
443 #include "xlat/clocknames.h"
446 printclockname(int clockid)
449 # include "xlat/cpuclocknames.h"
452 if ((clockid & CLOCKFD_MASK) == CLOCKFD)
453 tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
455 if(CPUCLOCK_PERTHREAD(clockid))
456 tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
458 tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
459 printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???");
465 printxval(clocknames, clockid, "CLOCK_???");
468 SYS_FUNC(clock_settime)
470 printclockname(tcp->u_arg[0]);
472 printtv(tcp, tcp->u_arg[1]);
477 SYS_FUNC(clock_gettime)
480 printclockname(tcp->u_arg[0]);
483 printtv(tcp, tcp->u_arg[1]);
488 SYS_FUNC(clock_nanosleep)
491 printclockname(tcp->u_arg[0]);
493 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
495 printtv(tcp, tcp->u_arg[2]);
498 printtv(tcp, tcp->u_arg[3]);
503 SYS_FUNC(clock_adjtime)
506 return do_adjtimex(tcp, tcp->u_arg[1]);
507 printclockname(tcp->u_arg[0]);
512 #include "xlat/sigev_value.h"
514 #if SUPPORTED_PERSONALITIES > 1
516 printsigevent32(struct tcb *tcp, long arg)
526 int function, attribute;
531 if (!umove_or_printaddr(tcp, arg, &sev)) {
532 tprintf("{%#x, ", sev.sigev_value);
533 if (sev.sigev_notify == SIGEV_SIGNAL)
534 tprintf("%s, ", signame(sev.sigev_signo));
536 tprintf("%u, ", sev.sigev_signo);
537 printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
539 if (sev.sigev_notify == SIGEV_THREAD_ID)
540 tprintf("{%d}", sev.un.tid);
541 else if (sev.sigev_notify == SIGEV_THREAD)
542 tprintf("{%#x, %#x}",
543 sev.un.thread.function,
544 sev.un.thread.attribute);
553 printsigevent(struct tcb *tcp, long arg)
557 #if SUPPORTED_PERSONALITIES > 1
558 if (current_wordsize == 4) {
559 printsigevent32(tcp, arg);
563 if (!umove_or_printaddr(tcp, arg, &sev)) {
564 tprintf("{%p, ", sev.sigev_value.sival_ptr);
565 if (sev.sigev_notify == SIGEV_SIGNAL)
566 tprintf("%s, ", signame(sev.sigev_signo));
568 tprintf("%u, ", sev.sigev_signo);
569 printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
571 if (sev.sigev_notify == SIGEV_THREAD_ID)
572 #if defined(HAVE_STRUCT_SIGEVENT__SIGEV_UN__PAD)
573 /* _pad[0] is the _tid field which might not be
574 present in the userlevel definition of the
576 tprintf("{%d}", sev._sigev_un._pad[0]);
577 #elif defined(HAVE_STRUCT_SIGEVENT___PAD)
578 tprintf("{%d}", sev.__pad[0]);
580 # warning unfamiliar struct sigevent => incomplete SIGEV_THREAD_ID decoding
583 else if (sev.sigev_notify == SIGEV_THREAD)
584 tprintf("{%p, %p}", sev.sigev_notify_function,
585 sev.sigev_notify_attributes);
592 SYS_FUNC(timer_create)
595 printclockname(tcp->u_arg[0]);
597 printsigevent(tcp, tcp->u_arg[1]);
600 printnum_int(tcp, tcp->u_arg[2], "%d");
605 SYS_FUNC(timer_settime)
608 tprintf("%d, ", (int) tcp->u_arg[0]);
609 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
611 printitv(tcp, tcp->u_arg[2]);
614 printitv(tcp, tcp->u_arg[3]);
619 SYS_FUNC(timer_gettime)
622 tprintf("%d, ", (int) tcp->u_arg[0]);
624 printitv(tcp, tcp->u_arg[1]);
629 #include "xlat/timerfdflags.h"
633 /* It does not matter that the kernel uses itimerspec. */
634 tprintf("%ld, ", tcp->u_arg[0]);
635 printclockname(tcp->u_arg[0]);
637 printflags(timerfdflags, tcp->u_arg[2], "TFD_???");
639 printitv(tcp, tcp->u_arg[3]);
641 return RVAL_DECODED | RVAL_FD;
644 SYS_FUNC(timerfd_create)
646 printclockname(tcp->u_arg[0]);
648 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
650 return RVAL_DECODED | RVAL_FD;
653 SYS_FUNC(timerfd_settime)
655 printfd(tcp, tcp->u_arg[0]);
657 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
659 printitv(tcp, tcp->u_arg[2]);
661 printitv(tcp, tcp->u_arg[3]);
666 SYS_FUNC(timerfd_gettime)
669 printfd(tcp, tcp->u_arg[0]);
672 printitv(tcp, tcp->u_arg[1]);