summaryrefslogtreecommitdiffstats
path: root/tools/bpf/bpftool
diff options
context:
space:
mode:
authorSandipan Das <sandipan@linux.vnet.ibm.com>2018-05-24 02:56:50 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-05-24 03:20:49 -0400
commitf84192ee00b7d8b3c38545d3a61d4191f80cc81a (patch)
tree236e1f0dada1768797eafacdb707fcce1b59ceb9 /tools/bpf/bpftool
parentdd0c5f072e650458feb307fe3a8602cc2ec369d4 (diff)
tools: bpftool: resolve calls without using imm field
Currently, we resolve the callee's address for a JITed function call by using the imm field of the call instruction as an offset from __bpf_call_base. If bpf_jit_kallsyms is enabled, we further use this address to get the callee's kernel symbol's name. For some architectures, such as powerpc64, the imm field is not large enough to hold this offset. So, instead of assigning this offset to the imm field, the verifier now assigns the subprog id. Also, a list of kernel symbol addresses for all the JITed functions is provided in the program info. We now use the imm field as an index for this list to lookup a callee's symbol's address and resolve its name. Suggested-by: Daniel Borkmann <daniel@iogearbox.net> 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>
Diffstat (limited to 'tools/bpf/bpftool')
-rw-r--r--tools/bpf/bpftool/prog.c24
-rw-r--r--tools/bpf/bpftool/xlated_dumper.c10
-rw-r--r--tools/bpf/bpftool/xlated_dumper.h2
3 files changed, 35 insertions, 1 deletions
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 9bdfdf2d3fbe..e05ab58d39e2 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -420,7 +420,9 @@ static int do_show(int argc, char **argv)
420 420
421static int do_dump(int argc, char **argv) 421static int do_dump(int argc, char **argv)
422{ 422{
423 unsigned long *func_ksyms = NULL;
423 struct bpf_prog_info info = {}; 424 struct bpf_prog_info info = {};
425 unsigned int nr_func_ksyms;
424 struct dump_data dd = {}; 426 struct dump_data dd = {};
425 __u32 len = sizeof(info); 427 __u32 len = sizeof(info);
426 unsigned int buf_size; 428 unsigned int buf_size;
@@ -496,10 +498,22 @@ static int do_dump(int argc, char **argv)
496 return -1; 498 return -1;
497 } 499 }
498 500
501 nr_func_ksyms = info.nr_jited_ksyms;
502 if (nr_func_ksyms) {
503 func_ksyms = malloc(nr_func_ksyms * sizeof(__u64));
504 if (!func_ksyms) {
505 p_err("mem alloc failed");
506 close(fd);
507 goto err_free;
508 }
509 }
510
499 memset(&info, 0, sizeof(info)); 511 memset(&info, 0, sizeof(info));
500 512
501 *member_ptr = ptr_to_u64(buf); 513 *member_ptr = ptr_to_u64(buf);
502 *member_len = buf_size; 514 *member_len = buf_size;
515 info.jited_ksyms = ptr_to_u64(func_ksyms);
516 info.nr_jited_ksyms = nr_func_ksyms;
503 517
504 err = bpf_obj_get_info_by_fd(fd, &info, &len); 518 err = bpf_obj_get_info_by_fd(fd, &info, &len);
505 close(fd); 519 close(fd);
@@ -513,6 +527,11 @@ static int do_dump(int argc, char **argv)
513 goto err_free; 527 goto err_free;
514 } 528 }
515 529
530 if (info.nr_jited_ksyms > nr_func_ksyms) {
531 p_err("too many addresses returned");
532 goto err_free;
533 }
534
516 if ((member_len == &info.jited_prog_len && 535 if ((member_len == &info.jited_prog_len &&
517 info.jited_prog_insns == 0) || 536 info.jited_prog_insns == 0) ||
518 (member_len == &info.xlated_prog_len && 537 (member_len == &info.xlated_prog_len &&
@@ -558,6 +577,9 @@ static int do_dump(int argc, char **argv)
558 dump_xlated_cfg(buf, *member_len); 577 dump_xlated_cfg(buf, *member_len);
559 } else { 578 } else {
560 kernel_syms_load(&dd); 579 kernel_syms_load(&dd);
580 dd.nr_jited_ksyms = info.nr_jited_ksyms;
581 dd.jited_ksyms = (__u64 *) info.jited_ksyms;
582
561 if (json_output) 583 if (json_output)
562 dump_xlated_json(&dd, buf, *member_len, opcodes); 584 dump_xlated_json(&dd, buf, *member_len, opcodes);
563 else 585 else
@@ -566,10 +588,12 @@ static int do_dump(int argc, char **argv)
566 } 588 }
567 589
568 free(buf); 590 free(buf);
591 free(func_ksyms);
569 return 0; 592 return 0;
570 593
571err_free: 594err_free:
572 free(buf); 595 free(buf);
596 free(func_ksyms);
573 return -1; 597 return -1;
574} 598}
575 599
diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c
index 7a3173b76c16..efdc8fecf2bb 100644
--- a/tools/bpf/bpftool/xlated_dumper.c
+++ b/tools/bpf/bpftool/xlated_dumper.c
@@ -174,7 +174,11 @@ static const char *print_call_pcrel(struct dump_data *dd,
174 unsigned long address, 174 unsigned long address,
175 const struct bpf_insn *insn) 175 const struct bpf_insn *insn)
176{ 176{
177 if (sym) 177 if (!dd->nr_jited_ksyms)
178 /* Do not show address for interpreted programs */
179 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
180 "%+d", insn->off);
181 else if (sym)
178 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff), 182 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
179 "%+d#%s", insn->off, sym->name); 183 "%+d#%s", insn->off, sym->name);
180 else 184 else
@@ -203,6 +207,10 @@ static const char *print_call(void *private_data,
203 unsigned long address = dd->address_call_base + insn->imm; 207 unsigned long address = dd->address_call_base + insn->imm;
204 struct kernel_sym *sym; 208 struct kernel_sym *sym;
205 209
210 if (insn->src_reg == BPF_PSEUDO_CALL &&
211 (__u32) insn->imm < dd->nr_jited_ksyms)
212 address = dd->jited_ksyms[insn->imm];
213
206 sym = kernel_syms_search(dd, address); 214 sym = kernel_syms_search(dd, address);
207 if (insn->src_reg == BPF_PSEUDO_CALL) 215 if (insn->src_reg == BPF_PSEUDO_CALL)
208 return print_call_pcrel(dd, sym, address, insn); 216 return print_call_pcrel(dd, sym, address, insn);
diff --git a/tools/bpf/bpftool/xlated_dumper.h b/tools/bpf/bpftool/xlated_dumper.h
index b34affa7ef2d..eafbb49c8d0b 100644
--- a/tools/bpf/bpftool/xlated_dumper.h
+++ b/tools/bpf/bpftool/xlated_dumper.h
@@ -49,6 +49,8 @@ struct dump_data {
49 unsigned long address_call_base; 49 unsigned long address_call_base;
50 struct kernel_sym *sym_mapping; 50 struct kernel_sym *sym_mapping;
51 __u32 sym_count; 51 __u32 sym_count;
52 __u64 *jited_ksyms;
53 __u32 nr_jited_ksyms;
52 char scratch_buff[SYM_MAX_NAME + 8]; 54 char scratch_buff[SYM_MAX_NAME + 8];
53}; 55};
54 56