1 // SPDX-License-Identifier: GPL-2.0
2 #include <test_progs.h>
3 #include "stacktrace_ips.skel.h"
4
5 #ifdef __x86_64__
check_stacktrace_ips(int fd,__u32 key,int cnt,...)6 static int check_stacktrace_ips(int fd, __u32 key, int cnt, ...)
7 {
8 __u64 ips[PERF_MAX_STACK_DEPTH];
9 struct ksyms *ksyms = NULL;
10 int i, err = 0;
11 va_list args;
12
13 /* sorted by addr */
14 ksyms = load_kallsyms_local();
15 if (!ASSERT_OK_PTR(ksyms, "load_kallsyms_local"))
16 return -1;
17
18 /* unlikely, but... */
19 if (!ASSERT_LT(cnt, PERF_MAX_STACK_DEPTH, "check_max"))
20 return -1;
21
22 err = bpf_map_lookup_elem(fd, &key, ips);
23 if (err)
24 goto out;
25
26 /*
27 * Compare all symbols provided via arguments with stacktrace ips,
28 * and their related symbol addresses.t
29 */
30 va_start(args, cnt);
31
32 for (i = 0; i < cnt; i++) {
33 unsigned long val;
34 struct ksym *ksym;
35
36 val = va_arg(args, unsigned long);
37 ksym = ksym_search_local(ksyms, ips[i]);
38 if (!ASSERT_OK_PTR(ksym, "ksym_search_local"))
39 break;
40 ASSERT_EQ(ksym->addr, val, "stack_cmp");
41 }
42
43 va_end(args);
44
45 out:
46 free_kallsyms_local(ksyms);
47 return err;
48 }
49
test_stacktrace_ips_kprobe_multi(bool retprobe)50 static void test_stacktrace_ips_kprobe_multi(bool retprobe)
51 {
52 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts,
53 .retprobe = retprobe
54 );
55 LIBBPF_OPTS(bpf_test_run_opts, topts);
56 struct stacktrace_ips *skel;
57
58 skel = stacktrace_ips__open_and_load();
59 if (!ASSERT_OK_PTR(skel, "stacktrace_ips__open_and_load"))
60 return;
61
62 if (!skel->kconfig->CONFIG_UNWINDER_ORC) {
63 test__skip();
64 goto cleanup;
65 }
66
67 skel->links.kprobe_multi_test = bpf_program__attach_kprobe_multi_opts(
68 skel->progs.kprobe_multi_test,
69 "bpf_testmod_stacktrace_test", &opts);
70 if (!ASSERT_OK_PTR(skel->links.kprobe_multi_test, "bpf_program__attach_kprobe_multi_opts"))
71 goto cleanup;
72
73 trigger_module_test_read(1);
74
75 load_kallsyms();
76
77 check_stacktrace_ips(bpf_map__fd(skel->maps.stackmap), skel->bss->stack_key, 4,
78 ksym_get_addr("bpf_testmod_stacktrace_test_3"),
79 ksym_get_addr("bpf_testmod_stacktrace_test_2"),
80 ksym_get_addr("bpf_testmod_stacktrace_test_1"),
81 ksym_get_addr("bpf_testmod_test_read"));
82
83 cleanup:
84 stacktrace_ips__destroy(skel);
85 }
86
test_stacktrace_ips_raw_tp(void)87 static void test_stacktrace_ips_raw_tp(void)
88 {
89 __u32 info_len = sizeof(struct bpf_prog_info);
90 LIBBPF_OPTS(bpf_test_run_opts, topts);
91 struct bpf_prog_info info = {};
92 struct stacktrace_ips *skel;
93 __u64 bpf_prog_ksym = 0;
94 int err;
95
96 skel = stacktrace_ips__open_and_load();
97 if (!ASSERT_OK_PTR(skel, "stacktrace_ips__open_and_load"))
98 return;
99
100 if (!skel->kconfig->CONFIG_UNWINDER_ORC) {
101 test__skip();
102 goto cleanup;
103 }
104
105 skel->links.rawtp_test = bpf_program__attach_raw_tracepoint(
106 skel->progs.rawtp_test,
107 "bpf_testmod_test_read");
108 if (!ASSERT_OK_PTR(skel->links.rawtp_test, "bpf_program__attach_raw_tracepoint"))
109 goto cleanup;
110
111 /* get bpf program address */
112 info.jited_ksyms = ptr_to_u64(&bpf_prog_ksym);
113 info.nr_jited_ksyms = 1;
114 err = bpf_prog_get_info_by_fd(bpf_program__fd(skel->progs.rawtp_test),
115 &info, &info_len);
116 if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd"))
117 goto cleanup;
118
119 trigger_module_test_read(1);
120
121 load_kallsyms();
122
123 check_stacktrace_ips(bpf_map__fd(skel->maps.stackmap), skel->bss->stack_key, 2,
124 bpf_prog_ksym,
125 ksym_get_addr("bpf_trace_run2"));
126
127 cleanup:
128 stacktrace_ips__destroy(skel);
129 }
130
__test_stacktrace_ips(void)131 static void __test_stacktrace_ips(void)
132 {
133 if (test__start_subtest("kprobe_multi"))
134 test_stacktrace_ips_kprobe_multi(false);
135 if (test__start_subtest("kretprobe_multi"))
136 test_stacktrace_ips_kprobe_multi(true);
137 if (test__start_subtest("raw_tp"))
138 test_stacktrace_ips_raw_tp();
139 }
140 #else
__test_stacktrace_ips(void)141 static void __test_stacktrace_ips(void)
142 {
143 test__skip();
144 }
145 #endif
146
test_stacktrace_ips(void)147 void test_stacktrace_ips(void)
148 {
149 __test_stacktrace_ips();
150 }
151