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 tolower(char c) 11 { 12 if (c >= 'A' && c <= 'Z') 13 c += ('a' - 'A'); 14 return c; 15 } 16 17 static inline char toupper(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 int ret; 37 38 if (!iter) 39 return 0; 40 41 if (seq_num == 0) { 42 BPF_SEQ_PRINTF(seq, "ADDR TYPE NAME MODULE_NAME KIND MAX_SIZE\n"); 43 return 0; 44 } 45 if (last_sym_value) 46 BPF_SEQ_PRINTF(seq, "0x%x\n", iter->value - last_sym_value); 47 else 48 BPF_SEQ_PRINTF(seq, "\n"); 49 50 value = iter->show_value ? iter->value : 0; 51 52 last_sym_value = value; 53 54 type = iter->type; 55 56 if (iter->module_name[0]) { 57 type = iter->exported ? toupper(type) : tolower(type); 58 BPF_SEQ_PRINTF(seq, "0x%llx %c %s [ %s ] ", 59 value, type, iter->name, iter->module_name); 60 } else { 61 BPF_SEQ_PRINTF(seq, "0x%llx %c %s ", value, type, iter->name); 62 } 63 if (!iter->pos_arch_end || iter->pos_arch_end > iter->pos) 64 BPF_SEQ_PRINTF(seq, "CORE "); 65 else if (!iter->pos_mod_end || iter->pos_mod_end > iter->pos) 66 BPF_SEQ_PRINTF(seq, "MOD "); 67 else if (!iter->pos_ftrace_mod_end || iter->pos_ftrace_mod_end > iter->pos) 68 BPF_SEQ_PRINTF(seq, "FTRACE_MOD "); 69 else if (!iter->pos_bpf_end || iter->pos_bpf_end > iter->pos) 70 BPF_SEQ_PRINTF(seq, "BPF "); 71 else 72 BPF_SEQ_PRINTF(seq, "KPROBE "); 73 return 0; 74 } 75