Branch data Line data Source code
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
37 : 10 : print_timezone(struct tcb *const tcp, const kernel_ulong_t addr)
38 : : {
39 : : struct timezone tz;
40 : :
41 [ + + ]: 10 : if (umove_or_printaddr(tcp, addr, &tz))
42 : 2 : return;
43 : :
44 : 8 : tprintf("{tz_minuteswest=%d, tz_dsttime=%d}",
45 : : tz.tz_minuteswest, tz.tz_dsttime);
46 : : }
47 : :
48 : 8 : SYS_FUNC(gettimeofday)
49 : : {
50 [ + + ]: 8 : if (exiting(tcp)) {
51 : 4 : print_timeval(tcp, tcp->u_arg[0]);
52 : 4 : tprints(", ");
53 : 4 : print_timezone(tcp, tcp->u_arg[1]);
54 : : }
55 : 8 : return 0;
56 : : }
57 : :
58 : : #ifdef ALPHA
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 : :
70 : 6 : SYS_FUNC(settimeofday)
71 : : {
72 : 6 : print_timeval(tcp, tcp->u_arg[0]);
73 : 6 : tprints(", ");
74 : 6 : print_timezone(tcp, tcp->u_arg[1]);
75 : :
76 : 6 : return RVAL_DECODED;
77 : : }
78 : :
79 : : #ifdef ALPHA
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 : :
90 : 62 : SYS_FUNC(nanosleep)
91 : : {
92 [ + + ]: 62 : if (entering(tcp)) {
93 : 32 : print_timespec(tcp, tcp->u_arg[0]);
94 : 32 : 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 [ + + ]: 30 : if (is_erestart(tcp)) {
104 : 4 : temporarily_clear_syserror(tcp);
105 : 4 : print_timespec(tcp, tcp->u_arg[1]);
106 : 4 : restore_cleared_syserror(tcp);
107 : : } else {
108 : 26 : printaddr(tcp->u_arg[1]);
109 : : }
110 : : }
111 : 62 : return 0;
112 : : }
113 : :
114 : : #include "xlat/itimer_which.h"
115 : :
116 : 16 : SYS_FUNC(getitimer)
117 : : {
118 [ + + ]: 16 : if (entering(tcp)) {
119 : 8 : printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
120 : 8 : tprints(", ");
121 : : } else {
122 : 8 : print_itimerval(tcp, tcp->u_arg[1]);
123 : : }
124 : 16 : return 0;
125 : : }
126 : :
127 : : #ifdef ALPHA
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 : :
140 : 28 : SYS_FUNC(setitimer)
141 : : {
142 [ + + ]: 28 : if (entering(tcp)) {
143 : 14 : printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
144 : 14 : tprints(", ");
145 : 14 : print_itimerval(tcp, tcp->u_arg[1]);
146 : 14 : tprints(", ");
147 : : } else {
148 : 14 : print_itimerval(tcp, tcp->u_arg[2]);
149 : : }
150 : 28 : return 0;
151 : : }
152 : :
153 : : #ifdef ALPHA
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
171 : 12 : do_adjtimex(struct tcb *const tcp, const kernel_ulong_t addr)
172 : : {
173 [ + + ]: 12 : if (print_timex(tcp, addr))
174 : : return 0;
175 : 2 : tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval);
176 [ - + ]: 2 : if (tcp->auxstr)
177 : : return RVAL_STR;
178 : 0 : return 0;
179 : : }
180 : :
181 : 8 : SYS_FUNC(adjtimex)
182 : : {
183 [ + + ]: 8 : if (exiting(tcp))
184 : 4 : 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
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 : 80 : printxval(clocknames, clockid, "CLOCK_???");
211 : : }
212 : :
213 : 12 : SYS_FUNC(clock_settime)
214 : : {
215 : 12 : printclockname(tcp->u_arg[0]);
216 : 12 : tprints(", ");
217 : 12 : print_timespec(tcp, tcp->u_arg[1]);
218 : :
219 : 12 : return RVAL_DECODED;
220 : : }
221 : :
222 : 24 : SYS_FUNC(clock_gettime)
223 : : {
224 [ + + ]: 24 : if (entering(tcp)) {
225 : 12 : printclockname(tcp->u_arg[0]);
226 : 12 : tprints(", ");
227 : : } else {
228 : 12 : print_timespec(tcp, tcp->u_arg[1]);
229 : : }
230 : 24 : return 0;
231 : : }
232 : :
233 : 64 : SYS_FUNC(clock_nanosleep)
234 : : {
235 [ + + ]: 64 : if (entering(tcp)) {
236 : 32 : printclockname(tcp->u_arg[0]);
237 : 32 : tprints(", ");
238 : 32 : printflags(clockflags, tcp->u_arg[1], "TIMER_???");
239 : 32 : tprints(", ");
240 : 32 : print_timespec(tcp, tcp->u_arg[2]);
241 : 32 : tprints(", ");
242 : : } else {
243 : : /*
244 : : * Second (returned) timespec is only significant
245 : : * if syscall was interrupted and flags is not TIMER_ABSTIME.
246 : : */
247 [ + + ][ + + ]: 32 : if (!tcp->u_arg[1] && is_erestart(tcp)) {
248 : 4 : temporarily_clear_syserror(tcp);
249 : 4 : print_timespec(tcp, tcp->u_arg[3]);
250 : 4 : restore_cleared_syserror(tcp);
251 : : } else {
252 : 28 : printaddr(tcp->u_arg[3]);
253 : : }
254 : : }
255 : 64 : return 0;
256 : : }
257 : :
258 : 16 : SYS_FUNC(clock_adjtime)
259 : : {
260 [ + + ]: 16 : if (exiting(tcp))
261 : 8 : return do_adjtimex(tcp, tcp->u_arg[1]);
262 : 8 : printclockname(tcp->u_arg[0]);
263 : 8 : tprints(", ");
264 : 8 : return 0;
265 : : }
266 : :
267 : 28 : SYS_FUNC(timer_create)
268 : : {
269 [ + + ]: 28 : if (entering(tcp)) {
270 : 14 : printclockname(tcp->u_arg[0]);
271 : 14 : tprints(", ");
272 : 14 : print_sigevent(tcp, tcp->u_arg[1]);
273 : 14 : tprints(", ");
274 : : } else {
275 : 14 : printnum_int(tcp, tcp->u_arg[2], "%d");
276 : : }
277 : 28 : return 0;
278 : : }
279 : :
280 : 12 : SYS_FUNC(timer_settime)
281 : : {
282 [ + + ]: 12 : if (entering(tcp)) {
283 : 6 : tprintf("%d, ", (int) tcp->u_arg[0]);
284 : 6 : printflags(clockflags, tcp->u_arg[1], "TIMER_???");
285 : 6 : tprints(", ");
286 : 6 : print_itimerspec(tcp, tcp->u_arg[2]);
287 : 6 : tprints(", ");
288 : : } else {
289 : 6 : print_itimerspec(tcp, tcp->u_arg[3]);
290 : : }
291 : 12 : return 0;
292 : : }
293 : :
294 : 4 : SYS_FUNC(timer_gettime)
295 : : {
296 [ + + ]: 4 : if (entering(tcp)) {
297 : 2 : tprintf("%d, ", (int) tcp->u_arg[0]);
298 : : } else {
299 : 2 : print_itimerspec(tcp, tcp->u_arg[1]);
300 : : }
301 : 4 : return 0;
302 : : }
303 : :
304 : : #include "xlat/timerfdflags.h"
305 : :
306 : 2 : SYS_FUNC(timerfd_create)
307 : : {
308 : 2 : printclockname(tcp->u_arg[0]);
309 : 2 : tprints(", ");
310 : 2 : printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
311 : :
312 : 2 : return RVAL_DECODED | RVAL_FD;
313 : : }
314 : :
315 : 8 : SYS_FUNC(timerfd_settime)
316 : : {
317 [ + + ]: 8 : if (entering(tcp)) {
318 : 4 : printfd(tcp, tcp->u_arg[0]);
319 : 4 : tprints(", ");
320 : 4 : printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
321 : 4 : tprints(", ");
322 : 4 : print_itimerspec(tcp, tcp->u_arg[2]);
323 : 4 : tprints(", ");
324 : : } else {
325 : 4 : print_itimerspec(tcp, tcp->u_arg[3]);
326 : : }
327 : 8 : return 0;
328 : : }
329 : :
330 : 4 : SYS_FUNC(timerfd_gettime)
331 : : {
332 [ + + ]: 4 : if (entering(tcp)) {
333 : 2 : printfd(tcp, tcp->u_arg[0]);
334 : 2 : tprints(", ");
335 : : } else {
336 : 2 : print_itimerspec(tcp, tcp->u_arg[1]);
337 : : }
338 : 4 : return 0;
339 : : }
|