• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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