• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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