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