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 sub1(int x)7__noinline int sub1(int x) 8 { 9 return x + 1; 10 } 11 12 static __noinline int sub5(int v); 13 sub2(int y)14__noinline int sub2(int y) 15 { 16 return sub5(y + 2); 17 } 18 sub3(int z)19static __noinline int sub3(int z) 20 { 21 return z + 3 + sub1(4); 22 } 23 sub4(int w)24static __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 */ sub5(int v)32static __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 */ get_task_tgid(uintptr_t t)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") prog1(void * ctx)53int 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") prog2(void * ctx)68int 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") prog3(void * ctx)81int 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") prog4(void * ctx)94int 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