]> granicus.if.org Git - strace/commitdiff
Implement printers for kernel_timespec32_t
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 9 May 2019 22:03:30 +0000 (22:03 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 9 May 2019 22:03:30 +0000 (22:03 +0000)
They are going to be used to re-implement parsers of syscalls that deal
with 32-bit timespec.

* defs.h (print_timespec32_data_size, print_timespec32_array_data_size,
print_timespec32, sprint_timespec32, print_timespec32_utime_pair,
print_itimerspec32): New prototypes.
* print_timespec.h: New file based on print_timespec.c.
* print_timespec32.c: New file.
* Makefile.am (strace_SOURCES): Add them.

Makefile.am
defs.h
print_timespec.h [new file with mode: 0644]
print_timespec32.c [new file with mode: 0644]

index 048e1229eb09c0ad8c16f63ef7e9dba76625cb08..3177b8241de78f5d22622b3cf21e26f29b7d179e 100644 (file)
@@ -243,6 +243,8 @@ strace_SOURCES =    \
        print_struct_stat.c \
        print_time.c    \
        print_timespec.c \
+       print_timespec.h \
+       print_timespec32.c \
        print_timeval.c \
        print_timex.c   \
        print_utils.h   \
diff --git a/defs.h b/defs.h
index 1a139f929973350286e63f127d9732b6f4a13e9a..b723cb88ba4b406894ccc47ce6368202521dd02d 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -1109,6 +1109,17 @@ tprint_iov(struct tcb *tcp, kernel_ulong_t len, kernel_ulong_t addr,
        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;
diff --git a/print_timespec.h b/print_timespec.h
new file mode 100644 (file)
index 0000000..aed0943
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * 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;
+}
diff --git a/print_timespec32.c b/print_timespec32.c
new file mode 100644 (file)
index 0000000..f6a16bc
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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 */