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 * Copyright (c) 1996-2017 The strace developers.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "defs.h"
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <sys/timex.h>
35
36 static void
print_timezone(struct tcb * const tcp,const kernel_ulong_t addr)37 print_timezone(struct tcb *const tcp, const kernel_ulong_t addr)
38 {
39 struct timezone tz;
40
41 if (umove_or_printaddr(tcp, addr, &tz))
42 return;
43
44 tprintf("{tz_minuteswest=%d, tz_dsttime=%d}",
45 tz.tz_minuteswest, tz.tz_dsttime);
46 }
47
SYS_FUNC(gettimeofday)48 SYS_FUNC(gettimeofday)
49 {
50 if (exiting(tcp)) {
51 print_timeval(tcp, tcp->u_arg[0]);
52 tprints(", ");
53 print_timezone(tcp, tcp->u_arg[1]);
54 }
55 return 0;
56 }
57
58 #ifdef ALPHA
SYS_FUNC(osf_gettimeofday)59 SYS_FUNC(osf_gettimeofday)
60 {
61 if (exiting(tcp)) {
62 print_timeval32(tcp, tcp->u_arg[0]);
63 tprints(", ");
64 print_timezone(tcp, tcp->u_arg[1]);
65 }
66 return 0;
67 }
68 #endif
69
SYS_FUNC(settimeofday)70 SYS_FUNC(settimeofday)
71 {
72 print_timeval(tcp, tcp->u_arg[0]);
73 tprints(", ");
74 print_timezone(tcp, tcp->u_arg[1]);
75
76 return RVAL_DECODED;
77 }
78
79 #ifdef ALPHA
SYS_FUNC(osf_settimeofday)80 SYS_FUNC(osf_settimeofday)
81 {
82 print_timeval32(tcp, tcp->u_arg[0]);
83 tprints(", ");
84 print_timezone(tcp, tcp->u_arg[1]);
85
86 return RVAL_DECODED;
87 }
88 #endif
89
SYS_FUNC(nanosleep)90 SYS_FUNC(nanosleep)
91 {
92 if (entering(tcp)) {
93 print_timespec(tcp, tcp->u_arg[0]);
94 tprints(", ");
95 } else {
96
97 /*
98 * Second (returned) timespec is only significant if syscall
99 * was interrupted. On success and in case of other errors we
100 * print only its address, since kernel doesn't modify it,
101 * and printing the value may show uninitialized data.
102 */
103 if (is_erestart(tcp)) {
104 temporarily_clear_syserror(tcp);
105 print_timespec(tcp, tcp->u_arg[1]);
106 restore_cleared_syserror(tcp);
107 } else {
108 printaddr(tcp->u_arg[1]);
109 }
110 }
111 return 0;
112 }
113
114 #include "xlat/itimer_which.h"
115
SYS_FUNC(getitimer)116 SYS_FUNC(getitimer)
117 {
118 if (entering(tcp)) {
119 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
120 tprints(", ");
121 } else {
122 print_itimerval(tcp, tcp->u_arg[1]);
123 }
124 return 0;
125 }
126
127 #ifdef ALPHA
SYS_FUNC(osf_getitimer)128 SYS_FUNC(osf_getitimer)
129 {
130 if (entering(tcp)) {
131 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
132 tprints(", ");
133 } else {
134 print_itimerval32(tcp, tcp->u_arg[1]);
135 }
136 return 0;
137 }
138 #endif
139
SYS_FUNC(setitimer)140 SYS_FUNC(setitimer)
141 {
142 if (entering(tcp)) {
143 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
144 tprints(", ");
145 print_itimerval(tcp, tcp->u_arg[1]);
146 tprints(", ");
147 } else {
148 print_itimerval(tcp, tcp->u_arg[2]);
149 }
150 return 0;
151 }
152
153 #ifdef ALPHA
SYS_FUNC(osf_setitimer)154 SYS_FUNC(osf_setitimer)
155 {
156 if (entering(tcp)) {
157 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
158 tprints(", ");
159 print_itimerval32(tcp, tcp->u_arg[1]);
160 tprints(", ");
161 } else {
162 print_itimerval32(tcp, tcp->u_arg[2]);
163 }
164 return 0;
165 }
166 #endif
167
168 #include "xlat/adjtimex_state.h"
169
170 static int
do_adjtimex(struct tcb * const tcp,const kernel_ulong_t addr)171 do_adjtimex(struct tcb *const tcp, const kernel_ulong_t addr)
172 {
173 if (print_timex(tcp, addr))
174 return 0;
175 tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval);
176 if (tcp->auxstr)
177 return RVAL_STR;
178 return 0;
179 }
180
SYS_FUNC(adjtimex)181 SYS_FUNC(adjtimex)
182 {
183 if (exiting(tcp))
184 return do_adjtimex(tcp, tcp->u_arg[0]);
185 return 0;
186 }
187
188 #include "xlat/clockflags.h"
189 #include "xlat/clocknames.h"
190
191 static void
printclockname(int clockid)192 printclockname(int clockid)
193 {
194 #ifdef CLOCKID_TO_FD
195 # include "xlat/cpuclocknames.h"
196
197 if (clockid < 0) {
198 if ((clockid & CLOCKFD_MASK) == CLOCKFD)
199 tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
200 else {
201 if (CPUCLOCK_PERTHREAD(clockid))
202 tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
203 else
204 tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
205 printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???");
206 tprints(")");
207 }
208 } else
209 #endif
210 printxval(clocknames, clockid, "CLOCK_???");
211 }
212
SYS_FUNC(clock_settime)213 SYS_FUNC(clock_settime)
214 {
215 printclockname(tcp->u_arg[0]);
216 tprints(", ");
217 print_timespec(tcp, tcp->u_arg[1]);
218
219 return RVAL_DECODED;
220 }
221
SYS_FUNC(clock_gettime)222 SYS_FUNC(clock_gettime)
223 {
224 if (entering(tcp)) {
225 printclockname(tcp->u_arg[0]);
226 tprints(", ");
227 } else {
228 print_timespec(tcp, tcp->u_arg[1]);
229 }
230 return 0;
231 }
232
SYS_FUNC(clock_nanosleep)233 SYS_FUNC(clock_nanosleep)
234 {
235 if (entering(tcp)) {
236 printclockname(tcp->u_arg[0]);
237 tprints(", ");
238 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
239 tprints(", ");
240 print_timespec(tcp, tcp->u_arg[2]);
241 tprints(", ");
242 } else {
243 /*
244 * Second (returned) timespec is only significant
245 * if syscall was interrupted and flags is not TIMER_ABSTIME.
246 */
247 if (!tcp->u_arg[1] && is_erestart(tcp)) {
248 temporarily_clear_syserror(tcp);
249 print_timespec(tcp, tcp->u_arg[3]);
250 restore_cleared_syserror(tcp);
251 } else {
252 printaddr(tcp->u_arg[3]);
253 }
254 }
255 return 0;
256 }
257
SYS_FUNC(clock_adjtime)258 SYS_FUNC(clock_adjtime)
259 {
260 if (exiting(tcp))
261 return do_adjtimex(tcp, tcp->u_arg[1]);
262 printclockname(tcp->u_arg[0]);
263 tprints(", ");
264 return 0;
265 }
266
SYS_FUNC(timer_create)267 SYS_FUNC(timer_create)
268 {
269 if (entering(tcp)) {
270 printclockname(tcp->u_arg[0]);
271 tprints(", ");
272 print_sigevent(tcp, tcp->u_arg[1]);
273 tprints(", ");
274 } else {
275 printnum_int(tcp, tcp->u_arg[2], "%d");
276 }
277 return 0;
278 }
279
SYS_FUNC(timer_settime)280 SYS_FUNC(timer_settime)
281 {
282 if (entering(tcp)) {
283 tprintf("%d, ", (int) tcp->u_arg[0]);
284 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
285 tprints(", ");
286 print_itimerspec(tcp, tcp->u_arg[2]);
287 tprints(", ");
288 } else {
289 print_itimerspec(tcp, tcp->u_arg[3]);
290 }
291 return 0;
292 }
293
SYS_FUNC(timer_gettime)294 SYS_FUNC(timer_gettime)
295 {
296 if (entering(tcp)) {
297 tprintf("%d, ", (int) tcp->u_arg[0]);
298 } else {
299 print_itimerspec(tcp, tcp->u_arg[1]);
300 }
301 return 0;
302 }
303
304 #include "xlat/timerfdflags.h"
305
SYS_FUNC(timerfd_create)306 SYS_FUNC(timerfd_create)
307 {
308 printclockname(tcp->u_arg[0]);
309 tprints(", ");
310 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
311
312 return RVAL_DECODED | RVAL_FD;
313 }
314
SYS_FUNC(timerfd_settime)315 SYS_FUNC(timerfd_settime)
316 {
317 if (entering(tcp)) {
318 printfd(tcp, tcp->u_arg[0]);
319 tprints(", ");
320 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
321 tprints(", ");
322 print_itimerspec(tcp, tcp->u_arg[2]);
323 tprints(", ");
324 } else {
325 print_itimerspec(tcp, tcp->u_arg[3]);
326 }
327 return 0;
328 }
329
SYS_FUNC(timerfd_gettime)330 SYS_FUNC(timerfd_gettime)
331 {
332 if (entering(tcp)) {
333 printfd(tcp, tcp->u_arg[0]);
334 tprints(", ");
335 } else {
336 print_itimerspec(tcp, tcp->u_arg[1]);
337 }
338 return 0;
339 }
340