20
20
#include "test_global_func17.skel.h"
21
21
#include "test_global_func_ctx_args.skel.h"
22
22
23
+ #include "bpf/libbpf_internal.h"
24
+ #include "btf_helpers.h"
25
+
26
+ static void check_ctx_arg_type (const struct btf * btf , const struct btf_param * p )
27
+ {
28
+ const struct btf_type * t ;
29
+ const char * s ;
30
+
31
+ t = btf__type_by_id (btf , p -> type );
32
+ if (!ASSERT_EQ (btf_kind (t ), BTF_KIND_PTR , "ptr_t" ))
33
+ return ;
34
+
35
+ s = btf_type_raw_dump (btf , t -> type );
36
+ if (!ASSERT_HAS_SUBSTR (s , "STRUCT 'bpf_perf_event_data' size=0 vlen=0" ,
37
+ "ctx_struct_t" ))
38
+ return ;
39
+ }
40
+
41
+ static void subtest_ctx_arg_rewrite (void )
42
+ {
43
+ struct test_global_func_ctx_args * skel = NULL ;
44
+ struct bpf_prog_info info ;
45
+ char func_info_buf [1024 ] __attribute__((aligned (8 )));
46
+ struct bpf_func_info_min * rec ;
47
+ struct btf * btf = NULL ;
48
+ __u32 info_len = sizeof (info );
49
+ int err , fd , i ;
50
+
51
+ skel = test_global_func_ctx_args__open ();
52
+ if (!ASSERT_OK_PTR (skel , "skel_open" ))
53
+ return ;
54
+
55
+ bpf_program__set_autoload (skel -> progs .arg_tag_ctx_perf , true);
56
+
57
+ err = test_global_func_ctx_args__load (skel );
58
+ if (!ASSERT_OK (err , "skel_load" ))
59
+ goto out ;
60
+
61
+ memset (& info , 0 , sizeof (info ));
62
+ info .func_info = ptr_to_u64 (& func_info_buf );
63
+ info .nr_func_info = 3 ;
64
+ info .func_info_rec_size = sizeof (struct bpf_func_info_min );
65
+
66
+ fd = bpf_program__fd (skel -> progs .arg_tag_ctx_perf );
67
+ err = bpf_prog_get_info_by_fd (fd , & info , & info_len );
68
+ if (!ASSERT_OK (err , "prog_info" ))
69
+ goto out ;
70
+
71
+ if (!ASSERT_EQ (info .nr_func_info , 3 , "nr_func_info" ))
72
+ goto out ;
73
+
74
+ btf = btf__load_from_kernel_by_id (info .btf_id );
75
+ if (!ASSERT_OK_PTR (btf , "obj_kern_btf" ))
76
+ goto out ;
77
+
78
+ rec = (struct bpf_func_info_min * )func_info_buf ;
79
+ for (i = 0 ; i < info .nr_func_info ; i ++ , rec = (void * )rec + info .func_info_rec_size ) {
80
+ const struct btf_type * fn_t , * proto_t ;
81
+ const char * name ;
82
+
83
+ if (rec -> insn_off == 0 )
84
+ continue ; /* main prog, skip */
85
+
86
+ fn_t = btf__type_by_id (btf , rec -> type_id );
87
+ if (!ASSERT_OK_PTR (fn_t , "fn_type" ))
88
+ goto out ;
89
+ if (!ASSERT_EQ (btf_kind (fn_t ), BTF_KIND_FUNC , "fn_type_kind" ))
90
+ goto out ;
91
+ proto_t = btf__type_by_id (btf , fn_t -> type );
92
+ if (!ASSERT_OK_PTR (proto_t , "proto_type" ))
93
+ goto out ;
94
+
95
+ name = btf__name_by_offset (btf , fn_t -> name_off );
96
+ if (strcmp (name , "subprog_ctx_tag" ) == 0 ) {
97
+ /* int subprog_ctx_tag(void *ctx __arg_ctx) */
98
+ if (!ASSERT_EQ (btf_vlen (proto_t ), 1 , "arg_cnt" ))
99
+ goto out ;
100
+
101
+ /* arg 0 is PTR -> STRUCT bpf_perf_event_data */
102
+ check_ctx_arg_type (btf , & btf_params (proto_t )[0 ]);
103
+ } else if (strcmp (name , "subprog_multi_ctx_tags" ) == 0 ) {
104
+ /* int subprog_multi_ctx_tags(void *ctx1 __arg_ctx,
105
+ * struct my_struct *mem,
106
+ * void *ctx2 __arg_ctx)
107
+ */
108
+ if (!ASSERT_EQ (btf_vlen (proto_t ), 3 , "arg_cnt" ))
109
+ goto out ;
110
+
111
+ /* arg 0 is PTR -> STRUCT bpf_perf_event_data */
112
+ check_ctx_arg_type (btf , & btf_params (proto_t )[0 ]);
113
+ /* arg 2 is PTR -> STRUCT bpf_perf_event_data */
114
+ check_ctx_arg_type (btf , & btf_params (proto_t )[2 ]);
115
+ } else {
116
+ ASSERT_FAIL ("unexpected subprog %s" , name );
117
+ goto out ;
118
+ }
119
+ }
120
+
121
+ out :
122
+ btf__free (btf );
123
+ test_global_func_ctx_args__destroy (skel );
124
+ }
125
+
23
126
void test_test_global_funcs (void )
24
127
{
25
128
RUN_TESTS (test_global_func1 );
@@ -40,4 +143,7 @@ void test_test_global_funcs(void)
40
143
RUN_TESTS (test_global_func16 );
41
144
RUN_TESTS (test_global_func17 );
42
145
RUN_TESTS (test_global_func_ctx_args );
146
+
147
+ if (test__start_subtest ("ctx_arg_rewrite" ))
148
+ subtest_ctx_arg_rewrite ();
43
149
}
0 commit comments