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 */