So we can then build light skeletons with loaders in any language. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@xxxxxxxxxx> --- tools/bpf/bpftool/gen.c | 95 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index cf8b4e525c88..818a5209b3ac 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -904,6 +904,96 @@ codegen_progs_skeleton(struct bpf_object *obj, size_t prog_cnt, bool populate_li } } +static int gen_json(struct bpf_object *obj, const char *obj_name, size_t file_sz, uint8_t *obj_data) +{ + struct bpf_program *prog; + struct bpf_map *map; + char ident[256]; + + jsonw_start_object(json_wtr); /* root object */ + + jsonw_string_field(json_wtr, "name", obj_name); + + jsonw_bool_field(json_wtr, "use_loader", use_loader); + + /* print all maps */ + jsonw_name(json_wtr, "maps"); + jsonw_start_array(json_wtr); + bpf_object__for_each_map(map, obj) { + if (!get_map_ident(map, ident, sizeof(ident))) { + p_err("ignoring unrecognized internal map '%s'...", + bpf_map__name(map)); + continue; + } + + jsonw_start_object(json_wtr); /* map object */ + jsonw_string_field(json_wtr, "ident", ident); + jsonw_string_field(json_wtr, "name", bpf_map__name(map)); + + /* print mmap data value */ + if (is_internal_mmapable_map(map, ident, sizeof(ident))) { + const void *mmap_data = NULL; + size_t mmap_size = 0; + + mmap_data = bpf_map__initial_value(map, &mmap_size); + + jsonw_uint_field(json_wtr, "size", mmap_size); + jsonw_uint_field(json_wtr, "mmap_sz", bpf_map_mmap_sz(map)); + jsonw_name(json_wtr, "data"); + print_hex_data_json((uint8_t *)mmap_data, mmap_size); + + } + jsonw_end_object(json_wtr); /* map object */ + } + jsonw_end_array(json_wtr); + + /* print all progs */ + jsonw_name(json_wtr, "progs"); + jsonw_start_array(json_wtr); + bpf_object__for_each_program(prog, obj) { + jsonw_start_object(json_wtr); /* prog object */ + jsonw_string_field(json_wtr, "name", bpf_program__name(prog)); + jsonw_string_field(json_wtr, "sec", bpf_program__section_name(prog)); + jsonw_end_object(json_wtr); /* prog object */ + } + jsonw_end_array(json_wtr); + + /* print object data */ + if (use_loader) { + DECLARE_LIBBPF_OPTS(gen_loader_opts, opts); + int err = 0; + + err = bpf_object__gen_loader(obj, &opts); + if (err) + return err; + + err = bpf_object__load(obj); + if (err) { + p_err("failed to load object file"); + return err; + } + /* If there was no error during load then gen_loader_opts + * are populated with the loader program. + */ + + jsonw_uint_field(json_wtr, "data_sz", opts.data_sz); + jsonw_name(json_wtr, "data"); + print_hex_data_json((uint8_t *)opts.data, opts.data_sz); + + jsonw_uint_field(json_wtr, "insns_sz", opts.insns_sz); + jsonw_name(json_wtr, "insns"); + print_hex_data_json((uint8_t *)opts.insns, opts.insns_sz); + + } else { + jsonw_name(json_wtr, "data"); + print_hex_data_json(obj_data, file_sz); + } + + jsonw_end_object(json_wtr); /* root object */ + + return 0; +} + static int do_skeleton(int argc, char **argv) { char header_guard[MAX_OBJ_NAME_LEN + sizeof("__SKEL_H__")]; @@ -986,6 +1076,11 @@ static int do_skeleton(int argc, char **argv) goto out; } + if (json_output) { + err = gen_json(obj, obj_name, file_sz, (uint8_t *)obj_data); + goto out; + } + bpf_object__for_each_map(map, obj) { if (!get_map_ident(map, ident, sizeof(ident))) { p_err("ignoring unrecognized internal map '%s'...", -- 2.38.1