Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

time.c 9.1KB

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