(root)/
strace-6.5/
src/
print_timeval.c
       1  /*
       2   * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@strace.io>
       3   * Copyright (c) 2016-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: LGPL-2.1-or-later
       7   */
       8  
       9  #include "defs.h"
      10  
      11  #include DEF_MPERS_TYPE(timeval_t)
      12  
      13  #include "kernel_timeval.h"
      14  
      15  typedef kernel_old_timeval_t timeval_t;
      16  
      17  #include MPERS_DEFS
      18  
      19  #include "xstring.h"
      20  
      21  static const char timeval_fmt[]  = "{tv_sec=%lld, tv_usec=%llu}";
      22  
      23  static void
      24  print_timeval_t(const timeval_t *t)
      25  {
      26  	tprint_struct_begin();
      27  	PRINT_FIELD_D(*t, tv_sec);
      28  	tprint_struct_next();
      29  	PRINT_FIELD_U(*t, tv_usec);
      30  	tprint_struct_end();
      31  }
      32  
      33  static bool
      34  print_timeval_t_utime(struct tcb *tcp, void *elem_buf, size_t elem_size,
      35  		      void *data)
      36  {
      37  	const timeval_t *const t = elem_buf;
      38  	print_timeval_t(t);
      39  	tprints_comment(sprinttime_usec(t->tv_sec,
      40  		zero_extend_signed_to_ull(t->tv_usec)));
      41  	return true;
      42  }
      43  
      44  MPERS_PRINTER_DECL(void, print_struct_timeval, const void *arg)
      45  {
      46  	print_timeval_t(arg);
      47  }
      48  
      49  MPERS_PRINTER_DECL(bool, print_struct_timeval_data_size,
      50  		   const void *arg, const size_t size)
      51  {
      52  	if (size < sizeof(timeval_t)) {
      53  		tprint_unavailable();
      54  		return false;
      55  	}
      56  
      57  	print_timeval_t(arg);
      58  	return true;
      59  }
      60  
      61  MPERS_PRINTER_DECL(int, print_timeval,
      62  		   struct tcb *const tcp, const kernel_ulong_t addr)
      63  {
      64  	timeval_t t;
      65  
      66  	if (umove_or_printaddr(tcp, addr, &t))
      67  		return -1;
      68  
      69  	print_timeval_t(&t);
      70  	return 0;
      71  }
      72  
      73  MPERS_PRINTER_DECL(int, print_timeval_utimes,
      74  		   struct tcb *const tcp, const kernel_ulong_t addr)
      75  {
      76  	timeval_t t[2];
      77  
      78  	if (umove_or_printaddr(tcp, addr, &t))
      79  		return -1;
      80  
      81  	print_local_array(tcp, t, print_timeval_t_utime);
      82  	return 0;
      83  }
      84  
      85  MPERS_PRINTER_DECL(const char *, sprint_timeval,
      86  		   struct tcb *const tcp, const kernel_ulong_t addr)
      87  {
      88  	timeval_t t;
      89  	static char buf[sizeof(timeval_fmt) + 3 * sizeof(t)];
      90  
      91  	if (!addr) {
      92  		strcpy(buf, "NULL");
      93  	} else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
      94  		   umove(tcp, addr, &t)) {
      95  		xsprintf(buf, "%#" PRI_klx, addr);
      96  	} else {
      97  		xsprintf(buf, timeval_fmt,
      98  			 (long long) t.tv_sec,
      99  			 zero_extend_signed_to_ull(t.tv_usec));
     100  	}
     101  
     102  	return buf;
     103  }
     104  
     105  MPERS_PRINTER_DECL(int, print_itimerval,
     106  		   struct tcb *const tcp, const kernel_ulong_t addr)
     107  {
     108  	struct { timeval_t it_interval, it_value; } t;
     109  
     110  	if (umove_or_printaddr(tcp, addr, &t))
     111  		return -1;
     112  
     113  	tprint_struct_begin();
     114  	PRINT_FIELD_OBJ_PTR(t, it_interval, print_timeval_t);
     115  	tprint_struct_next();
     116  	PRINT_FIELD_OBJ_PTR(t, it_value, print_timeval_t);
     117  	tprint_struct_end();
     118  	return 0;
     119  }
     120  
     121  #ifdef ALPHA
     122  
     123  void
     124  print_timeval32_t(const timeval32_t *t)
     125  {
     126  	tprint_struct_begin();
     127  	PRINT_FIELD_D(*t, tv_sec);
     128  	tprint_struct_next();
     129  	PRINT_FIELD_U(*t, tv_usec);
     130  	tprint_struct_end();
     131  }
     132  
     133  static bool
     134  print_timeval32_t_utime(struct tcb *tcp, void *elem_buf, size_t elem_size,
     135  			void *data)
     136  {
     137  	const timeval32_t *const t = elem_buf;
     138  	print_timeval32_t(t);
     139  	tprints_comment(sprinttime_usec(t->tv_sec,
     140  		zero_extend_signed_to_ull(t->tv_usec)));
     141  	return true;
     142  }
     143  
     144  int
     145  print_timeval32(struct tcb *const tcp, const kernel_ulong_t addr)
     146  {
     147  	timeval32_t t;
     148  
     149  	if (umove_or_printaddr(tcp, addr, &t))
     150  		return -1;
     151  
     152  	print_timeval32_t(&t);
     153  	return 0;
     154  }
     155  
     156  int
     157  print_timeval32_utimes(struct tcb *const tcp, const kernel_ulong_t addr)
     158  {
     159  	timeval32_t t[2];
     160  
     161  	if (umove_or_printaddr(tcp, addr, &t))
     162  		return -1;
     163  
     164  	print_local_array(tcp, t, print_timeval32_t_utime);
     165  	return 0;
     166  }
     167  
     168  int
     169  print_itimerval32(struct tcb *const tcp, const kernel_ulong_t addr)
     170  {
     171  	struct { timeval32_t it_interval, it_value; } t;
     172  
     173  	if (umove_or_printaddr(tcp, addr, &t))
     174  		return -1;
     175  
     176  	tprint_struct_begin();
     177  	PRINT_FIELD_OBJ_PTR(t, it_interval, print_timeval32_t);
     178  	tprint_struct_next();
     179  	PRINT_FIELD_OBJ_PTR(t, it_value, print_timeval32_t);
     180  	tprint_struct_end();
     181  	return 0;
     182  }
     183  
     184  const char *
     185  sprint_timeval32(struct tcb *const tcp, const kernel_ulong_t addr)
     186  {
     187  	timeval32_t t;
     188  	static char buf[sizeof(timeval_fmt) + 3 * sizeof(t)];
     189  
     190  	if (!addr) {
     191  		strcpy(buf, "NULL");
     192  	} else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
     193  		   umove(tcp, addr, &t)) {
     194  		xsprintf(buf, "%#" PRI_klx, addr);
     195  	} else {
     196  		xsprintf(buf, timeval_fmt,
     197  			 (long long) t.tv_sec,
     198  			 zero_extend_signed_to_ull(t.tv_usec));
     199  	}
     200  
     201  	return buf;
     202  }
     203  
     204  #endif /* ALPHA */