]> granicus.if.org Git - strace/blob - time.c
Add PAF_ARRAY_TRUNCATED flag for print_array_ex
[strace] / time.c
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-2019 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 <fcntl.h>
13 #include <signal.h>
14 #include <sys/timex.h>
15
16 static void
17 print_timezone(struct tcb *const tcp, const kernel_ulong_t addr)
18 {
19         struct timezone tz;
20
21         if (umove_or_printaddr(tcp, addr, &tz))
22                 return;
23
24         tprintf("{tz_minuteswest=%d, tz_dsttime=%d}",
25                 tz.tz_minuteswest, tz.tz_dsttime);
26 }
27
28 SYS_FUNC(gettimeofday)
29 {
30         if (exiting(tcp)) {
31                 print_timeval(tcp, tcp->u_arg[0]);
32                 tprints(", ");
33                 print_timezone(tcp, tcp->u_arg[1]);
34         }
35         return 0;
36 }
37
38 #ifdef ALPHA
39 SYS_FUNC(osf_gettimeofday)
40 {
41         if (exiting(tcp)) {
42                 print_timeval32(tcp, tcp->u_arg[0]);
43                 tprints(", ");
44                 print_timezone(tcp, tcp->u_arg[1]);
45         }
46         return 0;
47 }
48 #endif
49
50 SYS_FUNC(settimeofday)
51 {
52         print_timeval(tcp, tcp->u_arg[0]);
53         tprints(", ");
54         print_timezone(tcp, tcp->u_arg[1]);
55
56         return RVAL_DECODED;
57 }
58
59 #ifdef ALPHA
60 SYS_FUNC(osf_settimeofday)
61 {
62         print_timeval32(tcp, tcp->u_arg[0]);
63         tprints(", ");
64         print_timezone(tcp, tcp->u_arg[1]);
65
66         return RVAL_DECODED;
67 }
68 #endif
69
70 #if HAVE_ARCH_TIME32_SYSCALLS || HAVE_ARCH_OLD_TIME64_SYSCALLS
71 static int
72 do_nanosleep(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
73 {
74         if (entering(tcp)) {
75                 print_ts(tcp, tcp->u_arg[0]);
76                 tprints(", ");
77         } else {
78
79                 /*
80                  * Second (returned) timespec is only significant if syscall
81                  * was interrupted.  On success and in case of other errors we
82                  * print only its address, since kernel doesn't modify it,
83                  * and printing the value may show uninitialized data.
84                  */
85                 if (is_erestart(tcp)) {
86                         temporarily_clear_syserror(tcp);
87                         print_ts(tcp, tcp->u_arg[1]);
88                         restore_cleared_syserror(tcp);
89                 } else {
90                         printaddr(tcp->u_arg[1]);
91                 }
92         }
93         return 0;
94 }
95 #endif /* HAVE_ARCH_TIME32_SYSCALLS || HAVE_ARCH_OLD_TIME64_SYSCALLS */
96
97 #if HAVE_ARCH_TIME32_SYSCALLS
98 SYS_FUNC(nanosleep_time32)
99 {
100         return do_nanosleep(tcp, print_timespec32);
101 }
102 #endif
103
104 #if HAVE_ARCH_OLD_TIME64_SYSCALLS
105 SYS_FUNC(nanosleep_time64)
106 {
107         return do_nanosleep(tcp, print_timespec64);
108 }
109 #endif
110
111 #include "xlat/itimer_which.h"
112
113 SYS_FUNC(getitimer)
114 {
115         if (entering(tcp)) {
116                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
117                 tprints(", ");
118         } else {
119                 print_itimerval(tcp, tcp->u_arg[1]);
120         }
121         return 0;
122 }
123
124 #ifdef ALPHA
125 SYS_FUNC(osf_getitimer)
126 {
127         if (entering(tcp)) {
128                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
129                 tprints(", ");
130         } else {
131                 print_itimerval32(tcp, tcp->u_arg[1]);
132         }
133         return 0;
134 }
135 #endif
136
137 SYS_FUNC(setitimer)
138 {
139         if (entering(tcp)) {
140                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
141                 tprints(", ");
142                 print_itimerval(tcp, tcp->u_arg[1]);
143                 tprints(", ");
144         } else {
145                 print_itimerval(tcp, tcp->u_arg[2]);
146         }
147         return 0;
148 }
149
150 #ifdef ALPHA
151 SYS_FUNC(osf_setitimer)
152 {
153         if (entering(tcp)) {
154                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
155                 tprints(", ");
156                 print_itimerval32(tcp, tcp->u_arg[1]);
157                 tprints(", ");
158         } else {
159                 print_itimerval32(tcp, tcp->u_arg[2]);
160         }
161         return 0;
162 }
163 #endif
164
165 #include "xlat/adjtimex_state.h"
166
167 static int
168 do_adjtimex(struct tcb *const tcp, const print_obj_by_addr_fn print_tx,
169             const kernel_ulong_t addr)
170 {
171         if (print_tx(tcp, addr))
172                 return 0;
173         tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval);
174         return RVAL_STR;
175 }
176
177 #if HAVE_ARCH_TIME32_SYSCALLS
178 SYS_FUNC(adjtimex32)
179 {
180         if (exiting(tcp))
181                 return do_adjtimex(tcp, print_timex32, tcp->u_arg[0]);
182         return 0;
183 }
184 #endif
185
186 #if HAVE_ARCH_OLD_TIME64_SYSCALLS
187 SYS_FUNC(adjtimex64)
188 {
189         if (exiting(tcp))
190 # ifndef SPARC64
191                 return do_adjtimex(tcp, print_timex64, tcp->u_arg[0]);
192 # else
193                 return do_adjtimex(tcp, print_sparc64_timex, tcp->u_arg[0]);
194 # endif
195         return 0;
196 }
197 #endif
198
199 #include "xlat/clockflags.h"
200 #include "xlat/clocknames.h"
201
202 static void
203 printclockname(int clockid)
204 {
205 #ifdef CLOCKID_TO_FD
206 # include "xlat/cpuclocknames.h"
207
208         if (clockid < 0) {
209                 if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
210                         tprintf("%d", clockid);
211
212                 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
213                         return;
214
215                 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
216                         tprints(" /* ");
217
218                 if ((clockid & CLOCKFD_MASK) == CLOCKFD)
219                         tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
220                 else {
221                         tprintf("%s(%d,",
222                                 CPUCLOCK_PERTHREAD(clockid) ?
223                                         "MAKE_THREAD_CPUCLOCK" :
224                                         "MAKE_PROCESS_CPUCLOCK",
225                                 CPUCLOCK_PID(clockid));
226                         printxval(cpuclocknames, clockid & CLOCKFD_MASK,
227                                   "CPUCLOCK_???");
228                         tprints(")");
229                 }
230
231                 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
232                         tprints(" */");
233         } else
234 #endif
235                 printxval(clocknames, clockid, "CLOCK_???");
236 }
237
238 static int
239 do_clock_settime(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
240 {
241         printclockname(tcp->u_arg[0]);
242         tprints(", ");
243         print_ts(tcp, tcp->u_arg[1]);
244
245         return RVAL_DECODED;
246 }
247
248 #if HAVE_ARCH_TIME32_SYSCALLS
249 SYS_FUNC(clock_settime32)
250 {
251         return do_clock_settime(tcp, print_timespec32);
252 }
253 #endif
254
255 SYS_FUNC(clock_settime64)
256 {
257         return do_clock_settime(tcp, print_timespec64);
258 }
259
260 static int
261 do_clock_gettime(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
262 {
263         if (entering(tcp)) {
264                 printclockname(tcp->u_arg[0]);
265                 tprints(", ");
266         } else {
267                 print_ts(tcp, tcp->u_arg[1]);
268         }
269         return 0;
270 }
271
272 #if HAVE_ARCH_TIME32_SYSCALLS
273 SYS_FUNC(clock_gettime32)
274 {
275         return do_clock_gettime(tcp, print_timespec32);
276 }
277 #endif
278
279 SYS_FUNC(clock_gettime64)
280 {
281         return do_clock_gettime(tcp, print_timespec64);
282 }
283
284 static int
285 do_clock_nanosleep(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
286 {
287         if (entering(tcp)) {
288                 printclockname(tcp->u_arg[0]);
289                 tprints(", ");
290                 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
291                 tprints(", ");
292                 print_ts(tcp, tcp->u_arg[2]);
293                 tprints(", ");
294         } else {
295                 /*
296                  * Second (returned) timespec is only significant
297                  * if syscall was interrupted and flags is not TIMER_ABSTIME.
298                  */
299                 if (!tcp->u_arg[1] && is_erestart(tcp)) {
300                         temporarily_clear_syserror(tcp);
301                         print_ts(tcp, tcp->u_arg[3]);
302                         restore_cleared_syserror(tcp);
303                 } else {
304                         printaddr(tcp->u_arg[3]);
305                 }
306         }
307         return 0;
308 }
309
310 #if HAVE_ARCH_TIME32_SYSCALLS
311 SYS_FUNC(clock_nanosleep_time32)
312 {
313         return do_clock_nanosleep(tcp, print_timespec32);
314 }
315 #endif
316
317 SYS_FUNC(clock_nanosleep_time64)
318 {
319         return do_clock_nanosleep(tcp, print_timespec64);
320 }
321
322 static int
323 do_clock_adjtime(struct tcb *const tcp, const print_obj_by_addr_fn print_tx)
324 {
325         if (exiting(tcp))
326                 return do_adjtimex(tcp, print_tx, tcp->u_arg[1]);
327         printclockname(tcp->u_arg[0]);
328         tprints(", ");
329         return 0;
330 }
331
332 #if HAVE_ARCH_TIME32_SYSCALLS
333 SYS_FUNC(clock_adjtime32)
334 {
335         return do_clock_adjtime(tcp, print_timex32);
336 }
337 #endif
338
339 SYS_FUNC(clock_adjtime64)
340 {
341         return do_clock_adjtime(tcp, print_timex64);
342 }
343
344 #ifdef SPARC64
345 SYS_FUNC(clock_sparc64_adjtime)
346 {
347         return do_clock_adjtime(tcp, print_sparc64_timex);
348 }
349 #endif
350
351 SYS_FUNC(timer_create)
352 {
353         if (entering(tcp)) {
354                 printclockname(tcp->u_arg[0]);
355                 tprints(", ");
356                 print_sigevent(tcp, tcp->u_arg[1]);
357                 tprints(", ");
358         } else {
359                 printnum_int(tcp, tcp->u_arg[2], "%d");
360         }
361         return 0;
362 }
363
364 static int
365 do_timer_settime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
366 {
367         if (entering(tcp)) {
368                 tprintf("%d, ", (int) tcp->u_arg[0]);
369                 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
370                 tprints(", ");
371                 print_its(tcp, tcp->u_arg[2]);
372                 tprints(", ");
373         } else {
374                 print_its(tcp, tcp->u_arg[3]);
375         }
376         return 0;
377 }
378
379 #if HAVE_ARCH_TIME32_SYSCALLS
380 SYS_FUNC(timer_settime32)
381 {
382         return do_timer_settime(tcp, print_itimerspec32);
383 }
384 #endif
385
386 SYS_FUNC(timer_settime64)
387 {
388         return do_timer_settime(tcp, print_itimerspec64);
389 }
390
391 static int
392 do_timer_gettime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
393 {
394         if (entering(tcp)) {
395                 tprintf("%d, ", (int) tcp->u_arg[0]);
396         } else {
397                 print_its(tcp, tcp->u_arg[1]);
398         }
399         return 0;
400 }
401
402 #if HAVE_ARCH_TIME32_SYSCALLS
403 SYS_FUNC(timer_gettime32)
404 {
405         return do_timer_gettime(tcp, print_itimerspec32);
406 }
407 #endif
408
409 SYS_FUNC(timer_gettime64)
410 {
411         return do_timer_gettime(tcp, print_itimerspec64);
412 }
413
414 #include "xlat/timerfdflags.h"
415
416 SYS_FUNC(timerfd_create)
417 {
418         printclockname(tcp->u_arg[0]);
419         tprints(", ");
420         printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
421
422         return RVAL_DECODED | RVAL_FD;
423 }
424
425 static int
426 do_timerfd_settime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
427 {
428         if (entering(tcp)) {
429                 printfd(tcp, tcp->u_arg[0]);
430                 tprints(", ");
431                 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
432                 tprints(", ");
433                 print_its(tcp, tcp->u_arg[2]);
434                 tprints(", ");
435         } else {
436                 print_its(tcp, tcp->u_arg[3]);
437         }
438         return 0;
439 }
440
441 #if HAVE_ARCH_TIME32_SYSCALLS
442 SYS_FUNC(timerfd_settime32)
443 {
444         return do_timerfd_settime(tcp, print_itimerspec32);
445 }
446 #endif
447
448 SYS_FUNC(timerfd_settime64)
449 {
450         return do_timerfd_settime(tcp, print_itimerspec64);
451 }
452
453 static int
454 do_timerfd_gettime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
455 {
456         if (entering(tcp)) {
457                 printfd(tcp, tcp->u_arg[0]);
458                 tprints(", ");
459         } else {
460                 print_its(tcp, tcp->u_arg[1]);
461         }
462         return 0;
463 }
464
465 #if HAVE_ARCH_TIME32_SYSCALLS
466 SYS_FUNC(timerfd_gettime32)
467 {
468         return do_timerfd_gettime(tcp, print_itimerspec32);
469 }
470 #endif
471
472 SYS_FUNC(timerfd_gettime64)
473 {
474         return do_timerfd_gettime(tcp, print_itimerspec64);
475 }