summaryrefslogtreecommitdiff
path: root/tools/bpf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/bpf')
-rw-r--r--tools/bpf/bpftool/btf_dumper.c51
-rw-r--r--tools/bpf/bpftool/cfg.c22
-rw-r--r--tools/bpf/bpftool/cfg.h3
-rw-r--r--tools/bpf/bpftool/main.h2
-rw-r--r--tools/bpf/bpftool/prog.c2
-rw-r--r--tools/bpf/bpftool/xlated_dumper.c15
-rw-r--r--tools/bpf/bpftool/xlated_dumper.h3
7 files changed, 83 insertions, 15 deletions
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
index 583aa843df92..6c5e0e82da22 100644
--- a/tools/bpf/bpftool/btf_dumper.c
+++ b/tools/bpf/bpftool/btf_dumper.c
@@ -842,8 +842,37 @@ static void dotlabel_puts(const char *s)
}
}
+static const char *shorten_path(const char *path)
+{
+ const unsigned int MAX_PATH_LEN = 32;
+ size_t len = strlen(path);
+ const char *shortpath;
+
+ if (len <= MAX_PATH_LEN)
+ return path;
+
+ /* Search for last '/' under the MAX_PATH_LEN limit */
+ shortpath = strchr(path + len - MAX_PATH_LEN, '/');
+ if (shortpath) {
+ if (shortpath < path + strlen("..."))
+ /* We removed a very short prefix, e.g. "/w", and we'll
+ * make the path longer by prefixing with the ellipsis.
+ * Not worth it, keep initial path.
+ */
+ return path;
+ return shortpath;
+ }
+
+ /* File base name length is > MAX_PATH_LEN, search for last '/' */
+ shortpath = strrchr(path, '/');
+ if (shortpath)
+ return shortpath;
+
+ return path;
+}
+
void btf_dump_linfo_dotlabel(const struct btf *btf,
- const struct bpf_line_info *linfo)
+ const struct bpf_line_info *linfo, bool linum)
{
const char *line = btf__name_by_offset(btf, linfo->line_off);
@@ -851,6 +880,26 @@ void btf_dump_linfo_dotlabel(const struct btf *btf,
return;
line = ltrim(line);
+ if (linum) {
+ const char *file = btf__name_by_offset(btf, linfo->file_name_off);
+ const char *shortfile;
+
+ /* More forgiving on file because linum option is
+ * expected to provide more info than the already
+ * available src line.
+ */
+ if (!file)
+ shortfile = "";
+ else
+ shortfile = shorten_path(file);
+
+ printf("; [%s", shortfile > file ? "..." : "");
+ dotlabel_puts(shortfile);
+ printf(" line:%u col:%u]\\l\\\n",
+ BPF_LINE_INFO_LINE_NUM(linfo->line_col),
+ BPF_LINE_INFO_LINE_COL(linfo->line_col));
+ }
+
printf("; ");
dotlabel_puts(line);
printf("\\l\\\n");
diff --git a/tools/bpf/bpftool/cfg.c b/tools/bpf/bpftool/cfg.c
index 9fdc1f0cdd6e..eec437cca2ea 100644
--- a/tools/bpf/bpftool/cfg.c
+++ b/tools/bpf/bpftool/cfg.c
@@ -381,7 +381,8 @@ static void cfg_destroy(struct cfg *cfg)
}
static void
-draw_bb_node(struct func_node *func, struct bb_node *bb, struct dump_data *dd)
+draw_bb_node(struct func_node *func, struct bb_node *bb, struct dump_data *dd,
+ bool opcodes, bool linum)
{
const char *shape;
@@ -401,7 +402,8 @@ draw_bb_node(struct func_node *func, struct bb_node *bb, struct dump_data *dd)
unsigned int start_idx;
printf("{\\\n");
start_idx = bb->head - func->start;
- dump_xlated_for_graph(dd, bb->head, bb->tail, start_idx);
+ dump_xlated_for_graph(dd, bb->head, bb->tail, start_idx,
+ opcodes, linum);
printf("}");
}
@@ -427,12 +429,14 @@ static void draw_bb_succ_edges(struct func_node *func, struct bb_node *bb)
}
}
-static void func_output_bb_def(struct func_node *func, struct dump_data *dd)
+static void
+func_output_bb_def(struct func_node *func, struct dump_data *dd,
+ bool opcodes, bool linum)
{
struct bb_node *bb;
list_for_each_entry(bb, &func->bbs, l) {
- draw_bb_node(func, bb, dd);
+ draw_bb_node(func, bb, dd, opcodes, linum);
}
}
@@ -452,7 +456,8 @@ static void func_output_edges(struct func_node *func)
func_idx, ENTRY_BLOCK_INDEX, func_idx, EXIT_BLOCK_INDEX);
}
-static void cfg_dump(struct cfg *cfg, struct dump_data *dd)
+static void
+cfg_dump(struct cfg *cfg, struct dump_data *dd, bool opcodes, bool linum)
{
struct func_node *func;
@@ -460,14 +465,15 @@ static void cfg_dump(struct cfg *cfg, struct dump_data *dd)
list_for_each_entry(func, &cfg->funcs, l) {
printf("subgraph \"cluster_%d\" {\n\tstyle=\"dashed\";\n\tcolor=\"black\";\n\tlabel=\"func_%d ()\";\n",
func->idx, func->idx);
- func_output_bb_def(func, dd);
+ func_output_bb_def(func, dd, opcodes, linum);
func_output_edges(func);
printf("}\n");
}
printf("}\n");
}
-void dump_xlated_cfg(struct dump_data *dd, void *buf, unsigned int len)
+void dump_xlated_cfg(struct dump_data *dd, void *buf, unsigned int len,
+ bool opcodes, bool linum)
{
struct bpf_insn *insn = buf;
struct cfg cfg;
@@ -476,7 +482,7 @@ void dump_xlated_cfg(struct dump_data *dd, void *buf, unsigned int len)
if (cfg_build(&cfg, insn, len))
return;
- cfg_dump(&cfg, dd);
+ cfg_dump(&cfg, dd, opcodes, linum);
cfg_destroy(&cfg);
}
diff --git a/tools/bpf/bpftool/cfg.h b/tools/bpf/bpftool/cfg.h
index 909d17e6d4c2..b3793f4e1783 100644
--- a/tools/bpf/bpftool/cfg.h
+++ b/tools/bpf/bpftool/cfg.h
@@ -6,6 +6,7 @@
#include "xlated_dumper.h"
-void dump_xlated_cfg(struct dump_data *dd, void *buf, unsigned int len);
+void dump_xlated_cfg(struct dump_data *dd, void *buf, unsigned int len,
+ bool opcodes, bool linum);
#endif /* __BPF_TOOL_CFG_H */
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index e9ee514b22d4..00d11ca6d3f2 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -230,7 +230,7 @@ void btf_dump_linfo_plain(const struct btf *btf,
void btf_dump_linfo_json(const struct btf *btf,
const struct bpf_line_info *linfo, bool linum);
void btf_dump_linfo_dotlabel(const struct btf *btf,
- const struct bpf_line_info *linfo);
+ const struct bpf_line_info *linfo, bool linum);
struct nlattr;
struct ifinfomsg;
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 092525a6933a..430f72306409 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -852,7 +852,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
if (json_output)
dump_xlated_json(&dd, buf, member_len, opcodes, linum);
else if (visual)
- dump_xlated_cfg(&dd, buf, member_len);
+ dump_xlated_cfg(&dd, buf, member_len, opcodes, linum);
else
dump_xlated_plain(&dd, buf, member_len, opcodes, linum);
kernel_syms_destroy(&dd);
diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c
index 2ee83561b945..da608e10c843 100644
--- a/tools/bpf/bpftool/xlated_dumper.c
+++ b/tools/bpf/bpftool/xlated_dumper.c
@@ -361,7 +361,8 @@ void dump_xlated_plain(struct dump_data *dd, void *buf, unsigned int len,
}
void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end,
- unsigned int start_idx)
+ unsigned int start_idx,
+ bool opcodes, bool linum)
{
const struct bpf_insn_cbs cbs = {
.cb_print = print_insn_for_graph,
@@ -405,7 +406,7 @@ void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end,
linfo = bpf_prog_linfo__lfind(prog_linfo, insn_off, 0);
if (linfo && linfo != last_linfo) {
- btf_dump_linfo_dotlabel(btf, linfo);
+ btf_dump_linfo_dotlabel(btf, linfo, linum);
last_linfo = linfo;
}
}
@@ -413,6 +414,16 @@ void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end,
printf("%d: ", insn_off);
print_bpf_insn(&cbs, cur, true);
+ if (opcodes) {
+ printf("\\ \\ \\ \\ ");
+ fprint_hex(stdout, cur, 8, " ");
+ if (double_insn && cur <= insn_end - 1) {
+ printf(" ");
+ fprint_hex(stdout, cur + 1, 8, " ");
+ }
+ printf("\\l\\\n");
+ }
+
if (cur != insn_end)
printf("| ");
}
diff --git a/tools/bpf/bpftool/xlated_dumper.h b/tools/bpf/bpftool/xlated_dumper.h
index 54847e174273..9a946377b0e6 100644
--- a/tools/bpf/bpftool/xlated_dumper.h
+++ b/tools/bpf/bpftool/xlated_dumper.h
@@ -34,6 +34,7 @@ void dump_xlated_json(struct dump_data *dd, void *buf, unsigned int len,
void dump_xlated_plain(struct dump_data *dd, void *buf, unsigned int len,
bool opcodes, bool linum);
void dump_xlated_for_graph(struct dump_data *dd, void *buf, void *buf_end,
- unsigned int start_index);
+ unsigned int start_index,
+ bool opcodes, bool linum);
#endif