1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2020 Facebook */ 3 #include <linux/bpf.h> 4 #include <bpf/bpf_helpers.h> 5 #include <bpf/bpf_core_read.h> 6 7 #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record) 8 struct seq_file; 9 struct bpf_iter_meta { 10 struct seq_file *seq; 11 __u64 session_id; 12 __u64 seq_num; 13 }; 14 15 struct bpf_map { 16 __u32 id; 17 char name[16]; 18 __u32 max_entries; 19 }; 20 21 struct bpf_iter__bpf_map { 22 struct bpf_iter_meta *meta; 23 struct bpf_map *map; 24 }; 25 26 struct btf_type { 27 __u32 name_off; 28 }; 29 30 struct btf_header { 31 __u32 str_len; 32 }; 33 34 struct btf { 35 const char *strings; 36 struct btf_type **types; 37 struct btf_header hdr; 38 }; 39 40 struct bpf_prog_aux { 41 __u32 id; 42 char name[16]; 43 const char *attach_func_name; 44 struct bpf_prog *dst_prog; 45 struct bpf_func_info *func_info; 46 struct btf *btf; 47 }; 48 49 struct bpf_prog { 50 struct bpf_prog_aux *aux; 51 }; 52 53 struct bpf_iter__bpf_prog { 54 struct bpf_iter_meta *meta; 55 struct bpf_prog *prog; 56 }; 57 #pragma clang attribute pop 58 59 static const char *get_name(struct btf *btf, long btf_id, const char *fallback) 60 { 61 struct btf_type **types, *t; 62 unsigned int name_off; 63 const char *str; 64 65 if (!btf) 66 return fallback; 67 str = btf->strings; 68 types = btf->types; 69 bpf_probe_read_kernel(&t, sizeof(t), types + btf_id); 70 name_off = BPF_CORE_READ(t, name_off); 71 if (name_off >= btf->hdr.str_len) 72 return fallback; 73 return str + name_off; 74 } 75 76 __s64 bpf_map_sum_elem_count(struct bpf_map *map) __ksym; 77 78 SEC("iter/bpf_map") 79 int dump_bpf_map(struct bpf_iter__bpf_map *ctx) 80 { 81 struct seq_file *seq = ctx->meta->seq; 82 __u64 seq_num = ctx->meta->seq_num; 83 struct bpf_map *map = ctx->map; 84 85 if (!map) 86 return 0; 87 88 if (seq_num == 0) 89 BPF_SEQ_PRINTF(seq, " id name max_entries cur_entries\n"); 90 91 BPF_SEQ_PRINTF(seq, "%4u %-16s %10d %10lld\n", 92 map->id, map->name, map->max_entries, 93 bpf_map_sum_elem_count(map)); 94 95 return 0; 96 } 97 98 SEC("iter/bpf_prog") 99 int dump_bpf_prog(struct bpf_iter__bpf_prog *ctx) 100 { 101 struct seq_file *seq = ctx->meta->seq; 102 __u64 seq_num = ctx->meta->seq_num; 103 struct bpf_prog *prog = ctx->prog; 104 struct bpf_prog_aux *aux; 105 106 if (!prog) 107 return 0; 108 109 aux = prog->aux; 110 if (seq_num == 0) 111 BPF_SEQ_PRINTF(seq, " id name attached\n"); 112 113 BPF_SEQ_PRINTF(seq, "%4u %-16s %s %s\n", aux->id, 114 get_name(aux->btf, aux->func_info[0].type_id, aux->name), 115 aux->attach_func_name, aux->dst_prog->aux->name); 116 return 0; 117 } 118 char LICENSE[] SEC("license") = "GPL"; 119