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