1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (c) 2022, Oracle and/or its affiliates. */ |
3 | #include "bpf_iter.h" |
4 | #include <bpf/bpf_helpers.h> |
5 | |
6 | char _license[] SEC("license" ) = "GPL" ; |
7 | |
8 | unsigned long last_sym_value = 0; |
9 | |
10 | static inline char to_lower(char c) |
11 | { |
12 | if (c >= 'A' && c <= 'Z') |
13 | c += ('a' - 'A'); |
14 | return c; |
15 | } |
16 | |
17 | static inline char to_upper(char c) |
18 | { |
19 | if (c >= 'a' && c <= 'z') |
20 | c -= ('a' - 'A'); |
21 | return c; |
22 | } |
23 | |
24 | /* Dump symbols with max size; the latter is calculated by caching symbol N value |
25 | * and when iterating on symbol N+1, we can print max size of symbol N via |
26 | * address of N+1 - address of N. |
27 | */ |
28 | SEC("iter/ksym" ) |
29 | int dump_ksym(struct bpf_iter__ksym *ctx) |
30 | { |
31 | struct seq_file *seq = ctx->meta->seq; |
32 | struct kallsym_iter *iter = ctx->ksym; |
33 | __u32 seq_num = ctx->meta->seq_num; |
34 | unsigned long value; |
35 | char type; |
36 | |
37 | if (!iter) |
38 | return 0; |
39 | |
40 | if (seq_num == 0) { |
41 | BPF_SEQ_PRINTF(seq, "ADDR TYPE NAME MODULE_NAME KIND MAX_SIZE\n" ); |
42 | return 0; |
43 | } |
44 | if (last_sym_value) |
45 | BPF_SEQ_PRINTF(seq, "0x%x\n" , iter->value - last_sym_value); |
46 | else |
47 | BPF_SEQ_PRINTF(seq, "\n" ); |
48 | |
49 | value = iter->show_value ? iter->value : 0; |
50 | |
51 | last_sym_value = value; |
52 | |
53 | type = iter->type; |
54 | |
55 | if (iter->module_name[0]) { |
56 | type = iter->exported ? to_upper(c: type) : to_lower(c: type); |
57 | BPF_SEQ_PRINTF(seq, "0x%llx %c %s [ %s ] " , |
58 | value, type, iter->name, iter->module_name); |
59 | } else { |
60 | BPF_SEQ_PRINTF(seq, "0x%llx %c %s " , value, type, iter->name); |
61 | } |
62 | if (!iter->pos_mod_end || iter->pos_mod_end > iter->pos) |
63 | BPF_SEQ_PRINTF(seq, "MOD " ); |
64 | else if (!iter->pos_ftrace_mod_end || iter->pos_ftrace_mod_end > iter->pos) |
65 | BPF_SEQ_PRINTF(seq, "FTRACE_MOD " ); |
66 | else if (!iter->pos_bpf_end || iter->pos_bpf_end > iter->pos) |
67 | BPF_SEQ_PRINTF(seq, "BPF " ); |
68 | else |
69 | BPF_SEQ_PRINTF(seq, "KPROBE " ); |
70 | return 0; |
71 | } |
72 | |