1 /*
2 * This file is part of clock_xettime* strace tests.
3 *
4 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2015-2020 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include <stdio.h>
12 #include <time.h>
13 #include <unistd.h>
14 #include "kernel_timespec.h"
15
16 static const char *errstr;
17
18 static long
19 k_syscall(const unsigned int scno, const unsigned int id, void *const ts)
20 {
21 static const kernel_ulong_t bad =
22 (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
23 static const kernel_ulong_t fill =
24 (kernel_ulong_t) 0xdefaced00000000ULL;
25 const kernel_ulong_t arg1 = id | fill;
26 const kernel_ulong_t arg2 = f8ill_ptr_to_kulong(ts);
27 const long rc = syscall(scno, arg1, arg2, bad, bad, bad, bad);
28 errstr = sprintrc(rc);
29 return rc;
30 }
31
32 static long
33 k_getres(const unsigned int id, void *const ts)
34 {
35 return k_syscall(SYSCALL_NR_getres, id, ts);
36 }
37
38 static long
39 k_gettime(const unsigned int id, void *const ts)
40 {
41 return k_syscall(SYSCALL_NR_gettime, id, ts);
42 }
43
44 static long
45 k_settime(const unsigned int id, void *const ts)
46 {
47 return k_syscall(SYSCALL_NR_settime, id, ts);
48 }
49
50 int
51 main(void)
52 {
53 TAIL_ALLOC_OBJECT_CONST_PTR(clock_timespec_t, ts);
54 void *const efault = (void *) (1 + (char *) ts);
55
56 k_getres(CLOCK_MONOTONIC, NULL);
57 printf("%s(CLOCK_MONOTONIC, NULL) = %s\n", SYSCALL_NAME_getres, errstr);
58
59 k_getres(CLOCK_REALTIME, efault);
60 printf("%s(CLOCK_REALTIME, %p) = %s\n",
61 SYSCALL_NAME_getres, efault, errstr);
62
63 k_gettime(CLOCK_MONOTONIC, NULL);
64 printf("%s(CLOCK_MONOTONIC, NULL) = %s\n", SYSCALL_NAME_gettime, errstr);
65
66 k_gettime(CLOCK_REALTIME, efault);
67 printf("%s(CLOCK_REALTIME, %p) = %s\n",
68 SYSCALL_NAME_gettime, efault, errstr);
69
70 k_settime(CLOCK_MONOTONIC, NULL);
71 printf("%s(CLOCK_MONOTONIC, NULL) = %s\n", SYSCALL_NAME_settime, errstr);
72
73 k_settime(CLOCK_REALTIME, efault);
74 printf("%s(CLOCK_REALTIME, %p) = %s\n",
75 SYSCALL_NAME_settime, efault, errstr);
76
77 if (k_getres(CLOCK_MONOTONIC, ts))
78 perror_msg_and_skip("clock_getres CLOCK_MONOTONIC");
79 printf("%s(CLOCK_MONOTONIC, {tv_sec=%lld, tv_nsec=%llu}) = 0\n",
80 SYSCALL_NAME_getres, (long long) ts->tv_sec,
81 zero_extend_signed_to_ull(ts->tv_nsec));
82
83 if (k_gettime(CLOCK_PROCESS_CPUTIME_ID, ts))
84 perror_msg_and_skip("clock_gettime CLOCK_PROCESS_CPUTIME_ID");
85 printf("%s(CLOCK_PROCESS_CPUTIME_ID, {tv_sec=%lld, tv_nsec=%llu})"
86 " = 0\n",
87 SYSCALL_NAME_gettime, (long long) ts->tv_sec,
88 zero_extend_signed_to_ull(ts->tv_nsec));
89
90 ts->tv_sec = 0xdeface1;
91 ts->tv_nsec = 0xdeface2;
92 k_settime(CLOCK_THREAD_CPUTIME_ID, ts);
93 printf("%s(CLOCK_THREAD_CPUTIME_ID, {tv_sec=%lld, tv_nsec=%llu})"
94 " = %s\n",
95 SYSCALL_NAME_settime, (long long) ts->tv_sec,
96 zero_extend_signed_to_ull(ts->tv_nsec), errstr);
97
98 ts->tv_sec = 0xdeadbeefU;
99 ts->tv_nsec = 0xfacefeedU;
100 k_settime(CLOCK_THREAD_CPUTIME_ID, ts);
101 printf("%s(CLOCK_THREAD_CPUTIME_ID, {tv_sec=%lld, tv_nsec=%llu})"
102 " = %s\n",
103 SYSCALL_NAME_settime, (long long) ts->tv_sec,
104 zero_extend_signed_to_ull(ts->tv_nsec), errstr);
105
106 ts->tv_sec = (typeof(ts->tv_sec)) 0xcafef00ddeadbeefLL;
107 ts->tv_nsec = (typeof(ts->tv_nsec)) 0xbadc0dedfacefeedLL;
108 k_settime(CLOCK_THREAD_CPUTIME_ID, ts);
109 printf("%s(CLOCK_THREAD_CPUTIME_ID, {tv_sec=%lld, tv_nsec=%llu})"
110 " = %s\n",
111 SYSCALL_NAME_settime, (long long) ts->tv_sec,
112 zero_extend_signed_to_ull(ts->tv_nsec), errstr);
113
114 puts("+++ exited with 0 +++");
115 return 0;
116 }