Skip to content

Commit

Permalink
bpftool: Support printing opcodes and source file references in CFG
Browse files Browse the repository at this point in the history
Add support for displaying opcodes or/and file references (filepath,
line and column numbers) when dumping the control flow graphs of loaded
BPF programs with bpftool.

Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Acked-by: Stanislav Fomichev <sdf@google.com>
  • Loading branch information
qmonnet authored and Kernel Patches Daemon committed Mar 27, 2023
1 parent 2bb58f7 commit bde71f2
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 15 deletions.
19 changes: 18 additions & 1 deletion tools/bpf/bpftool/btf_dumper.c
Expand Up @@ -841,14 +841,31 @@ static void dotlabel_puts(const char *s)
}

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);

if (!line)
return;
line = ltrim(line);

if (linum) {
const char *file = btf__name_by_offset(btf, linfo->file_name_off);

/* More forgiving on file because linum option is
* expected to provide more info than the already
* available src line.
*/
if (!file)
file = "";

printf("; [file:");
dotlabel_puts(file);
printf("line_num:%u line_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");
Expand Down
22 changes: 14 additions & 8 deletions tools/bpf/bpftool/cfg.c
Expand Up @@ -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;

Expand All @@ -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("}");
}

Expand All @@ -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);
}
}

Expand All @@ -452,22 +456,24 @@ 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;

printf("digraph \"DOT graph for eBPF program\" {\n");
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;
Expand All @@ -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);
}
3 changes: 2 additions & 1 deletion tools/bpf/bpftool/cfg.h
Expand Up @@ -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 */
2 changes: 1 addition & 1 deletion tools/bpf/bpftool/main.h
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion tools/bpf/bpftool/prog.c
Expand Up @@ -854,7 +854,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
else 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);
Expand Down
15 changes: 13 additions & 2 deletions tools/bpf/bpftool/xlated_dumper.c
Expand Up @@ -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,
Expand Down Expand Up @@ -405,14 +406,24 @@ 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;
}
}

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(" | ");
}
Expand Down
3 changes: 2 additions & 1 deletion tools/bpf/bpftool/xlated_dumper.h
Expand Up @@ -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

0 comments on commit bde71f2

Please sign in to comment.