tprint_iov_upto(tcp, len, addr, decode_iov, -1);
}
+# if HAVE_ARCH_TIME32_SYSCALLS
+extern bool print_timespec32_data_size(const void *arg, size_t size);
+extern bool print_timespec32_array_data_size(const void *arg,
+ unsigned int nmemb,
+ size_t size);
+extern int print_timespec32(struct tcb *, kernel_ulong_t);
+extern const char *sprint_timespec32(struct tcb *, kernel_ulong_t);
+extern int print_timespec32_utime_pair(struct tcb *, kernel_ulong_t);
+extern int print_itimerspec32(struct tcb *, kernel_ulong_t);
+# endif /* HAVE_ARCH_TIME32_SYSCALLS */
+
# ifdef ALPHA
typedef struct {
int tv_sec, tv_usec;
--- /dev/null
+/*
+ * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2016-2019 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "xstring.h"
+
+#ifndef UTIME_NOW
+# define UTIME_NOW ((1l << 30) - 1l)
+#endif
+#ifndef UTIME_OMIT
+# define UTIME_OMIT ((1l << 30) - 2l)
+#endif
+
+#define TIMESPEC_TO_SEC_NSEC(t_) \
+ ((long long) (t_)->tv_sec), zero_extend_signed_to_ull((t_)->tv_nsec)
+
+static const char timespec_fmt[] = "{tv_sec=%lld, tv_nsec=%llu}";
+
+static void
+print_sec_nsec(long long sec, unsigned long long nsec)
+{
+ tprintf(timespec_fmt, sec, nsec);
+}
+
+static void
+print_timespec_t(const TIMESPEC_T *t)
+{
+ print_sec_nsec(TIMESPEC_TO_SEC_NSEC(t));
+}
+
+static void
+print_timespec_t_utime(const TIMESPEC_T *t)
+{
+ switch (t->tv_nsec) {
+ case UTIME_NOW:
+ case UTIME_OMIT:
+ if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
+ print_timespec_t(t);
+ if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
+ break;
+
+ (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE
+ ? tprints_comment : tprints)(t->tv_nsec == UTIME_NOW
+ ? "UTIME_NOW" : "UTIME_OMIT");
+ break;
+ default:
+ print_timespec_t(t);
+ tprints_comment(sprinttime_nsec(TIMESPEC_TO_SEC_NSEC(t)));
+ break;
+ }
+}
+
+bool
+PRINT_TIMESPEC_DATA_SIZE(const void *arg, const size_t size)
+{
+ if (size < sizeof(TIMESPEC_T)) {
+ tprints("?");
+ return false;
+ }
+
+ print_timespec_t(arg);
+ return true;
+}
+
+bool
+PRINT_TIMESPEC_ARRAY_DATA_SIZE(const void *arg, const unsigned int nmemb,
+ const size_t size)
+{
+ const TIMESPEC_T *ts = arg;
+ unsigned int i;
+
+ if (nmemb > size / sizeof(TIMESPEC_T)) {
+ tprints("?");
+ return false;
+ }
+
+ tprints("[");
+
+ for (i = 0; i < nmemb; i++) {
+ if (i)
+ tprints(", ");
+ print_timespec_t(&ts[i]);
+ }
+
+ tprints("]");
+ return true;
+}
+
+int
+PRINT_TIMESPEC(struct tcb *const tcp, const kernel_ulong_t addr)
+{
+ TIMESPEC_T t;
+
+ if (umove_or_printaddr(tcp, addr, &t))
+ return -1;
+
+ print_timespec_t(&t);
+ return 0;
+}
+
+const char *
+SPRINT_TIMESPEC(struct tcb *const tcp, const kernel_ulong_t addr)
+{
+ TIMESPEC_T t;
+ static char buf[sizeof(timespec_fmt) + 3 * sizeof(t)];
+
+ if (!addr) {
+ strcpy(buf, "NULL");
+ } else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
+ umove(tcp, addr, &t)) {
+ xsprintf(buf, "%#" PRI_klx, addr);
+ } else {
+ xsprintf(buf, timespec_fmt, TIMESPEC_TO_SEC_NSEC(&t));
+ }
+
+ return buf;
+}
+
+int
+PRINT_TIMESPEC_UTIME_PAIR(struct tcb *const tcp, const kernel_ulong_t addr)
+{
+ TIMESPEC_T t[2];
+
+ if (umove_or_printaddr(tcp, addr, &t))
+ return -1;
+
+ tprints("[");
+ print_timespec_t_utime(&t[0]);
+ tprints(", ");
+ print_timespec_t_utime(&t[1]);
+ tprints("]");
+ return 0;
+}
+
+int
+PRINT_ITIMERSPEC(struct tcb *const tcp, const kernel_ulong_t addr)
+{
+ TIMESPEC_T t[2];
+
+ if (umove_or_printaddr(tcp, addr, &t))
+ return -1;
+
+ tprints("{it_interval=");
+ print_timespec_t(&t[0]);
+ tprints(", it_value=");
+ print_timespec_t(&t[1]);
+ tprints("}");
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+
+#if HAVE_ARCH_TIME32_SYSCALLS
+
+# define TIMESPEC_T kernel_timespec32_t
+# define PRINT_TIMESPEC_DATA_SIZE print_timespec32_data_size
+# define PRINT_TIMESPEC_ARRAY_DATA_SIZE print_timespec32_array_data_size
+# define PRINT_TIMESPEC print_timespec32
+# define SPRINT_TIMESPEC sprint_timespec32
+# define PRINT_TIMESPEC_UTIME_PAIR print_timespec32_utime_pair
+# define PRINT_ITIMERSPEC print_itimerspec32
+
+# include "kernel_timespec.h"
+# include "print_timespec.h"
+
+#endif /* HAVE_ARCH_TIME32_SYSCALLS */