File: bpf-lib.h

package info (click to toggle)
dtrace 2.0.5-1
  • links: PTS
  • area: main
  • in suites: sid
  • size: 24,408 kB
  • sloc: ansic: 61,247; sh: 17,997; asm: 1,717; lex: 947; awk: 754; yacc: 695; perl: 37; sed: 17; makefile: 15
file content (90 lines) | stat: -rw-r--r-- 2,260 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
 * Oracle Linux DTrace.
 * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */

#ifndef BPF_LIB_H
#define BPF_LIB_H

/*
 * Explicit inline assembler to implement a dynamic upper bound check:
 *
 *	if (var > bnd)
 *		var = bnd;
 *
 * The BPF GCC compiler does not guarantee that the bound (expected to be a
 * variable that holds a constant value) will be encoded in the source register
 * while the BPF verifier does require that (for now).
 */
#define set_upper_bound(var, bnd) \
	asm ("jle %0, %1, 1f\n\t" \
	     "mov %0, %1\n\t" \
	     "1:" \
		: "+r" (var) \
		: "r" (bnd) \
		: /* no clobbers */ \
	);

/*
 * Explicit inline assembler to implement a dynamic lower bound check:
 *
 *	if (var < bnd)
 *		var = bnd;
 *
 * The BPF GCC compiler does not guarantee that the bound (expected to be a
 * variable that holds a constant value) will be encoded in the source register
 * while the BPF verifier does require that (for now).
 */
#define set_lower_bound(var, bnd) \
	asm ("jge %0, %1, 1f\n\t" \
	     "mov %0, %1\n\t" \
	     "1:" \
		: "+r" (var) \
		: "r" (bnd) \
		: /* no clobbers */ \
	);

/*
 * Explicit inline assembler to implement a non-negative bound check:
 *
 *	if (var < 0)
 *		var = 0;
 */
#define set_not_neg_bound(var) \
	asm ("jsge %0, 0, 1f\n\t" \
             "mov %0, 0\n\t" \
             "1:" \
                : "+r" (var) \
                : /* no inputs */ \
                : /* no clobbers */ \
        );

/*
 * Explicit inline assembler to implement atomic add:
 *
 *	*ptr += val;
 */
#define atomic_add(valp, val) \
	do { \
		register uint64_t *ptr asm("%r0") = (valp); \
		register uint64_t tmp asm("%r1") = (val); \
		asm (".byte 0xdb, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00" \
			: /* no outputs */ \
			: "r" (ptr), "r" (tmp) \
			: "memory" \
		); \
	} while (0)
#define atomic_add32(valp, val) \
	do { \
		register uint32_t *ptr asm("%r0") = (valp); \
		register uint32_t tmp asm("%r1") = (val); \
		asm (".byte 0xc3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00" \
			: /* no outputs */ \
			: "r" (ptr), "r" (tmp) \
			: "memory" \
		); \
	} while (0)

#endif /* BPF_LIB_H */