blob: a373641fab8b55caa3d8afa46302db7de9004921 [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
399#if LINUX_VERSION_CODE < 66332
400 tprintf("{mode=%d, offset=%ld, frequency=%ld, ",
401 tx.mode, tx.offset, tx.frequency);
402 tprintf("maxerror=%ld, esterror=%lu, status=%u, ",
403 tx.maxerror, tx.esterror, tx.status);
404 tprintf("time_constant=%ld, precision=%lu, ",
405 tx.time_constant, tx.precision);
406 tprintf("tolerance=%ld, time=", tx.tolerance);
407 tprint_timeval(tcp, &tx.time);
408#else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200409 tprints("{modes=");
Dmitry V. Levin71d70892007-01-13 11:17:38 +0000410 printflags(adjtimex_modes, tx.modes, "ADJ_???");
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000411 tprintf(", offset=%jd, freq=%jd, maxerror=%ju, esterror=%ju, status=",
412 (intmax_t) tx.offset, (intmax_t) tx.freq,
413 (uintmax_t) tx.maxerror, (uintmax_t) tx.esterror);
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000414 printflags(adjtimex_status, tx.status, "STA_???");
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000415 tprintf(", constant=%jd, precision=%ju, tolerance=%jd, time=",
416 (intmax_t) tx.constant, (uintmax_t) tx.precision,
417 (intmax_t) tx.tolerance);
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000418 tprint_timeval(tcp, &tx.time);
Dmitry V. Levine61086f2015-02-27 21:46:42 +0000419 tprintf(", tick=%jd, ppsfreq=%jd, jitter=%jd",
420 (intmax_t) tx.tick, (intmax_t) tx.ppsfreq, (intmax_t) tx.jitter);
421 tprintf(", shift=%d, stabil=%jd, jitcnt=%jd",
422 tx.shift, (intmax_t) tx.stabil, (intmax_t) tx.jitcnt);
423 tprintf(", calcnt=%jd, errcnt=%jd, stbcnt=%jd",
424 (intmax_t) tx.calcnt, (intmax_t) tx.errcnt, (intmax_t) tx.stbcnt);
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000425#endif
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200426 tprints("}");
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000427 return 0;
428}
429
Dmitry V. Levin73215472012-03-11 21:25:51 +0000430static int
431do_adjtimex(struct tcb *tcp, long addr)
432{
Dmitry V. Levin71178352015-07-16 18:18:09 +0000433 if (tprint_timex(tcp, addr))
Dmitry V. Levin73215472012-03-11 21:25:51 +0000434 return 0;
435 tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
436 if (tcp->auxstr)
437 return RVAL_STR;
438 return 0;
439}
440
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000441SYS_FUNC(adjtimex)
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000442{
Dmitry V. Levin73215472012-03-11 21:25:51 +0000443 if (exiting(tcp))
444 return do_adjtimex(tcp, tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000445 return 0;
446}
Roland McGrath1e356792003-03-30 23:52:28 +0000447
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000448#include "xlat/clockflags.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000449#include "xlat/clocknames.h"
Roland McGrath54a4edd2004-08-31 06:52:45 +0000450
Stefan Sørensena5fea902014-02-03 10:01:27 +0100451static void
452printclockname(int clockid)
453{
454#ifdef CLOCKID_TO_FD
Dmitry V. Levind35bdca2014-04-26 18:10:19 +0000455# include "xlat/cpuclocknames.h"
456
Stefan Sørensena5fea902014-02-03 10:01:27 +0100457 if (clockid < 0) {
458 if ((clockid & CLOCKFD_MASK) == CLOCKFD)
459 tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
460 else {
461 if(CPUCLOCK_PERTHREAD(clockid))
462 tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
463 else
464 tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
465 printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???");
466 tprints(")");
467 }
468 }
469 else
470#endif
471 printxval(clocknames, clockid, "CLOCK_???");
472}
473
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000474SYS_FUNC(clock_settime)
Roland McGrath1e356792003-03-30 23:52:28 +0000475{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000476 printclockname(tcp->u_arg[0]);
477 tprints(", ");
478 printtv(tcp, tcp->u_arg[1]);
479
480 return RVAL_DECODED;
Roland McGrath1e356792003-03-30 23:52:28 +0000481}
482
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000483SYS_FUNC(clock_gettime)
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 McGrath1e356792003-03-30 23:52:28 +0000488 } else {
Dmitry V. Levin9f702732015-07-16 16:22:07 +0000489 printtv(tcp, tcp->u_arg[1]);
Roland McGrath1e356792003-03-30 23:52:28 +0000490 }
491 return 0;
492}
493
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000494SYS_FUNC(clock_nanosleep)
Roland McGrath1e356792003-03-30 23:52:28 +0000495{
496 if (entering(tcp)) {
Stefan Sørensena5fea902014-02-03 10:01:27 +0100497 printclockname(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200498 tprints(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000499 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200500 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000501 printtv(tcp, tcp->u_arg[2]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200502 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000503 } else {
Dmitry V. Levin9f702732015-07-16 16:22:07 +0000504 printtv(tcp, tcp->u_arg[3]);
Roland McGrath1e356792003-03-30 23:52:28 +0000505 }
506 return 0;
507}
508
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000509SYS_FUNC(clock_adjtime)
Dmitry V. Levin73215472012-03-11 21:25:51 +0000510{
511 if (exiting(tcp))
512 return do_adjtimex(tcp, tcp->u_arg[1]);
Stefan Sørensena5fea902014-02-03 10:01:27 +0100513 printclockname(tcp->u_arg[0]);
Dmitry V. Levin73215472012-03-11 21:25:51 +0000514 tprints(", ");
515 return 0;
516}
517
Roland McGrath1e356792003-03-30 23:52:28 +0000518#ifndef SIGEV_THREAD_ID
519# define SIGEV_THREAD_ID 4
520#endif
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000521#include "xlat/sigev_value.h"
Roland McGrath1e356792003-03-30 23:52:28 +0000522
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000523#if SUPPORTED_PERSONALITIES > 1
524static void
525printsigevent32(struct tcb *tcp, long arg)
526{
Denys Vlasenko1d632462009-04-14 12:51:00 +0000527 struct {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000528 int sigev_value;
529 int sigev_signo;
530 int sigev_notify;
531
Denys Vlasenko1d632462009-04-14 12:51:00 +0000532 union {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000533 int tid;
Denys Vlasenko1d632462009-04-14 12:51:00 +0000534 struct {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000535 int function, attribute;
536 } thread;
537 } un;
538 } sev;
539
Dmitry V. Levin71178352015-07-16 18:18:09 +0000540 if (!umove_or_printaddr(tcp, arg, &sev)) {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000541 tprintf("{%#x, ", sev.sigev_value);
542 if (sev.sigev_notify == SIGEV_SIGNAL)
543 tprintf("%s, ", signame(sev.sigev_signo));
544 else
545 tprintf("%u, ", sev.sigev_signo);
Dmitry V. Levinbae549e2014-02-05 01:46:10 +0000546 printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200547 tprints(", ");
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000548 if (sev.sigev_notify == SIGEV_THREAD_ID)
549 tprintf("{%d}", sev.un.tid);
550 else if (sev.sigev_notify == SIGEV_THREAD)
551 tprintf("{%#x, %#x}",
552 sev.un.thread.function,
553 sev.un.thread.attribute);
554 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200555 tprints("{...}");
556 tprints("}");
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000557 }
558}
559#endif
560
Roland McGrath1e356792003-03-30 23:52:28 +0000561void
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000562printsigevent(struct tcb *tcp, long arg)
Roland McGrath1e356792003-03-30 23:52:28 +0000563{
564 struct sigevent sev;
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000565
566#if SUPPORTED_PERSONALITIES > 1
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100567 if (current_wordsize == 4) {
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000568 printsigevent32(tcp, arg);
569 return;
570 }
571#endif
Dmitry V. Levin71178352015-07-16 18:18:09 +0000572 if (!umove_or_printaddr(tcp, arg, &sev)) {
Roland McGrath675d4a62004-09-11 08:12:45 +0000573 tprintf("{%p, ", sev.sigev_value.sival_ptr);
574 if (sev.sigev_notify == SIGEV_SIGNAL)
575 tprintf("%s, ", signame(sev.sigev_signo));
576 else
577 tprintf("%u, ", sev.sigev_signo);
Dmitry V. Levinbae549e2014-02-05 01:46:10 +0000578 printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200579 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000580 if (sev.sigev_notify == SIGEV_THREAD_ID)
Dmitry V. Levinae5aa472013-11-11 23:54:30 +0000581#if defined(HAVE_STRUCT_SIGEVENT__SIGEV_UN__PAD)
Roland McGrath1e356792003-03-30 23:52:28 +0000582 /* _pad[0] is the _tid field which might not be
583 present in the userlevel definition of the
584 struct. */
585 tprintf("{%d}", sev._sigev_un._pad[0]);
Dmitry V. Levinae5aa472013-11-11 23:54:30 +0000586#elif defined(HAVE_STRUCT_SIGEVENT___PAD)
587 tprintf("{%d}", sev.__pad[0]);
588#else
589# warning unfamiliar struct sigevent => incomplete SIGEV_THREAD_ID decoding
590 tprints("{...}");
591#endif
Roland McGrathd4c85eb2004-04-16 21:48:44 +0000592 else if (sev.sigev_notify == SIGEV_THREAD)
593 tprintf("{%p, %p}", sev.sigev_notify_function,
594 sev.sigev_notify_attributes);
Roland McGrath1e356792003-03-30 23:52:28 +0000595 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200596 tprints("{...}");
597 tprints("}");
Roland McGrath1e356792003-03-30 23:52:28 +0000598 }
599}
600
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000601SYS_FUNC(timer_create)
Roland McGrath1e356792003-03-30 23:52:28 +0000602{
603 if (entering(tcp)) {
Stefan Sørensena5fea902014-02-03 10:01:27 +0100604 printclockname(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200605 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000606 printsigevent(tcp, tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200607 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000608 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000609 printnum_int(tcp, tcp->u_arg[2], "%d");
Roland McGrath1e356792003-03-30 23:52:28 +0000610 }
611 return 0;
612}
613
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000614SYS_FUNC(timer_settime)
Roland McGrath1e356792003-03-30 23:52:28 +0000615{
616 if (entering(tcp)) {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000617 tprintf("%d, ", (int) tcp->u_arg[0]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000618 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200619 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000620 printitv(tcp, tcp->u_arg[2]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200621 tprints(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000622 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000623 printitv(tcp, tcp->u_arg[3]);
Roland McGrath1e356792003-03-30 23:52:28 +0000624 }
625 return 0;
626}
627
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000628SYS_FUNC(timer_gettime)
Roland McGrath1e356792003-03-30 23:52:28 +0000629{
630 if (entering(tcp)) {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000631 tprintf("%d, ", (int) tcp->u_arg[0]);
Roland McGrath1e356792003-03-30 23:52:28 +0000632 } else {
Dmitry V. Levin71178352015-07-16 18:18:09 +0000633 printitv(tcp, tcp->u_arg[1]);
Roland McGrath1e356792003-03-30 23:52:28 +0000634 }
635 return 0;
636}
Roland McGrathd83c50b2004-10-06 22:27:43 +0000637
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000638#include "xlat/timerfdflags.h"
Roland McGrathe4662342007-08-02 01:25:34 +0000639
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000640SYS_FUNC(timerfd)
Roland McGrathe4662342007-08-02 01:25:34 +0000641{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000642 /* It does not matter that the kernel uses itimerspec. */
643 tprintf("%ld, ", tcp->u_arg[0]);
644 printclockname(tcp->u_arg[0]);
645 tprints(", ");
646 printflags(timerfdflags, tcp->u_arg[2], "TFD_???");
647 tprints(", ");
648 printitv(tcp, tcp->u_arg[3]);
649
650 return RVAL_DECODED;
Roland McGrathe4662342007-08-02 01:25:34 +0000651}
Roland McGrathde328e62008-05-20 04:56:13 +0000652
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000653SYS_FUNC(timerfd_create)
Roland McGrathde328e62008-05-20 04:56:13 +0000654{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000655 printclockname(tcp->u_arg[0]);
656 tprints(", ");
657 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
658
659 return RVAL_DECODED;
Roland McGrathde328e62008-05-20 04:56:13 +0000660}
661
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000662SYS_FUNC(timerfd_settime)
Roland McGrathde328e62008-05-20 04:56:13 +0000663{
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000664 printfd(tcp, tcp->u_arg[0]);
665 tprints(", ");
666 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
667 tprints(", ");
668 printitv(tcp, tcp->u_arg[2]);
669 tprints(", ");
670 printitv(tcp, tcp->u_arg[3]);
671
672 return RVAL_DECODED;
Roland McGrathde328e62008-05-20 04:56:13 +0000673}
674
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000675SYS_FUNC(timerfd_gettime)
Roland McGrathde328e62008-05-20 04:56:13 +0000676{
677 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300678 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200679 tprints(", ");
Dmitry V. Levin76c8f662015-07-16 21:07:06 +0000680 } else {
Roland McGrathde328e62008-05-20 04:56:13 +0000681 printitv(tcp, tcp->u_arg[1]);
682 }
683 return 0;
684}