bpftool: add C output format option to btf dump subcommand
Utilize new libbpf's btf_dump API to emit BTF as a C definitions. Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Andrii Nakryiko <andriin@fb.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Родитель
2d2a3ad872
Коммит
2119f2189d
|
@ -340,11 +340,49 @@ static int dump_btf_raw(const struct btf *btf,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __printf(2, 0) btf_dump_printf(void *ctx,
|
||||||
|
const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
vfprintf(stdout, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dump_btf_c(const struct btf *btf,
|
||||||
|
__u32 *root_type_ids, int root_type_cnt)
|
||||||
|
{
|
||||||
|
struct btf_dump *d;
|
||||||
|
int err = 0, i;
|
||||||
|
|
||||||
|
d = btf_dump__new(btf, NULL, NULL, btf_dump_printf);
|
||||||
|
if (IS_ERR(d))
|
||||||
|
return PTR_ERR(d);
|
||||||
|
|
||||||
|
if (root_type_cnt) {
|
||||||
|
for (i = 0; i < root_type_cnt; i++) {
|
||||||
|
err = btf_dump__dump_type(d, root_type_ids[i]);
|
||||||
|
if (err)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int cnt = btf__get_nr_types(btf);
|
||||||
|
|
||||||
|
for (i = 1; i <= cnt; i++) {
|
||||||
|
err = btf_dump__dump_type(d, i);
|
||||||
|
if (err)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
btf_dump__free(d);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int do_dump(int argc, char **argv)
|
static int do_dump(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct btf *btf = NULL;
|
struct btf *btf = NULL;
|
||||||
__u32 root_type_ids[2];
|
__u32 root_type_ids[2];
|
||||||
int root_type_cnt = 0;
|
int root_type_cnt = 0;
|
||||||
|
bool dump_c = false;
|
||||||
__u32 btf_id = -1;
|
__u32 btf_id = -1;
|
||||||
const char *src;
|
const char *src;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
@ -431,6 +469,29 @@ static int do_dump(int argc, char **argv)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (argc) {
|
||||||
|
if (is_prefix(*argv, "format")) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (argc < 1) {
|
||||||
|
p_err("expecting value for 'format' option\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (strcmp(*argv, "c") == 0) {
|
||||||
|
dump_c = true;
|
||||||
|
} else if (strcmp(*argv, "raw") == 0) {
|
||||||
|
dump_c = false;
|
||||||
|
} else {
|
||||||
|
p_err("unrecognized format specifier: '%s', possible values: raw, c",
|
||||||
|
*argv);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
NEXT_ARG();
|
||||||
|
} else {
|
||||||
|
p_err("unrecognized option: '%s'", *argv);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!btf) {
|
if (!btf) {
|
||||||
err = btf__get_from_id(btf_id, &btf);
|
err = btf__get_from_id(btf_id, &btf);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -444,7 +505,16 @@ static int do_dump(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_btf_raw(btf, root_type_ids, root_type_cnt);
|
if (dump_c) {
|
||||||
|
if (json_output) {
|
||||||
|
p_err("JSON output for C-syntax dump is not supported");
|
||||||
|
err = -ENOTSUP;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
err = dump_btf_c(btf, root_type_ids, root_type_cnt);
|
||||||
|
} else {
|
||||||
|
err = dump_btf_raw(btf, root_type_ids, root_type_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -460,10 +530,11 @@ static int do_help(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s btf dump BTF_SRC\n"
|
"Usage: %s btf dump BTF_SRC [format FORMAT]\n"
|
||||||
" %s btf help\n"
|
" %s btf help\n"
|
||||||
"\n"
|
"\n"
|
||||||
" BTF_SRC := { id BTF_ID | prog PROG | map MAP [{key | value | kv | all}] | file FILE }\n"
|
" BTF_SRC := { id BTF_ID | prog PROG | map MAP [{key | value | kv | all}] | file FILE }\n"
|
||||||
|
" FORMAT := { raw | c }\n"
|
||||||
" " HELP_SPEC_MAP "\n"
|
" " HELP_SPEC_MAP "\n"
|
||||||
" " HELP_SPEC_PROGRAM "\n"
|
" " HELP_SPEC_PROGRAM "\n"
|
||||||
" " HELP_SPEC_OPTIONS "\n"
|
" " HELP_SPEC_OPTIONS "\n"
|
||||||
|
|
Загрузка…
Ссылка в новой задаче