This patches uses bpf_program__get_prog_info_linear() to simplify the
logic in prog.c do_dump().

Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Signed-off-by: Song Liu <songliubrav...@fb.com>
---
 tools/bpf/bpftool/prog.c | 266 +++++++++------------------------------
 1 file changed, 59 insertions(+), 207 deletions(-)

diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 0640e9bc0ada..206b820df7c2 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -393,41 +393,31 @@ static int do_show(int argc, char **argv)
 
 static int do_dump(int argc, char **argv)
 {
-       unsigned int finfo_rec_size, linfo_rec_size, jited_linfo_rec_size;
-       void *func_info = NULL, *linfo = NULL, *jited_linfo = NULL;
-       unsigned int nr_finfo, nr_linfo = 0, nr_jited_linfo = 0;
+       struct bpf_prog_info_linear *info_linear;
        struct bpf_prog_linfo *prog_linfo = NULL;
-       unsigned long *func_ksyms = NULL;
-       struct bpf_prog_info info = {};
-       unsigned int *func_lens = NULL;
+       enum {DUMP_JITED, DUMP_XLATED} mode;
        const char *disasm_opt = NULL;
-       unsigned int nr_func_ksyms;
-       unsigned int nr_func_lens;
+       struct bpf_prog_info *info;
        struct dump_data dd = {};
-       __u32 len = sizeof(info);
+       void *func_info = NULL;
        struct btf *btf = NULL;
-       unsigned int buf_size;
        char *filepath = NULL;
        bool opcodes = false;
        bool visual = false;
        char func_sig[1024];
        unsigned char *buf;
        bool linum = false;
-       __u32 *member_len;
-       __u64 *member_ptr;
+       __u32 member_len;
+       __u64 arrays;
        ssize_t n;
-       int err;
        int fd;
 
        if (is_prefix(*argv, "jited")) {
                if (disasm_init())
                        return -1;
-
-               member_len = &info.jited_prog_len;
-               member_ptr = &info.jited_prog_insns;
+               mode = DUMP_JITED;
        } else if (is_prefix(*argv, "xlated")) {
-               member_len = &info.xlated_prog_len;
-               member_ptr = &info.xlated_prog_insns;
+               mode = DUMP_XLATED;
        } else {
                p_err("expected 'xlated' or 'jited', got: %s", *argv);
                return -1;
@@ -466,175 +456,50 @@ static int do_dump(int argc, char **argv)
                return -1;
        }
 
-       err = bpf_obj_get_info_by_fd(fd, &info, &len);
-       if (err) {
-               p_err("can't get prog info: %s", strerror(errno));
-               return -1;
-       }
-
-       if (!*member_len) {
-               p_info("no instructions returned");
-               close(fd);
-               return 0;
-       }
+       if (mode == DUMP_JITED)
+               arrays = 1UL << BPF_PROG_INFO_JITED_INSNS;
+       else
+               arrays = 1UL << BPF_PROG_INFO_XLATED_INSNS;
 
-       buf_size = *member_len;
+       arrays |= 1UL << BPF_PROG_INFO_JITED_KSYMS;
+       arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS;
+       arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO;
+       arrays |= 1UL << BPF_PROG_INFO_LINE_INFO;
+       arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO;
 
-       buf = malloc(buf_size);
-       if (!buf) {
-               p_err("mem alloc failed");
-               close(fd);
+       info_linear = bpf_program__get_prog_info_linear(fd, arrays);
+       close(fd);
+       if (IS_ERR_OR_NULL(info_linear)) {
+               p_err("can't get prog info: %s", strerror(errno));
                return -1;
        }
 
-       nr_func_ksyms = info.nr_jited_ksyms;
-       if (nr_func_ksyms) {
-               func_ksyms = malloc(nr_func_ksyms * sizeof(__u64));
-               if (!func_ksyms) {
-                       p_err("mem alloc failed");
-                       close(fd);
-                       goto err_free;
-               }
-       }
-
-       nr_func_lens = info.nr_jited_func_lens;
-       if (nr_func_lens) {
-               func_lens = malloc(nr_func_lens * sizeof(__u32));
-               if (!func_lens) {
-                       p_err("mem alloc failed");
-                       close(fd);
+       info = &info_linear->info;
+       if (mode == DUMP_JITED) {
+               if (info->jited_prog_len == 0) {
+                       p_info("no instructions returned");
                        goto err_free;
                }
-       }
-
-       nr_finfo = info.nr_func_info;
-       finfo_rec_size = info.func_info_rec_size;
-       if (nr_finfo && finfo_rec_size) {
-               func_info = malloc(nr_finfo * finfo_rec_size);
-               if (!func_info) {
-                       p_err("mem alloc failed");
-                       close(fd);
+               buf = (unsigned char *)(info->jited_prog_insns);
+               member_len = info->jited_prog_len;
+       } else {        /* DUMP_XLATED */
+               if (info->xlated_prog_len == 0) {
+                       p_err("error retrieving insn dump: kernel.kptr_restrict 
set?");
                        goto err_free;
                }
+               buf = (unsigned char *)info->xlated_prog_insns;
+               member_len = info->xlated_prog_len;
        }
 
-       linfo_rec_size = info.line_info_rec_size;
-       if (info.nr_line_info && linfo_rec_size && info.btf_id) {
-               nr_linfo = info.nr_line_info;
-               linfo = malloc(nr_linfo * linfo_rec_size);
-               if (!linfo) {
-                       p_err("mem alloc failed");
-                       close(fd);
-                       goto err_free;
-               }
-       }
-
-       jited_linfo_rec_size = info.jited_line_info_rec_size;
-       if (info.nr_jited_line_info &&
-           jited_linfo_rec_size &&
-           info.nr_jited_ksyms &&
-           info.nr_jited_func_lens &&
-           info.btf_id) {
-               nr_jited_linfo = info.nr_jited_line_info;
-               jited_linfo = malloc(nr_jited_linfo * jited_linfo_rec_size);
-               if (!jited_linfo) {
-                       p_err("mem alloc failed");
-                       close(fd);
-                       goto err_free;
-               }
-       }
-
-       memset(&info, 0, sizeof(info));
-
-       *member_ptr = ptr_to_u64(buf);
-       *member_len = buf_size;
-       info.jited_ksyms = ptr_to_u64(func_ksyms);
-       info.nr_jited_ksyms = nr_func_ksyms;
-       info.jited_func_lens = ptr_to_u64(func_lens);
-       info.nr_jited_func_lens = nr_func_lens;
-       info.nr_func_info = nr_finfo;
-       info.func_info_rec_size = finfo_rec_size;
-       info.func_info = ptr_to_u64(func_info);
-       info.nr_line_info = nr_linfo;
-       info.line_info_rec_size = linfo_rec_size;
-       info.line_info = ptr_to_u64(linfo);
-       info.nr_jited_line_info = nr_jited_linfo;
-       info.jited_line_info_rec_size = jited_linfo_rec_size;
-       info.jited_line_info = ptr_to_u64(jited_linfo);
-
-       err = bpf_obj_get_info_by_fd(fd, &info, &len);
-       close(fd);
-       if (err) {
-               p_err("can't get prog info: %s", strerror(errno));
-               goto err_free;
-       }
-
-       if (*member_len > buf_size) {
-               p_err("too many instructions returned");
-               goto err_free;
-       }
-
-       if (info.nr_jited_ksyms > nr_func_ksyms) {
-               p_err("too many addresses returned");
-               goto err_free;
-       }
-
-       if (info.nr_jited_func_lens > nr_func_lens) {
-               p_err("too many values returned");
-               goto err_free;
-       }
-
-       if (info.nr_func_info != nr_finfo) {
-               p_err("incorrect nr_func_info %d vs. expected %d",
-                     info.nr_func_info, nr_finfo);
-               goto err_free;
-       }
-
-       if (info.func_info_rec_size != finfo_rec_size) {
-               p_err("incorrect func_info_rec_size %d vs. expected %d",
-                     info.func_info_rec_size, finfo_rec_size);
-               goto err_free;
-       }
-
-       if (linfo && info.nr_line_info != nr_linfo) {
-               p_err("incorrect nr_line_info %u vs. expected %u",
-                     info.nr_line_info, nr_linfo);
-               goto err_free;
-       }
-
-       if (info.line_info_rec_size != linfo_rec_size) {
-               p_err("incorrect line_info_rec_size %u vs. expected %u",
-                     info.line_info_rec_size, linfo_rec_size);
-               goto err_free;
-       }
-
-       if (jited_linfo && info.nr_jited_line_info != nr_jited_linfo) {
-               p_err("incorrect nr_jited_line_info %u vs. expected %u",
-                     info.nr_jited_line_info, nr_jited_linfo);
-               goto err_free;
-       }
-
-       if (info.jited_line_info_rec_size != jited_linfo_rec_size) {
-               p_err("incorrect jited_line_info_rec_size %u vs. expected %u",
-                     info.jited_line_info_rec_size, jited_linfo_rec_size);
-               goto err_free;
-       }
-
-       if ((member_len == &info.jited_prog_len &&
-            info.jited_prog_insns == 0) ||
-           (member_len == &info.xlated_prog_len &&
-            info.xlated_prog_insns == 0)) {
-               p_err("error retrieving insn dump: kernel.kptr_restrict set?");
-               goto err_free;
-       }
-
-       if (info.btf_id && btf__get_from_id(info.btf_id, &btf)) {
+       if (info->btf_id && btf__get_from_id(info->btf_id, &btf)) {
                p_err("failed to get btf");
                goto err_free;
        }
 
-       if (nr_linfo) {
-               prog_linfo = bpf_prog_linfo__new(&info);
+       func_info = (void *)info->func_info;
+
+       if (info->nr_line_info) {
+               prog_linfo = bpf_prog_linfo__new(info);
                if (!prog_linfo)
                        p_info("error in processing bpf_line_info.  continue 
without it.");
        }
@@ -647,9 +512,9 @@ static int do_dump(int argc, char **argv)
                        goto err_free;
                }
 
-               n = write(fd, buf, *member_len);
+               n = write(fd, buf, member_len);
                close(fd);
-               if (n != *member_len) {
+               if (n != member_len) {
                        p_err("error writing output file: %s",
                              n < 0 ? strerror(errno) : "short write");
                        goto err_free;
@@ -657,19 +522,19 @@ static int do_dump(int argc, char **argv)
 
                if (json_output)
                        jsonw_null(json_wtr);
-       } else if (member_len == &info.jited_prog_len) {
+       } else if (mode == DUMP_JITED) {
                const char *name = NULL;
 
-               if (info.ifindex) {
-                       name = ifindex_to_bfd_params(info.ifindex,
-                                                    info.netns_dev,
-                                                    info.netns_ino,
+               if (info->ifindex) {
+                       name = ifindex_to_bfd_params(info->ifindex,
+                                                    info->netns_dev,
+                                                    info->netns_ino,
                                                     &disasm_opt);
                        if (!name)
                                goto err_free;
                }
 
-               if (info.nr_jited_func_lens && info.jited_func_lens) {
+               if (info->nr_jited_func_lens && info->jited_func_lens) {
                        struct kernel_sym *sym = NULL;
                        struct bpf_func_info *record;
                        char sym_name[SYM_MAX_NAME];
@@ -677,17 +542,16 @@ static int do_dump(int argc, char **argv)
                        __u64 *ksyms = NULL;
                        __u32 *lens;
                        __u32 i;
-
-                       if (info.nr_jited_ksyms) {
+                       if (info->nr_jited_ksyms) {
                                kernel_syms_load(&dd);
-                               ksyms = (__u64 *) info.jited_ksyms;
+                               ksyms = (__u64 *) info->jited_ksyms;
                        }
 
                        if (json_output)
                                jsonw_start_array(json_wtr);
 
-                       lens = (__u32 *) info.jited_func_lens;
-                       for (i = 0; i < info.nr_jited_func_lens; i++) {
+                       lens = (__u32 *) info->jited_func_lens;
+                       for (i = 0; i < info->nr_jited_func_lens; i++) {
                                if (ksyms) {
                                        sym = kernel_syms_search(&dd, ksyms[i]);
                                        if (sym)
@@ -699,7 +563,7 @@ static int do_dump(int argc, char **argv)
                                }
 
                                if (func_info) {
-                                       record = func_info + i * finfo_rec_size;
+                                       record = func_info + i * 
info->func_info_rec_size;
                                        btf_dumper_type_only(btf, 
record->type_id,
                                                             func_sig,
                                                             sizeof(func_sig));
@@ -736,49 +600,37 @@ static int do_dump(int argc, char **argv)
                        if (json_output)
                                jsonw_end_array(json_wtr);
                } else {
-                       disasm_print_insn(buf, *member_len, opcodes, name,
+                       disasm_print_insn(buf, member_len, opcodes, name,
                                          disasm_opt, btf, NULL, 0, 0, false);
                }
        } else if (visual) {
                if (json_output)
                        jsonw_null(json_wtr);
                else
-                       dump_xlated_cfg(buf, *member_len);
+                       dump_xlated_cfg(buf, member_len);
        } else {
                kernel_syms_load(&dd);
-               dd.nr_jited_ksyms = info.nr_jited_ksyms;
-               dd.jited_ksyms = (__u64 *) info.jited_ksyms;
+               dd.nr_jited_ksyms = info->nr_jited_ksyms;
+               dd.jited_ksyms = (__u64 *) info->jited_ksyms;
                dd.btf = btf;
                dd.func_info = func_info;
-               dd.finfo_rec_size = finfo_rec_size;
+               dd.finfo_rec_size = info->func_info_rec_size;
                dd.prog_linfo = prog_linfo;
 
                if (json_output)
-                       dump_xlated_json(&dd, buf, *member_len, opcodes,
+                       dump_xlated_json(&dd, buf, member_len, opcodes,
                                         linum);
                else
-                       dump_xlated_plain(&dd, buf, *member_len, opcodes,
+                       dump_xlated_plain(&dd, buf, member_len, opcodes,
                                          linum);
                kernel_syms_destroy(&dd);
        }
 
-       free(buf);
-       free(func_ksyms);
-       free(func_lens);
-       free(func_info);
-       free(linfo);
-       free(jited_linfo);
-       bpf_prog_linfo__free(prog_linfo);
+       free(info_linear);
        return 0;
 
 err_free:
-       free(buf);
-       free(func_ksyms);
-       free(func_lens);
-       free(func_info);
-       free(linfo);
-       free(jited_linfo);
-       bpf_prog_linfo__free(prog_linfo);
+       free(info_linear);
        return -1;
 }
 
-- 
2.17.1

Reply via email to