static int do_dump(int argc, char **argv)
 {
+       unsigned long *func_ksyms = NULL;
        struct bpf_prog_info info = {};
+       unsigned int nr_func_ksyms;
        struct dump_data dd = {};
        __u32 len = sizeof(info);
        unsigned int buf_size;
                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;
+               }
+       }
+
        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;
 
        err = bpf_obj_get_info_by_fd(fd, &info, &len);
        close(fd);
                goto err_free;
        }
 
+       if (info.nr_jited_ksyms > nr_func_ksyms) {
+               p_err("too many addresses returned");
+               goto err_free;
+       }
+
        if ((member_len == &info.jited_prog_len &&
             info.jited_prog_insns == 0) ||
            (member_len == &info.xlated_prog_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;
+
                if (json_output)
                        dump_xlated_json(&dd, buf, *member_len, opcodes);
                else
        }
 
        free(buf);
+       free(func_ksyms);
        return 0;
 
 err_free:
        free(buf);
+       free(func_ksyms);
        return -1;
 }
 
 
                                    unsigned long address,
                                    const struct bpf_insn *insn)
 {
-       if (sym)
+       if (!dd->nr_jited_ksyms)
+               /* Do not show address for interpreted programs */
+               snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
+                       "%+d", insn->off);
+       else if (sym)
                snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
                         "%+d#%s", insn->off, sym->name);
        else
        unsigned long address = dd->address_call_base + insn->imm;
        struct kernel_sym *sym;
 
+       if (insn->src_reg == BPF_PSEUDO_CALL &&
+           (__u32) insn->imm < dd->nr_jited_ksyms)
+               address = dd->jited_ksyms[insn->imm];
+
        sym = kernel_syms_search(dd, address);
        if (insn->src_reg == BPF_PSEUDO_CALL)
                return print_call_pcrel(dd, sym, address, insn);