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