mirror of
				https://github.com/xdp-project/bpf-examples.git
				synced 2024-05-06 15:54:53 +00:00 
			
		
		
		
	This is taken from the Cilium project: https://github.com/cilium/cilium/blob/master/bpf/include/bpf/compiler.h The use-case was adding READ_ONCE and WRITE_ONCE, but via re-using the Cilium version we get a lot more useful compiler annotations. Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
		
			
				
	
	
		
			125 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* SPDX-License-Identifier: GPL-2.0 */
 | |
| /* Copyright (C) 2016-2020 Authors of Cilium */
 | |
| 
 | |
| #ifndef __BPF_COMPILER_H_
 | |
| #define __BPF_COMPILER_H_
 | |
| 
 | |
| #ifndef __non_bpf_context
 | |
| # include "stddef.h"
 | |
| #endif
 | |
| 
 | |
| #ifndef __section
 | |
| # define __section(X)		__attribute__((section(X), used))
 | |
| #endif
 | |
| 
 | |
| #ifndef __maybe_unused
 | |
| # define __maybe_unused		__attribute__((__unused__))
 | |
| #endif
 | |
| 
 | |
| #ifndef offsetof
 | |
| # define offsetof(T, M)		__builtin_offsetof(T, M)
 | |
| #endif
 | |
| 
 | |
| #ifndef field_sizeof
 | |
| # define field_sizeof(T, M)	sizeof((((T *)NULL)->M))
 | |
| #endif
 | |
| 
 | |
| #ifndef __packed
 | |
| # define __packed		__attribute__((packed))
 | |
| #endif
 | |
| 
 | |
| #ifndef __nobuiltin
 | |
| # if __clang_major__ >= 10
 | |
| #  define __nobuiltin(X)	__attribute__((no_builtin(X)))
 | |
| # else
 | |
| #  define __nobuiltin(X)
 | |
| # endif
 | |
| #endif
 | |
| 
 | |
| #ifndef likely
 | |
| # define likely(X)		__builtin_expect(!!(X), 1)
 | |
| #endif
 | |
| 
 | |
| #ifndef unlikely
 | |
| # define unlikely(X)		__builtin_expect(!!(X), 0)
 | |
| #endif
 | |
| 
 | |
| #ifndef always_succeeds		/* Mainly for documentation purpose. */
 | |
| # define always_succeeds(X)	likely(X)
 | |
| #endif
 | |
| 
 | |
| #undef __always_inline		/* stddef.h defines its own */
 | |
| #define __always_inline		inline __attribute__((always_inline))
 | |
| 
 | |
| #ifndef __stringify
 | |
| # define __stringify(X)		#X
 | |
| #endif
 | |
| 
 | |
| #ifndef __fetch
 | |
| # define __fetch(X)		(__u32)(__u64)(&(X))
 | |
| #endif
 | |
| 
 | |
| #ifndef __aligned
 | |
| # define __aligned(X)		__attribute__((aligned(X)))
 | |
| #endif
 | |
| 
 | |
| #ifndef build_bug_on
 | |
| # define build_bug_on(E)	((void)sizeof(char[1 - 2*!!(E)]))
 | |
| #endif
 | |
| 
 | |
| #ifndef __throw_build_bug
 | |
| # define __throw_build_bug()	__builtin_trap()
 | |
| #endif
 | |
| 
 | |
| #ifndef __printf
 | |
| # define __printf(X, Y)		__attribute__((__format__(printf, X, Y)))
 | |
| #endif
 | |
| 
 | |
| #ifndef barrier
 | |
| # define barrier()		asm volatile("": : :"memory")
 | |
| #endif
 | |
| 
 | |
| #ifndef barrier_data
 | |
| # define barrier_data(ptr)	asm volatile("": :"r"(ptr) :"memory")
 | |
| #endif
 | |
| 
 | |
| static __always_inline void bpf_barrier(void)
 | |
| {
 | |
| 	/* Workaround to avoid verifier complaint:
 | |
| 	 * "dereference of modified ctx ptr R5 off=48+0, ctx+const is allowed,
 | |
| 	 *        ctx+const+const is not"
 | |
| 	 */
 | |
| 	barrier();
 | |
| }
 | |
| 
 | |
| #ifndef ARRAY_SIZE
 | |
| # define ARRAY_SIZE(A)		(sizeof(A) / sizeof((A)[0]))
 | |
| #endif
 | |
| 
 | |
| #ifndef __READ_ONCE
 | |
| # define __READ_ONCE(X)		(*(volatile typeof(X) *)&X)
 | |
| #endif
 | |
| 
 | |
| #ifndef __WRITE_ONCE
 | |
| # define __WRITE_ONCE(X, V)	(*(volatile typeof(X) *)&X) = (V)
 | |
| #endif
 | |
| 
 | |
| /* {READ,WRITE}_ONCE() with verifier workaround via bpf_barrier(). */
 | |
| 
 | |
| #ifndef READ_ONCE
 | |
| # define READ_ONCE(X)						\
 | |
| 			({ typeof(X) __val = __READ_ONCE(X);	\
 | |
| 			   bpf_barrier();			\
 | |
| 			   __val; })
 | |
| #endif
 | |
| 
 | |
| #ifndef WRITE_ONCE
 | |
| # define WRITE_ONCE(X, V)					\
 | |
| 				({ typeof(X) __val = (V);	\
 | |
| 				   __WRITE_ONCE(X, __val);	\
 | |
| 				   bpf_barrier();		\
 | |
| 				   __val; })
 | |
| #endif
 | |
| 
 | |
| #endif /* __BPF_COMPILER_H_ */
 |