blob: dfddc45673cbcb809dd110d0cf4ebbee40f67656 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
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 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000028 */
29
30#include "defs.h"
Mike Frysingerf1639d82014-12-30 19:08:50 -050031#include <fcntl.h>
Dmitry V. Levin0e946ab2015-07-17 23:56:54 +000032#include <signal.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000033#include <linux/version.h>
Wichert Akkermand856b992000-10-13 12:47:12 +000034#include <sys/timex.h>
Roland McGrath6afc5652007-07-24 01:57:11 +000035
36#ifndef UTIME_NOW
37#define UTIME_NOW ((1l << 30) - 1l)
38#endif
39#ifndef UTIME_OMIT
40#define UTIME_OMIT ((1l << 30) - 2l)
41#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000042
Dmitry V. Levine61086f2015-02-27 21:46:42 +000043#if SUPPORTED_PERSONALITIES > 1
44# if defined X86_64 || defined X32
45# define current_time_t_is_compat (current_personality == 1)
46# else
47# define current_time_t_is_compat (current_wordsize == 4)
48# endif
49#else
50# define current_time_t_is_compat 0
51#endif
52
Dmitry V. Levina7945a32006-12-13 17:10:11 +000053struct timeval32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000054{
Dmitry V. Levina7945a32006-12-13 17:10:11 +000055 u_int32_t tv_sec, tv_usec;
56};
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000057
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +000058static void
59tprint_timeval32(struct tcb *tcp, const struct timeval32 *tv)
60{
61 tprintf("{%u, %u}", tv->tv_sec, tv->tv_usec);
62}
63
64static void
65tprint_timeval(struct tcb *tcp, const struct timeval *tv)
66{
Dmitry V. Levine61086f2015-02-27 21:46:42 +000067 tprintf("{%ju, %ju}", (uintmax_t) tv->tv_sec, (uintmax_t) tv->tv_usec);
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +000068}
69
Dmitry V. Levina7945a32006-12-13 17:10:11 +000070void
Roland McGrath6afc5652007-07-24 01:57:11 +000071printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special)
Dmitry V. Levina7945a32006-12-13 17:10:11 +000072{
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +010073 char buf[TIMEVAL_TEXT_BUFSIZE];
74 sprinttv(buf, tcp, addr, bitness, special);
75 tprints(buf);
Dmitry V. Levina7945a32006-12-13 17:10:11 +000076}
Wichert Akkerman221f54f1999-11-18 17:26:45 +000077
Dmitry V. Levinee21a5b2014-12-26 23:55:38 +000078static char *
Dmitry V. Levine61086f2015-02-27 21:46:42 +000079do_sprinttv(char *buf, const uintmax_t sec, const uintmax_t usec,
Dmitry V. Levinee21a5b2014-12-26 23:55:38 +000080 const int special)
81{
82 if (special) {
83 switch (usec) {
84 case UTIME_NOW:
85 return stpcpy(buf, "UTIME_NOW");
86 case UTIME_OMIT:
87 return stpcpy(buf, "UTIME_OMIT");
88 }
89 }
Dmitry V. Levine61086f2015-02-27 21:46:42 +000090 return buf + sprintf(buf, "{%ju, %ju}", sec, usec);
Dmitry V. Levinee21a5b2014-12-26 23:55:38 +000091}
92
Denys Vlasenko2fb4db32011-08-31 12:26:03 +020093char *
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +010094sprinttv(char *buf, struct tcb *tcp, long addr, enum bitness_t bitness, int special)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +000095{
Dmitry V. Levina7945a32006-12-13 17:10:11 +000096 if (addr == 0)
Denys Vlasenko2fb4db32011-08-31 12:26:03 +020097 return stpcpy(buf, "NULL");
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +000098
Dmitry V. Levin9f702732015-07-16 16:22:07 +000099 if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)))
Denys Vlasenkob9c7ae62011-09-01 11:40:40 +0200100 return buf + sprintf(buf, "%#lx", addr);
Denys Vlasenko2fb4db32011-08-31 12:26:03 +0200101
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000102 if (bitness == BITNESS_32 || current_time_t_is_compat)
Denys Vlasenko2fb4db32011-08-31 12:26:03 +0200103 {
104 struct timeval32 tv;
105
Dmitry V. Levinee21a5b2014-12-26 23:55:38 +0000106 if (umove(tcp, addr, &tv) >= 0)
107 return do_sprinttv(buf, tv.tv_sec, tv.tv_usec, special);
Denys Vlasenko2fb4db32011-08-31 12:26:03 +0200108 } else {
109 struct timeval tv;
110
Dmitry V. Levinee21a5b2014-12-26 23:55:38 +0000111 if (umove(tcp, addr, &tv) >= 0)
112 return do_sprinttv(buf, tv.tv_sec, tv.tv_usec, special);
Denys Vlasenko2fb4db32011-08-31 12:26:03 +0200113 }
Denys Vlasenko2fb4db32011-08-31 12:26:03 +0200114
Dmitry V. Levin9f702732015-07-16 16:22:07 +0000115 return buf + sprintf(buf, "%#lx", addr);
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000116}
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000117
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100118void
119print_timespec(struct tcb *tcp, long addr)
Roland McGrath6bc09da2007-11-01 21:50:54 +0000120{
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100121 char buf[TIMESPEC_TEXT_BUFSIZE];
122 sprint_timespec(buf, tcp, addr);
123 tprints(buf);
Roland McGrath6bc09da2007-11-01 21:50:54 +0000124}
125
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100126void
127sprint_timespec(char *buf, struct tcb *tcp, long addr)
Roland McGrath6bc09da2007-11-01 21:50:54 +0000128{
129 if (addr == 0)
130 strcpy(buf, "NULL");
131 else if (!verbose(tcp))
132 sprintf(buf, "%#lx", addr);
133 else {
Denys Vlasenko1d632462009-04-14 12:51:00 +0000134 int rc;
Roland McGrath6bc09da2007-11-01 21:50:54 +0000135
Denys Vlasenko84703742012-02-25 02:38:52 +0100136#if SUPPORTED_PERSONALITIES > 1
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000137 if (current_time_t_is_compat) {
Roland McGrath6bc09da2007-11-01 21:50:54 +0000138 struct timeval32 tv;
139
Denys Vlasenko5d645812011-08-20 12:48:18 +0200140 rc = umove(tcp, addr, &tv);
141 if (rc >= 0)
Roland McGrath6bc09da2007-11-01 21:50:54 +0000142 sprintf(buf, "{%u, %u}",
143 tv.tv_sec, tv.tv_usec);
144 } else
Roland McGrath6bc09da2007-11-01 21:50:54 +0000145#endif
Denys Vlasenko1d632462009-04-14 12:51:00 +0000146 {
Roland McGrath6bc09da2007-11-01 21:50:54 +0000147 struct timespec ts;
148
Denys Vlasenko5d645812011-08-20 12:48:18 +0200149 rc = umove(tcp, addr, &ts);
150 if (rc >= 0)
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000151 sprintf(buf, "{%ju, %ju}",
152 (uintmax_t) ts.tv_sec,
153 (uintmax_t) ts.tv_nsec);
Roland McGrath6bc09da2007-11-01 21:50:54 +0000154 }
Roland McGrath6bc09da2007-11-01 21:50:54 +0000155 if (rc < 0)
156 strcpy(buf, "{...}");
157 }
158}
159
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000160SYS_FUNC(time)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000161{
162 if (exiting(tcp)) {
Dmitry V. Levin1c603a92015-02-17 22:03:17 +0000163 printnum_long(tcp, tcp->u_arg[0], "%ld");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000164 }
165 return 0;
166}
167
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000168SYS_FUNC(gettimeofday)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000169{
170 if (exiting(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000171 printtv(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200172 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000173 printtv(tcp, tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000174 }
175 return 0;
176}
177
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000178#ifdef ALPHA
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000179SYS_FUNC(osf_gettimeofday)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000180{
Denys Vlasenko1d632462009-04-14 12:51:00 +0000181 if (exiting(tcp)) {
Denys Vlasenko1d632462009-04-14 12:51:00 +0000182 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200183 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +0000184 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
Denys Vlasenko1d632462009-04-14 12:51:00 +0000185 }
186 return 0;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000187}
188#endif
189
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000190SYS_FUNC(settimeofday)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000191{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000192 printtv(tcp, tcp->u_arg[0]);
193 tprints(", ");
194 printtv(tcp, tcp->u_arg[1]);
195
196 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000197}
198
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000199#ifdef ALPHA
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000200SYS_FUNC(osf_settimeofday)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000201{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000202 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
203 tprints(", ");
204 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
205
206 return RVAL_DECODED;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000207}
208#endif
209
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000210SYS_FUNC(adjtime)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000211{
212 if (entering(tcp)) {
213 printtv(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200214 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000215 } else {
Dmitry V. Levin9f702732015-07-16 16:22:07 +0000216 printtv(tcp, tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000217 }
218 return 0;
219}
220
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000221SYS_FUNC(nanosleep)
Dmitry V. Levin2e55ff42008-09-03 01:02:46 +0000222{
223 if (entering(tcp)) {
224 print_timespec(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200225 tprints(", ");
Dmitry V. Levin2e55ff42008-09-03 01:02:46 +0000226 } else {
Denys Vlasenko64acaa12012-01-28 02:29:36 +0100227 /* Second (returned) timespec is only significant
Denys Vlasenko47932212013-06-30 23:53:49 +0200228 * if syscall was interrupted. On success, we print
229 * only its address, since kernel doesn't modify it,
230 * and printing the value may show uninitialized data.
Denys Vlasenko64acaa12012-01-28 02:29:36 +0100231 */
Denys Vlasenko47932212013-06-30 23:53:49 +0200232 switch (tcp->u_error) {
233 default:
234 /* Not interrupted (slept entire interval) */
Dmitry V. Levin71178352015-07-16 18:18:09 +0000235 printaddr(tcp->u_arg[1]);
236 break;
Denys Vlasenko47932212013-06-30 23:53:49 +0200237 case ERESTARTSYS:
238 case ERESTARTNOINTR:
239 case ERESTARTNOHAND:
240 case ERESTART_RESTARTBLOCK:
241 /* Interrupted */
Dmitry V. Levin2e55ff42008-09-03 01:02:46 +0000242 print_timespec(tcp, tcp->u_arg[1]);
Denys Vlasenko47932212013-06-30 23:53:49 +0200243 }
Dmitry V. Levin2e55ff42008-09-03 01:02:46 +0000244 }
245 return 0;
246}
247
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000248#include "xlat/itimer_which.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000249
250static void
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000251printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000252{
Dmitry V. Levin71178352015-07-16 18:18:09 +0000253 if (bitness == BITNESS_32 || current_time_t_is_compat) {
254 struct {
255 struct timeval32 it_interval, it_value;
256 } itv;
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000257
Dmitry V. Levin71178352015-07-16 18:18:09 +0000258 if (!umove_or_printaddr(tcp, addr, &itv)) {
259 tprints("{it_interval=");
260 tprint_timeval32(tcp, &itv.it_interval);
261 tprints(", it_value=");
262 tprint_timeval32(tcp, &itv.it_value);
263 tprints("}");
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000264 }
Dmitry V. Levin71178352015-07-16 18:18:09 +0000265 } else {
266 struct itimerval itv;
267
268 if (!umove_or_printaddr(tcp, addr, &itv)) {
269 tprints("{it_interval=");
270 tprint_timeval(tcp, &itv.it_interval);
271 tprints(", it_value=");
272 tprint_timeval(tcp, &itv.it_value);
273 tprints("}");
274 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000275 }
276}
277
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000278#define printitv(tcp, addr) \
279 printitv_bitness((tcp), (addr), BITNESS_CURRENT)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000280
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000281SYS_FUNC(getitimer)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000282{
283 if (entering(tcp)) {
Dmitry V. Levin297b5942014-04-25 23:39:20 +0000284 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200285 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000286 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000287 printitv(tcp, tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000288 }
289 return 0;
290}
291
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000292#ifdef ALPHA
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000293SYS_FUNC(osf_getitimer)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000294{
Denys Vlasenko1d632462009-04-14 12:51:00 +0000295 if (entering(tcp)) {
Dmitry V. Levin297b5942014-04-25 23:39:20 +0000296 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200297 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +0000298 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000299 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
Denys Vlasenko1d632462009-04-14 12:51:00 +0000300 }
301 return 0;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000302}
303#endif
304
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000305SYS_FUNC(setitimer)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000306{
307 if (entering(tcp)) {
Dmitry V. Levin297b5942014-04-25 23:39:20 +0000308 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200309 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000310 printitv(tcp, tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200311 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000312 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000313 printitv(tcp, tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000314 }
315 return 0;
316}
317
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000318#ifdef ALPHA
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000319SYS_FUNC(osf_setitimer)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000320{
Denys Vlasenko1d632462009-04-14 12:51:00 +0000321 if (entering(tcp)) {
Dmitry V. Levin297b5942014-04-25 23:39:20 +0000322 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200323 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +0000324 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200325 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +0000326 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000327 printitv_bitness(tcp, tcp->u_arg[2], BITNESS_32);
Denys Vlasenko1d632462009-04-14 12:51:00 +0000328 }
329 return 0;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000330}
331#endif
332
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000333#include "xlat/adjtimex_modes.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000334#include "xlat/adjtimex_status.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000335#include "xlat/adjtimex_state.h"
Dmitry V. Levin1a684d62006-12-13 17:42:32 +0000336
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000337#if SUPPORTED_PERSONALITIES > 1
338static int
339tprint_timex32(struct tcb *tcp, long addr)
340{
Denys Vlasenko1d632462009-04-14 12:51:00 +0000341 struct {
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000342 unsigned int modes;
343 int offset;
344 int freq;
345 int maxerror;
346 int esterror;
347 int status;
348 int constant;
349 int precision;
350 int tolerance;
351 struct timeval32 time;
352 int tick;
353 int ppsfreq;
354 int jitter;
355 int shift;
356 int stabil;
357 int jitcnt;
358 int calcnt;
359 int errcnt;
360 int stbcnt;
361 } tx;
362
Dmitry V. Levin71178352015-07-16 18:18:09 +0000363 if (umove_or_printaddr(tcp, addr, &tx))
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000364 return -1;
365
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200366 tprints("{modes=");
Dmitry V. Levin71d70892007-01-13 11:17:38 +0000367 printflags(adjtimex_modes, tx.modes, "ADJ_???");
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000368 tprintf(", offset=%d, freq=%d, maxerror=%d, ",
369 tx.offset, tx.freq, tx.maxerror);
370 tprintf("esterror=%u, status=", tx.esterror);
371 printflags(adjtimex_status, tx.status, "STA_???");
372 tprintf(", constant=%d, precision=%u, ",
373 tx.constant, tx.precision);
374 tprintf("tolerance=%d, time=", tx.tolerance);
375 tprint_timeval32(tcp, &tx.time);
376 tprintf(", tick=%d, ppsfreq=%d, jitter=%d",
377 tx.tick, tx.ppsfreq, tx.jitter);
378 tprintf(", shift=%d, stabil=%d, jitcnt=%d",
379 tx.shift, tx.stabil, tx.jitcnt);
380 tprintf(", calcnt=%d, errcnt=%d, stbcnt=%d",
381 tx.calcnt, tx.errcnt, tx.stbcnt);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200382 tprints("}");
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000383 return 0;
384}
385#endif /* SUPPORTED_PERSONALITIES > 1 */
386
387static int
388tprint_timex(struct tcb *tcp, long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000389{
Dmitry V. Levin1a684d62006-12-13 17:42:32 +0000390 struct timex tx;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000391
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000392#if SUPPORTED_PERSONALITIES > 1
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000393 if (current_time_t_is_compat)
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000394 return tprint_timex32(tcp, addr);
395#endif
Dmitry V. Levin71178352015-07-16 18:18:09 +0000396 if (umove_or_printaddr(tcp, addr, &tx))
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000397 return -1;
398
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200399 tprints("{modes=");
Dmitry V. Levin71d70892007-01-13 11:17:38 +0000400 printflags(adjtimex_modes, tx.modes, "ADJ_???");
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000401 tprintf(", offset=%jd, freq=%jd, maxerror=%ju, esterror=%ju, status=",
402 (intmax_t) tx.offset, (intmax_t) tx.freq,
403 (uintmax_t) tx.maxerror, (uintmax_t) tx.esterror);
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000404 printflags(adjtimex_status, tx.status, "STA_???");
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000405 tprintf(", constant=%jd, precision=%ju, tolerance=%jd, time=",
406 (intmax_t) tx.constant, (uintmax_t) tx.precision,
407 (intmax_t) tx.tolerance);
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000408 tprint_timeval(tcp, &tx.time);
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000409 tprintf(", tick=%jd, ppsfreq=%jd, jitter=%jd",
410 (intmax_t) tx.tick, (intmax_t) tx.ppsfreq, (intmax_t) tx.jitter);
411 tprintf(", shift=%d, stabil=%jd, jitcnt=%jd",
412 tx.shift, (intmax_t) tx.stabil, (intmax_t) tx.jitcnt);
413 tprintf(", calcnt=%jd, errcnt=%jd, stbcnt=%jd",
414 (intmax_t) tx.calcnt, (intmax_t) tx.errcnt, (intmax_t) tx.stbcnt);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200415 tprints("}");
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000416 return 0;
417}
418
Dmitry V. Levin73215472012-03-11 21:25:51 +0000419static int
420do_adjtimex(struct tcb *tcp, long addr)
421{
Dmitry V. Levin71178352015-07-16 18:18:09 +0000422 if (tprint_timex(tcp, addr))
Dmitry V. Levin73215472012-03-11 21:25:51 +0000423 return 0;
424 tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
425 if (tcp->auxstr)
426 return RVAL_STR;
427 return 0;
428}
429
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000430SYS_FUNC(adjtimex)
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000431{
Dmitry V. Levin73215472012-03-11 21:25:51 +0000432 if (exiting(tcp))
433 return do_adjtimex(tcp, tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000434 return 0;
435}
Roland McGrath1e356792003-03-30 23:52:28 +0000436
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000437#include "xlat/clockflags.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000438#include "xlat/clocknames.h"
Roland McGrath54a4edd2004-08-31 06:52:45 +0000439
Stefan Sørensena5fea902014-02-03 10:01:27 +0100440static void
441printclockname(int clockid)
442{
443#ifdef CLOCKID_TO_FD
Dmitry V. Levind35bdca2014-04-26 18:10:19 +0000444# include "xlat/cpuclocknames.h"
445
Stefan Sørensena5fea902014-02-03 10:01:27 +0100446 if (clockid < 0) {
447 if ((clockid & CLOCKFD_MASK) == CLOCKFD)
448 tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
449 else {
450 if(CPUCLOCK_PERTHREAD(clockid))
451 tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
452 else
453 tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
454 printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???");
455 tprints(")");
456 }
457 }
458 else
459#endif
460 printxval(clocknames, clockid, "CLOCK_???");
461}
462
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000463SYS_FUNC(clock_settime)
Roland McGrath1e356792003-03-30 23:52:28 +0000464{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000465 printclockname(tcp->u_arg[0]);
466 tprints(", ");
467 printtv(tcp, tcp->u_arg[1]);
468
469 return RVAL_DECODED;
Roland McGrath1e356792003-03-30 23:52:28 +0000470}
471
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000472SYS_FUNC(clock_gettime)
Roland McGrath1e356792003-03-30 23:52:28 +0000473{
474 if (entering(tcp)) {
Stefan Sørensena5fea902014-02-03 10:01:27 +0100475 printclockname(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200476 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000477 } else {
Dmitry V. Levin9f702732015-07-16 16:22:07 +0000478 printtv(tcp, tcp->u_arg[1]);
Roland McGrath1e356792003-03-30 23:52:28 +0000479 }
480 return 0;
481}
482
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000483SYS_FUNC(clock_nanosleep)
Roland McGrath1e356792003-03-30 23:52:28 +0000484{
485 if (entering(tcp)) {
Stefan Sørensena5fea902014-02-03 10:01:27 +0100486 printclockname(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200487 tprints(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000488 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200489 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000490 printtv(tcp, tcp->u_arg[2]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200491 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000492 } else {
Dmitry V. Levin9f702732015-07-16 16:22:07 +0000493 printtv(tcp, tcp->u_arg[3]);
Roland McGrath1e356792003-03-30 23:52:28 +0000494 }
495 return 0;
496}
497
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000498SYS_FUNC(clock_adjtime)
Dmitry V. Levin73215472012-03-11 21:25:51 +0000499{
500 if (exiting(tcp))
501 return do_adjtimex(tcp, tcp->u_arg[1]);
Stefan Sørensena5fea902014-02-03 10:01:27 +0100502 printclockname(tcp->u_arg[0]);
Dmitry V. Levin73215472012-03-11 21:25:51 +0000503 tprints(", ");
504 return 0;
505}
506
Roland McGrath1e356792003-03-30 23:52:28 +0000507#ifndef SIGEV_THREAD_ID
508# define SIGEV_THREAD_ID 4
509#endif
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000510#include "xlat/sigev_value.h"
Roland McGrath1e356792003-03-30 23:52:28 +0000511
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000512#if SUPPORTED_PERSONALITIES > 1
513static void
514printsigevent32(struct tcb *tcp, long arg)
515{
Denys Vlasenko1d632462009-04-14 12:51:00 +0000516 struct {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000517 int sigev_value;
518 int sigev_signo;
519 int sigev_notify;
520
Denys Vlasenko1d632462009-04-14 12:51:00 +0000521 union {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000522 int tid;
Denys Vlasenko1d632462009-04-14 12:51:00 +0000523 struct {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000524 int function, attribute;
525 } thread;
526 } un;
527 } sev;
528
Dmitry V. Levin71178352015-07-16 18:18:09 +0000529 if (!umove_or_printaddr(tcp, arg, &sev)) {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000530 tprintf("{%#x, ", sev.sigev_value);
531 if (sev.sigev_notify == SIGEV_SIGNAL)
532 tprintf("%s, ", signame(sev.sigev_signo));
533 else
534 tprintf("%u, ", sev.sigev_signo);
Dmitry V. Levinbae549e2014-02-05 01:46:10 +0000535 printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200536 tprints(", ");
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000537 if (sev.sigev_notify == SIGEV_THREAD_ID)
538 tprintf("{%d}", sev.un.tid);
539 else if (sev.sigev_notify == SIGEV_THREAD)
540 tprintf("{%#x, %#x}",
541 sev.un.thread.function,
542 sev.un.thread.attribute);
543 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200544 tprints("{...}");
545 tprints("}");
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000546 }
547}
548#endif
549
Roland McGrath1e356792003-03-30 23:52:28 +0000550void
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000551printsigevent(struct tcb *tcp, long arg)
Roland McGrath1e356792003-03-30 23:52:28 +0000552{
553 struct sigevent sev;
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000554
555#if SUPPORTED_PERSONALITIES > 1
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100556 if (current_wordsize == 4) {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000557 printsigevent32(tcp, arg);
558 return;
559 }
560#endif
Dmitry V. Levin71178352015-07-16 18:18:09 +0000561 if (!umove_or_printaddr(tcp, arg, &sev)) {
Roland McGrath675d4a62004-09-11 08:12:45 +0000562 tprintf("{%p, ", sev.sigev_value.sival_ptr);
563 if (sev.sigev_notify == SIGEV_SIGNAL)
564 tprintf("%s, ", signame(sev.sigev_signo));
565 else
566 tprintf("%u, ", sev.sigev_signo);
Dmitry V. Levinbae549e2014-02-05 01:46:10 +0000567 printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200568 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000569 if (sev.sigev_notify == SIGEV_THREAD_ID)
Dmitry V. Levinae5aa472013-11-11 23:54:30 +0000570#if defined(HAVE_STRUCT_SIGEVENT__SIGEV_UN__PAD)
Roland McGrath1e356792003-03-30 23:52:28 +0000571 /* _pad[0] is the _tid field which might not be
572 present in the userlevel definition of the
573 struct. */
574 tprintf("{%d}", sev._sigev_un._pad[0]);
Dmitry V. Levinae5aa472013-11-11 23:54:30 +0000575#elif defined(HAVE_STRUCT_SIGEVENT___PAD)
576 tprintf("{%d}", sev.__pad[0]);
577#else
578# warning unfamiliar struct sigevent => incomplete SIGEV_THREAD_ID decoding
579 tprints("{...}");
580#endif
Roland McGrathd4c85eb2004-04-16 21:48:44 +0000581 else if (sev.sigev_notify == SIGEV_THREAD)
582 tprintf("{%p, %p}", sev.sigev_notify_function,
583 sev.sigev_notify_attributes);
Roland McGrath1e356792003-03-30 23:52:28 +0000584 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200585 tprints("{...}");
586 tprints("}");
Roland McGrath1e356792003-03-30 23:52:28 +0000587 }
588}
589
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000590SYS_FUNC(timer_create)
Roland McGrath1e356792003-03-30 23:52:28 +0000591{
592 if (entering(tcp)) {
Stefan Sørensena5fea902014-02-03 10:01:27 +0100593 printclockname(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200594 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000595 printsigevent(tcp, tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200596 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000597 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000598 printnum_int(tcp, tcp->u_arg[2], "%d");
Roland McGrath1e356792003-03-30 23:52:28 +0000599 }
600 return 0;
601}
602
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000603SYS_FUNC(timer_settime)
Roland McGrath1e356792003-03-30 23:52:28 +0000604{
605 if (entering(tcp)) {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000606 tprintf("%d, ", (int) tcp->u_arg[0]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000607 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200608 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000609 printitv(tcp, tcp->u_arg[2]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200610 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000611 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000612 printitv(tcp, tcp->u_arg[3]);
Roland McGrath1e356792003-03-30 23:52:28 +0000613 }
614 return 0;
615}
616
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000617SYS_FUNC(timer_gettime)
Roland McGrath1e356792003-03-30 23:52:28 +0000618{
619 if (entering(tcp)) {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000620 tprintf("%d, ", (int) tcp->u_arg[0]);
Roland McGrath1e356792003-03-30 23:52:28 +0000621 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000622 printitv(tcp, tcp->u_arg[1]);
Roland McGrath1e356792003-03-30 23:52:28 +0000623 }
624 return 0;
625}
Roland McGrathd83c50b2004-10-06 22:27:43 +0000626
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000627#include "xlat/timerfdflags.h"
Roland McGrathe4662342007-08-02 01:25:34 +0000628
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000629SYS_FUNC(timerfd)
Roland McGrathe4662342007-08-02 01:25:34 +0000630{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000631 /* It does not matter that the kernel uses itimerspec. */
632 tprintf("%ld, ", tcp->u_arg[0]);
633 printclockname(tcp->u_arg[0]);
634 tprints(", ");
635 printflags(timerfdflags, tcp->u_arg[2], "TFD_???");
636 tprints(", ");
637 printitv(tcp, tcp->u_arg[3]);
638
Dmitry V. Levin07c878a2015-08-02 01:37:19 +0000639 return RVAL_DECODED | RVAL_FD;
Roland McGrathe4662342007-08-02 01:25:34 +0000640}
Roland McGrathde328e62008-05-20 04:56:13 +0000641
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000642SYS_FUNC(timerfd_create)
Roland McGrathde328e62008-05-20 04:56:13 +0000643{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000644 printclockname(tcp->u_arg[0]);
645 tprints(", ");
646 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
647
Dmitry V. Levin07c878a2015-08-02 01:37:19 +0000648 return RVAL_DECODED | RVAL_FD;
Roland McGrathde328e62008-05-20 04:56:13 +0000649}
650
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000651SYS_FUNC(timerfd_settime)
Roland McGrathde328e62008-05-20 04:56:13 +0000652{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000653 printfd(tcp, tcp->u_arg[0]);
654 tprints(", ");
655 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
656 tprints(", ");
657 printitv(tcp, tcp->u_arg[2]);
658 tprints(", ");
659 printitv(tcp, tcp->u_arg[3]);
660
661 return RVAL_DECODED;
Roland McGrathde328e62008-05-20 04:56:13 +0000662}
663
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000664SYS_FUNC(timerfd_gettime)
Roland McGrathde328e62008-05-20 04:56:13 +0000665{
666 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300667 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200668 tprints(", ");
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000669 } else {
Roland McGrathde328e62008-05-20 04:56:13 +0000670 printitv(tcp, tcp->u_arg[1]);
671 }
672 return 0;
673}