1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __BPF_UTIL__ 3 #define __BPF_UTIL__ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <errno.h> 9 #include <syscall.h> 10 #include <bpf/libbpf.h> /* libbpf_num_possible_cpus */ 11 #include <linux/args.h> 12 13 static inline unsigned int bpf_num_possible_cpus(void) 14 { 15 int possible_cpus = libbpf_num_possible_cpus(); 16 17 if (possible_cpus < 0) { 18 printf("Failed to get # of possible cpus: '%s'!\n", 19 strerror(-possible_cpus)); 20 exit(1); 21 } 22 return possible_cpus; 23 } 24 25 /* 26 * Simplified strscpy() implementation. The kernel one is in lib/string.c 27 */ 28 static inline ssize_t sized_strscpy(char *dest, const char *src, size_t count) 29 { 30 long res = 0; 31 32 if (count == 0) 33 return -E2BIG; 34 35 while (count > 1) { 36 char c; 37 38 c = src[res]; 39 dest[res] = c; 40 if (!c) 41 return res; 42 res++; 43 count--; 44 } 45 46 /* Force NUL-termination. */ 47 dest[res] = '\0'; 48 49 /* Return E2BIG if the source didn't stop */ 50 return src[res] ? -E2BIG : res; 51 } 52 53 #define __strscpy0(dst, src, ...) \ 54 sized_strscpy(dst, src, sizeof(dst)) 55 #define __strscpy1(dst, src, size) \ 56 sized_strscpy(dst, src, size) 57 58 #undef strscpy /* Redefine the placeholder from tools/include/linux/string.h */ 59 #define strscpy(dst, src, ...) \ 60 CONCATENATE(__strscpy, COUNT_ARGS(__VA_ARGS__))(dst, src, __VA_ARGS__) 61 62 #define __bpf_percpu_val_align __attribute__((__aligned__(8))) 63 64 #define BPF_DECLARE_PERCPU(type, name) \ 65 struct { type v; /* padding */ } __bpf_percpu_val_align \ 66 name[bpf_num_possible_cpus()] 67 #define bpf_percpu(name, cpu) name[(cpu)].v 68 69 #ifndef ARRAY_SIZE 70 # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 71 #endif 72 73 #ifndef sizeof_field 74 #define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER)) 75 #endif 76 77 #ifndef offsetofend 78 #define offsetofend(TYPE, MEMBER) \ 79 (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER)) 80 #endif 81 82 /* Availability of gettid across glibc versions is hit-and-miss, therefore 83 * fallback to syscall in this macro and use it everywhere. 84 */ 85 #ifndef sys_gettid 86 #define sys_gettid() syscall(SYS_gettid) 87 #endif 88 89 /* and poison usage to ensure it does not creep back in. */ 90 #pragma GCC poison gettid 91 92 #ifndef ENOTSUPP 93 #define ENOTSUPP 524 94 #endif 95 96 #endif /* __BPF_UTIL__ */ 97