|
@@ -422,7 +422,9 @@ static int do_dump(int argc, char **argv)
|
|
|
{
|
|
|
unsigned long *func_ksyms = NULL;
|
|
|
struct bpf_prog_info info = {};
|
|
|
+ unsigned int *func_lens = NULL;
|
|
|
unsigned int nr_func_ksyms;
|
|
|
+ unsigned int nr_func_lens;
|
|
|
struct dump_data dd = {};
|
|
|
__u32 len = sizeof(info);
|
|
|
unsigned int buf_size;
|
|
@@ -508,12 +510,24 @@ static int do_dump(int argc, char **argv)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ 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);
|
|
|
+ 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;
|
|
|
|
|
|
err = bpf_obj_get_info_by_fd(fd, &info, &len);
|
|
|
close(fd);
|
|
@@ -532,6 +546,11 @@ static int do_dump(int argc, char **argv)
|
|
|
goto err_free;
|
|
|
}
|
|
|
|
|
|
+ if (info.nr_jited_func_lens > nr_func_lens) {
|
|
|
+ p_err("too many values returned");
|
|
|
+ goto err_free;
|
|
|
+ }
|
|
|
+
|
|
|
if ((member_len == &info.jited_prog_len &&
|
|
|
info.jited_prog_insns == 0) ||
|
|
|
(member_len == &info.xlated_prog_len &&
|
|
@@ -569,7 +588,57 @@ static int do_dump(int argc, char **argv)
|
|
|
goto err_free;
|
|
|
}
|
|
|
|
|
|
- disasm_print_insn(buf, *member_len, opcodes, name);
|
|
|
+ if (info.nr_jited_func_lens && info.jited_func_lens) {
|
|
|
+ struct kernel_sym *sym = NULL;
|
|
|
+ char sym_name[SYM_MAX_NAME];
|
|
|
+ unsigned char *img = buf;
|
|
|
+ __u64 *ksyms = NULL;
|
|
|
+ __u32 *lens;
|
|
|
+ __u32 i;
|
|
|
+
|
|
|
+ if (info.nr_jited_ksyms) {
|
|
|
+ kernel_syms_load(&dd);
|
|
|
+ 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++) {
|
|
|
+ if (ksyms) {
|
|
|
+ sym = kernel_syms_search(&dd, ksyms[i]);
|
|
|
+ if (sym)
|
|
|
+ sprintf(sym_name, "%s", sym->name);
|
|
|
+ else
|
|
|
+ sprintf(sym_name, "0x%016llx", ksyms[i]);
|
|
|
+ } else {
|
|
|
+ strcpy(sym_name, "unknown");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (json_output) {
|
|
|
+ jsonw_start_object(json_wtr);
|
|
|
+ jsonw_name(json_wtr, "name");
|
|
|
+ jsonw_string(json_wtr, sym_name);
|
|
|
+ jsonw_name(json_wtr, "insns");
|
|
|
+ } else {
|
|
|
+ printf("%s:\n", sym_name);
|
|
|
+ }
|
|
|
+
|
|
|
+ disasm_print_insn(img, lens[i], opcodes, name);
|
|
|
+ img += lens[i];
|
|
|
+
|
|
|
+ if (json_output)
|
|
|
+ jsonw_end_object(json_wtr);
|
|
|
+ else
|
|
|
+ printf("\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (json_output)
|
|
|
+ jsonw_end_array(json_wtr);
|
|
|
+ } else {
|
|
|
+ disasm_print_insn(buf, *member_len, opcodes, name);
|
|
|
+ }
|
|
|
} else if (visual) {
|
|
|
if (json_output)
|
|
|
jsonw_null(json_wtr);
|
|
@@ -589,11 +658,13 @@ static int do_dump(int argc, char **argv)
|
|
|
|
|
|
free(buf);
|
|
|
free(func_ksyms);
|
|
|
+ free(func_lens);
|
|
|
return 0;
|
|
|
|
|
|
err_free:
|
|
|
free(buf);
|
|
|
free(func_ksyms);
|
|
|
+ free(func_lens);
|
|
|
return -1;
|
|
|
}
|
|
|
|