(root)/
strace-6.5/
src/
util.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-1999 Wichert Akkerman <wichert@cistron.nl>
       6   * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
       7   *                     Linux for s390 port by D.J. Barrow
       8   *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
       9   * Copyright (c) 1999-2023 The strace developers.
      10   * All rights reserved.
      11   *
      12   * SPDX-License-Identifier: LGPL-2.1-or-later
      13   */
      14  
      15  #include "defs.h"
      16  #include <limits.h>
      17  #include <fcntl.h>
      18  #include <stdarg.h>
      19  #include <sys/stat.h>
      20  #include <sys/sysmacros.h>
      21  #ifdef HAVE_SYS_XATTR_H
      22  # include <sys/xattr.h>
      23  #endif
      24  #include <sys/uio.h>
      25  
      26  #include "largefile_wrappers.h"
      27  #include "number_set.h"
      28  #include "print_fields.h"
      29  #include "print_utils.h"
      30  #include "secontext.h"
      31  #include "static_assert.h"
      32  #include "string_to_uint.h"
      33  #include "xlat.h"
      34  #include "xstring.h"
      35  
      36  const struct xlat_data *
      37  find_xlat_val_ex(const struct xlat_data * const items, const char * const s,
      38  		 const size_t num_items, const unsigned int flags)
      39  {
      40  	for (size_t i = 0; i < num_items; i++) {
      41  		if (!(flags & FXL_CASE_SENSITIVE ? strcmp
      42  						 : strcasecmp)(items[i].str, s))
      43  			return items + i;
      44  	}
      45  
      46  	return NULL;
      47  }
      48  
      49  uint64_t
      50  find_arg_val_(const char *arg, const struct xlat_data *strs, size_t strs_size,
      51  	       uint64_t default_val, uint64_t not_found)
      52  {
      53  	if (!arg)
      54  		return default_val;
      55  
      56  	const struct xlat_data *res = find_xlat_val_ex(strs, arg, strs_size, 0);
      57  
      58  	return  res ? res->val : not_found;
      59  }
      60  
      61  int
      62  str2timescale_ex(const char *arg, int empty_dflt, int null_dflt,
      63  		 int *width)
      64  {
      65  	static const struct xlat_data units[] = {
      66  		{ 1000000000U | (0ULL << 32), "s" },
      67  		{ 1000000U    | (3ULL << 32), "ms" },
      68  		{ 1000U       | (6ULL << 32), "us" },
      69  		{ 1U          | (9ULL << 32), "ns" },
      70  	};
      71  
      72  	if (!arg)
      73  		return null_dflt;
      74  	if (!arg[0])
      75  		return empty_dflt;
      76  
      77  	uint64_t res = find_arg_val(arg, units, null_dflt, -1ULL);
      78  
      79  	if (width && res != -1ULL)
      80  		*width = res >> 32;
      81  
      82  	return res & 0xffffffff;
      83  }
      84  
      85  int
      86  ts_nz(const struct timespec *a)
      87  {
      88  	return a->tv_sec || a->tv_nsec;
      89  }
      90  
      91  int
      92  ts_cmp(const struct timespec *a, const struct timespec *b)
      93  {
      94  	if (a->tv_sec < b->tv_sec
      95  	    || (a->tv_sec == b->tv_sec && a->tv_nsec < b->tv_nsec))
      96  		return -1;
      97  	if (a->tv_sec > b->tv_sec
      98  	    || (a->tv_sec == b->tv_sec && a->tv_nsec > b->tv_nsec))
      99  		return 1;
     100  	return 0;
     101  }
     102  
     103  double
     104  ts_float(const struct timespec *tv)
     105  {
     106  	return tv->tv_sec + tv->tv_nsec/1000000000.0;
     107  }
     108  
     109  void
     110  ts_add(struct timespec *tv, const struct timespec *a, const struct timespec *b)
     111  {
     112  	tv->tv_sec = a->tv_sec + b->tv_sec;
     113  	tv->tv_nsec = a->tv_nsec + b->tv_nsec;
     114  	if (tv->tv_nsec >= 1000000000) {
     115  		tv->tv_sec++;
     116  		tv->tv_nsec -= 1000000000;
     117  	}
     118  }
     119  
     120  void
     121  ts_sub(struct timespec *tv, const struct timespec *a, const struct timespec *b)
     122  {
     123  	tv->tv_sec = a->tv_sec - b->tv_sec;
     124  	tv->tv_nsec = a->tv_nsec - b->tv_nsec;
     125  	if (tv->tv_nsec < 0) {
     126  		tv->tv_sec--;
     127  		tv->tv_nsec += 1000000000;
     128  	}
     129  }
     130  
     131  void
     132  ts_div(struct timespec *tv, const struct timespec *a, uint64_t n)
     133  {
     134  	long long nsec = (a->tv_sec % n * 1000000000LL + a->tv_nsec + n / 2) / n;
     135  	tv->tv_sec = a->tv_sec / n + nsec / 1000000000;
     136  	tv->tv_nsec = nsec % 1000000000;
     137  }
     138  
     139  const struct timespec *
     140  ts_min(const struct timespec *a, const struct timespec *b)
     141  {
     142  	return ts_cmp(a, b) < 0 ? a : b;
     143  }
     144  
     145  const struct timespec *
     146  ts_max(const struct timespec *a, const struct timespec *b)
     147  {
     148  	return ts_cmp(a, b) > 0 ? a : b;
     149  }
     150  
     151  int
     152  parse_ts(const char *s, struct timespec *t)
     153  {
     154  	enum { NS_IN_S = 1000000000 };
     155  
     156  	static const char float_accept[] =  "eE.-+0123456789";
     157  	static const char int_accept[] = "+0123456789";
     158  
     159  	size_t float_len = strspn(s, float_accept);
     160  	size_t int_len = strspn(s, int_accept);
     161  	char *endptr = NULL;
     162  	double float_val = -1;
     163  	long long int_val = -1;
     164  
     165  	if (float_len > int_len) {
     166  		errno = 0;
     167  
     168  		float_val = strtod(s, &endptr);
     169  
     170  		if (endptr == s || errno)
     171  			return -1;
     172  		if (float_val < 0)
     173  			return -1;
     174  	} else {
     175  		int_val = string_to_uint_ex(s, &endptr, LLONG_MAX, "smun");
     176  
     177  		if (int_val < 0)
     178  			return -1;
     179  	}
     180  
     181  	int scale = str2timescale_sfx(endptr, NULL);
     182  	if (scale <= 0)
     183  		return -1;
     184  
     185  	if (float_len > int_len) {
     186  		t->tv_sec = float_val / (NS_IN_S / scale);
     187  		t->tv_nsec = ((uint64_t) ((float_val -
     188  					   (t->tv_sec * (NS_IN_S / scale)))
     189  					  * scale)) % NS_IN_S;
     190  	} else {
     191  		t->tv_sec = int_val / (NS_IN_S / scale);
     192  		t->tv_nsec = (int_val % (NS_IN_S / scale)) * scale;
     193  	}
     194  
     195  	return 0;
     196  }
     197  
     198  #define ILOG10_ITER_(val_, div_, ret_, pow_)	\
     199  	do {					\
     200  		if ((val_) >= (div_)) {		\
     201  			(val_) /= (div_);	\
     202  			(ret_) += (pow_);	\
     203  		}				\
     204  	} while (0)				\
     205  	/* End of ILOG10_ITER_ */
     206  
     207  /* Returns 0 for 0. */
     208  static int
     209  ilog10(uint64_t val)
     210  {
     211  	int ret = 0;
     212  
     213  	ILOG10_ITER_(val, 10000000000000000ULL, ret, 16);
     214  	ILOG10_ITER_(val, 100000000,            ret, 8);
     215  	ILOG10_ITER_(val, 10000,                ret, 4);
     216  	ILOG10_ITER_(val, 100,                  ret, 2);
     217  	ILOG10_ITER_(val, 10,                   ret, 1);
     218  
     219  	return ret;
     220  }
     221  
     222  void
     223  print_ticks(uint64_t val, long freq, unsigned int precision)
     224  {
     225  	PRINT_VAL_U(val);
     226  	if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_RAW
     227  	    && freq > 0 && val > 0) {
     228  		tprintf_comment("%" PRIu64 ".%0*" PRIu64 " s",
     229  				val / freq, precision, val % freq);
     230  	}
     231  }
     232  
     233  void
     234  print_ticks_d(int64_t val, long freq, unsigned int precision)
     235  {
     236  	PRINT_VAL_D(val);
     237  	/* freq > 1 to avoid special casing for val ==  */
     238  	if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_RAW
     239  	    && freq > 1 && val != 0) {
     240  		tprintf_comment("%s%lld.%0*lld s",
     241  				val < 0 ? "-" : "", llabs(val / freq),
     242  				precision, llabs(val % freq));
     243  	}
     244  }
     245  
     246  void
     247  print_clock_t(uint64_t val)
     248  {
     249  	static long clk_tck;
     250  	static int frac_width;
     251  
     252  	if (!clk_tck) {
     253  		errno = 0;
     254  		clk_tck = sysconf(_SC_CLK_TCK);
     255  		if (clk_tck == -1 && errno)
     256  			debug_func_perror_msg("sysconf(_SC_CLK_TCK)");
     257  		if (clk_tck == 0)
     258  			clk_tck = -1;
     259  		if (clk_tck > 0)
     260  			frac_width = MIN(ilog10(clk_tck), 9);
     261  	}
     262  
     263  	print_ticks(val, clk_tck, frac_width);
     264  }
     265  
     266  #if !defined HAVE_STPCPY
     267  char *
     268  stpcpy(char *dst, const char *src)
     269  {
     270  	while ((*dst = *src++) != '\0')
     271  		dst++;
     272  	return dst;
     273  }
     274  #endif
     275  
     276  /* Find a next bit which is set.
     277   * Starts testing at cur_bit.
     278   * Returns -1 if no more bits are set.
     279   *
     280   * We never touch bytes we don't need to.
     281   * On big-endian, array is assumed to consist of
     282   * current_wordsize wide words: for example, is current_wordsize is 4,
     283   * the bytes are walked in 3,2,1,0, 7,6,5,4, 11,10,9,8 ... sequence.
     284   * On little-endian machines, word size is immaterial.
     285   */
     286  int
     287  next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits)
     288  {
     289  	const unsigned endian = 1;
     290  	int little_endian = *(char *) (void *) &endian;
     291  
     292  	const uint8_t *array = bit_array;
     293  	unsigned pos = cur_bit / 8;
     294  	unsigned pos_xor_mask = little_endian ? 0 : current_wordsize-1;
     295  
     296  	for (;;) {
     297  		uint8_t bitmask;
     298  		uint8_t cur_byte;
     299  
     300  		if (cur_bit >= size_bits)
     301  			return -1;
     302  		cur_byte = array[pos ^ pos_xor_mask];
     303  		if (cur_byte == 0) {
     304  			cur_bit = (cur_bit + 8) & (-8);
     305  			pos++;
     306  			continue;
     307  		}
     308  		bitmask = 1 << (cur_bit & 7);
     309  		for (;;) {
     310  			if (cur_byte & bitmask)
     311  				return cur_bit;
     312  			cur_bit++;
     313  			if (cur_bit >= size_bits)
     314  				return -1;
     315  			bitmask <<= 1;
     316  			/* This check *can't be* optimized out: */
     317  			if (bitmask == 0)
     318  				break;
     319  		}
     320  		pos++;
     321  	}
     322  }
     323  
     324  /*
     325   * Fetch 64bit argument at position arg_no and
     326   * return the index of the next argument.
     327   */
     328  unsigned int
     329  getllval(struct tcb *tcp, unsigned long long *val, unsigned int arg_no)
     330  {
     331  #if SIZEOF_KERNEL_LONG_T > 4
     332  # ifndef current_klongsize
     333  	if (current_klongsize < SIZEOF_KERNEL_LONG_T) {
     334  #  if defined(AARCH64) || defined(POWERPC64) || defined(POWERPC64LE)
     335  		/* Align arg_no to the next even number. */
     336  		arg_no = (arg_no + 1) & 0xe;
     337  #  endif /* AARCH64 || POWERPC64 || POWERPC64LE */
     338  		*val = ULONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
     339  		arg_no += 2;
     340  	} else
     341  # endif /* !current_klongsize */
     342  	{
     343  		*val = tcp->u_arg[arg_no];
     344  		arg_no++;
     345  	}
     346  #else /* SIZEOF_KERNEL_LONG_T == 4 */
     347  # if defined __ARM_EABI__	\
     348    || defined LINUX_MIPSO32	\
     349    || defined POWERPC		\
     350    || defined XTENSA
     351  	/* Align arg_no to the next even number. */
     352  	arg_no = (arg_no + 1) & 0xe;
     353  # elif defined SH
     354  	/*
     355  	 * The SH4 ABI does allow long longs in odd-numbered registers, but
     356  	 * does not allow them to be split between registers and memory - and
     357  	 * there are only four argument registers for normal functions.  As a
     358  	 * result, pread, for example, takes an extra padding argument before
     359  	 * the offset.  This was changed late in the 2.4 series (around 2.4.20).
     360  	 */
     361  	if (arg_no == 3)
     362  		arg_no++;
     363  # endif /* __ARM_EABI__ || LINUX_MIPSO32 || POWERPC || XTENSA || SH */
     364  	*val = ULONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
     365  	arg_no += 2;
     366  #endif
     367  
     368  	return arg_no;
     369  }
     370  
     371  /*
     372   * Print 64bit argument at position arg_no as a signed long long
     373   * and return the index of the next argument.
     374   */
     375  unsigned int
     376  print_arg_lld(struct tcb *tcp, unsigned int arg_no)
     377  {
     378  	unsigned long long val = 0;
     379  
     380  	arg_no = getllval(tcp, &val, arg_no);
     381  	PRINT_VAL_D(val);
     382  	return arg_no;
     383  }
     384  
     385  /*
     386   * Print 64bit argument at position arg_no as an unsigned long long
     387   * and return the index of the next argument.
     388   */
     389  unsigned int
     390  print_arg_llu(struct tcb *tcp, unsigned int arg_no)
     391  {
     392  	unsigned long long val = 0;
     393  
     394  	arg_no = getllval(tcp, &val, arg_no);
     395  	PRINT_VAL_U(val);
     396  	return arg_no;
     397  }
     398  
     399  void
     400  printaddr64(const uint64_t addr)
     401  {
     402  	if (!addr)
     403  		tprint_null();
     404  	else
     405  		PRINT_VAL_X(addr);
     406  }
     407  
     408  #define DEF_PRINTNUM(name, type) \
     409  bool									\
     410  printnum_ ## name(struct tcb *const tcp, const kernel_ulong_t addr,	\
     411  		  const char *const fmt)				\
     412  {									\
     413  	type num;							\
     414  	if (umove_or_printaddr(tcp, addr, &num))			\
     415  		return false;						\
     416  	tprint_indirect_begin();					\
     417  	tprintf_string(fmt, num);					\
     418  	tprint_indirect_end();						\
     419  	return true;							\
     420  }
     421  
     422  #define DEF_PRINTNUM_ADDR(name, type) \
     423  bool									\
     424  printnum_addr_ ## name(struct tcb *tcp, const kernel_ulong_t addr)	\
     425  {									\
     426  	type num;							\
     427  	if (umove_or_printaddr(tcp, addr, &num))			\
     428  		return false;						\
     429  	tprint_indirect_begin();					\
     430  	printaddr64(num);						\
     431  	tprint_indirect_end();						\
     432  	return true;							\
     433  }
     434  
     435  #define DEF_PRINTPAIR(name, type) \
     436  bool									\
     437  printpair_ ## name(struct tcb *const tcp, const kernel_ulong_t addr,	\
     438  		   const char *const fmt)				\
     439  {									\
     440  	type pair[2];							\
     441  	if (umove_or_printaddr(tcp, addr, &pair))			\
     442  		return false;						\
     443  	tprint_array_begin();						\
     444  	tprintf_string(fmt, pair[0]);					\
     445  	tprint_array_next();						\
     446  	tprintf_string(fmt, pair[1]);					\
     447  	tprint_array_end();						\
     448  	return true;							\
     449  }
     450  
     451  DEF_PRINTNUM(int, int)
     452  DEF_PRINTNUM_ADDR(int, unsigned int)
     453  DEF_PRINTPAIR(int, int)
     454  DEF_PRINTNUM(short, short)
     455  DEF_PRINTNUM(int64, uint64_t)
     456  DEF_PRINTNUM_ADDR(int64, uint64_t)
     457  DEF_PRINTPAIR(int64, uint64_t)
     458  
     459  bool
     460  printnum_fd(struct tcb *const tcp, const kernel_ulong_t addr)
     461  {
     462  	int fd;
     463  	if (umove_or_printaddr(tcp, addr, &fd))
     464  		return false;
     465  	tprint_indirect_begin();
     466  	printfd(tcp, fd);
     467  	tprint_indirect_end();
     468  	return true;
     469  }
     470  
     471  bool
     472  printnum_pid(struct tcb *const tcp, const kernel_ulong_t addr, enum pid_type type)
     473  {
     474  	int pid;
     475  	if (umove_or_printaddr(tcp, addr, &pid))
     476  		return false;
     477  	tprint_indirect_begin();
     478  	printpid(tcp, pid, type);
     479  	tprint_indirect_end();
     480  	return true;
     481  }
     482  
     483  /**
     484   * Prints time to a (static internal) buffer and returns pointer to it.
     485   * Returns NULL if the provided time specification is not correct.
     486   *
     487   * @param sec		Seconds since epoch.
     488   * @param part_sec	Amount of second parts since the start of a second.
     489   * @param max_part_sec	Maximum value of a valid part_sec.
     490   * @param width		1 + floor(log10(max_part_sec)).
     491   * @return		Pointer to a statically allocated string on success,
     492   *			NULL on error.
     493   */
     494  static const char *
     495  sprinttime_ex(const long long sec, const unsigned long long part_sec,
     496  	      const unsigned int max_part_sec, const int width)
     497  {
     498  	static char buf[sizeof(int) * 3 * 6 + sizeof(part_sec) * 3
     499  			+ sizeof("+0000")];
     500  
     501  	if ((sec == 0 && part_sec == 0) || part_sec > max_part_sec)
     502  		return NULL;
     503  
     504  	time_t t = (time_t) sec;
     505  	struct tm *tmp = (sec == t) ? localtime(&t) : NULL;
     506  	if (!tmp)
     507  		return NULL;
     508  
     509  	size_t pos = strftime(buf, sizeof(buf), "%FT%T", tmp);
     510  	if (!pos)
     511  		return NULL;
     512  
     513  	if (part_sec > 0)
     514  		pos += xsnprintf(buf + pos, sizeof(buf) - pos, ".%0*llu",
     515  				 width, part_sec);
     516  
     517  	return strftime(buf + pos, sizeof(buf) - pos, "%z", tmp) ? buf : NULL;
     518  }
     519  
     520  const char *
     521  sprinttime(long long sec)
     522  {
     523  	return sprinttime_ex(sec, 0, 0, 0);
     524  }
     525  
     526  const char *
     527  sprinttime_usec(long long sec, unsigned long long usec)
     528  {
     529  	return sprinttime_ex(sec, usec, 999999, 6);
     530  }
     531  
     532  const char *
     533  sprinttime_nsec(long long sec, unsigned long long nsec)
     534  {
     535  	return sprinttime_ex(sec, nsec, 999999999, 9);
     536  }
     537  
     538  void
     539  print_uuid(const unsigned char *uuid)
     540  {
     541  	const char str[] = {
     542  		BYTE_HEX_CHARS(uuid[0]),
     543  		BYTE_HEX_CHARS(uuid[1]),
     544  		BYTE_HEX_CHARS(uuid[2]),
     545  		BYTE_HEX_CHARS(uuid[3]),
     546  		'-',
     547  		BYTE_HEX_CHARS(uuid[4]),
     548  		BYTE_HEX_CHARS(uuid[5]),
     549  		'-',
     550  		BYTE_HEX_CHARS(uuid[6]),
     551  		BYTE_HEX_CHARS(uuid[7]),
     552  		'-',
     553  		BYTE_HEX_CHARS(uuid[8]),
     554  		BYTE_HEX_CHARS(uuid[9]),
     555  		'-',
     556  		BYTE_HEX_CHARS(uuid[10]),
     557  		BYTE_HEX_CHARS(uuid[11]),
     558  		BYTE_HEX_CHARS(uuid[12]),
     559  		BYTE_HEX_CHARS(uuid[13]),
     560  		BYTE_HEX_CHARS(uuid[14]),
     561  		BYTE_HEX_CHARS(uuid[15]),
     562  		'\0'
     563  	};
     564  
     565  	tprints_string(str);
     566  }
     567  
     568  enum sock_proto
     569  getfdproto(struct tcb *tcp, int fd)
     570  {
     571  #ifdef HAVE_SYS_XATTR_H
     572  	size_t bufsize = 256;
     573  	char buf[bufsize];
     574  	ssize_t r;
     575  	char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
     576  
     577  	if (fd < 0)
     578  		return SOCK_PROTO_UNKNOWN;
     579  
     580  	xsprintf(path, "/proc/%u/fd/%u", get_proc_pid(tcp->pid), fd);
     581  	r = getxattr(path, "system.sockprotoname", buf, bufsize - 1);
     582  	if (r <= 0)
     583  		return SOCK_PROTO_UNKNOWN;
     584  	else {
     585  		/*
     586  		 * This is a protection for the case when the kernel
     587  		 * side does not append a null byte to the buffer.
     588  		 */
     589  		buf[r] = '\0';
     590  
     591  		return get_proto_by_name(buf);
     592  	}
     593  #else
     594  	return SOCK_PROTO_UNKNOWN;
     595  #endif
     596  }
     597  
     598  static unsigned long
     599  get_inode_of_socket_path(const char *path)
     600  {
     601  	const char *str = STR_STRIP_PREFIX(path, "socket:[");
     602  	char *end;
     603  	size_t len;
     604  	unsigned long r;
     605  
     606  	if ((str != path)
     607  	    && (len = strlen(str))
     608  	    && (str[len - 1] == ']')
     609  	    && (r = strtoul(str, &end, 10))
     610  	    && (end == &str[len - 1]))
     611  		return r;
     612  
     613  	return 0;
     614  }
     615  
     616  unsigned long
     617  getfdinode(struct tcb *tcp, int fd)
     618  {
     619  	char path[PATH_MAX + 1];
     620  
     621  	if (getfdpath(tcp, fd, path, sizeof(path)) >= 0)
     622  		return get_inode_of_socket_path(path);
     623  
     624  	return 0;
     625  }
     626  
     627  static void
     628  print_string_in_angle_brackets(const char *str)
     629  {
     630  	tprint_associated_info_begin();
     631  	tprints_string(str);
     632  	tprint_associated_info_end();
     633  }
     634  
     635  static bool
     636  printsocket(struct tcb *tcp, int fd, const char *path)
     637  {
     638  	unsigned long inode = get_inode_of_socket_path(path);
     639  	if (!inode)
     640  		return false;
     641  
     642  	const char *details = get_sockaddr_by_inode(tcp, fd, inode);
     643  	print_string_in_angle_brackets(details ?: path);
     644  
     645  	return true;
     646  }
     647  
     648  struct finfo *
     649  get_finfo_for_dev(const char *path, struct finfo *finfo)
     650  {
     651  	strace_stat_t st;
     652  
     653  	finfo->path = path;
     654  	finfo->type = FINFO_UNSET;
     655  	finfo->deleted = false;
     656  
     657  	if (path[0] != '/')
     658  		return finfo;
     659  
     660  	if (stat_file(path, &st)) {
     661  		debug_func_perror_msg("stat(\"%s\")", path);
     662  		return finfo;
     663  	}
     664  
     665  	switch (st.st_mode & S_IFMT) {
     666  	case S_IFBLK:
     667  		finfo->type = FINFO_DEV_BLK;
     668  		break;
     669  	case S_IFCHR:
     670  		finfo->type = FINFO_DEV_CHR;
     671  		break;
     672  	default:
     673  		return finfo;
     674  	}
     675  
     676  	finfo->dev.major = major(st.st_rdev);
     677  	finfo->dev.minor = minor(st.st_rdev);
     678  
     679  	return finfo;
     680  }
     681  
     682  static bool
     683  printdev(struct tcb *tcp, int fd, const char *path, const struct finfo *finfo)
     684  {
     685  	struct finfo finfo_buf;
     686  	if (!finfo)
     687  		finfo = get_finfo_for_dev(path, &finfo_buf);
     688  
     689  	switch (finfo->type) {
     690  	case FINFO_DEV_BLK:
     691  	case FINFO_DEV_CHR:
     692  		tprint_associated_info_begin();
     693  		print_quoted_string_ex(finfo->path, strlen(finfo->path),
     694  				       QUOTE_OMIT_LEADING_TRAILING_QUOTES,
     695  				       "<>");
     696  		tprint_associated_info_begin();
     697  		tprintf_string("%s %u:%u",
     698  			       (finfo->type == FINFO_DEV_BLK)? "block" : "char",
     699  			       finfo->dev.major, finfo->dev.minor);
     700  		tprint_associated_info_end();
     701  		tprint_associated_info_end();
     702  		return true;
     703  	default:
     704  		break;
     705  	}
     706  
     707  	return false;
     708  }
     709  
     710  typedef bool (*scan_fdinfo_fn)(const char *value, void *data);
     711  
     712  static bool
     713  scan_fdinfo(pid_t pid_of_fd, int fd, const char *search_pfx,
     714  	    size_t search_pfx_len, scan_fdinfo_fn fn, void *data)
     715  {
     716  	int proc_pid = 0;
     717  	translate_pid(NULL, pid_of_fd, PT_TID, &proc_pid);
     718  	if (!proc_pid)
     719  		return false;
     720  
     721  	char fdi_path[sizeof("/proc/%u/fdinfo/%u") + 2 * sizeof(int) * 3];
     722  	xsprintf(fdi_path, "/proc/%u/fdinfo/%u", proc_pid, fd);
     723  
     724  	FILE *f = fopen_stream(fdi_path, "r");
     725  	if (!f)
     726  		return false;
     727  
     728  	char *line = NULL;
     729  	size_t sz = 0;
     730  	bool result = false;
     731  
     732  	while (getline(&line, &sz, f) > 0) {
     733  		const char *value =
     734  			str_strip_prefix_len(line, search_pfx, search_pfx_len);
     735  		if (value != line && fn(value, data)) {
     736  			result = true;
     737  			break;
     738  		}
     739  	}
     740  
     741  	free(line);
     742  	fclose(f);
     743  
     744  	return result;
     745  }
     746  
     747  static bool
     748  parse_fdinfo_pid(const char *value, void *data)
     749  {
     750  	pid_t *pid = data;
     751  	*pid = string_to_uint_ex(value, NULL, INT_MAX, "\n");
     752  	return true;
     753  }
     754  
     755  pid_t
     756  pidfd_get_pid(pid_t pid_of_fd, int fd)
     757  {
     758  	static const char pid_pfx[] = "Pid:\t";
     759  	pid_t pid = -1;
     760  
     761  	scan_fdinfo(pid_of_fd, fd, pid_pfx, sizeof(pid_pfx) - 1,
     762  		    parse_fdinfo_pid, &pid);
     763  	return pid;
     764  }
     765  
     766  static bool
     767  printpidfd(pid_t pid_of_fd, int fd, const char *path)
     768  {
     769  	static const char pidfd_path[] = "anon_inode:[pidfd]";
     770  
     771  	if (strcmp(path, pidfd_path))
     772  		return false;
     773  
     774  	pid_t pid = pidfd_get_pid(pid_of_fd, fd);
     775  	if (pid > 0) {
     776  		tprint_associated_info_begin();
     777  		tprints_string("pid:");
     778  		/*
     779  		 * The pid translation is not needed because
     780  		 * the pid is in strace's namespace.
     781  		 */
     782  		printpid(NULL, pid, PT_TID);
     783  		tprint_associated_info_end();
     784  	} else {
     785  		print_string_in_angle_brackets(path);
     786  	}
     787  
     788  	return true;
     789  }
     790  
     791  static bool
     792  print_fdinfo_sigmask(const char *value, void *data)
     793  {
     794  #ifdef WORDS_BIGENDIAN
     795  	unsigned int pos_xor_mask = current_wordsize - 1;
     796  #else
     797  	unsigned int pos_xor_mask = 0;
     798  #endif
     799  	size_t sigset_size = strlen(value) / 2;
     800  	uint8_t *sigmask = xmalloc(sigset_size);
     801  
     802  	for (size_t i = 0; i < sigset_size; ++i) {
     803  		uint8_t byte;
     804  		if (sscanf(value + i * 2, "%02hhx", &byte) != 1) {
     805  			free(sigmask);
     806  			return false;
     807  		}
     808  		sigmask[(sigset_size - 1 - i) ^ pos_xor_mask] = byte;
     809  	}
     810  
     811  	tprint_associated_info_begin();
     812  	tprints_string(sprintsigmask_n("signalfd:", sigmask, sigset_size));
     813  	tprint_associated_info_end();
     814  
     815  	free(sigmask);
     816  	return true;
     817  }
     818  
     819  static bool
     820  printsignalfd(pid_t pid_of_fd, int fd, const char *path)
     821  {
     822  	static const char signalfd_path[] = "anon_inode:[signalfd]";
     823  	static const char sigmask_pfx[] = "sigmask:\t";
     824  
     825  	if (strcmp(path, signalfd_path))
     826  		return false;
     827  
     828  	return scan_fdinfo(pid_of_fd, fd, sigmask_pfx, sizeof(sigmask_pfx) - 1,
     829  			   print_fdinfo_sigmask, NULL);
     830  }
     831  
     832  static void
     833  print_quoted_string_in_angle_brackets(const char *str, const bool deleted)
     834  {
     835  	tprint_associated_info_begin();
     836  	print_quoted_string_ex(str, strlen(str),
     837  			       QUOTE_OMIT_LEADING_TRAILING_QUOTES, "<>");
     838  	tprint_associated_info_end();
     839  
     840  	if (deleted)
     841  		tprints_string("(deleted)");
     842  }
     843  
     844  void
     845  printfd_pid_with_finfo(struct tcb *tcp, pid_t pid, int fd, const struct finfo *finfo)
     846  {
     847  	PRINT_VAL_D(fd);
     848  
     849  	char patha[PATH_MAX + 1];
     850  	bool deleted;
     851  	if (pid > 0 && !number_set_array_is_empty(decode_fd_set, 0)
     852  	    && (finfo || (getfdpath_pid(pid, fd, patha, sizeof(patha), &deleted) >= 0))) {
     853  		const char *path = finfo? finfo->path: patha;
     854  		if (is_number_in_set(DECODE_FD_SOCKET, decode_fd_set) &&
     855  		    printsocket(tcp, fd, path))
     856  			goto printed;
     857  		if (is_number_in_set(DECODE_FD_DEV, decode_fd_set) &&
     858  		    printdev(tcp, fd, path, finfo))
     859  			goto printed;
     860  		if (is_number_in_set(DECODE_FD_PIDFD, decode_fd_set) &&
     861  		    printpidfd(pid, fd, path))
     862  			goto printed;
     863  		if (is_number_in_set(DECODE_FD_SIGNALFD, decode_fd_set) &&
     864  		    printsignalfd(pid, fd, path))
     865  			goto printed;
     866  		if (is_number_in_set(DECODE_FD_PATH, decode_fd_set))
     867  			print_quoted_string_in_angle_brackets(path,
     868  							      finfo? finfo->deleted: deleted);
     869  printed:	;
     870  	}
     871  
     872  	selinux_printfdcon(pid, fd);
     873  }
     874  
     875  void
     876  printfd_pid_tracee_ns(struct tcb *tcp, pid_t pid, int fd)
     877  {
     878  	int strace_pid = translate_pid(tcp, pid, PT_TGID, NULL);
     879  	printfd_pid(tcp, strace_pid, fd);
     880  }
     881  
     882  const char *
     883  pid_to_str(pid_t pid)
     884  {
     885  	if (!pid)
     886  		return "self";
     887  
     888  	static char buf[sizeof("-2147483648")];
     889  	xsprintf(buf, "%d", pid);
     890  	return buf;
     891  }
     892  
     893  size_t
     894  proc_status_get_id_list(int proc_pid, int *id_buf, size_t id_buf_size,
     895  			const char *str, size_t str_size)
     896  {
     897  	size_t n = 0;
     898  
     899  	if (!str_size)
     900  		str_size = strlen(str);
     901  
     902  	char status_path[PATH_MAX + 1];
     903  	xsprintf(status_path, "/proc/%s/status", pid_to_str(proc_pid));
     904  	FILE *f = fopen_stream(status_path, "r");
     905  	if (!f)
     906  		return 0;
     907  
     908  	char *line = NULL;
     909  	size_t linesize = 0;
     910  	char *p = NULL;
     911  
     912  	while (getline(&line, &linesize, f) > 0) {
     913  		if (strncmp(line, str, str_size) == 0) {
     914  			p = line + str_size;
     915  			break;
     916  		}
     917  	}
     918  
     919  	while (p) {
     920  		errno = 0;
     921  		long id = strtol(p, NULL, 10);
     922  
     923  		if (id < 0 || id > INT_MAX || errno) {
     924  			debug_func_perror_msg("converting \"%s\" to int", p);
     925  			break;
     926  		}
     927  
     928  		if (id_buf && n < id_buf_size)
     929  			id_buf[n] = (int) id;
     930  
     931  		n++;
     932  		strsep(&p, "\t");
     933  	}
     934  
     935  	free(line);
     936  	fclose(f);
     937  
     938  	return n;
     939  }
     940  
     941  /*
     942   * Quote string `instr' of length `size'
     943   * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
     944   *
     945   * `escape_chars' specifies characters (in addition to characters with
     946   * codes 0..31, 127..255, single and double quotes) that should be escaped.
     947   *
     948   * If QUOTE_0_TERMINATED `style' flag is set,
     949   * treat `instr' as a NUL-terminated string,
     950   * checking up to (`size' + 1) bytes of `instr'.
     951   *
     952   * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
     953   * do not add leading and trailing quoting symbols.
     954   *
     955   * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
     956   * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
     957   */
     958  int
     959  string_quote(const char *instr, char *outstr, const unsigned int size,
     960  	     const unsigned int style, const char *escape_chars)
     961  {
     962  	const unsigned char *ustr = (const unsigned char *) instr;
     963  	char *s = outstr;
     964  	unsigned int i;
     965  	int usehex, c, eol;
     966  	bool printable;
     967  	enum xflag_opts xstyle = style & QUOTE_OVERWRITE_HEXSTR
     968  					? ((style & QUOTE_HEXSTR_MASK)
     969  					   >> QUOTE_HEXSTR_SHIFT)
     970  					: xflag;
     971  
     972  	if (style & QUOTE_0_TERMINATED)
     973  		eol = '\0';
     974  	else
     975  		eol = 0x100; /* this can never match a char */
     976  
     977  	usehex = 0;
     978  	if (xstyle == HEXSTR_ALL) {
     979  		usehex = 1;
     980  	} else if (xstyle == HEXSTR_NON_ASCII) {
     981  		/* Check for presence of symbol which require
     982  		   to hex-quote the whole string. */
     983  		for (i = 0; i < size; ++i) {
     984  			c = ustr[i];
     985  			/* Check for NUL-terminated string. */
     986  			if (c == eol)
     987  				break;
     988  
     989  			/* Force hex unless c is printable or whitespace */
     990  			if (c > 0x7e) {
     991  				usehex = 1;
     992  				break;
     993  			}
     994  			/* In ASCII isspace is only these chars: "\t\n\v\f\r".
     995  			 * They happen to have ASCII codes 9,10,11,12,13.
     996  			 */
     997  			if (c < ' ' && (unsigned)(c - 9) >= 5) {
     998  				usehex = 1;
     999  				break;
    1000  			}
    1001  		}
    1002  	}
    1003  
    1004  	if (style & QUOTE_EMIT_COMMENT)
    1005  		s = stpcpy(s, " /* ");
    1006  	if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
    1007  		*s++ = '\"';
    1008  
    1009  	if (usehex) {
    1010  		/* Hex-quote the whole string. */
    1011  		for (i = 0; i < size; ++i) {
    1012  			c = ustr[i];
    1013  			/* Check for NUL-terminated string. */
    1014  			if (c == eol)
    1015  				goto asciz_ended;
    1016  			*s++ = '\\';
    1017  			*s++ = 'x';
    1018  			s = sprint_byte_hex(s, c);
    1019  		}
    1020  
    1021  		goto string_ended;
    1022  	}
    1023  
    1024  	for (i = 0; i < size; ++i) {
    1025  		c = ustr[i];
    1026  		/* Check for NUL-terminated string. */
    1027  		if (c == eol)
    1028  			goto asciz_ended;
    1029  		if ((i == (size - 1)) &&
    1030  		    (style & QUOTE_OMIT_TRAILING_0) && (c == '\0'))
    1031  			goto asciz_ended;
    1032  		switch (c) {
    1033  		case '\"': case '\\':
    1034  			*s++ = '\\';
    1035  			*s++ = c;
    1036  			break;
    1037  		case '\f':
    1038  			*s++ = '\\';
    1039  			*s++ = 'f';
    1040  			break;
    1041  		case '\n':
    1042  			*s++ = '\\';
    1043  			*s++ = 'n';
    1044  			break;
    1045  		case '\r':
    1046  			*s++ = '\\';
    1047  			*s++ = 'r';
    1048  			break;
    1049  		case '\t':
    1050  			*s++ = '\\';
    1051  			*s++ = 't';
    1052  			break;
    1053  		case '\v':
    1054  			*s++ = '\\';
    1055  			*s++ = 'v';
    1056  			break;
    1057  		default:
    1058  			printable = is_print(c);
    1059  
    1060  			if (printable && escape_chars)
    1061  				printable = !strchr(escape_chars, c);
    1062  
    1063  			if (printable) {
    1064  				*s++ = c;
    1065  			} else {
    1066  				if (xstyle == HEXSTR_NON_ASCII_CHARS) {
    1067  					/* Print he\x */
    1068  					*s++ = '\\';
    1069  					*s++ = 'x';
    1070  					s = sprint_byte_hex(s, c);
    1071  				} else {
    1072  					/* Print \octal */
    1073  					*s++ = '\\';
    1074  					s = sprint_byte_oct(s, c,
    1075  							i + 1 < size
    1076  							&& ustr[i + 1] >= '0'
    1077  							&& ustr[i + 1] <= '7');
    1078  				}
    1079  			}
    1080  		}
    1081  	}
    1082  
    1083   string_ended:
    1084  	if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
    1085  		*s++ = '\"';
    1086  	if (style & QUOTE_EMIT_COMMENT)
    1087  		s = stpcpy(s, " */");
    1088  	*s = '\0';
    1089  
    1090  	/* Return zero if we printed entire ASCIZ string (didn't truncate it) */
    1091  	if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
    1092  		/* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
    1093  		 * but next char is NUL.
    1094  		 */
    1095  		return 0;
    1096  	}
    1097  
    1098  	return 1;
    1099  
    1100   asciz_ended:
    1101  	if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
    1102  		*s++ = '\"';
    1103  	if (style & QUOTE_EMIT_COMMENT)
    1104  		s = stpcpy(s, " */");
    1105  	*s = '\0';
    1106  	/* Return zero: we printed entire ASCIZ string (didn't truncate it) */
    1107  	return 0;
    1108  }
    1109  
    1110  #ifndef ALLOCA_CUTOFF
    1111  # define ALLOCA_CUTOFF	4032
    1112  #endif
    1113  #define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
    1114  
    1115  /*
    1116   * Quote string `str' of length `size' and print the result.
    1117   *
    1118   * If QUOTE_0_TERMINATED `style' flag is set,
    1119   * treat `str' as a NUL-terminated string and
    1120   * quote at most (`size' - 1) bytes.
    1121   *
    1122   * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
    1123   * do not add leading and trailing quoting symbols.
    1124   *
    1125   * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
    1126   * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
    1127   */
    1128  int
    1129  print_quoted_string_ex(const char *str, unsigned int size,
    1130  		       const unsigned int style, const char *escape_chars)
    1131  {
    1132  	char *buf;
    1133  	char *outstr;
    1134  	unsigned int alloc_size;
    1135  	int rc;
    1136  
    1137  	if (size && style & QUOTE_0_TERMINATED)
    1138  		--size;
    1139  
    1140  	alloc_size = 4 * size;
    1141  	if (alloc_size / 4 != size) {
    1142  		error_func_msg("requested %u bytes exceeds %u bytes limit",
    1143  			       size, -1U / 4);
    1144  		tprint_unavailable();
    1145  		return -1;
    1146  	}
    1147  	alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2) +
    1148  		(style & QUOTE_EMIT_COMMENT ? 7 : 0);
    1149  
    1150  	if (use_alloca(alloc_size)) {
    1151  		outstr = alloca(alloc_size);
    1152  		buf = NULL;
    1153  	} else {
    1154  		outstr = buf = malloc(alloc_size);
    1155  		if (!buf) {
    1156  			error_func_msg("memory exhausted when tried to allocate"
    1157  				       " %u bytes", alloc_size);
    1158  			tprint_unavailable();
    1159  			return -1;
    1160  		}
    1161  	}
    1162  
    1163  	rc = string_quote(str, outstr, size, style, escape_chars);
    1164  	tprints_string(outstr);
    1165  
    1166  	if (((style & (QUOTE_0_TERMINATED | QUOTE_EXPECT_TRAILING_0))
    1167  	     == (QUOTE_0_TERMINATED | QUOTE_EXPECT_TRAILING_0)) && rc) {
    1168  		tprint_more_data_follows();
    1169  	}
    1170  
    1171  	free(buf);
    1172  	return rc;
    1173  }
    1174  
    1175  inline int
    1176  print_quoted_string(const char *str, unsigned int size,
    1177  		    const unsigned int style)
    1178  {
    1179  	return print_quoted_string_ex(str, size, style, NULL);
    1180  }
    1181  
    1182  /*
    1183   * Quote a NUL-terminated string `str' of length up to `size' - 1
    1184   * and print the result.
    1185   *
    1186   * Returns 0 if NUL was seen, 1 otherwise.
    1187   */
    1188  int
    1189  print_quoted_cstring(const char *str, unsigned int size)
    1190  {
    1191  	int unterminated =
    1192  		print_quoted_string(str, size, QUOTE_0_TERMINATED);
    1193  
    1194  	if (unterminated)
    1195  		tprint_more_data_follows();
    1196  
    1197  	return unterminated;
    1198  }
    1199  
    1200  /*
    1201   * Print path string specified by address `addr' and length `n'.
    1202   * If path length exceeds `n', append `...' to the output.
    1203   *
    1204   * Returns the result of umovestr.
    1205   */
    1206  int
    1207  printpathn(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int n)
    1208  {
    1209  	char path[PATH_MAX];
    1210  	int nul_seen;
    1211  
    1212  	if (!addr) {
    1213  		tprint_null();
    1214  		return -1;
    1215  	}
    1216  
    1217  	/* Cap path length to the path buffer size */
    1218  	if (n > sizeof(path) - 1)
    1219  		n = sizeof(path) - 1;
    1220  
    1221  	/* Fetch one byte more to find out whether path length > n. */
    1222  	nul_seen = umovestr(tcp, addr, n + 1, path);
    1223  	if (nul_seen < 0)
    1224  		printaddr(addr);
    1225  	else {
    1226  		path[n++] = !nul_seen;
    1227  		print_quoted_cstring(path, n);
    1228  
    1229  		if (nul_seen)
    1230  			selinux_printfilecon(tcp, path);
    1231  	}
    1232  
    1233  	return nul_seen;
    1234  }
    1235  
    1236  int
    1237  printpath(struct tcb *const tcp, const kernel_ulong_t addr)
    1238  {
    1239  	/* Size must correspond to char path[] size in printpathn */
    1240  	return printpathn(tcp, addr, PATH_MAX - 1);
    1241  }
    1242  
    1243  /*
    1244   * Print string specified by address `addr' and length `len'.
    1245   * If `user_style' has QUOTE_0_TERMINATED bit set, treat the string
    1246   * as a NUL-terminated string.
    1247   * Pass `user_style' on to `string_quote'.
    1248   * Append `...' to the output if either the string length exceeds `max_strlen',
    1249   * or QUOTE_0_TERMINATED bit is set and the string length exceeds `len'.
    1250   *
    1251   * Returns the result of umovestr if style has QUOTE_0_TERMINATED,
    1252   * or the result of umoven otherwise.
    1253   */
    1254  int
    1255  printstr_ex(struct tcb *const tcp, const kernel_ulong_t addr,
    1256  	    const kernel_ulong_t len, const unsigned int user_style)
    1257  {
    1258  	static char *str;
    1259  	static char *outstr;
    1260  
    1261  	unsigned int size;
    1262  	unsigned int style = user_style;
    1263  	int rc;
    1264  	int ellipsis;
    1265  
    1266  	if (!addr) {
    1267  		tprint_null();
    1268  		return -1;
    1269  	}
    1270  	/* Allocate static buffers if they are not allocated yet. */
    1271  	if (!str) {
    1272  		const unsigned int outstr_size =
    1273  			4 * max_strlen + /* for quotes and NUL */ 3;
    1274  		/*
    1275  		 * We can assume that outstr_size / 4 == max_strlen
    1276  		 * since we have a guarantee that max_strlen <= -1U / 4.
    1277  		 */
    1278  
    1279  		str = xmalloc(max_strlen + 1);
    1280  		outstr = xmalloc(outstr_size);
    1281  	}
    1282  
    1283  	/* Fetch one byte more because string_quote may look one byte ahead. */
    1284  	size = max_strlen + 1;
    1285  
    1286  	if (size > len)
    1287  		size = len;
    1288  	if (style & QUOTE_0_TERMINATED)
    1289  		rc = umovestr(tcp, addr, size, str);
    1290  	else
    1291  		rc = umoven(tcp, addr, size, str);
    1292  
    1293  	if (rc < 0) {
    1294  		printaddr(addr);
    1295  		return rc;
    1296  	}
    1297  
    1298  	if (size > max_strlen)
    1299  		size = max_strlen;
    1300  	else
    1301  		str[size] = '\xff';
    1302  
    1303  	if ((style & (QUOTE_0_TERMINATED | QUOTE_EXPECT_TRAILING_0))
    1304  	    == (QUOTE_0_TERMINATED | QUOTE_EXPECT_TRAILING_0)
    1305  	    && size == len && size) {
    1306  		--size;
    1307  	}
    1308  
    1309  	/* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
    1310  	 * or we were requested to print more than -s NUM chars)...
    1311  	 */
    1312  	ellipsis = string_quote(str, outstr, size, style, NULL)
    1313  		   && len
    1314  		   && ((style & (QUOTE_0_TERMINATED | QUOTE_EXPECT_TRAILING_0))
    1315  		       || len > max_strlen);
    1316  
    1317  	tprints_string(outstr);
    1318  	if (ellipsis)
    1319  		tprint_more_data_follows();
    1320  
    1321  	return rc;
    1322  }
    1323  
    1324  bool
    1325  print_nonzero_bytes(struct tcb *const tcp,
    1326  		    void (*const prefix_fun)(void),
    1327  		    const kernel_ulong_t start_addr,
    1328  		    const unsigned int start_offs,
    1329  		    const unsigned int total_len,
    1330  		    const unsigned int style)
    1331  {
    1332  	if (start_offs >= total_len)
    1333  		return false;
    1334  
    1335  	const kernel_ulong_t addr = start_addr + start_offs;
    1336  	const unsigned int len = total_len - start_offs;
    1337  	const unsigned int size = MIN(len, max_strlen);
    1338  
    1339  	char *str = malloc(len);
    1340  
    1341  	if (!str) {
    1342  		error_func_msg("memory exhausted when tried to allocate"
    1343                                 " %u bytes", len);
    1344  		prefix_fun();
    1345  		tprint_unavailable();
    1346  		return true;
    1347  	}
    1348  
    1349  	bool ret = true;
    1350  
    1351  	if (umoven(tcp, addr, len, str)) {
    1352  		prefix_fun();
    1353  		tprint_unavailable();
    1354  	} else if (is_filled(str, 0, len)) {
    1355  		ret = false;
    1356  	} else {
    1357  		prefix_fun();
    1358  		tprintf_string("/* bytes %u..%u */ ", start_offs, total_len - 1);
    1359  
    1360  		print_quoted_string(str, size, style);
    1361  
    1362  		if (size < len)
    1363  			tprint_more_data_follows();
    1364  	}
    1365  
    1366  	free(str);
    1367  	return ret;
    1368  }
    1369  
    1370  void
    1371  dumpiov_upto(struct tcb *const tcp, const int len, const kernel_ulong_t addr,
    1372  	     kernel_ulong_t data_size)
    1373  {
    1374  #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
    1375  	union {
    1376  		struct { uint32_t base; uint32_t len; } *iov32;
    1377  		struct { uint64_t base; uint64_t len; } *iov64;
    1378  	} iovu;
    1379  # define iov iovu.iov64
    1380  # define sizeof_iov \
    1381  	(current_wordsize == 4 ? (unsigned int) sizeof(*iovu.iov32)	\
    1382  			       : (unsigned int) sizeof(*iovu.iov64))
    1383  # define iov_iov_base(i) \
    1384  	(current_wordsize == 4 ? (uint64_t) iovu.iov32[i].base : iovu.iov64[i].base)
    1385  # define iov_iov_len(i) \
    1386  	(current_wordsize == 4 ? (uint64_t) iovu.iov32[i].len : iovu.iov64[i].len)
    1387  #else
    1388  	struct iovec *iov;
    1389  # define sizeof_iov ((unsigned int) sizeof(*iov))
    1390  # define iov_iov_base(i) ptr_to_kulong(iov[i].iov_base)
    1391  # define iov_iov_len(i) iov[i].iov_len
    1392  #endif
    1393  	unsigned int size = sizeof_iov * len;
    1394  	if (size / sizeof_iov != (unsigned int) len) {
    1395  		error_func_msg("requested %u iovec elements exceeds"
    1396  			       " %u iovec limit", len, -1U / sizeof_iov);
    1397  		return;
    1398  	}
    1399  
    1400  	iov = malloc(size);
    1401  	if (!iov) {
    1402  		error_func_msg("memory exhausted when tried to allocate"
    1403  			       " %u bytes", size);
    1404  		return;
    1405  	}
    1406  	if (umoven(tcp, addr, size, iov) >= 0) {
    1407  		for (int i = 0; i < len; ++i) {
    1408  			kernel_ulong_t iov_len = iov_iov_len(i);
    1409  			if (iov_len > data_size)
    1410  				iov_len = data_size;
    1411  			if (!iov_len)
    1412  				break;
    1413  			data_size -= iov_len;
    1414  			/* include the buffer number to make it easy to
    1415  			 * match up the trace with the source */
    1416  			tprintf_string(" * %" PRI_klu " bytes in buffer %d\n",
    1417  				       iov_len, i);
    1418  			dumpstr(tcp, iov_iov_base(i), iov_len);
    1419  		}
    1420  	}
    1421  	free(iov);
    1422  #undef sizeof_iov
    1423  #undef iov_iov_base
    1424  #undef iov_iov_len
    1425  #undef iov
    1426  }
    1427  
    1428  void
    1429  dumpstr(struct tcb *const tcp, const kernel_ulong_t addr,
    1430  	const kernel_ulong_t len)
    1431  {
    1432  	/* xx xx xx xx xx xx xx xx  xx xx xx xx xx xx xx xx  1234567890123456 */
    1433  	enum {
    1434  		HEX_BIT = 4,
    1435  
    1436  		DUMPSTR_GROUP_BYTES = 8,
    1437  		DUMPSTR_GROUPS = 2,
    1438  		DUMPSTR_WIDTH_BYTES = DUMPSTR_GROUP_BYTES * DUMPSTR_GROUPS,
    1439  
    1440  		/** Width of formatted dump in characters.  */
    1441  		DUMPSTR_WIDTH_CHARS = DUMPSTR_WIDTH_BYTES +
    1442  			sizeof("xx") * DUMPSTR_WIDTH_BYTES + DUMPSTR_GROUPS,
    1443  
    1444  		DUMPSTR_GROUP_MASK = DUMPSTR_GROUP_BYTES - 1,
    1445  		DUMPSTR_BYTES_MASK = DUMPSTR_WIDTH_BYTES - 1,
    1446  
    1447  		/** Minimal width of the offset field in the output.  */
    1448  		DUMPSTR_OFFS_MIN_CHARS = 5,
    1449  
    1450  		/** Arbitrarily chosen internal dumpstr buffer limit.  */
    1451  		DUMPSTR_BUF_MAXSZ = 1 << 16,
    1452  	};
    1453  
    1454  	static_assert(!(DUMPSTR_BUF_MAXSZ % DUMPSTR_WIDTH_BYTES),
    1455  		      "Maximum internal buffer size should be divisible "
    1456  		      "by amount of bytes dumped per line");
    1457  	static_assert(!(DUMPSTR_GROUP_BYTES & DUMPSTR_GROUP_MASK),
    1458  		      "DUMPSTR_GROUP_BYTES is not power of 2");
    1459  	static_assert(!(DUMPSTR_WIDTH_BYTES & DUMPSTR_BYTES_MASK),
    1460  		      "DUMPSTR_WIDTH_BYTES is not power of 2");
    1461  
    1462  	if (len > len + DUMPSTR_WIDTH_BYTES || addr + len < addr) {
    1463  		debug_func_msg("len %" PRI_klu " at addr %#" PRI_klx
    1464  			       " is too big, skipped", len, addr);
    1465  		return;
    1466  	}
    1467  
    1468  	static kernel_ulong_t strsize;
    1469  	static unsigned char *str;
    1470  
    1471  	const kernel_ulong_t alloc_size =
    1472  		MIN(ROUNDUP(len, DUMPSTR_WIDTH_BYTES), DUMPSTR_BUF_MAXSZ);
    1473  
    1474  	if (strsize < alloc_size) {
    1475  		free(str);
    1476  		str = malloc(alloc_size);
    1477  		if (!str) {
    1478  			strsize = 0;
    1479  			error_func_msg("memory exhausted when tried to allocate"
    1480  				       " %" PRI_klu " bytes", alloc_size);
    1481  			return;
    1482  		}
    1483  		strsize = alloc_size;
    1484  	}
    1485  
    1486  	/**
    1487  	 * Characters needed in order to print the offset field. We calculate
    1488  	 * it this way in order to avoid ilog2_64 call most of the time.
    1489  	 */
    1490  	const int offs_chars = len > (1 << (DUMPSTR_OFFS_MIN_CHARS * HEX_BIT))
    1491  		? 1 + ilog2_klong(len - 1) / HEX_BIT : DUMPSTR_OFFS_MIN_CHARS;
    1492  	kernel_ulong_t i = 0;
    1493  	const unsigned char *src;
    1494  
    1495  	while (i < len) {
    1496  		/*
    1497  		 * It is important to overwrite all the byte values, as we
    1498  		 * re-use the buffer in order to avoid its re-initialisation.
    1499  		 */
    1500  		static char outbuf[] = {
    1501  			[0 ... DUMPSTR_WIDTH_CHARS - 1] = ' ',
    1502  			'\0'
    1503  		};
    1504  		char *dst = outbuf;
    1505  
    1506  		/* Fetching data from tracee.  */
    1507  		if (!i || (i % DUMPSTR_BUF_MAXSZ) == 0) {
    1508  			kernel_ulong_t fetch_size = MIN(len - i, alloc_size);
    1509  
    1510  			if (umoven(tcp, addr + i, fetch_size, str) < 0) {
    1511  				/*
    1512  				 * Don't silently abort if we have printed
    1513  				 * something already.
    1514  				 */
    1515  				if (i)
    1516  					tprintf_string(" | <Cannot fetch %" PRI_klu
    1517  						       " byte%s from pid %d"
    1518  						       " @%#" PRI_klx ">\n",
    1519  						       fetch_size,
    1520  						       fetch_size == 1 ? "" : "s",
    1521  						       tcp->pid, addr + i);
    1522  				return;
    1523  			}
    1524  			src = str;
    1525  		}
    1526  
    1527  		/* hex dump */
    1528  		do {
    1529  			if (i < len) {
    1530  				dst = sprint_byte_hex(dst, *src);
    1531  			} else {
    1532  				*dst++ = ' ';
    1533  				*dst++ = ' ';
    1534  			}
    1535  			dst++; /* space is there */
    1536  			i++;
    1537  			if ((i & DUMPSTR_GROUP_MASK) == 0)
    1538  				dst++; /* space is there */
    1539  			src++;
    1540  		} while (i & DUMPSTR_BYTES_MASK);
    1541  
    1542  		/* ASCII dump */
    1543  		i -= DUMPSTR_WIDTH_BYTES;
    1544  		src -= DUMPSTR_WIDTH_BYTES;
    1545  		do {
    1546  			if (i < len) {
    1547  				if (is_print(*src))
    1548  					*dst++ = *src;
    1549  				else
    1550  					*dst++ = '.';
    1551  			} else {
    1552  				*dst++ = ' ';
    1553  			}
    1554  			src++;
    1555  		} while (++i & DUMPSTR_BYTES_MASK);
    1556  
    1557  		tprintf_string(" | %0*" PRI_klx "  %s |\n",
    1558  			       offs_chars, i - DUMPSTR_WIDTH_BYTES, outbuf);
    1559  	}
    1560  }
    1561  
    1562  bool
    1563  tfetch_mem64(struct tcb *const tcp, const uint64_t addr,
    1564  	     const unsigned int len, void *const our_addr)
    1565  {
    1566  	return addr && verbose(tcp) &&
    1567  	       (entering(tcp) || !syserror(tcp)) &&
    1568  	       !umoven(tcp, addr, len, our_addr);
    1569  }
    1570  
    1571  bool
    1572  tfetch_mem64_ignore_syserror(struct tcb *const tcp, const uint64_t addr,
    1573  			     const unsigned int len, void *const our_addr)
    1574  {
    1575  	return addr && verbose(tcp) &&
    1576  	       !umoven(tcp, addr, len, our_addr);
    1577  }
    1578  
    1579  int
    1580  umoven_or_printaddr64(struct tcb *const tcp, const uint64_t addr,
    1581  		      const unsigned int len, void *const our_addr)
    1582  {
    1583  	if (tfetch_mem64(tcp, addr, len, our_addr))
    1584  		return 0;
    1585  	printaddr64(addr);
    1586  	return -1;
    1587  }
    1588  
    1589  int
    1590  umoven_or_printaddr64_ignore_syserror(struct tcb *const tcp,
    1591  				      const uint64_t addr,
    1592  				      const unsigned int len,
    1593  				      void *const our_addr)
    1594  {
    1595  	if (tfetch_mem64_ignore_syserror(tcp, addr, len, our_addr))
    1596  		return 0;
    1597  	printaddr64(addr);
    1598  	return -1;
    1599  }
    1600  
    1601  int
    1602  umoven_to_uint64_or_printaddr64(struct tcb *const tcp, const uint64_t addr,
    1603  				unsigned int len, uint64_t *const our_addr)
    1604  {
    1605  	union {
    1606  		uint64_t val;
    1607  		uint8_t  bytes[sizeof(uint64_t)];
    1608  	} data = { .val = 0 };
    1609  	const size_t offs = is_bigendian ? sizeof(data) - len : 0;
    1610  
    1611  	if (len <= sizeof(data) &&
    1612  	    tfetch_mem64_ignore_syserror(tcp, addr, len, data.bytes + offs)) {
    1613  		*our_addr = data.val;
    1614  		return 0;
    1615  	}
    1616  	printaddr64(addr);
    1617  	return -1;
    1618  }
    1619  
    1620  bool
    1621  print_int_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
    1622  		       void *data)
    1623  {
    1624  	switch (elem_size) {
    1625  	case sizeof(int8_t):  PRINT_VAL_D(*(int8_t *) elem_buf);  break;
    1626  	case sizeof(int16_t): PRINT_VAL_D(*(int16_t *) elem_buf); break;
    1627  	case sizeof(int32_t): PRINT_VAL_D(*(int32_t *) elem_buf); break;
    1628  	case sizeof(int64_t): PRINT_VAL_D(*(int64_t *) elem_buf); break;
    1629  	default:
    1630  		error_func_msg("Unexpected elem_size: %zu", elem_size);
    1631  		return false;
    1632  	}
    1633  
    1634  	return true;
    1635  }
    1636  
    1637  bool
    1638  print_uint_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
    1639  			void *data)
    1640  {
    1641  	switch (elem_size) {
    1642  	case sizeof(uint8_t):  PRINT_VAL_U(*(uint8_t *) elem_buf);  break;
    1643  	case sizeof(uint16_t): PRINT_VAL_U(*(uint16_t *) elem_buf); break;
    1644  	case sizeof(uint32_t): PRINT_VAL_U(*(uint32_t *) elem_buf); break;
    1645  	case sizeof(uint64_t): PRINT_VAL_U(*(uint64_t *) elem_buf); break;
    1646  	default:
    1647  		error_func_msg("Unexpected elem_size: %zu", elem_size);
    1648  		return false;
    1649  	}
    1650  
    1651  	return true;
    1652  }
    1653  
    1654  bool
    1655  print_xint_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
    1656  			void *data)
    1657  {
    1658  	switch (elem_size) {
    1659  	case sizeof(uint8_t):  PRINT_VAL_X(*(uint8_t *) elem_buf);  break;
    1660  	case sizeof(uint16_t): PRINT_VAL_X(*(uint16_t *) elem_buf); break;
    1661  	case sizeof(uint32_t): PRINT_VAL_X(*(uint32_t *) elem_buf); break;
    1662  	case sizeof(uint64_t): PRINT_VAL_X(*(uint64_t *) elem_buf); break;
    1663  	default:
    1664  		error_func_msg("Unexpected elem_size: %zu", elem_size);
    1665  		return false;
    1666  	}
    1667  
    1668  	return true;
    1669  }
    1670  
    1671  bool
    1672  print_fd_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
    1673  		      void *data)
    1674  {
    1675  	printfd(tcp, *(int *) elem_buf);
    1676  	return true;
    1677  }
    1678  
    1679  /*
    1680   * Iteratively fetch and print up to nmemb elements of elem_size size
    1681   * from the array that starts at tracee's address start_addr.
    1682   *
    1683   * Array elements are being fetched to the address specified by elem_buf.
    1684   *
    1685   * The fetcher callback function specified by tfetch_mem_func should follow
    1686   * the same semantics as tfetch_mem function.
    1687   *
    1688   * The printer callback function specified by print_func is expected
    1689   * to print something; if it returns false, no more iterations will be made.
    1690   *
    1691   * The pointer specified by opaque_data is passed to each invocation
    1692   * of print_func callback function.
    1693   *
    1694   * This function prints:
    1695   * - "NULL", if start_addr is NULL;
    1696   * - "[]", if nmemb is 0;
    1697   * - start_addr, if nmemb * elem_size overflows or wraps around;
    1698   * - start_addr, if the first tfetch_mem_func invocation returned false;
    1699   * - elements of the array, delimited by ", ", with the array itself
    1700   *   enclosed with [] brackets.
    1701   *
    1702   * If abbrev(tcp) is true, then
    1703   * - the maximum number of elements printed equals to max_strlen;
    1704   * - "..." is printed instead of max_strlen+1 element
    1705   *   and no more iterations will be made.
    1706   *
    1707   * This function returns true only if tfetch_mem_func has returned true
    1708   * at least once.
    1709   */
    1710  bool
    1711  print_array_ex(struct tcb *const tcp,
    1712  	       const kernel_ulong_t start_addr,
    1713  	       const size_t nmemb,
    1714  	       void *elem_buf,
    1715  	       const size_t elem_size,
    1716  	       tfetch_mem_fn tfetch_mem_func,
    1717  	       print_fn print_func,
    1718  	       void *const opaque_data,
    1719  	       unsigned int flags,
    1720  	       const struct xlat *index_xlat,
    1721  	       const char *index_dflt)
    1722  {
    1723  	if (!start_addr) {
    1724  		tprint_null();
    1725  		return false;
    1726  	}
    1727  
    1728  	if (!nmemb) {
    1729  		tprint_array_begin();
    1730  		if (flags & PAF_ARRAY_TRUNCATED)
    1731  			tprint_more_data_follows();
    1732  		tprint_array_end();
    1733  		return false;
    1734  	}
    1735  
    1736  	const size_t size = nmemb * elem_size;
    1737  	const kernel_ulong_t end_addr = start_addr + size;
    1738  
    1739  	if (end_addr <= start_addr || size / elem_size != nmemb) {
    1740  		if (tfetch_mem_func)
    1741  			printaddr(start_addr);
    1742  		else
    1743  			tprint_unavailable();
    1744  		return false;
    1745  	}
    1746  
    1747  	const kernel_ulong_t abbrev_end =
    1748  		(abbrev(tcp) && max_strlen < nmemb) ?
    1749  			start_addr + elem_size * max_strlen : end_addr;
    1750  	kernel_ulong_t cur;
    1751  	kernel_ulong_t idx = 0;
    1752  	enum xlat_style xlat_style = flags & XLAT_STYLE_MASK;
    1753  	bool truncated = false;
    1754  
    1755  	for (cur = start_addr; cur < end_addr; cur += elem_size, idx++) {
    1756  		if (cur != start_addr)
    1757  			tprint_array_next();
    1758  
    1759  		if (tfetch_mem_func) {
    1760  			if (!tfetch_mem_func(tcp, cur, elem_size, elem_buf)) {
    1761  				if (cur == start_addr)
    1762  					printaddr(cur);
    1763  				else {
    1764  					tprint_more_data_follows();
    1765  					printaddr_comment(cur);
    1766  					truncated = true;
    1767  				}
    1768  				break;
    1769  			}
    1770  		} else {
    1771  			elem_buf = (void *) (uintptr_t) cur;
    1772  		}
    1773  
    1774  		if (cur == start_addr)
    1775  			tprint_array_begin();
    1776  
    1777  		if (cur >= abbrev_end) {
    1778  			tprint_more_data_follows();
    1779  			cur = end_addr;
    1780  			truncated = true;
    1781  			break;
    1782  		}
    1783  
    1784  		if (flags & PAF_PRINT_INDICES) {
    1785  			tprint_array_index_begin();
    1786  
    1787  			if (!index_xlat) {
    1788  				print_xlat_ex(idx, NULL, xlat_style);
    1789  			} else {
    1790  				printxval_ex(index_xlat, idx, index_dflt,
    1791  					     xlat_style);
    1792  			}
    1793  
    1794  			tprint_array_index_equal();
    1795  		}
    1796  
    1797  		bool break_needed =
    1798  			!print_func(tcp, elem_buf, elem_size, opaque_data);
    1799  
    1800  		if (flags & PAF_PRINT_INDICES)
    1801  			tprint_array_index_end();
    1802  
    1803  		if (break_needed) {
    1804  			cur = end_addr;
    1805  			break;
    1806  		}
    1807  	}
    1808  
    1809  	if ((cur != start_addr) || !tfetch_mem_func) {
    1810  		if ((flags & PAF_ARRAY_TRUNCATED) && !truncated) {
    1811  			if (cur != start_addr)
    1812  				tprint_array_next();
    1813  
    1814  			tprint_more_data_follows();
    1815  		}
    1816  
    1817  		tprint_array_end();
    1818  	}
    1819  
    1820  	return cur >= end_addr;
    1821  }
    1822  
    1823  int
    1824  printargs(struct tcb *tcp)
    1825  {
    1826  	const unsigned int n = n_args(tcp);
    1827  	for (unsigned int i = 0; i < n; ++i) {
    1828  		if (i)
    1829  			tprint_arg_next();
    1830  		PRINT_VAL_X(tcp->u_arg[i]);
    1831  	}
    1832  	return RVAL_DECODED;
    1833  }
    1834  
    1835  int
    1836  printargs_u(struct tcb *tcp)
    1837  {
    1838  	const unsigned int n = n_args(tcp);
    1839  	for (unsigned int i = 0; i < n; ++i) {
    1840  		if (i)
    1841  			tprint_arg_next();
    1842  		PRINT_VAL_U((unsigned int) tcp->u_arg[i]);
    1843  	}
    1844  	return RVAL_DECODED;
    1845  }
    1846  
    1847  int
    1848  printargs_d(struct tcb *tcp)
    1849  {
    1850  	const unsigned int n = n_args(tcp);
    1851  	for (unsigned int i = 0; i < n; ++i) {
    1852  		if (i)
    1853  			tprint_arg_next();
    1854  		PRINT_VAL_D((int) tcp->u_arg[i]);
    1855  	}
    1856  	return RVAL_DECODED;
    1857  }
    1858  
    1859  /* Print abnormal high bits of a kernel_ulong_t value. */
    1860  void
    1861  print_abnormal_hi(const kernel_ulong_t val)
    1862  {
    1863  	if (current_klongsize > 4) {
    1864  		const unsigned int hi = (unsigned int) ((uint64_t) val >> 32);
    1865  		if (hi) {
    1866  			tprint_shift_begin();
    1867  			PRINT_VAL_X(hi);
    1868  			tprint_shift();
    1869  			PRINT_VAL_U(32);
    1870  			tprint_shift_end();
    1871  			tprint_flags_or();
    1872  		}
    1873  	}
    1874  }
    1875  
    1876  int
    1877  read_int_from_file(const char *const fname, int *const pvalue)
    1878  {
    1879  	const int fd = open_file(fname, O_RDONLY);
    1880  	if (fd < 0)
    1881  		return -1;
    1882  
    1883  	long lval;
    1884  	char buf[sizeof(lval) * 3];
    1885  	int n = read(fd, buf, sizeof(buf) - 1);
    1886  	int saved_errno = errno;
    1887  	close(fd);
    1888  
    1889  	if (n < 0) {
    1890  		errno = saved_errno;
    1891  		return -1;
    1892  	}
    1893  
    1894  	buf[n] = '\0';
    1895  	char *endptr = 0;
    1896  	errno = 0;
    1897  	lval = strtol(buf, &endptr, 10);
    1898  	if (!endptr || (*endptr && '\n' != *endptr)
    1899  #if INT_MAX < LONG_MAX
    1900  	    || lval > INT_MAX || lval < INT_MIN
    1901  #endif
    1902  	    || ERANGE == errno) {
    1903  		if (!errno)
    1904  			errno = EINVAL;
    1905  		return -1;
    1906  	}
    1907  
    1908  	*pvalue = (int) lval;
    1909  	return 0;
    1910  }