1#include "vmlinux.h" 2#include <bpf/bpf_helpers.h> 3#include <bpf/bpf_core_read.h> 4 5const char LICENSE[] SEC("license") = "GPL"; 6 7__noinline int sub1(int x) 8{ 9 return x + 1; 10} 11 12static __noinline int sub5(int v); 13 14__noinline int sub2(int y) 15{ 16 return sub5(y + 2); 17} 18 19static __noinline int sub3(int z) 20{ 21 return z + 3 + sub1(4); 22} 23 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 */ 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 */ 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 47int res1 = 0; 48int res2 = 0; 49int res3 = 0; 50int res4 = 0; 51 52SEC("raw_tp/sys_enter") 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 67SEC("raw_tp/sys_exit") 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 */ 80SEC("raw_tp/sys_enter") 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 */ 93SEC("raw_tp/sys_exit") 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