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-2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: LGPL-2.1-or-later
9 */
10
11 #include "defs.h"
12 #include "kernel_fcntl.h"
13 #include <signal.h>
14 #include <sys/timex.h>
15
16 #if HAVE_ARCH_TIME32_SYSCALLS || HAVE_ARCH_OLD_TIME64_SYSCALLS
17 static void
18 print_timezone(struct tcb *const tcp, const kernel_ulong_t addr)
19 {
20 struct timezone tz;
21
22 if (umove_or_printaddr(tcp, addr, &tz))
23 return;
24
25 tprint_struct_begin();
26 PRINT_FIELD_D(tz, tz_minuteswest);
27 tprint_struct_next();
28 PRINT_FIELD_D(tz, tz_dsttime);
29 tprint_struct_end();
30 }
31
32 SYS_FUNC(gettimeofday)
33 {
34 if (exiting(tcp)) {
35 /* tv */
36 print_timeval(tcp, tcp->u_arg[0]);
37 tprint_arg_next();
38
39 /* tz */
40 print_timezone(tcp, tcp->u_arg[1]);
41 }
42 return 0;
43 }
44
45 SYS_FUNC(settimeofday)
46 {
47 /* tv */
48 print_timeval(tcp, tcp->u_arg[0]);
49 tprint_arg_next();
50
51 /* tz */
52 print_timezone(tcp, tcp->u_arg[1]);
53
54 return RVAL_DECODED;
55 }
56 #endif
57
58 #ifdef ALPHA
59 SYS_FUNC(osf_gettimeofday)
60 {
61 if (exiting(tcp)) {
62 /* tv */
63 print_timeval32(tcp, tcp->u_arg[0]);
64 tprint_arg_next();
65
66 /* tz */
67 print_timezone(tcp, tcp->u_arg[1]);
68 }
69 return 0;
70 }
71 #endif
72
73 #ifdef ALPHA
74 SYS_FUNC(osf_settimeofday)
75 {
76 /* tv */
77 print_timeval32(tcp, tcp->u_arg[0]);
78 tprint_arg_next();
79
80 /* tz */
81 print_timezone(tcp, tcp->u_arg[1]);
82
83 return RVAL_DECODED;
84 }
85 #endif
86
87 #if HAVE_ARCH_TIME32_SYSCALLS || HAVE_ARCH_OLD_TIME64_SYSCALLS
88 static int
89 do_nanosleep(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
90 {
91 if (entering(tcp)) {
92 /* req */
93 print_ts(tcp, tcp->u_arg[0]);
94 tprint_arg_next();
95 } else {
96 /* rem */
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_ts(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 #endif /* HAVE_ARCH_TIME32_SYSCALLS || HAVE_ARCH_OLD_TIME64_SYSCALLS */
114
115 #if HAVE_ARCH_TIME32_SYSCALLS
116 SYS_FUNC(nanosleep_time32)
117 {
118 return do_nanosleep(tcp, print_timespec32);
119 }
120 #endif
121
122 #if HAVE_ARCH_OLD_TIME64_SYSCALLS
123 SYS_FUNC(nanosleep_time64)
124 {
125 return do_nanosleep(tcp, print_timespec64);
126 }
127 #endif
128
129 #include "xlat/itimer_which.h"
130
131 SYS_FUNC(getitimer)
132 {
133 if (entering(tcp)) {
134 /* which */
135 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
136 tprint_arg_next();
137 } else {
138 /* curr_value */
139 print_itimerval(tcp, tcp->u_arg[1]);
140 }
141 return 0;
142 }
143
144 #ifdef ALPHA
145 SYS_FUNC(osf_getitimer)
146 {
147 if (entering(tcp)) {
148 /* which */
149 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
150 tprint_arg_next();
151 } else {
152 /* curr_value */
153 print_itimerval32(tcp, tcp->u_arg[1]);
154 }
155 return 0;
156 }
157 #endif
158
159 SYS_FUNC(setitimer)
160 {
161 if (entering(tcp)) {
162 /* which */
163 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
164 tprint_arg_next();
165
166 /* new_value */
167 print_itimerval(tcp, tcp->u_arg[1]);
168 tprint_arg_next();
169 } else {
170 /* old_value */
171 print_itimerval(tcp, tcp->u_arg[2]);
172 }
173 return 0;
174 }
175
176 #ifdef ALPHA
177 SYS_FUNC(osf_setitimer)
178 {
179 if (entering(tcp)) {
180 /* which */
181 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
182 tprint_arg_next();
183
184 /* new_value */
185 print_itimerval32(tcp, tcp->u_arg[1]);
186 tprint_arg_next();
187 } else {
188 /* old_value */
189 print_itimerval32(tcp, tcp->u_arg[2]);
190 }
191 return 0;
192 }
193 #endif
194
195 #include "xlat/adjtimex_state.h"
196
197 static int
198 do_adjtimex(struct tcb *const tcp, const print_obj_by_addr_fn print_tx,
199 const kernel_ulong_t addr)
200 {
201 /* buf */
202 if (print_tx(tcp, addr))
203 return 0;
204 tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval);
205 return RVAL_STR;
206 }
207
208 #if HAVE_ARCH_TIME32_SYSCALLS
209 SYS_FUNC(adjtimex32)
210 {
211 if (exiting(tcp))
212 return do_adjtimex(tcp, print_timex32, tcp->u_arg[0]);
213 return 0;
214 }
215 #endif
216
217 #if HAVE_ARCH_OLD_TIME64_SYSCALLS
218 SYS_FUNC(adjtimex64)
219 {
220 if (exiting(tcp))
221 # ifndef SPARC64
222 return do_adjtimex(tcp, print_timex64, tcp->u_arg[0]);
223 # else
224 return do_adjtimex(tcp, print_sparc64_timex, tcp->u_arg[0]);
225 # endif
226 return 0;
227 }
228 #endif
229
230 #include "xlat/clockflags.h"
231 #include "xlat/clocknames.h"
232
233 static void
234 printclockname(int clockid)
235 {
236 #ifdef CLOCKID_TO_FD
237 # include "xlat/cpuclocknames.h"
238
239 if (clockid < 0) {
240 if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
241 PRINT_VAL_D(clockid);
242
243 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
244 return;
245
246 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
247 tprint_comment_begin();
248
249 if ((clockid & CLOCKFD_MASK) == CLOCKFD)
250 tprints_arg_begin("FD_TO_CLOCKID");
251 PRINT_VAL_D(CLOCKID_TO_FD(clockid));
252 else {
253 tprints_arg_begin(CPUCLOCK_PERTHREAD(clockid) ?
254 "MAKE_THREAD_CPUCLOCK" :
255 "MAKE_PROCESS_CPUCLOCK");
256 PRINT_VAL_D(CPUCLOCK_PID(clockid));
257 tprint_arg_next();
258 printxval(cpuclocknames, clockid & CLOCKFD_MASK,
259 "CPUCLOCK_???");
260 }
261 tprint_arg_end();
262
263 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
264 tprint_comment_end();
265 } else
266 #endif
267 printxval(clocknames, clockid, "CLOCK_???");
268 }
269
270 static int
271 do_clock_settime(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
272 {
273 /* clockid */
274 printclockname(tcp->u_arg[0]);
275 tprint_arg_next();
276
277 /* tp */
278 print_ts(tcp, tcp->u_arg[1]);
279
280 return RVAL_DECODED;
281 }
282
283 #if HAVE_ARCH_TIME32_SYSCALLS
284 SYS_FUNC(clock_settime32)
285 {
286 return do_clock_settime(tcp, print_timespec32);
287 }
288 #endif
289
290 SYS_FUNC(clock_settime64)
291 {
292 return do_clock_settime(tcp, print_timespec64);
293 }
294
295 static int
296 do_clock_gettime(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
297 {
298 if (entering(tcp)) {
299 /* clockid */
300 printclockname(tcp->u_arg[0]);
301 tprint_arg_next();
302 } else {
303 /* tp */
304 print_ts(tcp, tcp->u_arg[1]);
305 }
306 return 0;
307 }
308
309 #if HAVE_ARCH_TIME32_SYSCALLS
310 SYS_FUNC(clock_gettime32)
311 {
312 return do_clock_gettime(tcp, print_timespec32);
313 }
314 #endif
315
316 SYS_FUNC(clock_gettime64)
317 {
318 return do_clock_gettime(tcp, print_timespec64);
319 }
320
321 static int
322 do_clock_nanosleep(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
323 {
324 if (entering(tcp)) {
325 /* clockid */
326 printclockname(tcp->u_arg[0]);
327 tprint_arg_next();
328
329 /* flags */
330 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
331 tprint_arg_next();
332
333 /* request */
334 print_ts(tcp, tcp->u_arg[2]);
335 tprint_arg_next();
336 } else {
337 /* remain */
338 /*
339 * Second (returned) timespec is only significant
340 * if syscall was interrupted and flags is not TIMER_ABSTIME.
341 */
342 if (!tcp->u_arg[1] && is_erestart(tcp)) {
343 temporarily_clear_syserror(tcp);
344 print_ts(tcp, tcp->u_arg[3]);
345 restore_cleared_syserror(tcp);
346 } else {
347 printaddr(tcp->u_arg[3]);
348 }
349 }
350 return 0;
351 }
352
353 #if HAVE_ARCH_TIME32_SYSCALLS
354 SYS_FUNC(clock_nanosleep_time32)
355 {
356 return do_clock_nanosleep(tcp, print_timespec32);
357 }
358 #endif
359
360 SYS_FUNC(clock_nanosleep_time64)
361 {
362 return do_clock_nanosleep(tcp, print_timespec64);
363 }
364
365 static int
366 do_clock_adjtime(struct tcb *const tcp, const print_obj_by_addr_fn print_tx)
367 {
368 if (entering(tcp)) {
369 /* clockid */
370 printclockname(tcp->u_arg[0]);
371 tprint_arg_next();
372 return 0;
373 } else {
374 return do_adjtimex(tcp, print_tx, tcp->u_arg[1]);
375 }
376 }
377
378 #if HAVE_ARCH_TIME32_SYSCALLS
379 SYS_FUNC(clock_adjtime32)
380 {
381 return do_clock_adjtime(tcp, print_timex32);
382 }
383 #endif
384
385 SYS_FUNC(clock_adjtime64)
386 {
387 return do_clock_adjtime(tcp, print_timex64);
388 }
389
390 #ifdef SPARC64
391 SYS_FUNC(clock_sparc64_adjtime)
392 {
393 return do_clock_adjtime(tcp, print_sparc64_timex);
394 }
395 #endif
396
397 SYS_FUNC(timer_create)
398 {
399 if (entering(tcp)) {
400 /* clockid */
401 printclockname(tcp->u_arg[0]);
402 tprint_arg_next();
403
404 /* sevp */
405 print_sigevent(tcp, tcp->u_arg[1]);
406 tprint_arg_next();
407 } else {
408 /* timerid */
409 printnum_int(tcp, tcp->u_arg[2], "%d");
410 }
411 return 0;
412 }
413
414 static int
415 do_timer_settime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
416 {
417 if (entering(tcp)) {
418 /* timerid */
419 PRINT_VAL_D((int) tcp->u_arg[0]);
420 tprint_arg_next();
421
422 /* flags */
423 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
424 tprint_arg_next();
425
426 /* new_value */
427 print_its(tcp, tcp->u_arg[2]);
428 tprint_arg_next();
429 } else {
430 /* old_value */
431 print_its(tcp, tcp->u_arg[3]);
432 }
433 return 0;
434 }
435
436 #if HAVE_ARCH_TIME32_SYSCALLS
437 SYS_FUNC(timer_settime32)
438 {
439 return do_timer_settime(tcp, print_itimerspec32);
440 }
441 #endif
442
443 SYS_FUNC(timer_settime64)
444 {
445 return do_timer_settime(tcp, print_itimerspec64);
446 }
447
448 static int
449 do_timer_gettime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
450 {
451 if (entering(tcp)) {
452 /* timerid */
453 PRINT_VAL_D((int) tcp->u_arg[0]);
454 tprint_arg_next();
455 } else {
456 /* curr_value */
457 print_its(tcp, tcp->u_arg[1]);
458 }
459 return 0;
460 }
461
462 #if HAVE_ARCH_TIME32_SYSCALLS
463 SYS_FUNC(timer_gettime32)
464 {
465 return do_timer_gettime(tcp, print_itimerspec32);
466 }
467 #endif
468
469 SYS_FUNC(timer_gettime64)
470 {
471 return do_timer_gettime(tcp, print_itimerspec64);
472 }
473
474 #include "xlat/timerfdflags.h"
475
476 SYS_FUNC(timerfd_create)
477 {
478 /* clockid */
479 printclockname(tcp->u_arg[0]);
480 tprint_arg_next();
481
482 /* flags */
483 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
484
485 return RVAL_DECODED | RVAL_FD;
486 }
487
488 static int
489 do_timerfd_settime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
490 {
491 if (entering(tcp)) {
492 /* fd */
493 printfd(tcp, tcp->u_arg[0]);
494 tprint_arg_next();
495
496 /* flags */
497 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
498 tprint_arg_next();
499
500 /* new_value */
501 print_its(tcp, tcp->u_arg[2]);
502 tprint_arg_next();
503 } else {
504 /* old_value */
505 print_its(tcp, tcp->u_arg[3]);
506 }
507 return 0;
508 }
509
510 #if HAVE_ARCH_TIME32_SYSCALLS
511 SYS_FUNC(timerfd_settime32)
512 {
513 return do_timerfd_settime(tcp, print_itimerspec32);
514 }
515 #endif
516
517 SYS_FUNC(timerfd_settime64)
518 {
519 return do_timerfd_settime(tcp, print_itimerspec64);
520 }
521
522 static int
523 do_timerfd_gettime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
524 {
525 if (entering(tcp)) {
526 /* fd */
527 printfd(tcp, tcp->u_arg[0]);
528 tprint_arg_next();
529 } else {
530 /* curr_value */
531 print_its(tcp, tcp->u_arg[1]);
532 }
533 return 0;
534 }
535
536 #if HAVE_ARCH_TIME32_SYSCALLS
537 SYS_FUNC(timerfd_gettime32)
538 {
539 return do_timerfd_gettime(tcp, print_itimerspec32);
540 }
541 #endif
542
543 SYS_FUNC(timerfd_gettime64)
544 {
545 return do_timerfd_gettime(tcp, print_itimerspec64);
546 }