1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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