diff options
Diffstat (limited to 'tools')
-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 | /* -------------------------------------------------------------------- */ |