aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/newt.c129
1 files changed, 127 insertions, 2 deletions
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index 91de99b58445..fc4a2b3aa65e 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -13,6 +13,7 @@
13#include <slang.h> 13#include <slang.h>
14#include <signal.h> 14#include <signal.h>
15#include <stdlib.h> 15#include <stdlib.h>
16#include <elf.h>
16#include <newt.h> 17#include <newt.h>
17#include <sys/ttydefaults.h> 18#include <sys/ttydefaults.h>
18 19
@@ -280,6 +281,7 @@ struct ui_browser {
280 u16 top, left, width, height; 281 u16 top, left, width, height;
281 void *priv; 282 void *priv;
282 unsigned int (*refresh_entries)(struct ui_browser *self); 283 unsigned int (*refresh_entries)(struct ui_browser *self);
284 void (*write)(struct ui_browser *self, void *entry, int row);
283 void (*seek)(struct ui_browser *self, 285 void (*seek)(struct ui_browser *self,
284 off_t offset, int whence); 286 off_t offset, int whence);
285 u32 nr_entries; 287 u32 nr_entries;
@@ -316,6 +318,58 @@ static void ui_browser__list_head_seek(struct ui_browser *self,
316 self->first_visible_entry = pos; 318 self->first_visible_entry = pos;
317} 319}
318 320
321static void ui_browser__rb_tree_seek(struct ui_browser *self,
322 off_t offset, int whence)
323{
324 struct rb_root *root = self->entries;
325 struct rb_node *nd;
326
327 switch (whence) {
328 case SEEK_SET:
329 nd = rb_first(root);
330 break;
331 case SEEK_CUR:
332 nd = self->first_visible_entry;
333 break;
334 case SEEK_END:
335 nd = rb_last(root);
336 break;
337 default:
338 return;
339 }
340
341 if (offset > 0) {
342 while (offset-- != 0)
343 nd = rb_next(nd);
344 } else {
345 while (offset++ != 0)
346 nd = rb_prev(nd);
347 }
348
349 self->first_visible_entry = nd;
350}
351
352static unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self)
353{
354 struct rb_node *nd;
355 int row = 0;
356
357 if (self->first_visible_entry == NULL)
358 self->first_visible_entry = rb_first(self->entries);
359
360 nd = self->first_visible_entry;
361
362 while (nd != NULL) {
363 SLsmg_gotorc(self->top + row, self->left);
364 self->write(self, nd, row);
365 if (++row == self->height)
366 break;
367 nd = rb_next(nd);
368 }
369
370 return row;
371}
372
319static bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row) 373static bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row)
320{ 374{
321 return (self->first_visible_entry_idx + row) == self->index; 375 return (self->first_visible_entry_idx + row) == self->index;
@@ -592,6 +646,70 @@ int hist_entry__tui_annotate(struct hist_entry *self)
592 return ret; 646 return ret;
593} 647}
594 648
649/* -------------------------------------------------------------------- */
650
651struct map_browser {
652 struct ui_browser b;
653 struct map *map;
654 u16 namelen;
655 u8 addrlen;
656};
657
658static void map_browser__write(struct ui_browser *self, void *nd, int row)
659{
660 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
661 struct map_browser *mb = container_of(self, struct map_browser, b);
662 bool current_entry = ui_browser__is_current_entry(self, row);
663 int color = ui_browser__percent_color(0, current_entry);
664
665 SLsmg_set_color(color);
666 slsmg_printf("%*llx %*llx %c ",
667 mb->addrlen, sym->start, mb->addrlen, sym->end,
668 sym->binding == STB_GLOBAL ? 'g' :
669 sym->binding == STB_LOCAL ? 'l' : 'w');
670 slsmg_write_nstring(sym->name, mb->namelen);
671}
672
673static int map__browse(struct map *self)
674{
675 struct map_browser mb = {
676 .b = {
677 .entries = &self->dso->symbols[self->type],
678 .refresh_entries = ui_browser__rb_tree_refresh,
679 .seek = ui_browser__rb_tree_seek,
680 .write = map_browser__write,
681 },
682 };
683 struct newtExitStruct es;
684 struct rb_node *nd;
685 char tmp[BITS_PER_LONG / 4];
686 u64 maxaddr = 0;
687 int ret;
688
689 ui_helpline__push("Press <- or ESC to exit");
690
691 for (nd = rb_first(mb.b.entries); nd; nd = rb_next(nd)) {
692 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
693
694 if (mb.namelen < pos->namelen)
695 mb.namelen = pos->namelen;
696 if (maxaddr < pos->end)
697 maxaddr = pos->end;
698 ++mb.b.nr_entries;
699 }
700
701 mb.addrlen = snprintf(tmp, sizeof(tmp), "%llx", maxaddr);
702 mb.b.width += mb.addrlen * 2 + 4 + mb.namelen;
703 ui_browser__show(&mb.b, self->dso->long_name);
704 ret = ui_browser__run(&mb.b, &es);
705 newtFormDestroy(mb.b.form);
706 newtPopWindow();
707 ui_helpline__pop();
708 return ret;
709}
710
711/* -------------------------------------------------------------------- */
712
595struct hist_browser { 713struct hist_browser {
596 struct ui_browser b; 714 struct ui_browser b;
597 struct hists *hists; 715 struct hists *hists;
@@ -680,7 +798,8 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name)
680 const struct dso *dso; 798 const struct dso *dso;
681 char *options[16]; 799 char *options[16];
682 int nr_options = 0, choice = 0, i, 800 int nr_options = 0, choice = 0, i,
683 annotate = -2, zoom_dso = -2, zoom_thread = -2; 801 annotate = -2, zoom_dso = -2, zoom_thread = -2,
802 browse_map = -2;
684 803
685 if (hist_browser__run(browser, msg, &es)) 804 if (hist_browser__run(browser, msg, &es))
686 break; 805 break;
@@ -771,6 +890,10 @@ do_help:
771 (dso->kernel ? "the Kernel" : dso->short_name)) > 0) 890 (dso->kernel ? "the Kernel" : dso->short_name)) > 0)
772 zoom_dso = nr_options++; 891 zoom_dso = nr_options++;
773 892
893 if (browser->selection->map != NULL &&
894 asprintf(&options[nr_options], "Browse map details") > 0)
895 browse_map = nr_options++;
896
774 options[nr_options++] = (char *)"Exit"; 897 options[nr_options++] = (char *)"Exit";
775 898
776 choice = popup_menu(nr_options, options); 899 choice = popup_menu(nr_options, options);
@@ -800,7 +923,9 @@ do_annotate:
800 continue; 923 continue;
801 924
802 hist_entry__tui_annotate(he); 925 hist_entry__tui_annotate(he);
803 } else if (choice == zoom_dso) { 926 } else if (choice == browse_map)
927 map__browse(browser->selection->map);
928 else if (choice == zoom_dso) {
804zoom_dso: 929zoom_dso:
805 if (dso_filter) { 930 if (dso_filter) {
806 pstack__remove(fstack, &dso_filter); 931 pstack__remove(fstack, &dso_filter);