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 SEC("iter/bpf_map") 77 int dump_bpf_map(struct bpf_iter__bpf_map *ctx) 78 { 79 struct seq_file *seq = ctx->meta->seq; 80 __u64 seq_num = ctx->meta->seq_num; 81 struct bpf_map *map = ctx->map; 82 83 if (!map) 84 return 0; 85 86 if (seq_num == 0) 87 BPF_SEQ_PRINTF(seq, " id name max_entries\n"); 88 89 BPF_SEQ_PRINTF(seq, "%4u %-16s%6d\n", map->id, map->name, map->max_entries); 90 return 0; 91 } 92 93 SEC("iter/bpf_prog") 94 int dump_bpf_prog(struct bpf_iter__bpf_prog *ctx) 95 { 96 struct seq_file *seq = ctx->meta->seq; 97 __u64 seq_num = ctx->meta->seq_num; 98 struct bpf_prog *prog = ctx->prog; 99 struct bpf_prog_aux *aux; 100 101 if (!prog) 102 return 0; 103 104 aux = prog->aux; 105 if (seq_num == 0) 106 BPF_SEQ_PRINTF(seq, " id name attached\n"); 107 108 BPF_SEQ_PRINTF(seq, "%4u %-16s %s %s\n", aux->id, 109 get_name(aux->btf, aux->func_info[0].type_id, aux->name), 110 aux->attach_func_name, aux->dst_prog->aux->name); 111 return 0; 112 } 113 char LICENSE[] SEC("license") = "GPL"; 114