tools: bpftool: add delimiters to multi-function JITed dumps
This splits up the contiguous JITed dump obtained via the bpf system call into more relatable chunks for each function in the program. If the kernel symbols corresponding to these are known, they are printed in the header for each JIT image dump otherwise the masked start address is printed. Before applying this patch: # bpftool prog dump jited id 1 0: push %rbp 1: mov %rsp,%rbp ... 70: leaveq 71: retq 72: push %rbp 73: mov %rsp,%rbp ... dd: leaveq de: retq # bpftool -p prog dump jited id 1 [{ "pc": "0x0", "operation": "push", "operands": ["%rbp" ] },{ ... },{ "pc": "0x71", "operation": "retq", "operands": [null ] },{ "pc": "0x72", "operation": "push", "operands": ["%rbp" ] },{ ... },{ "pc": "0xde", "operation": "retq", "operands": [null ] } ] After applying this patch: # echo 0 > /proc/sys/net/core/bpf_jit_kallsyms # bpftool prog dump jited id 1 0xffffffffc02c7000: 0: push %rbp 1: mov %rsp,%rbp ... 70: leaveq 71: retq 0xffffffffc02cf000: 0: push %rbp 1: mov %rsp,%rbp ... 6b: leaveq 6c: retq # bpftool -p prog dump jited id 1 [{ "name": "0xffffffffc02c7000", "insns": [{ "pc": "0x0", "operation": "push", "operands": ["%rbp" ] },{ ... },{ "pc": "0x71", "operation": "retq", "operands": [null ] } ] },{ "name": "0xffffffffc02cf000", "insns": [{ "pc": "0x0", "operation": "push", "operands": ["%rbp" ] },{ ... },{ "pc": "0x6c", "operation": "retq", "operands": [null ] } ] } ] # echo 1 > /proc/sys/net/core/bpf_jit_kallsyms # bpftool prog dump jited id 1 bpf_prog_b811aab41a39ad3d_foo: 0: push %rbp 1: mov %rsp,%rbp ... 70: leaveq 71: retq bpf_prog_cf418ac8b67bebd9_F: 0: push %rbp 1: mov %rsp,%rbp ... 6b: leaveq 6c: retq # bpftool -p prog dump jited id 1 [{ "name": "bpf_prog_b811aab41a39ad3d_foo", "insns": [{ "pc": "0x0", "operation": "push", "operands": ["%rbp" ] },{ ... },{ "pc": "0x71", "operation": "retq", "operands": [null ] } ] },{ "name": "bpf_prog_cf418ac8b67bebd9_F", "insns": [{ "pc": "0x0", "operation": "push", "operands": ["%rbp" ] },{ ... },{ "pc": "0x6c", "operation": "retq", "operands": [null ] } ] } ] Signed-off-by: Sandipan Das <sandipan@linux.vnet.ibm.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:

committed by
Daniel Borkmann

parent
bd980d43b9
commit
f7f62c7134
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user