diff options
author | Yonghong Song <yhs@fb.com> | 2018-11-19 18:29:21 -0500 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2018-11-20 13:54:39 -0500 |
commit | 254471e57a86b8dc1a2cc19848e99f5d7c0558f4 (patch) | |
tree | 1892de2dc8c361322df68d459f0e63e59d901450 | |
parent | 999d82cbc04416cc7f2b5cb6daab947c16f0fd3a (diff) |
tools/bpf: bpftool: add support for func types
This patch added support to print function signature
if btf func_info is available. Note that ksym
now uses function name instead of prog_name as
prog_name has a limit of 16 bytes including
ending '\0'.
The following is a sample output for selftests
test_btf with file test_btf_haskv.o for translated insns
and jited insns respectively.
$ bpftool prog dump xlated id 1
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
0: (85) call pc+2#bpf_prog_2dcecc18072623fc_test_long_fname_1
1: (b7) r0 = 0
2: (95) exit
int test_long_fname_1(struct dummy_tracepoint_args * arg):
3: (85) call pc+1#bpf_prog_89d64e4abf0f0126_test_long_fname_2
4: (95) exit
int test_long_fname_2(struct dummy_tracepoint_args * arg):
5: (b7) r2 = 0
6: (63) *(u32 *)(r10 -4) = r2
7: (79) r1 = *(u64 *)(r1 +8)
...
22: (07) r1 += 1
23: (63) *(u32 *)(r0 +4) = r1
24: (95) exit
$ bpftool prog dump jited id 1
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
0: push %rbp
1: mov %rsp,%rbp
......
3c: add $0x28,%rbp
40: leaveq
41: retq
int test_long_fname_1(struct dummy_tracepoint_args * arg):
bpf_prog_2dcecc18072623fc_test_long_fname_1:
0: push %rbp
1: mov %rsp,%rbp
......
3a: add $0x28,%rbp
3e: leaveq
3f: retq
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_89d64e4abf0f0126_test_long_fname_2:
0: push %rbp
1: mov %rsp,%rbp
......
80: add $0x28,%rbp
84: leaveq
85: retq
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r-- | tools/bpf/bpftool/btf_dumper.c | 136 | ||||
-rw-r--r-- | tools/bpf/bpftool/main.h | 2 | ||||
-rw-r--r-- | tools/bpf/bpftool/prog.c | 56 | ||||
-rw-r--r-- | tools/bpf/bpftool/xlated_dumper.c | 33 | ||||
-rw-r--r-- | tools/bpf/bpftool/xlated_dumper.h | 3 |
5 files changed, 230 insertions, 0 deletions
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c index 55bc512a1831..c3fd3a7cb787 100644 --- a/tools/bpf/bpftool/btf_dumper.c +++ b/tools/bpf/bpftool/btf_dumper.c | |||
@@ -249,3 +249,139 @@ int btf_dumper_type(const struct btf_dumper *d, __u32 type_id, | |||
249 | { | 249 | { |
250 | return btf_dumper_do_type(d, type_id, 0, data); | 250 | return btf_dumper_do_type(d, type_id, 0, data); |
251 | } | 251 | } |
252 | |||
253 | #define BTF_PRINT_ARG(...) \ | ||
254 | do { \ | ||
255 | pos += snprintf(func_sig + pos, size - pos, \ | ||
256 | __VA_ARGS__); \ | ||
257 | if (pos >= size) \ | ||
258 | return -1; \ | ||
259 | } while (0) | ||
260 | #define BTF_PRINT_TYPE(type) \ | ||
261 | do { \ | ||
262 | pos = __btf_dumper_type_only(btf, type, func_sig, \ | ||
263 | pos, size); \ | ||
264 | if (pos == -1) \ | ||
265 | return -1; \ | ||
266 | } while (0) | ||
267 | |||
268 | static int btf_dump_func(const struct btf *btf, char *func_sig, | ||
269 | const struct btf_type *func_proto, | ||
270 | const struct btf_type *func, int pos, int size); | ||
271 | |||
272 | static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id, | ||
273 | char *func_sig, int pos, int size) | ||
274 | { | ||
275 | const struct btf_type *proto_type; | ||
276 | const struct btf_array *array; | ||
277 | const struct btf_type *t; | ||
278 | |||
279 | if (!type_id) { | ||
280 | BTF_PRINT_ARG("void "); | ||
281 | return pos; | ||
282 | } | ||
283 | |||
284 | t = btf__type_by_id(btf, type_id); | ||
285 | |||
286 | switch (BTF_INFO_KIND(t->info)) { | ||
287 | case BTF_KIND_INT: | ||
288 | BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off)); | ||
289 | break; | ||
290 | case BTF_KIND_STRUCT: | ||
291 | BTF_PRINT_ARG("struct %s ", | ||
292 | btf__name_by_offset(btf, t->name_off)); | ||
293 | break; | ||
294 | case BTF_KIND_UNION: | ||
295 | BTF_PRINT_ARG("union %s ", | ||
296 | btf__name_by_offset(btf, t->name_off)); | ||
297 | break; | ||
298 | case BTF_KIND_ENUM: | ||
299 | BTF_PRINT_ARG("enum %s ", | ||
300 | btf__name_by_offset(btf, t->name_off)); | ||
301 | break; | ||
302 | case BTF_KIND_ARRAY: | ||
303 | array = (struct btf_array *)(t + 1); | ||
304 | BTF_PRINT_TYPE(array->type); | ||
305 | BTF_PRINT_ARG("[%d]", array->nelems); | ||
306 | break; | ||
307 | case BTF_KIND_PTR: | ||
308 | BTF_PRINT_TYPE(t->type); | ||
309 | BTF_PRINT_ARG("* "); | ||
310 | break; | ||
311 | case BTF_KIND_UNKN: | ||
312 | case BTF_KIND_FWD: | ||
313 | case BTF_KIND_TYPEDEF: | ||
314 | return -1; | ||
315 | case BTF_KIND_VOLATILE: | ||
316 | BTF_PRINT_ARG("volatile "); | ||
317 | BTF_PRINT_TYPE(t->type); | ||
318 | break; | ||
319 | case BTF_KIND_CONST: | ||
320 | BTF_PRINT_ARG("const "); | ||
321 | BTF_PRINT_TYPE(t->type); | ||
322 | break; | ||
323 | case BTF_KIND_RESTRICT: | ||
324 | BTF_PRINT_ARG("restrict "); | ||
325 | BTF_PRINT_TYPE(t->type); | ||
326 | break; | ||
327 | case BTF_KIND_FUNC_PROTO: | ||
328 | pos = btf_dump_func(btf, func_sig, t, NULL, pos, size); | ||
329 | if (pos == -1) | ||
330 | return -1; | ||
331 | break; | ||
332 | case BTF_KIND_FUNC: | ||
333 | proto_type = btf__type_by_id(btf, t->type); | ||
334 | pos = btf_dump_func(btf, func_sig, proto_type, t, pos, size); | ||
335 | if (pos == -1) | ||
336 | return -1; | ||
337 | break; | ||
338 | default: | ||
339 | return -1; | ||
340 | } | ||
341 | |||
342 | return pos; | ||
343 | } | ||
344 | |||
345 | static int btf_dump_func(const struct btf *btf, char *func_sig, | ||
346 | const struct btf_type *func_proto, | ||
347 | const struct btf_type *func, int pos, int size) | ||
348 | { | ||
349 | int i, vlen; | ||
350 | |||
351 | BTF_PRINT_TYPE(func_proto->type); | ||
352 | if (func) | ||
353 | BTF_PRINT_ARG("%s(", btf__name_by_offset(btf, func->name_off)); | ||
354 | else | ||
355 | BTF_PRINT_ARG("("); | ||
356 | vlen = BTF_INFO_VLEN(func_proto->info); | ||
357 | for (i = 0; i < vlen; i++) { | ||
358 | struct btf_param *arg = &((struct btf_param *)(func_proto + 1))[i]; | ||
359 | |||
360 | if (i) | ||
361 | BTF_PRINT_ARG(", "); | ||
362 | if (arg->type) { | ||
363 | BTF_PRINT_TYPE(arg->type); | ||
364 | BTF_PRINT_ARG("%s", | ||
365 | btf__name_by_offset(btf, arg->name_off)); | ||
366 | } else { | ||
367 | BTF_PRINT_ARG("..."); | ||
368 | } | ||
369 | } | ||
370 | BTF_PRINT_ARG(")"); | ||
371 | |||
372 | return pos; | ||
373 | } | ||
374 | |||
375 | void btf_dumper_type_only(const struct btf *btf, __u32 type_id, char *func_sig, | ||
376 | int size) | ||
377 | { | ||
378 | int err; | ||
379 | |||
380 | func_sig[0] = '\0'; | ||
381 | if (!btf) | ||
382 | return; | ||
383 | |||
384 | err = __btf_dumper_type_only(btf, type_id, func_sig, 0, size); | ||
385 | if (err < 0) | ||
386 | func_sig[0] = '\0'; | ||
387 | } | ||
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index 10c6c16fae29..3e8979567cf1 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h | |||
@@ -187,6 +187,8 @@ struct btf_dumper { | |||
187 | */ | 187 | */ |
188 | int btf_dumper_type(const struct btf_dumper *d, __u32 type_id, | 188 | int btf_dumper_type(const struct btf_dumper *d, __u32 type_id, |
189 | const void *data); | 189 | const void *data); |
190 | void btf_dumper_type_only(const struct btf *btf, __u32 func_type_id, | ||
191 | char *func_only, int size); | ||
190 | 192 | ||
191 | struct nlattr; | 193 | struct nlattr; |
192 | struct ifinfomsg; | 194 | struct ifinfomsg; |
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index c176e1aa66fe..37b1daf19da6 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/err.h> | 47 | #include <linux/err.h> |
48 | 48 | ||
49 | #include <bpf.h> | 49 | #include <bpf.h> |
50 | #include <btf.h> | ||
50 | #include <libbpf.h> | 51 | #include <libbpf.h> |
51 | 52 | ||
52 | #include "cfg.h" | 53 | #include "cfg.h" |
@@ -451,14 +452,19 @@ static int do_dump(int argc, char **argv) | |||
451 | struct bpf_prog_info info = {}; | 452 | struct bpf_prog_info info = {}; |
452 | unsigned int *func_lens = NULL; | 453 | unsigned int *func_lens = NULL; |
453 | const char *disasm_opt = NULL; | 454 | const char *disasm_opt = NULL; |
455 | unsigned int finfo_rec_size; | ||
454 | unsigned int nr_func_ksyms; | 456 | unsigned int nr_func_ksyms; |
455 | unsigned int nr_func_lens; | 457 | unsigned int nr_func_lens; |
456 | struct dump_data dd = {}; | 458 | struct dump_data dd = {}; |
457 | __u32 len = sizeof(info); | 459 | __u32 len = sizeof(info); |
460 | struct btf *btf = NULL; | ||
461 | void *func_info = NULL; | ||
462 | unsigned int finfo_cnt; | ||
458 | unsigned int buf_size; | 463 | unsigned int buf_size; |
459 | char *filepath = NULL; | 464 | char *filepath = NULL; |
460 | bool opcodes = false; | 465 | bool opcodes = false; |
461 | bool visual = false; | 466 | bool visual = false; |
467 | char func_sig[1024]; | ||
462 | unsigned char *buf; | 468 | unsigned char *buf; |
463 | __u32 *member_len; | 469 | __u32 *member_len; |
464 | __u64 *member_ptr; | 470 | __u64 *member_ptr; |
@@ -551,6 +557,17 @@ static int do_dump(int argc, char **argv) | |||
551 | } | 557 | } |
552 | } | 558 | } |
553 | 559 | ||
560 | finfo_cnt = info.func_info_cnt; | ||
561 | finfo_rec_size = info.func_info_rec_size; | ||
562 | if (finfo_cnt && finfo_rec_size) { | ||
563 | func_info = malloc(finfo_cnt * finfo_rec_size); | ||
564 | if (!func_info) { | ||
565 | p_err("mem alloc failed"); | ||
566 | close(fd); | ||
567 | goto err_free; | ||
568 | } | ||
569 | } | ||
570 | |||
554 | memset(&info, 0, sizeof(info)); | 571 | memset(&info, 0, sizeof(info)); |
555 | 572 | ||
556 | *member_ptr = ptr_to_u64(buf); | 573 | *member_ptr = ptr_to_u64(buf); |
@@ -559,6 +576,9 @@ static int do_dump(int argc, char **argv) | |||
559 | info.nr_jited_ksyms = nr_func_ksyms; | 576 | info.nr_jited_ksyms = nr_func_ksyms; |
560 | info.jited_func_lens = ptr_to_u64(func_lens); | 577 | info.jited_func_lens = ptr_to_u64(func_lens); |
561 | info.nr_jited_func_lens = nr_func_lens; | 578 | info.nr_jited_func_lens = nr_func_lens; |
579 | info.func_info_cnt = finfo_cnt; | ||
580 | info.func_info_rec_size = finfo_rec_size; | ||
581 | info.func_info = ptr_to_u64(func_info); | ||
562 | 582 | ||
563 | err = bpf_obj_get_info_by_fd(fd, &info, &len); | 583 | err = bpf_obj_get_info_by_fd(fd, &info, &len); |
564 | close(fd); | 584 | close(fd); |
@@ -582,6 +602,18 @@ static int do_dump(int argc, char **argv) | |||
582 | goto err_free; | 602 | goto err_free; |
583 | } | 603 | } |
584 | 604 | ||
605 | if (info.func_info_cnt != finfo_cnt) { | ||
606 | p_err("incorrect func_info_cnt %d vs. expected %d", | ||
607 | info.func_info_cnt, finfo_cnt); | ||
608 | goto err_free; | ||
609 | } | ||
610 | |||
611 | if (info.func_info_rec_size != finfo_rec_size) { | ||
612 | p_err("incorrect func_info_rec_size %d vs. expected %d", | ||
613 | info.func_info_rec_size, finfo_rec_size); | ||
614 | goto err_free; | ||
615 | } | ||
616 | |||
585 | if ((member_len == &info.jited_prog_len && | 617 | if ((member_len == &info.jited_prog_len && |
586 | info.jited_prog_insns == 0) || | 618 | info.jited_prog_insns == 0) || |
587 | (member_len == &info.xlated_prog_len && | 619 | (member_len == &info.xlated_prog_len && |
@@ -590,6 +622,11 @@ static int do_dump(int argc, char **argv) | |||
590 | goto err_free; | 622 | goto err_free; |
591 | } | 623 | } |
592 | 624 | ||
625 | if (info.btf_id && btf_get_from_id(info.btf_id, &btf)) { | ||
626 | p_err("failed to get btf"); | ||
627 | goto err_free; | ||
628 | } | ||
629 | |||
593 | if (filepath) { | 630 | if (filepath) { |
594 | fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0600); | 631 | fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0600); |
595 | if (fd < 0) { | 632 | if (fd < 0) { |
@@ -622,6 +659,7 @@ static int do_dump(int argc, char **argv) | |||
622 | 659 | ||
623 | if (info.nr_jited_func_lens && info.jited_func_lens) { | 660 | if (info.nr_jited_func_lens && info.jited_func_lens) { |
624 | struct kernel_sym *sym = NULL; | 661 | struct kernel_sym *sym = NULL; |
662 | struct bpf_func_info *record; | ||
625 | char sym_name[SYM_MAX_NAME]; | 663 | char sym_name[SYM_MAX_NAME]; |
626 | unsigned char *img = buf; | 664 | unsigned char *img = buf; |
627 | __u64 *ksyms = NULL; | 665 | __u64 *ksyms = NULL; |
@@ -648,12 +686,25 @@ static int do_dump(int argc, char **argv) | |||
648 | strcpy(sym_name, "unknown"); | 686 | strcpy(sym_name, "unknown"); |
649 | } | 687 | } |
650 | 688 | ||
689 | if (func_info) { | ||
690 | record = func_info + i * finfo_rec_size; | ||
691 | btf_dumper_type_only(btf, record->type_id, | ||
692 | func_sig, | ||
693 | sizeof(func_sig)); | ||
694 | } | ||
695 | |||
651 | if (json_output) { | 696 | if (json_output) { |
652 | jsonw_start_object(json_wtr); | 697 | jsonw_start_object(json_wtr); |
698 | if (func_info && func_sig[0] != '\0') { | ||
699 | jsonw_name(json_wtr, "proto"); | ||
700 | jsonw_string(json_wtr, func_sig); | ||
701 | } | ||
653 | jsonw_name(json_wtr, "name"); | 702 | jsonw_name(json_wtr, "name"); |
654 | jsonw_string(json_wtr, sym_name); | 703 | jsonw_string(json_wtr, sym_name); |
655 | jsonw_name(json_wtr, "insns"); | 704 | jsonw_name(json_wtr, "insns"); |
656 | } else { | 705 | } else { |
706 | if (func_info && func_sig[0] != '\0') | ||
707 | printf("%s:\n", func_sig); | ||
657 | printf("%s:\n", sym_name); | 708 | printf("%s:\n", sym_name); |
658 | } | 709 | } |
659 | 710 | ||
@@ -682,6 +733,9 @@ static int do_dump(int argc, char **argv) | |||
682 | kernel_syms_load(&dd); | 733 | kernel_syms_load(&dd); |
683 | dd.nr_jited_ksyms = info.nr_jited_ksyms; | 734 | dd.nr_jited_ksyms = info.nr_jited_ksyms; |
684 | dd.jited_ksyms = (__u64 *) info.jited_ksyms; | 735 | dd.jited_ksyms = (__u64 *) info.jited_ksyms; |
736 | dd.btf = btf; | ||
737 | dd.func_info = func_info; | ||
738 | dd.finfo_rec_size = finfo_rec_size; | ||
685 | 739 | ||
686 | if (json_output) | 740 | if (json_output) |
687 | dump_xlated_json(&dd, buf, *member_len, opcodes); | 741 | dump_xlated_json(&dd, buf, *member_len, opcodes); |
@@ -693,12 +747,14 @@ static int do_dump(int argc, char **argv) | |||
693 | free(buf); | 747 | free(buf); |
694 | free(func_ksyms); | 748 | free(func_ksyms); |
695 | free(func_lens); | 749 | free(func_lens); |
750 | free(func_info); | ||
696 | return 0; | 751 | return 0; |
697 | 752 | ||
698 | err_free: | 753 | err_free: |
699 | free(buf); | 754 | free(buf); |
700 | free(func_ksyms); | 755 | free(func_ksyms); |
701 | free(func_lens); | 756 | free(func_lens); |
757 | free(func_info); | ||
702 | return -1; | 758 | return -1; |
703 | } | 759 | } |
704 | 760 | ||
diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c index 3284759df98a..e06ac0286a75 100644 --- a/tools/bpf/bpftool/xlated_dumper.c +++ b/tools/bpf/bpftool/xlated_dumper.c | |||
@@ -242,11 +242,15 @@ void dump_xlated_json(struct dump_data *dd, void *buf, unsigned int len, | |||
242 | .cb_imm = print_imm, | 242 | .cb_imm = print_imm, |
243 | .private_data = dd, | 243 | .private_data = dd, |
244 | }; | 244 | }; |
245 | struct bpf_func_info *record; | ||
245 | struct bpf_insn *insn = buf; | 246 | struct bpf_insn *insn = buf; |
247 | struct btf *btf = dd->btf; | ||
246 | bool double_insn = false; | 248 | bool double_insn = false; |
249 | char func_sig[1024]; | ||
247 | unsigned int i; | 250 | unsigned int i; |
248 | 251 | ||
249 | jsonw_start_array(json_wtr); | 252 | jsonw_start_array(json_wtr); |
253 | record = dd->func_info; | ||
250 | for (i = 0; i < len / sizeof(*insn); i++) { | 254 | for (i = 0; i < len / sizeof(*insn); i++) { |
251 | if (double_insn) { | 255 | if (double_insn) { |
252 | double_insn = false; | 256 | double_insn = false; |
@@ -255,6 +259,20 @@ void dump_xlated_json(struct dump_data *dd, void *buf, unsigned int len, | |||
255 | double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW); | 259 | double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW); |
256 | 260 | ||
257 | jsonw_start_object(json_wtr); | 261 | jsonw_start_object(json_wtr); |
262 | |||
263 | if (btf && record) { | ||
264 | if (record->insn_offset == i) { | ||
265 | btf_dumper_type_only(btf, record->type_id, | ||
266 | func_sig, | ||
267 | sizeof(func_sig)); | ||
268 | if (func_sig[0] != '\0') { | ||
269 | jsonw_name(json_wtr, "proto"); | ||
270 | jsonw_string(json_wtr, func_sig); | ||
271 | } | ||
272 | record = (void *)record + dd->finfo_rec_size; | ||
273 | } | ||
274 | } | ||
275 | |||
258 | jsonw_name(json_wtr, "disasm"); | 276 | jsonw_name(json_wtr, "disasm"); |
259 | print_bpf_insn(&cbs, insn + i, true); | 277 | print_bpf_insn(&cbs, insn + i, true); |
260 | 278 | ||
@@ -297,16 +315,31 @@ void dump_xlated_plain(struct dump_data *dd, void *buf, unsigned int len, | |||
297 | .cb_imm = print_imm, | 315 | .cb_imm = print_imm, |
298 | .private_data = dd, | 316 | .private_data = dd, |
299 | }; | 317 | }; |
318 | struct bpf_func_info *record; | ||
300 | struct bpf_insn *insn = buf; | 319 | struct bpf_insn *insn = buf; |
320 | struct btf *btf = dd->btf; | ||
301 | bool double_insn = false; | 321 | bool double_insn = false; |
322 | char func_sig[1024]; | ||
302 | unsigned int i; | 323 | unsigned int i; |
303 | 324 | ||
325 | record = dd->func_info; | ||
304 | for (i = 0; i < len / sizeof(*insn); i++) { | 326 | for (i = 0; i < len / sizeof(*insn); i++) { |
305 | if (double_insn) { | 327 | if (double_insn) { |
306 | double_insn = false; | 328 | double_insn = false; |
307 | continue; | 329 | continue; |
308 | } | 330 | } |
309 | 331 | ||
332 | if (btf && record) { | ||
333 | if (record->insn_offset == i) { | ||
334 | btf_dumper_type_only(btf, record->type_id, | ||
335 | func_sig, | ||
336 | sizeof(func_sig)); | ||
337 | if (func_sig[0] != '\0') | ||
338 | printf("%s:\n", func_sig); | ||
339 | record = (void *)record + dd->finfo_rec_size; | ||
340 | } | ||
341 | } | ||
342 | |||
310 | double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW); | 343 | double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW); |
311 | 344 | ||
312 | printf("% 4d: ", i); | 345 | printf("% 4d: ", i); |
diff --git a/tools/bpf/bpftool/xlated_dumper.h b/tools/bpf/bpftool/xlated_dumper.h index 33d86e2b369b..aec31723e1e5 100644 --- a/tools/bpf/bpftool/xlated_dumper.h +++ b/tools/bpf/bpftool/xlated_dumper.h | |||
@@ -51,6 +51,9 @@ struct dump_data { | |||
51 | __u32 sym_count; | 51 | __u32 sym_count; |
52 | __u64 *jited_ksyms; | 52 | __u64 *jited_ksyms; |
53 | __u32 nr_jited_ksyms; | 53 | __u32 nr_jited_ksyms; |
54 | struct btf *btf; | ||
55 | void *func_info; | ||
56 | __u32 finfo_rec_size; | ||
54 | char scratch_buff[SYM_MAX_NAME + 8]; | 57 | char scratch_buff[SYM_MAX_NAME + 8]; |
55 | }; | 58 | }; |
56 | 59 | ||