(root)/
strace-6.5/
src/
time.c
       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-2021 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: LGPL-2.1-or-later
       9   */
      10  
      11  #include "defs.h"
      12  #include "kernel_fcntl.h"
      13  #include <signal.h>
      14  #include <sys/timex.h>
      15  
      16  #if HAVE_ARCH_TIME32_SYSCALLS || HAVE_ARCH_OLD_TIME64_SYSCALLS
      17  static void
      18  print_timezone(struct tcb *const tcp, const kernel_ulong_t addr)
      19  {
      20  	struct timezone tz;
      21  
      22  	if (umove_or_printaddr(tcp, addr, &tz))
      23  		return;
      24  
      25  	tprint_struct_begin();
      26  	PRINT_FIELD_D(tz, tz_minuteswest);
      27  	tprint_struct_next();
      28  	PRINT_FIELD_D(tz, tz_dsttime);
      29  	tprint_struct_end();
      30  }
      31  
      32  SYS_FUNC(gettimeofday)
      33  {
      34  	if (exiting(tcp)) {
      35  		/* tv */
      36  		print_timeval(tcp, tcp->u_arg[0]);
      37  		tprint_arg_next();
      38  
      39  		/* tz */
      40  		print_timezone(tcp, tcp->u_arg[1]);
      41  	}
      42  	return 0;
      43  }
      44  
      45  SYS_FUNC(settimeofday)
      46  {
      47  	/* tv */
      48  	print_timeval(tcp, tcp->u_arg[0]);
      49  	tprint_arg_next();
      50  
      51  	/* tz */
      52  	print_timezone(tcp, tcp->u_arg[1]);
      53  
      54  	return RVAL_DECODED;
      55  }
      56  #endif
      57  
      58  #ifdef ALPHA
      59  SYS_FUNC(osf_gettimeofday)
      60  {
      61  	if (exiting(tcp)) {
      62  		/* tv */
      63  		print_timeval32(tcp, tcp->u_arg[0]);
      64  		tprint_arg_next();
      65  
      66  		/* tz */
      67  		print_timezone(tcp, tcp->u_arg[1]);
      68  	}
      69  	return 0;
      70  }
      71  #endif
      72  
      73  #ifdef ALPHA
      74  SYS_FUNC(osf_settimeofday)
      75  {
      76  	/* tv */
      77  	print_timeval32(tcp, tcp->u_arg[0]);
      78  	tprint_arg_next();
      79  
      80  	/* tz */
      81  	print_timezone(tcp, tcp->u_arg[1]);
      82  
      83  	return RVAL_DECODED;
      84  }
      85  #endif
      86  
      87  #if HAVE_ARCH_TIME32_SYSCALLS || HAVE_ARCH_OLD_TIME64_SYSCALLS
      88  static int
      89  do_nanosleep(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
      90  {
      91  	if (entering(tcp)) {
      92  		/* req */
      93  		print_ts(tcp, tcp->u_arg[0]);
      94  		tprint_arg_next();
      95  	} else {
      96  		/* rem */
      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_ts(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  #endif /* HAVE_ARCH_TIME32_SYSCALLS || HAVE_ARCH_OLD_TIME64_SYSCALLS */
     114  
     115  #if HAVE_ARCH_TIME32_SYSCALLS
     116  SYS_FUNC(nanosleep_time32)
     117  {
     118  	return do_nanosleep(tcp, print_timespec32);
     119  }
     120  #endif
     121  
     122  #if HAVE_ARCH_OLD_TIME64_SYSCALLS
     123  SYS_FUNC(nanosleep_time64)
     124  {
     125  	return do_nanosleep(tcp, print_timespec64);
     126  }
     127  #endif
     128  
     129  #include "xlat/itimer_which.h"
     130  
     131  SYS_FUNC(getitimer)
     132  {
     133  	if (entering(tcp)) {
     134  		/* which */
     135  		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
     136  		tprint_arg_next();
     137  	} else {
     138  		/* curr_value */
     139  		print_itimerval(tcp, tcp->u_arg[1]);
     140  	}
     141  	return 0;
     142  }
     143  
     144  #ifdef ALPHA
     145  SYS_FUNC(osf_getitimer)
     146  {
     147  	if (entering(tcp)) {
     148  		/* which */
     149  		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
     150  		tprint_arg_next();
     151  	} else {
     152  		/* curr_value */
     153  		print_itimerval32(tcp, tcp->u_arg[1]);
     154  	}
     155  	return 0;
     156  }
     157  #endif
     158  
     159  SYS_FUNC(setitimer)
     160  {
     161  	if (entering(tcp)) {
     162  		/* which */
     163  		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
     164  		tprint_arg_next();
     165  
     166  		/* new_value */
     167  		print_itimerval(tcp, tcp->u_arg[1]);
     168  		tprint_arg_next();
     169  	} else {
     170  		/* old_value */
     171  		print_itimerval(tcp, tcp->u_arg[2]);
     172  	}
     173  	return 0;
     174  }
     175  
     176  #ifdef ALPHA
     177  SYS_FUNC(osf_setitimer)
     178  {
     179  	if (entering(tcp)) {
     180  		/* which */
     181  		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
     182  		tprint_arg_next();
     183  
     184  		/* new_value */
     185  		print_itimerval32(tcp, tcp->u_arg[1]);
     186  		tprint_arg_next();
     187  	} else {
     188  		/* old_value */
     189  		print_itimerval32(tcp, tcp->u_arg[2]);
     190  	}
     191  	return 0;
     192  }
     193  #endif
     194  
     195  #include "xlat/adjtimex_state.h"
     196  
     197  static int
     198  do_adjtimex(struct tcb *const tcp, const print_obj_by_addr_fn print_tx,
     199  	    const kernel_ulong_t addr)
     200  {
     201  	/* buf */
     202  	if (print_tx(tcp, addr))
     203  		return 0;
     204  	tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval);
     205  	return RVAL_STR;
     206  }
     207  
     208  #if HAVE_ARCH_TIME32_SYSCALLS
     209  SYS_FUNC(adjtimex32)
     210  {
     211  	if (exiting(tcp))
     212  		return do_adjtimex(tcp, print_timex32, tcp->u_arg[0]);
     213  	return 0;
     214  }
     215  #endif
     216  
     217  #if HAVE_ARCH_OLD_TIME64_SYSCALLS
     218  SYS_FUNC(adjtimex64)
     219  {
     220  	if (exiting(tcp))
     221  # ifndef SPARC64
     222  		return do_adjtimex(tcp, print_timex64, tcp->u_arg[0]);
     223  # else
     224  		return do_adjtimex(tcp, print_sparc64_timex, tcp->u_arg[0]);
     225  # endif
     226  	return 0;
     227  }
     228  #endif
     229  
     230  #include "xlat/clockflags.h"
     231  #include "xlat/clocknames.h"
     232  
     233  static void
     234  printclockname(int clockid)
     235  {
     236  #ifdef CLOCKID_TO_FD
     237  # include "xlat/cpuclocknames.h"
     238  
     239  	if (clockid < 0) {
     240  		if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
     241  			PRINT_VAL_D(clockid);
     242  
     243  		if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
     244  			return;
     245  
     246  		if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
     247  			tprint_comment_begin();
     248  
     249  		if ((clockid & CLOCKFD_MASK) == CLOCKFD)
     250  			tprints_arg_begin("FD_TO_CLOCKID");
     251  			PRINT_VAL_D(CLOCKID_TO_FD(clockid));
     252  		else {
     253  			tprints_arg_begin(CPUCLOCK_PERTHREAD(clockid) ?
     254  					  "MAKE_THREAD_CPUCLOCK" :
     255  					  "MAKE_PROCESS_CPUCLOCK");
     256  			PRINT_VAL_D(CPUCLOCK_PID(clockid));
     257  			tprint_arg_next();
     258  			printxval(cpuclocknames, clockid & CLOCKFD_MASK,
     259  				  "CPUCLOCK_???");
     260  		}
     261  		tprint_arg_end();
     262  
     263  		if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
     264  			tprint_comment_end();
     265  	} else
     266  #endif
     267  		printxval(clocknames, clockid, "CLOCK_???");
     268  }
     269  
     270  static int
     271  do_clock_settime(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
     272  {
     273  	/* clockid */
     274  	printclockname(tcp->u_arg[0]);
     275  	tprint_arg_next();
     276  
     277  	/* tp */
     278  	print_ts(tcp, tcp->u_arg[1]);
     279  
     280  	return RVAL_DECODED;
     281  }
     282  
     283  #if HAVE_ARCH_TIME32_SYSCALLS
     284  SYS_FUNC(clock_settime32)
     285  {
     286  	return do_clock_settime(tcp, print_timespec32);
     287  }
     288  #endif
     289  
     290  SYS_FUNC(clock_settime64)
     291  {
     292  	return do_clock_settime(tcp, print_timespec64);
     293  }
     294  
     295  static int
     296  do_clock_gettime(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
     297  {
     298  	if (entering(tcp)) {
     299  		/* clockid */
     300  		printclockname(tcp->u_arg[0]);
     301  		tprint_arg_next();
     302  	} else {
     303  		/* tp */
     304  		print_ts(tcp, tcp->u_arg[1]);
     305  	}
     306  	return 0;
     307  }
     308  
     309  #if HAVE_ARCH_TIME32_SYSCALLS
     310  SYS_FUNC(clock_gettime32)
     311  {
     312  	return do_clock_gettime(tcp, print_timespec32);
     313  }
     314  #endif
     315  
     316  SYS_FUNC(clock_gettime64)
     317  {
     318  	return do_clock_gettime(tcp, print_timespec64);
     319  }
     320  
     321  static int
     322  do_clock_nanosleep(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
     323  {
     324  	if (entering(tcp)) {
     325  		/* clockid */
     326  		printclockname(tcp->u_arg[0]);
     327  		tprint_arg_next();
     328  
     329  		/* flags */
     330  		printflags(clockflags, tcp->u_arg[1], "TIMER_???");
     331  		tprint_arg_next();
     332  
     333  		/* request */
     334  		print_ts(tcp, tcp->u_arg[2]);
     335  		tprint_arg_next();
     336  	} else {
     337  		/* remain */
     338  		/*
     339  		 * Second (returned) timespec is only significant
     340  		 * if syscall was interrupted and flags is not TIMER_ABSTIME.
     341  		 */
     342  		if (!tcp->u_arg[1] && is_erestart(tcp)) {
     343  			temporarily_clear_syserror(tcp);
     344  			print_ts(tcp, tcp->u_arg[3]);
     345  			restore_cleared_syserror(tcp);
     346  		} else {
     347  			printaddr(tcp->u_arg[3]);
     348  		}
     349  	}
     350  	return 0;
     351  }
     352  
     353  #if HAVE_ARCH_TIME32_SYSCALLS
     354  SYS_FUNC(clock_nanosleep_time32)
     355  {
     356  	return do_clock_nanosleep(tcp, print_timespec32);
     357  }
     358  #endif
     359  
     360  SYS_FUNC(clock_nanosleep_time64)
     361  {
     362  	return do_clock_nanosleep(tcp, print_timespec64);
     363  }
     364  
     365  static int
     366  do_clock_adjtime(struct tcb *const tcp, const print_obj_by_addr_fn print_tx)
     367  {
     368  	if (entering(tcp)) {
     369  		/* clockid */
     370  		printclockname(tcp->u_arg[0]);
     371  		tprint_arg_next();
     372  		return 0;
     373  	} else {
     374  		return do_adjtimex(tcp, print_tx, tcp->u_arg[1]);
     375  	}
     376  }
     377  
     378  #if HAVE_ARCH_TIME32_SYSCALLS
     379  SYS_FUNC(clock_adjtime32)
     380  {
     381  	return do_clock_adjtime(tcp, print_timex32);
     382  }
     383  #endif
     384  
     385  SYS_FUNC(clock_adjtime64)
     386  {
     387  	return do_clock_adjtime(tcp, print_timex64);
     388  }
     389  
     390  #ifdef SPARC64
     391  SYS_FUNC(clock_sparc64_adjtime)
     392  {
     393  	return do_clock_adjtime(tcp, print_sparc64_timex);
     394  }
     395  #endif
     396  
     397  SYS_FUNC(timer_create)
     398  {
     399  	if (entering(tcp)) {
     400  		/* clockid */
     401  		printclockname(tcp->u_arg[0]);
     402  		tprint_arg_next();
     403  
     404  		/* sevp */
     405  		print_sigevent(tcp, tcp->u_arg[1]);
     406  		tprint_arg_next();
     407  	} else {
     408  		/* timerid */
     409  		printnum_int(tcp, tcp->u_arg[2], "%d");
     410  	}
     411  	return 0;
     412  }
     413  
     414  static int
     415  do_timer_settime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
     416  {
     417  	if (entering(tcp)) {
     418  		/* timerid */
     419  		PRINT_VAL_D((int) tcp->u_arg[0]);
     420  		tprint_arg_next();
     421  
     422  		/* flags */
     423  		printflags(clockflags, tcp->u_arg[1], "TIMER_???");
     424  		tprint_arg_next();
     425  
     426  		/* new_value */
     427  		print_its(tcp, tcp->u_arg[2]);
     428  		tprint_arg_next();
     429  	} else {
     430  		/* old_value */
     431  		print_its(tcp, tcp->u_arg[3]);
     432  	}
     433  	return 0;
     434  }
     435  
     436  #if HAVE_ARCH_TIME32_SYSCALLS
     437  SYS_FUNC(timer_settime32)
     438  {
     439  	return do_timer_settime(tcp, print_itimerspec32);
     440  }
     441  #endif
     442  
     443  SYS_FUNC(timer_settime64)
     444  {
     445  	return do_timer_settime(tcp, print_itimerspec64);
     446  }
     447  
     448  static int
     449  do_timer_gettime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
     450  {
     451  	if (entering(tcp)) {
     452  		/* timerid */
     453  		PRINT_VAL_D((int) tcp->u_arg[0]);
     454  		tprint_arg_next();
     455  	} else {
     456  		/* curr_value */
     457  		print_its(tcp, tcp->u_arg[1]);
     458  	}
     459  	return 0;
     460  }
     461  
     462  #if HAVE_ARCH_TIME32_SYSCALLS
     463  SYS_FUNC(timer_gettime32)
     464  {
     465  	return do_timer_gettime(tcp, print_itimerspec32);
     466  }
     467  #endif
     468  
     469  SYS_FUNC(timer_gettime64)
     470  {
     471  	return do_timer_gettime(tcp, print_itimerspec64);
     472  }
     473  
     474  #include "xlat/timerfdflags.h"
     475  
     476  SYS_FUNC(timerfd_create)
     477  {
     478  	/* clockid */
     479  	printclockname(tcp->u_arg[0]);
     480  	tprint_arg_next();
     481  
     482  	/* flags */
     483  	printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
     484  
     485  	return RVAL_DECODED | RVAL_FD;
     486  }
     487  
     488  static int
     489  do_timerfd_settime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
     490  {
     491  	if (entering(tcp)) {
     492  		/* fd */
     493  		printfd(tcp, tcp->u_arg[0]);
     494  		tprint_arg_next();
     495  
     496  		/* flags */
     497  		printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
     498  		tprint_arg_next();
     499  
     500  		/* new_value */
     501  		print_its(tcp, tcp->u_arg[2]);
     502  		tprint_arg_next();
     503  	} else {
     504  		/* old_value */
     505  		print_its(tcp, tcp->u_arg[3]);
     506  	}
     507  	return 0;
     508  }
     509  
     510  #if HAVE_ARCH_TIME32_SYSCALLS
     511  SYS_FUNC(timerfd_settime32)
     512  {
     513  	return do_timerfd_settime(tcp, print_itimerspec32);
     514  }
     515  #endif
     516  
     517  SYS_FUNC(timerfd_settime64)
     518  {
     519  	return do_timerfd_settime(tcp, print_itimerspec64);
     520  }
     521  
     522  static int
     523  do_timerfd_gettime(struct tcb *const tcp, const print_obj_by_addr_fn print_its)
     524  {
     525  	if (entering(tcp)) {
     526  		/* fd */
     527  		printfd(tcp, tcp->u_arg[0]);
     528  		tprint_arg_next();
     529  	} else {
     530  		/* curr_value */
     531  		print_its(tcp, tcp->u_arg[1]);
     532  	}
     533  	return 0;
     534  }
     535  
     536  #if HAVE_ARCH_TIME32_SYSCALLS
     537  SYS_FUNC(timerfd_gettime32)
     538  {
     539  	return do_timerfd_gettime(tcp, print_itimerspec32);
     540  }
     541  #endif
     542  
     543  SYS_FUNC(timerfd_gettime64)
     544  {
     545  	return do_timerfd_gettime(tcp, print_itimerspec64);
     546  }