1 #include "vmlinux.h"
2 #include <bpf/bpf_helpers.h>
3 #include <bpf/bpf_core_read.h>
4 
5 const char LICENSE[] SEC("license") = "GPL";
6 
7 __noinline int sub1(int x)
8 {
9 	return x + 1;
10 }
11 
12 static __noinline int sub5(int v);
13 
14 __noinline int sub2(int y)
15 {
16 	return sub5(y + 2);
17 }
18 
19 static __noinline int sub3(int z)
20 {
21 	return z + 3 + sub1(4);
22 }
23 
24 static __noinline int sub4(int w)
25 {
26 	return w + sub3(5) + sub1(6);
27 }
28 
29 /* sub5() is an identitify function, just to test weirder functions layout and
30  * call patterns
31  */
32 static __noinline int sub5(int v)
33 {
34 	return sub1(v) - 1; /* compensates sub1()'s + 1 */
35 }
36 
37 /* unfortunately verifier rejects `struct task_struct *t` as an unkown pointer
38  * type, so we need to accept pointer as integer and then cast it inside the
39  * function
40  */
41 __noinline int get_task_tgid(uintptr_t t)
42 {
43 	/* this ensures that CO-RE relocs work in multi-subprogs .text */
44 	return BPF_CORE_READ((struct task_struct *)(void *)t, tgid);
45 }
46 
47 int res1 = 0;
48 int res2 = 0;
49 int res3 = 0;
50 int res4 = 0;
51 
52 SEC("raw_tp/sys_enter")
53 int prog1(void *ctx)
54 {
55 	/* perform some CO-RE relocations to ensure they work with multi-prog
56 	 * sections correctly
57 	 */
58 	struct task_struct *t = (void *)bpf_get_current_task();
59 
60 	if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))
61 		return 1;
62 
63 	res1 = sub1(1) + sub3(2); /* (1 + 1) + (2 + 3 + (4 + 1)) = 12 */
64 	return 0;
65 }
66 
67 SEC("raw_tp/sys_exit")
68 int prog2(void *ctx)
69 {
70 	struct task_struct *t = (void *)bpf_get_current_task();
71 
72 	if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))
73 		return 1;
74 
75 	res2 = sub2(3) + sub3(4); /* (3 + 2) + (4 + 3 + (4 + 1)) = 17 */
76 	return 0;
77 }
78 
79 /* prog3 has the same section name as prog1 */
80 SEC("raw_tp/sys_enter")
81 int prog3(void *ctx)
82 {
83 	struct task_struct *t = (void *)bpf_get_current_task();
84 
85 	if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))
86 		return 1;
87 
88 	res3 = sub3(5) + 6; /* (5 + 3 + (4 + 1)) + 6 = 19 */
89 	return 0;
90 }
91 
92 /* prog4 has the same section name as prog2 */
93 SEC("raw_tp/sys_exit")
94 int prog4(void *ctx)
95 {
96 	struct task_struct *t = (void *)bpf_get_current_task();
97 
98 	if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))
99 		return 1;
100 
101 	res4 = sub4(7) + sub1(8); /* (7 + (5 + 3 + (4 + 1)) + (6 + 1)) + (8 + 1) = 36 */
102 	return 0;
103 }
104