diff options
| -rw-r--r-- | tools/perf/builtin-report.c | 18 | ||||
| -rw-r--r-- | tools/perf/util/newt.c | 109 |
2 files changed, 117 insertions, 10 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2f4b92925b26..4a7a74362451 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -478,8 +478,24 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) | |||
| 478 | * so don't allocate extra space that won't be used in the stdio | 478 | * so don't allocate extra space that won't be used in the stdio |
| 479 | * implementation. | 479 | * implementation. |
| 480 | */ | 480 | */ |
| 481 | if (use_browser > 0) | 481 | if (use_browser > 0) { |
| 482 | symbol_conf.priv_size = sizeof(struct sym_priv); | 482 | symbol_conf.priv_size = sizeof(struct sym_priv); |
| 483 | /* | ||
| 484 | * For searching by name on the "Browse map details". | ||
| 485 | * providing it only in verbose mode not to bloat too | ||
| 486 | * much struct symbol. | ||
| 487 | */ | ||
| 488 | if (verbose) { | ||
| 489 | /* | ||
| 490 | * XXX: Need to provide a less kludgy way to ask for | ||
| 491 | * more space per symbol, the u32 is for the index on | ||
| 492 | * the ui browser. | ||
| 493 | * See symbol__browser_index. | ||
| 494 | */ | ||
| 495 | symbol_conf.priv_size += sizeof(u32); | ||
| 496 | symbol_conf.sort_by_name = true; | ||
| 497 | } | ||
| 498 | } | ||
| 483 | 499 | ||
| 484 | if (symbol__init() < 0) | 500 | if (symbol__init() < 0) |
| 485 | return -1; | 501 | return -1; |
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index f98a2406dd86..e2deae0704d7 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c | |||
| @@ -128,6 +128,39 @@ static void ui_helpline__puts(const char *msg) | |||
| 128 | ui_helpline__push(msg); | 128 | ui_helpline__push(msg); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | static int ui_entry__read(const char *title, char *bf, size_t size, int width) | ||
| 132 | { | ||
| 133 | struct newtExitStruct es; | ||
| 134 | newtComponent form, entry; | ||
| 135 | const char *result; | ||
| 136 | int err = -1; | ||
| 137 | |||
| 138 | newtCenteredWindow(width, 1, title); | ||
| 139 | form = newtForm(NULL, NULL, 0); | ||
| 140 | if (form == NULL) | ||
| 141 | return -1; | ||
| 142 | |||
| 143 | entry = newtEntry(0, 0, "0x", width, &result, NEWT_FLAG_SCROLL); | ||
| 144 | if (entry == NULL) | ||
| 145 | goto out_free_form; | ||
| 146 | |||
| 147 | newtFormAddComponent(form, entry); | ||
| 148 | newtFormAddHotKey(form, NEWT_KEY_ENTER); | ||
| 149 | newtFormAddHotKey(form, NEWT_KEY_ESCAPE); | ||
| 150 | newtFormAddHotKey(form, NEWT_KEY_LEFT); | ||
| 151 | newtFormAddHotKey(form, CTRL('c')); | ||
| 152 | newtFormRun(form, &es); | ||
| 153 | |||
| 154 | if (result != NULL) { | ||
| 155 | strncpy(bf, result, size); | ||
| 156 | err = 0; | ||
| 157 | } | ||
| 158 | out_free_form: | ||
| 159 | newtPopWindow(); | ||
| 160 | newtFormDestroy(form); | ||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 131 | static char browser__last_msg[1024]; | 164 | static char browser__last_msg[1024]; |
| 132 | 165 | ||
| 133 | int browser__show_help(const char *format, va_list ap) | 166 | int browser__show_help(const char *format, va_list ap) |
| @@ -670,6 +703,67 @@ static void map_browser__write(struct ui_browser *self, void *nd, int row) | |||
| 670 | slsmg_write_nstring(sym->name, mb->namelen); | 703 | slsmg_write_nstring(sym->name, mb->namelen); |
| 671 | } | 704 | } |
| 672 | 705 | ||
| 706 | /* FIXME uber-kludgy, see comment on cmd_report... */ | ||
| 707 | static u32 *symbol__browser_index(struct symbol *self) | ||
| 708 | { | ||
| 709 | return ((void *)self) - sizeof(struct rb_node) - sizeof(u32); | ||
| 710 | } | ||
| 711 | |||
| 712 | static int map_browser__search(struct map_browser *self) | ||
| 713 | { | ||
| 714 | char target[512]; | ||
| 715 | struct symbol *sym; | ||
| 716 | int err = ui_entry__read("Search by name/addr", target, sizeof(target), 40); | ||
| 717 | |||
| 718 | if (err) | ||
| 719 | return err; | ||
| 720 | |||
| 721 | if (target[0] == '0' && tolower(target[1]) == 'x') { | ||
| 722 | u64 addr = strtoull(target, NULL, 16); | ||
| 723 | sym = map__find_symbol(self->map, addr, NULL); | ||
| 724 | } else | ||
| 725 | sym = map__find_symbol_by_name(self->map, target, NULL); | ||
| 726 | |||
| 727 | if (sym != NULL) { | ||
| 728 | u32 *idx = symbol__browser_index(sym); | ||
| 729 | |||
| 730 | self->b.first_visible_entry = &sym->rb_node; | ||
| 731 | self->b.index = self->b.first_visible_entry_idx = *idx; | ||
| 732 | } else | ||
| 733 | ui_helpline__fpush("%s not found!", target); | ||
| 734 | |||
| 735 | return 0; | ||
| 736 | } | ||
| 737 | |||
| 738 | static int map_browser__run(struct map_browser *self, struct newtExitStruct *es) | ||
| 739 | { | ||
| 740 | if (ui_browser__show(&self->b, self->map->dso->long_name) < 0) | ||
| 741 | return -1; | ||
| 742 | |||
| 743 | ui_helpline__fpush("Press <- or ESC to exit, %s / to search", | ||
| 744 | verbose ? "" : "restart with -v to use"); | ||
| 745 | newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT); | ||
| 746 | newtFormAddHotKey(self->b.form, NEWT_KEY_ENTER); | ||
| 747 | if (verbose) | ||
| 748 | newtFormAddHotKey(self->b.form, '/'); | ||
| 749 | |||
| 750 | while (1) { | ||
| 751 | ui_browser__run(&self->b, es); | ||
| 752 | |||
| 753 | if (es->reason != NEWT_EXIT_HOTKEY) | ||
| 754 | break; | ||
| 755 | if (verbose && es->u.key == '/') | ||
| 756 | map_browser__search(self); | ||
| 757 | else | ||
| 758 | break; | ||
| 759 | } | ||
| 760 | |||
| 761 | newtFormDestroy(self->b.form); | ||
| 762 | newtPopWindow(); | ||
| 763 | ui_helpline__pop(); | ||
| 764 | return 0; | ||
| 765 | } | ||
| 766 | |||
| 673 | static int map__browse(struct map *self) | 767 | static int map__browse(struct map *self) |
| 674 | { | 768 | { |
| 675 | struct map_browser mb = { | 769 | struct map_browser mb = { |
| @@ -679,14 +773,12 @@ static int map__browse(struct map *self) | |||
| 679 | .seek = ui_browser__rb_tree_seek, | 773 | .seek = ui_browser__rb_tree_seek, |
| 680 | .write = map_browser__write, | 774 | .write = map_browser__write, |
| 681 | }, | 775 | }, |
| 776 | .map = self, | ||
| 682 | }; | 777 | }; |
| 683 | struct newtExitStruct es; | 778 | struct newtExitStruct es; |
| 684 | struct rb_node *nd; | 779 | struct rb_node *nd; |
| 685 | char tmp[BITS_PER_LONG / 4]; | 780 | char tmp[BITS_PER_LONG / 4]; |
| 686 | u64 maxaddr = 0; | 781 | u64 maxaddr = 0; |
| 687 | int ret; | ||
| 688 | |||
| 689 | ui_helpline__push("Press <- or ESC to exit"); | ||
| 690 | 782 | ||
| 691 | for (nd = rb_first(mb.b.entries); nd; nd = rb_next(nd)) { | 783 | for (nd = rb_first(mb.b.entries); nd; nd = rb_next(nd)) { |
| 692 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); | 784 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); |
| @@ -695,17 +787,16 @@ static int map__browse(struct map *self) | |||
| 695 | mb.namelen = pos->namelen; | 787 | mb.namelen = pos->namelen; |
| 696 | if (maxaddr < pos->end) | 788 | if (maxaddr < pos->end) |
| 697 | maxaddr = pos->end; | 789 | maxaddr = pos->end; |
| 790 | if (verbose) { | ||
| 791 | u32 *idx = symbol__browser_index(pos); | ||
| 792 | *idx = mb.b.nr_entries; | ||
| 793 | } | ||
| 698 | ++mb.b.nr_entries; | 794 | ++mb.b.nr_entries; |
| 699 | } | 795 | } |
| 700 | 796 | ||
| 701 | mb.addrlen = snprintf(tmp, sizeof(tmp), "%llx", maxaddr); | 797 | mb.addrlen = snprintf(tmp, sizeof(tmp), "%llx", maxaddr); |
| 702 | mb.b.width += mb.addrlen * 2 + 4 + mb.namelen; | 798 | mb.b.width += mb.addrlen * 2 + 4 + mb.namelen; |
| 703 | ui_browser__show(&mb.b, self->dso->long_name); | 799 | return map_browser__run(&mb, &es); |
| 704 | ret = ui_browser__run(&mb.b, &es); | ||
| 705 | newtFormDestroy(mb.b.form); | ||
| 706 | newtPopWindow(); | ||
| 707 | ui_helpline__pop(); | ||
| 708 | return ret; | ||
| 709 | } | 800 | } |
| 710 | 801 | ||
| 711 | /* -------------------------------------------------------------------- */ | 802 | /* -------------------------------------------------------------------- */ |
