(root)/
strace-6.5/
src/
print_fields.h
       1  /*
       2   * Copyright (c) 2016-2017 Dmitry V. Levin <ldv@strace.io>
       3   * Copyright (c) 2017-2023 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: LGPL-2.1-or-later
       7   */
       8  
       9  #ifndef STRACE_PRINT_FIELDS_H
      10  # define STRACE_PRINT_FIELDS_H
      11  
      12  # include "static_assert.h"
      13  
      14  # ifdef IN_STRACE
      15  
      16  #  define STRACE_PRINTS(s_) tprints_string(s_)
      17  
      18  /*
      19   * The printf-like function to use in header files
      20   * shared between strace and its tests.
      21   */
      22  #  define STRACE_PRINTF tprintf_string
      23  
      24  # else /* !IN_STRACE */
      25  
      26  #  include <stdio.h>
      27  
      28  #  define STRACE_PRINTS(s_) fputs((s_), stdout)
      29  
      30  /*
      31   * The printf-like function to use in header files
      32   * shared between strace and its tests.
      33   */
      34  #  define STRACE_PRINTF printf
      35  
      36  # endif /* !IN_STRACE */
      37  
      38  
      39  static inline void
      40  tprint_struct_begin(void)
      41  {
      42  	STRACE_PRINTS("{");
      43  }
      44  
      45  static inline void
      46  tprint_struct_next(void)
      47  {
      48  	STRACE_PRINTS(", ");
      49  }
      50  
      51  static inline void
      52  tprint_struct_end(void)
      53  {
      54  	STRACE_PRINTS("}");
      55  }
      56  
      57  static inline void
      58  tprint_union_begin(void)
      59  {
      60  	STRACE_PRINTS("{");
      61  }
      62  
      63  static inline void
      64  tprint_union_next(void)
      65  {
      66  	STRACE_PRINTS(", ");
      67  }
      68  
      69  static inline void
      70  tprint_union_end(void)
      71  {
      72  	STRACE_PRINTS("}");
      73  }
      74  
      75  static inline void
      76  tprint_array_begin(void)
      77  {
      78  	STRACE_PRINTS("[");
      79  }
      80  
      81  static inline void
      82  tprint_array_next(void)
      83  {
      84  	STRACE_PRINTS(", ");
      85  }
      86  
      87  static inline void
      88  tprint_array_end(void)
      89  {
      90  	STRACE_PRINTS("]");
      91  }
      92  
      93  static inline void
      94  tprint_array_index_begin(void)
      95  {
      96  	STRACE_PRINTS("[");
      97  }
      98  
      99  static inline void
     100  tprint_array_index_equal(void)
     101  {
     102  	STRACE_PRINTS("]=");
     103  }
     104  
     105  static inline void
     106  tprint_array_index_end(void)
     107  {
     108  }
     109  
     110  static inline void
     111  tprint_arg_next(void)
     112  {
     113  	STRACE_PRINTS(", ");
     114  }
     115  
     116  static inline void
     117  tprint_arg_end(void)
     118  {
     119  	STRACE_PRINTS(")");
     120  }
     121  
     122  static inline void
     123  tprint_bitset_begin(void)
     124  {
     125  	STRACE_PRINTS("[");
     126  }
     127  
     128  static inline void
     129  tprint_bitset_next(void)
     130  {
     131  	STRACE_PRINTS(" ");
     132  }
     133  
     134  static inline void
     135  tprint_bitset_end(void)
     136  {
     137  	STRACE_PRINTS("]");
     138  }
     139  
     140  static inline void
     141  tprint_comment_begin(void)
     142  {
     143  	STRACE_PRINTS(" /* ");
     144  }
     145  
     146  static inline void
     147  tprint_comment_end(void)
     148  {
     149  	STRACE_PRINTS(" */");
     150  }
     151  
     152  static inline void
     153  tprint_indirect_begin(void)
     154  {
     155  	STRACE_PRINTS("[");
     156  }
     157  
     158  static inline void
     159  tprint_indirect_end(void)
     160  {
     161  	STRACE_PRINTS("]");
     162  }
     163  
     164  static inline void
     165  tprint_attribute_begin(void)
     166  {
     167  	STRACE_PRINTS("[");
     168  }
     169  
     170  static inline void
     171  tprint_attribute_end(void)
     172  {
     173  	STRACE_PRINTS("]");
     174  }
     175  
     176  static inline void
     177  tprint_associated_info_begin(void)
     178  {
     179  	STRACE_PRINTS("<");
     180  }
     181  
     182  static inline void
     183  tprint_associated_info_end(void)
     184  {
     185  	STRACE_PRINTS(">");
     186  }
     187  
     188  static inline void
     189  tprint_more_data_follows(void)
     190  {
     191  	STRACE_PRINTS("...");
     192  }
     193  
     194  static inline void
     195  tprint_value_changed(void)
     196  {
     197  	STRACE_PRINTS(" => ");
     198  }
     199  
     200  static inline void
     201  tprint_alternative_value(void)
     202  {
     203  	STRACE_PRINTS(" or ");
     204  }
     205  
     206  static inline void
     207  tprint_unavailable(void)
     208  {
     209  	STRACE_PRINTS("???");
     210  }
     211  
     212  static inline void
     213  tprint_shift_begin(void)
     214  {
     215  }
     216  
     217  static inline void
     218  tprint_shift_end(void)
     219  {
     220  }
     221  
     222  static inline void
     223  tprint_shift(void)
     224  {
     225  	STRACE_PRINTS("<<");
     226  }
     227  
     228  static inline void
     229  tprint_flags_begin(void)
     230  {
     231  }
     232  
     233  static inline void
     234  tprint_flags_or(void)
     235  {
     236  	STRACE_PRINTS("|");
     237  }
     238  
     239  static inline void
     240  tprint_flags_end(void)
     241  {
     242  }
     243  
     244  static inline void
     245  tprint_plus(void)
     246  {
     247  	STRACE_PRINTS("+");
     248  }
     249  
     250  static inline void
     251  tprint_space(void)
     252  {
     253  	STRACE_PRINTS(" ");
     254  }
     255  
     256  static inline void
     257  tprint_null(void)
     258  {
     259  	STRACE_PRINTS("NULL");
     260  }
     261  
     262  static inline void
     263  tprint_newline(void)
     264  {
     265  	STRACE_PRINTS("\n");
     266  }
     267  
     268  static inline void
     269  tprints_field_name(const char *name)
     270  {
     271  	STRACE_PRINTF("%s=", name);
     272  }
     273  
     274  static inline void
     275  tprints_arg_name_begin(const char *name)
     276  {
     277  	STRACE_PRINTF("%s=", name);
     278  }
     279  
     280  static inline void
     281  tprint_arg_name_end(void)
     282  {
     283  }
     284  
     285  static inline void
     286  tprints_arg_begin(const char *name)
     287  {
     288  	STRACE_PRINTF("%s(", name);
     289  }
     290  
     291  static inline void
     292  tprint_sysret_begin(void)
     293  {
     294  	STRACE_PRINTS("=");
     295  }
     296  
     297  static inline void
     298  tprints_sysret_next(const char *name)
     299  {
     300  	tprint_space();
     301  }
     302  
     303  static inline void
     304  tprints_sysret_string(const char *name, const char *str)
     305  {
     306  	tprints_sysret_next(name);
     307  	STRACE_PRINTF("(%s)", str);
     308  }
     309  
     310  static inline void
     311  tprint_sysret_pseudo_rval(void)
     312  {
     313  	STRACE_PRINTS("?");
     314  }
     315  
     316  static inline void
     317  tprint_sysret_end(void)
     318  {
     319  }
     320  
     321  # define PRINT_VAL_D(val_)	\
     322  	STRACE_PRINTF("%lld", sign_extend_unsigned_to_ll(val_))
     323  
     324  # define PRINT_VAL_U(val_)	\
     325  	STRACE_PRINTF("%llu", zero_extend_signed_to_ull(val_))
     326  
     327  # define PRINT_VAL_X(val_)	\
     328  	STRACE_PRINTF("%#llx", zero_extend_signed_to_ull(val_))
     329  
     330  # define PRINT_VAL_03O(val_)	\
     331  	STRACE_PRINTF("%#03llo", zero_extend_signed_to_ull(val_))
     332  
     333  # define PRINT_VAL_0X(val_)						\
     334  	STRACE_PRINTF("%#0*llx", (int) sizeof(val_) * 2,		\
     335  		      zero_extend_signed_to_ull(val_))
     336  
     337  # define PRINT_VAL_ID(val_)						\
     338  	do {								\
     339  		if (sign_extend_unsigned_to_ll(val_) == -1LL)		\
     340  			PRINT_VAL_D(-1);				\
     341  		else							\
     342  			PRINT_VAL_U(val_);				\
     343  	} while (0)
     344  
     345  # define PRINT_FIELD_D(where_, field_)					\
     346  	do {								\
     347  		tprints_field_name(#field_);				\
     348  		PRINT_VAL_D((where_).field_);				\
     349  	} while (0)
     350  
     351  # define PRINT_FIELD_U(where_, field_)					\
     352  	do {								\
     353  		tprints_field_name(#field_);				\
     354  		PRINT_VAL_U((where_).field_);				\
     355  	} while (0)
     356  
     357  # define PRINT_FIELD_U_CAST(where_, field_, type_)			\
     358  	do {								\
     359  		tprints_field_name(#field_);				\
     360  		PRINT_VAL_U((type_)((where_).field_));			\
     361  	} while (0)
     362  
     363  # define PRINT_FIELD_X(where_, field_)					\
     364  	do {								\
     365  		tprints_field_name(#field_);				\
     366  		PRINT_VAL_X((where_).field_);				\
     367  	} while (0)
     368  
     369  # define PRINT_FIELD_X_CAST(where_, field_, type_)			\
     370  	do {								\
     371  		tprints_field_name(#field_);				\
     372  		PRINT_VAL_X((type_)((where_).field_));			\
     373  	} while (0)
     374  
     375  # define PRINT_FIELD_ADDR64(where_, field_)				\
     376  	do {								\
     377  		tprints_field_name(#field_);				\
     378  		printaddr64((where_).field_);				\
     379  	} while (0)
     380  
     381  # define PRINT_FIELD_0X(where_, field_)					\
     382  	do {								\
     383  		tprints_field_name(#field_);				\
     384  		PRINT_VAL_0X((where_).field_);				\
     385  	} while (0)
     386  
     387  # define PRINT_FIELD_VAL_ARRAY(where_, field_, print_val_)		\
     388  	do {								\
     389  		tprints_field_name(#field_);				\
     390  		for (size_t i_ = 0;					\
     391  		     i_ < ARRAY_SIZE((where_).field_);			\
     392  		     ++i_) {						\
     393  			if (i_)						\
     394  				tprint_array_next();			\
     395  			else						\
     396  				tprint_array_begin();			\
     397  			print_val_((where_).field_[i_]);		\
     398  		}							\
     399  		tprint_array_end();					\
     400  	} while (0)
     401  
     402  # define PRINT_FIELD_D_ARRAY(where_, field_)				\
     403  	PRINT_FIELD_VAL_ARRAY((where_), field_, PRINT_VAL_D)
     404  
     405  # define PRINT_FIELD_U_ARRAY(where_, field_)				\
     406  	PRINT_FIELD_VAL_ARRAY((where_), field_, PRINT_VAL_U)
     407  
     408  # define PRINT_FIELD_X_ARRAY(where_, field_)				\
     409  	PRINT_FIELD_VAL_ARRAY((where_), field_, PRINT_VAL_X)
     410  
     411  # define PRINT_FIELD_VAL_ARRAY2D(where_, field_, print_val_)		\
     412  	do {								\
     413  		tprints_field_name(#field_);				\
     414  		for (size_t i_ = 0;					\
     415  		     i_ < ARRAY_SIZE((where_).field_);			\
     416  		     ++i_) {						\
     417  			if (i_)						\
     418  				tprint_array_next();			\
     419  			else						\
     420  				tprint_array_begin();			\
     421  			for (size_t j_ = 0;				\
     422  			     j_ < ARRAY_SIZE((where_).field_[i_]);	\
     423  			     ++j_) {					\
     424  				if (j_)					\
     425  					tprint_array_next();		\
     426  				else					\
     427  					tprint_array_begin();		\
     428  				print_val_((where_).field_[i_][j_]);	\
     429  			}						\
     430  			tprint_array_end();				\
     431  		}							\
     432  		tprint_array_end();					\
     433  	} while (0)
     434  
     435  # define PRINT_FIELD_X_ARRAY2D(where_, field_)				\
     436  	PRINT_FIELD_VAL_ARRAY2D((where_), field_, PRINT_VAL_X)
     437  
     438  # define PRINT_FIELD_COOKIE(where_, field_)				\
     439  	do {								\
     440  		static_assert(ARRAY_SIZE((where_).field_) == 2,		\
     441  			      "unexpected array size");			\
     442  		PRINT_FIELD_U_ARRAY((where_), field_);			\
     443  	} while (0)
     444  
     445  # define PRINT_FIELD_FLAGS(where_, field_, xlat_, dflt_)		\
     446  	do {								\
     447  		tprints_field_name(#field_);				\
     448  		printflags64((xlat_),					\
     449  			     zero_extend_signed_to_ull((where_).field_),\
     450  			     (dflt_));					\
     451  	} while (0)
     452  
     453  # define PRINT_FIELD_FLAGS_VERBOSE(where_, field_, xlat_, dflt_)	\
     454  	do {								\
     455  		tprints_field_name(#field_);				\
     456  		tprint_flags_begin();					\
     457  		printflags_ex(zero_extend_signed_to_ull((where_).field_), \
     458  			      (dflt_),					\
     459  			      xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW \
     460  				? XLAT_STYLE_RAW : XLAT_STYLE_VERBOSE,	\
     461  			      (xlat_), NULL);				\
     462  		tprint_flags_end();					\
     463  	} while (0)
     464  
     465  # define PRINT_FIELD_XVAL(where_, field_, xlat_, dflt_)			\
     466  	do {								\
     467  		tprints_field_name(#field_);				\
     468  		printxval64((xlat_),					\
     469  			    zero_extend_signed_to_ull((where_).field_),	\
     470  			    (dflt_));					\
     471  	} while (0)
     472  
     473  # define PRINT_FIELD_XVAL_VERBOSE(where_, field_, xlat_, dflt_)		\
     474  	do {								\
     475  		tprints_field_name(#field_);				\
     476  		printxval_ex((xlat_),					\
     477  			     zero_extend_signed_to_ull((where_).field_), \
     478  			     (dflt_),					\
     479  			     xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW \
     480  				? XLAT_STYLE_RAW : XLAT_STYLE_VERBOSE);	\
     481  	} while (0)
     482  
     483  # define PRINT_FIELD_XVAL_D(where_, field_, xlat_, dflt_)		\
     484  	do {								\
     485  		tprints_field_name(#field_);				\
     486  		printxval64_d((xlat_),					\
     487  			      sign_extend_unsigned_to_ll((where_).field_), \
     488  			      (dflt_));					\
     489  	} while (0)
     490  
     491  # define PRINT_FIELD_XVAL_U(where_, field_, xlat_, dflt_)		\
     492  	do {								\
     493  		tprints_field_name(#field_);				\
     494  		printxval64_u((xlat_),					\
     495  			      zero_extend_signed_to_ull((where_).field_), \
     496  			      (dflt_));					\
     497  	} while (0)
     498  
     499  # define PRINT_FIELD_XVAL_U_VERBOSE(where_, field_, xlat_, dflt_)	\
     500  	do {								\
     501  		tprints_field_name(#field_);				\
     502  		printxval_ex((xlat_),					\
     503  			     zero_extend_signed_to_ull((where_).field_), \
     504  			     (dflt_),					\
     505  			     (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW \
     506  				? XLAT_STYLE_RAW : XLAT_STYLE_VERBOSE)	\
     507  			     | XLAT_STYLE_FMT_U);			\
     508  	} while (0)
     509  
     510  # define PRINT_FIELD_ERR_D(where_, field_)				\
     511  	do {								\
     512  		tprints_field_name(#field_);				\
     513  		print_err(sign_extend_unsigned_to_ll((where_).field_),	\
     514  			  true);					\
     515  	} while (0)
     516  
     517  # define PRINT_FIELD_ERR_U(where_, field_)				\
     518  	do {								\
     519  		tprints_field_name(#field_);				\
     520  		print_err(zero_extend_signed_to_ull((where_).field_),	\
     521  			  false);					\
     522  	} while (0)
     523  
     524  /*
     525   * Generic "ID" printing. ID is considered unsigned except for the special value
     526   * of -1.
     527   */
     528  # define PRINT_FIELD_ID(where_, field_)					\
     529  	do {								\
     530  		tprints_field_name(#field_);				\
     531  		PRINT_VAL_ID((where_).field_);				\
     532  	} while (0)
     533  
     534  # define PRINT_FIELD_UUID(where_, field_)				\
     535  	do {								\
     536  		tprints_field_name(#field_);				\
     537  		print_uuid((const unsigned char *) ((where_).field_));	\
     538  	} while (0)
     539  
     540  # define PRINT_FIELD_U64(where_, field_)					\
     541  	do {									\
     542  		tprints_field_name(#field_);					\
     543  		if (zero_extend_signed_to_ull((where_).field_) == UINT64_MAX)	\
     544  			print_xlat_u(UINT64_MAX);				\
     545  		else								\
     546  			PRINT_VAL_U((where_).field_);				\
     547  	} while (0)
     548  
     549  # define PRINT_FIELD_TICKS(where_, field_, freq_, precision_)		\
     550  	do {								\
     551  		tprints_field_name(#field_);				\
     552  		print_ticks((where_).field_, (freq_), (precision_));	\
     553  	} while (0)
     554  
     555  # define PRINT_FIELD_TICKS_D(where_, field_, freq_, precision_)		\
     556  	do {								\
     557  		tprints_field_name(#field_);				\
     558  		print_ticks_d((where_).field_, (freq_), (precision_));	\
     559  	} while (0)
     560  
     561  # define PRINT_FIELD_CLOCK_T(where_, field_)				\
     562  	do {								\
     563  		tprints_field_name(#field_);				\
     564  		print_clock_t((where_).field_);				\
     565  	} while (0)
     566  
     567  # define PRINT_FIELD_STRING(where_, field_, len_, style_)		\
     568  	do {								\
     569  		tprints_field_name(#field_);				\
     570  		print_quoted_string((const char *)(where_).field_,	\
     571  				    (len_), (style_));			\
     572  	} while (0)
     573  
     574  # define PRINT_FIELD_CSTRING(where_, field_)				\
     575  	do {								\
     576  		tprints_field_name(#field_);				\
     577  		print_quoted_cstring((const char *) (where_).field_,	\
     578  				     sizeof((where_).field_) +		\
     579  				     MUST_BE_ARRAY((where_).field_));	\
     580  	} while (0)
     581  
     582  # define PRINT_FIELD_CSTRING_SZ(where_, field_, size_)			\
     583  	do {								\
     584  		tprints_field_name(#field_);				\
     585  		print_quoted_cstring((const char *) (where_).field_,	\
     586  				     (size_));				\
     587  	} while (0)
     588  
     589  # define PRINT_FIELD_ARRAY(where_, field_, tcp_, print_func_)		\
     590  	do {								\
     591  		tprints_field_name(#field_);				\
     592  		print_local_array((tcp_), (where_).field_,		\
     593  				  (print_func_));			\
     594  	} while (0)
     595  
     596  # define PRINT_FIELD_ARRAY_INDEXED(where_, field_, tcp_, print_func_,	\
     597  				   ind_xlat_, ind_dflt_)		\
     598  	do {								\
     599  		tprints_field_name(#field_);				\
     600  		print_local_array_ex((tcp_), (where_).field_,		\
     601  				  ARRAY_SIZE((where_).field_),		\
     602  				  sizeof(((where_).field_)[0]),		\
     603  				  (print_func_),			\
     604  				  NULL, PAF_PRINT_INDICES | XLAT_STYLE_FMT_U, \
     605  				  (ind_xlat_), (ind_dflt_));		\
     606  	} while (0)
     607  
     608  # define PRINT_FIELD_ARRAY_UPTO(where_, field_,				\
     609  				upto_, tcp_, print_func_)		\
     610  	do {								\
     611  		tprints_field_name(#field_);				\
     612  		print_local_array_upto((tcp_), (where_).field_,		\
     613  				       (upto_), (print_func_));		\
     614  	} while (0)
     615  
     616  # define PRINT_FIELD_HEX_ARRAY(where_, field_)				\
     617  	do {								\
     618  		tprints_field_name(#field_);				\
     619  		print_quoted_string((const char *)(where_).field_,	\
     620  				    sizeof((where_).field_) +		\
     621  					    MUST_BE_ARRAY((where_).field_), \
     622  				    QUOTE_FORCE_HEX); \
     623  	} while (0)
     624  
     625  # define PRINT_FIELD_HEX_ARRAY_UPTO(where_, field_, upto_)		\
     626  	do {								\
     627  		tprints_field_name(#field_);				\
     628  		print_quoted_string((const char *)(where_).field_,	\
     629  				    (upto_), QUOTE_FORCE_HEX);		\
     630  	} while (0)
     631  
     632  # define PRINT_FIELD_INET_ADDR(where_, field_, af_)			\
     633  	print_inet_addr((af_), &(where_).field_,			\
     634  			sizeof((where_).field_), #field_)
     635  
     636  # define PRINT_FIELD_NET_PORT(where_, field_)				\
     637  	do {								\
     638  		tprints_field_name(#field_);				\
     639  									\
     640  		if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)	\
     641  			print_quoted_string((const char *)		\
     642  					&(where_).field_,		\
     643  					sizeof((where_).field_),	\
     644  					QUOTE_FORCE_HEX);		\
     645  									\
     646  		if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)	\
     647  			break;						\
     648  									\
     649  		if (xlat_verbose(xlat_verbosity)			\
     650  				== XLAT_STYLE_VERBOSE)			\
     651  			tprint_comment_begin();				\
     652  									\
     653  		tprints_arg_begin("htons");				\
     654  		unsigned short us_ = ntohs((where_).field_);		\
     655  		PRINT_VAL_U(us_);					\
     656  		tprint_arg_end();					\
     657  									\
     658  		if (xlat_verbose(xlat_verbosity)			\
     659  				== XLAT_STYLE_VERBOSE)			\
     660  			tprint_comment_end();				\
     661  	} while (0)
     662  
     663  # define PRINT_FIELD_IFINDEX(where_, field_)				\
     664  	do {								\
     665  		tprints_field_name(#field_);				\
     666  		print_ifindex((where_).field_);				\
     667  	} while (0)
     668  
     669  # define PRINT_FIELD_SOCKADDR(where_, field_, tcp_)			\
     670  	do {								\
     671  		tprints_field_name(#field_);				\
     672  		print_sockaddr(tcp_, &(where_).field_,			\
     673  			       sizeof((where_).field_));		\
     674  	} while (0)
     675  
     676  # define PRINT_FIELD_DEV(where_, field_)				\
     677  	do {								\
     678  		tprints_field_name(#field_);				\
     679  		print_dev_t((where_).field_);				\
     680  	} while (0)
     681  
     682  # define PRINT_FIELD_PTR(where_, field_)				\
     683  	do {								\
     684  		tprints_field_name(#field_);				\
     685  		printaddr((mpers_ptr_t) (where_).field_);		\
     686  	} while (0)
     687  
     688  # define PRINT_FIELD_FD(where_, field_, tcp_)				\
     689  	do {								\
     690  		tprints_field_name(#field_);				\
     691  		printfd((tcp_), (where_).field_);			\
     692  	} while (0)
     693  
     694  # define PRINT_FIELD_DIRFD(where_, field_, tcp_)			\
     695  	do {								\
     696  		tprints_field_name(#field_);				\
     697  		print_dirfd((tcp_), (where_).field_);			\
     698  	} while (0)
     699  
     700  # define PRINT_FIELD_CHAR(where_, field_, flags_)		\
     701  	do {								\
     702  		tprints_field_name(#field_);				\
     703  		print_char((where_).field_, (flags_));			\
     704  	} while (0)
     705  
     706  # define PRINT_FIELD_TGID(where_, field_, tcp_)				\
     707  	do {								\
     708  		tprints_field_name(#field_);				\
     709  		printpid((tcp_), (where_).field_, PT_TGID);		\
     710  	} while (0)
     711  
     712  # define PRINT_FIELD_SYSCALL_NAME(where_, field_, audit_arch_)		\
     713  	do {								\
     714  		tprints_field_name(#field_);				\
     715  		const char *nr_prefix_ = NULL;				\
     716  		const char *name = syscall_name_arch((where_).field_,	\
     717  					(audit_arch_), &nr_prefix_);	\
     718  		if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV	\
     719  		    || !nr_prefix_)					\
     720  			PRINT_VAL_U((where_).field_);			\
     721  		if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW	\
     722  		    || !name)						\
     723  			break;						\
     724  		if (!nr_prefix_ ||					\
     725  		    xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)	\
     726  			tprint_comment_begin();				\
     727  		if (nr_prefix_)						\
     728  			tprints_string(nr_prefix_);			\
     729  		tprints_string(name);					\
     730  		if (!nr_prefix_ ||					\
     731  		    xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)	\
     732  			tprint_comment_end();				\
     733  	} while (0)
     734  
     735  # define PRINT_FIELD_MAC(where_, field_)				\
     736  	PRINT_FIELD_MAC_SZ((where_), field_, ARRAY_SIZE((where_).field_))
     737  
     738  # define PRINT_FIELD_MAC_SZ(where_, field_, size_)			\
     739  	do {								\
     740  		static_assert(sizeof(((where_).field_)[0]) == 1,	\
     741  			      "MAC address is not a byte array");	\
     742  		tprints_field_name(#field_);				\
     743  		print_mac_addr("", (const uint8_t *) ((where_).field_),	\
     744  			MIN((size_), ARRAY_SIZE((where_).field_)));	\
     745  	} while (0)
     746  
     747  # define PRINT_FIELD_HWADDR_SZ(where_, field_, size_, hwtype_)		\
     748  	do {								\
     749  		static_assert(sizeof(((where_).field_)[0]) == 1,	\
     750  			      "hwaddress is not a byte array");		\
     751  		tprints_field_name(#field_);				\
     752  		print_hwaddr("", (const uint8_t *) ((where_).field_),	\
     753  			       (size_), (hwtype_));			\
     754  	} while (0)
     755  
     756  
     757  # define PRINT_FIELD_OBJ_PTR(where_, field_, print_func_, ...)		\
     758  	do {								\
     759  		tprints_field_name(#field_);				\
     760  		(print_func_)(&((where_).field_), ##__VA_ARGS__);	\
     761  	} while (0)
     762  
     763  # define PRINT_FIELD_OBJ_TCB_PTR(where_, field_,			\
     764  				 tcp_, print_func_, ...)		\
     765  	do {								\
     766  		tprints_field_name(#field_);				\
     767  		(print_func_)((tcp_), &((where_).field_),		\
     768  			      ##__VA_ARGS__);				\
     769  	} while (0)
     770  
     771  # define PRINT_FIELD_OBJ_VAL(where_, field_, print_func_, ...)		\
     772  	do {								\
     773  		tprints_field_name(#field_);				\
     774  		(print_func_)((where_).field_, ##__VA_ARGS__);		\
     775  	} while (0)
     776  
     777  # define PRINT_FIELD_OBJ_U(where_, field_, print_func_, ...)		\
     778  	do {								\
     779  		tprints_field_name(#field_);				\
     780  		(print_func_)(zero_extend_signed_to_ull((where_).field_),\
     781  			      ##__VA_ARGS__);				\
     782  	} while (0)
     783  
     784  # define PRINT_FIELD_OBJ_TCB_VAL(where_, field_,			\
     785  			     tcp_, print_func_, ...)			\
     786  	do {								\
     787  		tprints_field_name(#field_);				\
     788  		(print_func_)((tcp_), (where_).field_, ##__VA_ARGS__);	\
     789  	} while (0)
     790  
     791  
     792  # define MAYBE_PRINT_FIELD_LEN(print_prefix_, where_, field_,		\
     793  			len_, print_func_, ...)				\
     794  	do {								\
     795  		unsigned int start = offsetof(typeof(where_), field_);	\
     796  		unsigned int end = start + sizeof((where_).field_);	\
     797  		if (len_ > start) {					\
     798  			print_prefix_;					\
     799  			if (len_ >= end) {				\
     800  				print_func_((where_), field_,		\
     801  					    ##__VA_ARGS__);		\
     802  			} else {					\
     803  				tprints_field_name(#field_);		\
     804  				print_quoted_string(			\
     805  					(void *)&(where_).field_,	\
     806  					len_ - start, QUOTE_FORCE_HEX);	\
     807  			}						\
     808  		}							\
     809  	} while (0)
     810  
     811  #endif /* !STRACE_PRINT_FIELDS_H */