1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/bpf.h> 3 #include <bpf/bpf_helpers.h> 4 #include <bpf/bpf_tracing.h> 5 #include <errno.h> 6 7 char _license[] SEC("license") = "GPL"; 8 9 __u64 test1_result = 0; 10 SEC("fentry/bpf_fentry_test1") 11 int BPF_PROG(test1) 12 { 13 __u64 cnt = bpf_get_func_arg_cnt(ctx); 14 __u64 a = 0, z = 0, ret = 0; 15 __s64 err; 16 17 test1_result = cnt == 1; 18 19 /* valid arguments */ 20 err = bpf_get_func_arg(ctx, 0, &a); 21 22 /* We need to cast access to traced function argument values with 23 * proper type cast, because trampoline uses type specific instruction 24 * to save it, like for 'int a' with 32-bit mov like: 25 * 26 * mov %edi,-0x8(%rbp) 27 * 28 * so the upper 4 bytes are not zeroed. 29 */ 30 test1_result &= err == 0 && ((int) a == 1); 31 32 /* not valid argument */ 33 err = bpf_get_func_arg(ctx, 1, &z); 34 test1_result &= err == -EINVAL; 35 36 /* return value fails in fentry */ 37 err = bpf_get_func_ret(ctx, &ret); 38 test1_result &= err == -EOPNOTSUPP; 39 return 0; 40 } 41 42 __u64 test2_result = 0; 43 SEC("fexit/bpf_fentry_test2") 44 int BPF_PROG(test2) 45 { 46 __u64 cnt = bpf_get_func_arg_cnt(ctx); 47 __u64 a = 0, b = 0, z = 0, ret = 0; 48 __s64 err; 49 50 test2_result = cnt == 2; 51 52 /* valid arguments */ 53 err = bpf_get_func_arg(ctx, 0, &a); 54 test2_result &= err == 0 && (int) a == 2; 55 56 err = bpf_get_func_arg(ctx, 1, &b); 57 test2_result &= err == 0 && b == 3; 58 59 /* not valid argument */ 60 err = bpf_get_func_arg(ctx, 2, &z); 61 test2_result &= err == -EINVAL; 62 63 /* return value */ 64 err = bpf_get_func_ret(ctx, &ret); 65 test2_result &= err == 0 && ret == 5; 66 return 0; 67 } 68 69 __u64 test3_result = 0; 70 SEC("fmod_ret/bpf_modify_return_test") 71 int BPF_PROG(fmod_ret_test, int _a, int *_b, int _ret) 72 { 73 __u64 cnt = bpf_get_func_arg_cnt(ctx); 74 __u64 a = 0, b = 0, z = 0, ret = 0; 75 __s64 err; 76 77 test3_result = cnt == 2; 78 79 /* valid arguments */ 80 err = bpf_get_func_arg(ctx, 0, &a); 81 test3_result &= err == 0 && ((int) a == 1); 82 83 err = bpf_get_func_arg(ctx, 1, &b); 84 test3_result &= err == 0 && ((int *) b == _b); 85 86 /* not valid argument */ 87 err = bpf_get_func_arg(ctx, 2, &z); 88 test3_result &= err == -EINVAL; 89 90 /* return value */ 91 err = bpf_get_func_ret(ctx, &ret); 92 test3_result &= err == 0 && ret == 0; 93 94 /* change return value, it's checked in fexit_test program */ 95 return 1234; 96 } 97 98 __u64 test4_result = 0; 99 SEC("fexit/bpf_modify_return_test") 100 int BPF_PROG(fexit_test, int _a, int *_b, int _ret) 101 { 102 __u64 cnt = bpf_get_func_arg_cnt(ctx); 103 __u64 a = 0, b = 0, z = 0, ret = 0; 104 __s64 err; 105 106 test4_result = cnt == 2; 107 108 /* valid arguments */ 109 err = bpf_get_func_arg(ctx, 0, &a); 110 test4_result &= err == 0 && ((int) a == 1); 111 112 err = bpf_get_func_arg(ctx, 1, &b); 113 test4_result &= err == 0 && ((int *) b == _b); 114 115 /* not valid argument */ 116 err = bpf_get_func_arg(ctx, 2, &z); 117 test4_result &= err == -EINVAL; 118 119 /* return value */ 120 err = bpf_get_func_ret(ctx, &ret); 121 test4_result &= err == 0 && ret == 1234; 122 return 0; 123 } 124