(root)/
strace-6.5/
src/
macros.h
       1  /*
       2   * Copyright (c) 2001-2023 The strace developers.
       3   * All rights reserved.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   */
       7  
       8  #ifndef STRACE_MACROS_H
       9  # define STRACE_MACROS_H
      10  
      11  # include <stdbool.h>
      12  # include <stddef.h>
      13  # include <sys/types.h>
      14  
      15  # include "gcc_compat.h"
      16  # include "static_assert.h"
      17  
      18  /*
      19   * Evaluates to:
      20   * a syntax error, if the argument is 0;
      21   * 0, otherwise.
      22   */
      23  # define FAIL_BUILD_ON_ZERO(e_)	(sizeof(int[-1 + 2 * !!(e_)]) * 0)
      24  
      25  /*
      26   * Evaluates to:
      27   * 1, if the given type is known to be a non-array type;
      28   * 0, otherwise.
      29   */
      30  # define IS_NOT_ARRAY(a_)	IS_SAME_TYPE((a_), &(a_)[0])
      31  
      32  /*
      33   * Evaluates to:
      34   * a syntax error, if the argument is not an array;
      35   * 0, otherwise.
      36   */
      37  # define MUST_BE_ARRAY(a_)	FAIL_BUILD_ON_ZERO(!IS_NOT_ARRAY(a_))
      38  
      39  /* Evaluates to the number of elements in the specified array.  */
      40  # define ARRAY_SIZE(a_)	(sizeof(a_) / sizeof((a_)[0]) + MUST_BE_ARRAY(a_))
      41  
      42  # define ARRSZ_PAIR(a_) a_, ARRAY_SIZE(a_)
      43  
      44  # define STRINGIFY(...)		#__VA_ARGS__
      45  # define STRINGIFY_VAL(...)	STRINGIFY(__VA_ARGS__)
      46  
      47  # ifndef MAX
      48  #  define MAX(a, b)		(((a) > (b)) ? (a) : (b))
      49  # endif
      50  # ifndef MIN
      51  #  define MIN(a, b)		(((a) < (b)) ? (a) : (b))
      52  # endif
      53  # define CLAMP(val, min, max)	MIN(MAX(val, min), max)
      54  
      55  # ifndef ROUNDUP_DIV
      56  #  define ROUNDUP_DIV(val_, div_) (((val_) + (div_) - 1) / (div_))
      57  # endif
      58  
      59  # ifndef ROUNDUP
      60  #  define ROUNDUP(val_, div_) (ROUNDUP_DIV((val_), (div_)) * (div_))
      61  # endif
      62  
      63  # define sizeof_field(type_, member_) (sizeof(((type_ *)0)->member_))
      64  
      65  # define typeof_field(type_, member_) typeof(((type_ *)0)->member_)
      66  
      67  # ifndef offsetofend
      68  #  define offsetofend(type_, member_)	\
      69  	(offsetof(type_, member_) + sizeof_field(type_, member_))
      70  # endif
      71  
      72  # ifndef cast_ptr
      73  #  define cast_ptr(type_, var_)	\
      74  	((type_) (uintptr_t) (const volatile void *) (var_))
      75  # endif
      76  
      77  # ifndef containerof
      78  /**
      79   * Return a pointer to a structure that contains the provided variable.
      80   *
      81   * @param ptr_    Pointer to data that is a field of the container structure.
      82   * @param struct_ Type of the container structure.
      83   * @param member_ Name of the member field.
      84   * @return  Pointer to the container structure.
      85   */
      86  #  define containerof(ptr_, struct_, member_)	\
      87  	cast_ptr(struct_ *,			\
      88  		 (const volatile char *) (ptr_) - offsetof(struct_, member_))
      89  # endif
      90  
      91  static inline bool
      92  is_filled(const char *ptr, char fill, size_t size)
      93  {
      94  	while (size--)
      95  		if (*ptr++ != fill)
      96  			return false;
      97  
      98  	return true;
      99  }
     100  
     101  # define IS_ARRAY_ZERO(arr_)	\
     102  	is_filled((const char *) (arr_), 0, sizeof(arr_) + MUST_BE_ARRAY(arr_))
     103  
     104  # ifndef BIT32
     105  #  define BIT32(x_) (1U << (x_))
     106  # endif
     107  
     108  # ifndef BIT64
     109  #  define BIT64(x_) (1ULL << (x_))
     110  # endif
     111  
     112  # ifndef MASK32
     113  #  define MASK32(x_) (BIT32(x_) - 1U)
     114  # endif
     115  
     116  # ifndef MASK64
     117  #  define MASK64(x_) (BIT64(x_) - 1ULL)
     118  # endif
     119  
     120  /*
     121   * "Safe" versions that avoid UB for values that are >= type bit size
     122   * (the usually expected behaviour of the bit shift in that case is zero,
     123   * but at least powerpc is notorious for returning the input value when shift
     124   * by 64 bits is performed).
     125   */
     126  
     127  # define BIT32_SAFE(x_) ((x_) < 32 ? BIT32(x_) : 0)
     128  # define BIT64_SAFE(x_) ((x_) < 64 ? BIT64(x_) : 0)
     129  # define MASK32_SAFE(x_) (BIT32_SAFE(x_) - 1U)
     130  # define MASK64_SAFE(x_) (BIT64_SAFE(x_) - 1ULL)
     131  
     132  # define FLAG(name_) name_ = BIT32(name_##_BIT)
     133  
     134  /**
     135   * A shorthand for a build-time check of a type size that provides
     136   * a corresponding "update the decoder" message in a case of failure.
     137   * @param type_ Type whose size is to be checked.
     138   * @param sz_   Expected type size in bytes.
     139   */
     140  # define CHECK_TYPE_SIZE(type_, sz_) \
     141  	static_assert(sizeof(type_) == (sz_), \
     142  		      "Unexpected size of " #type_ " (" #sz_ " expected).  " \
     143  		      "--enabled-bundled=yes configure option may be used " \
     144  		      "to work around that.") \
     145  	/* End of CHECK_TYPE_SIZE */
     146  
     147  /** Checks that ioctl code's size field contains the expected value. */
     148  # define CHECK_IOCTL_SIZE(ioc_, sz_) \
     149  	static_assert(_IOC_SIZE(ioc_) == (sz_), \
     150  		"Unexpected size field value in " #ioc_ \
     151  		" (" #sz_" expected).  --enabled-bundled=yes configure " \
     152  		"option may be used to work around that.") \
     153  	/* End of CHECK_IOCTL_SIZE */
     154  
     155  # ifdef WORDS_BIGENDIAN
     156  #  define BE16(val_) val_
     157  #  define BE32(val_) val_
     158  #  define BE64(val_) val_
     159  # else
     160  #  define BE16(val_) ((((val_) & 0xff) << 8) | (((val_) >> 8) & 0xff))
     161  #  define BE32(val_) ((BE16(val_) << 16) | BE16((val_) >> 16))
     162  #  define BE64(val_) ((BE32(val_) << 32) | BE32((val_) >> 32))
     163  # endif
     164  
     165  #endif /* !STRACE_MACROS_H */