From: Lorenzo Fontana <fontanalorenz@gmail.com>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net
Subject: [PATCH bpf-next 2/2] tools/bpf/bpftool: xlated dump from ELF file directly
Date: Tue, 13 Jul 2021 20:35:32 +0200 [thread overview]
Message-ID: <f01efeef-9653-0f5f-b76e-d37597ba08d5@gmail.com> (raw)
In-Reply-To: <aa97c776-9a82-9acc-fb13-dd082fdcaa61@gmail.com>
bpftool can dump an xlated or jitted representation
of the programs already loaded into the kernel.
That capability is very useful for understanding what
are the instructions the kernel will execute for that program.
However, sometimes the verifier does not load the program and
one cannot use this feature until changes are made to make the
verifier happy again.
This patch reuses the same dump function to dump the program
from an ELF file directly instead of loading the instructions
from a loaded file descriptor. In this way, the user
can use all the bpftool features for "xlated" without loading.
In particular, the "visual" command is very useful when combined
to this because the dot graph makes easy to spot bad instruction
sequences.
Usage:
bpftool prog dump xlated elf program.o
It also works with the other commands like 'visual' to print
an dot representation of the program.
bpftool prog dump xlated elf program.o visual
Signed-off-by: Lorenzo Fontana <fontanalorenz@gmail.com>
---
tools/bpf/bpftool/common.c | 15 ++++++++++++---
tools/bpf/bpftool/main.h | 2 +-
tools/bpf/bpftool/prog.c | 26 +++++++++++++++++++++++---
3 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
index 1828bba19020..b28d15505705 100644
--- a/tools/bpf/bpftool/common.c
+++ b/tools/bpf/bpftool/common.c
@@ -703,7 +703,7 @@ static int prog_fd_by_nametag(void *nametag, int **fds, bool tag)
return -1;
}
-int prog_parse_fds(int *argc, char ***argv, int **fds)
+int prog_parse_fds(int *argc, char ***argv, int **fds, char **elf_filepath)
{
if (is_prefix(**argv, "id")) {
unsigned int id;
@@ -763,9 +763,18 @@ int prog_parse_fds(int *argc, char ***argv, int **fds)
if ((*fds)[0] < 0)
return -1;
return 1;
+ } else if (is_prefix(**argv, "elf")) {
+ NEXT_ARGP();
+ if (!argc) {
+ p_err("expected ELF file path");
+ return -1;
+ }
+ *elf_filepath = **argv;
+ NEXT_ARGP();
+ return 1;
}
- p_err("expected 'id', 'tag', 'name' or 'pinned', got: '%s'?", **argv);
+ p_err("expected 'id', 'tag', 'name', 'elf' or 'pinned', got: '%s'?", **argv);
return -1;
}
@@ -779,7 +788,7 @@ int prog_parse_fd(int *argc, char ***argv)
p_err("mem alloc failed");
return -1;
}
- nb_fds = prog_parse_fds(argc, argv, &fds);
+ nb_fds = prog_parse_fds(argc, argv, &fds, NULL);
if (nb_fds != 1) {
if (nb_fds > 1) {
p_err("several programs match this handle");
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index c1cf29798b99..f4e426d03b4a 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -187,7 +187,7 @@ int do_iter(int argc, char **argv) __weak;
int parse_u32_arg(int *argc, char ***argv, __u32 *val, const char *what);
int prog_parse_fd(int *argc, char ***argv);
-int prog_parse_fds(int *argc, char ***argv, int **fds);
+int prog_parse_fds(int *argc, char ***argv, int **fds, char **elf_filepath);
int map_parse_fd(int *argc, char ***argv);
int map_parse_fds(int *argc, char ***argv, int **fds);
int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len);
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index cc48726740ad..04fa9a83ef7e 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -537,7 +537,7 @@ static int do_show_subset(int argc, char **argv)
p_err("mem alloc failed");
return -1;
}
- nb_fds = prog_parse_fds(&argc, &argv, &fds);
+ nb_fds = prog_parse_fds(&argc, &argv, &fds, NULL);
if (nb_fds < 1)
goto exit_free;
@@ -787,7 +787,10 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
static int do_dump(int argc, char **argv)
{
struct bpf_prog_info_linear *info_linear;
+ struct bpf_object *obj;
+ struct bpf_program *prog;
char *filepath = NULL;
+ char *elf_filepath = NULL;
bool opcodes = false;
bool visual = false;
enum dump_mode mode;
@@ -817,7 +820,8 @@ static int do_dump(int argc, char **argv)
p_err("mem alloc failed");
return -1;
}
- nb_fds = prog_parse_fds(&argc, &argv, &fds);
+ elf_filepath = malloc(sizeof(char) * PATH_MAX);
+ nb_fds = prog_parse_fds(&argc, &argv, &fds, &elf_filepath);
if (nb_fds < 1)
goto exit_free;
@@ -849,7 +853,6 @@ static int do_dump(int argc, char **argv)
linum = true;
NEXT_ARG();
}
-
if (argc) {
usage();
goto exit_close;
@@ -866,9 +869,26 @@ static int do_dump(int argc, char **argv)
arrays |= 1UL << BPF_PROG_INFO_LINE_INFO;
arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO;
+ if (elf_filepath != NULL) {
+ obj = bpf_object__open(elf_filepath);
+ if (libbpf_get_error(obj)) {
+ p_err("ERROR: opening BPF object file failed");
+ return 0;
+ }
+
+ bpf_object__for_each_program(prog, obj) {
+ struct bpf_prog_info pinfo;
+ pinfo.xlated_prog_insns = ptr_to_u64(bpf_program__insns(prog));
+ pinfo.xlated_prog_len = bpf_program__size(prog);
+ err = prog_dump(&pinfo, mode, filepath, opcodes, visual, linum);
+ }
+ return 0;
+ }
+
if (json_output && nb_fds > 1)
jsonw_start_array(json_wtr); /* root array */
for (i = 0; i < nb_fds; i++) {
+ printf("uno\n");
info_linear = bpf_program__get_prog_info_linear(fds[i], arrays);
if (IS_ERR_OR_NULL(info_linear)) {
p_err("can't get prog info: %s", strerror(errno));
--
2.32.0
next prev parent reply other threads:[~2021-07-13 18:35 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-13 18:33 [PATCH bpf-next 1/2] tools/lib/bpf: bpf_program__insns allow to retrieve insns in libbpf Lorenzo Fontana
2021-07-13 18:35 ` Lorenzo Fontana [this message]
2021-07-14 0:00 ` [PATCH bpf-next 2/2] tools/bpf/bpftool: xlated dump from ELF file directly Lorenzo Fontana
2021-07-15 5:48 ` John Fastabend
2021-07-15 8:10 ` liwei (GF)
2021-07-15 9:55 ` Quentin Monnet
2021-07-14 4:19 ` [PATCH bpf-next 1/2] tools/lib/bpf: bpf_program__insns allow to retrieve insns in libbpf kernel test robot
2021-07-15 5:48 ` John Fastabend
2021-07-15 10:12 ` Quentin Monnet
2021-07-15 21:40 ` Andrii Nakryiko
2021-07-16 1:51 ` Alexei Starovoitov
2021-07-19 16:42 ` Lorenzo Fontana
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f01efeef-9653-0f5f-b76e-d37597ba08d5@gmail.com \
--to=fontanalorenz@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).