1 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2
3 #ifndef __TOOLS_LIBC_COMPAT_H
4 #define __TOOLS_LIBC_COMPAT_H
5
6 #include <limits.h>
7 #include <stdlib.h>
8
9 #ifndef unlikely
10 #define unlikely(x) __builtin_expect(!!(x), 0)
11 #endif
12
13 #ifndef __has_builtin
14 #define __has_builtin(x) 0
15 #endif
16
17 /*
18 * Re-implement glibc's reallocarray(). This function is not available in all
19 * versions of glibc. The version of bpftool shipped with the kernel deals with
20 * this by doing an extra feature detection, and by using a stub in
21 * <tools/libc_compat.h> (this file) when COMPAT_NEED_REALLOCARRAY is set.
22 * Let's keep things simple here: it is trivial to re-implement the function.
23 * Libbpf does the same in libbpf_internal.h: we can copy its version.
24 */
bpftool_reallocarray(void * ptr,size_t nmemb,size_t size)25 static inline void *bpftool_reallocarray(void *ptr, size_t nmemb, size_t size)
26 {
27 size_t total;
28
29 #if __has_builtin(__builtin_mul_overflow)
30 if (unlikely(__builtin_mul_overflow(nmemb, size, &total)))
31 return NULL;
32 #else
33 if (size == 0 || nmemb > ULONG_MAX / size)
34 return NULL;
35 total = nmemb * size;
36 #endif
37 return realloc(ptr, total);
38 }
39
40 /*
41 * Overwrite default reallocarray(). It would probably be cleaner to use
42 * "bpftool_reallocarray()" in the source code to make the distinction
43 * explicit, but we want to avoid touching the code to remain in sync with the
44 * kernel and ease maintenance.
45 */
46 #define reallocarray(ptr, nmemb, size) bpftool_reallocarray(ptr, nmemb, size)
47
48 #endif
49