lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:   Wed, 28 Jun 2017 12:14:19 +0900
From:   Taeung Song <treeze.taeung@...il.com>
To:     Arnaldo Carvalho de Melo <acme@...nel.org>
Cc:     linux-kernel@...r.kernel.org, Milian Wolff <milian.wolff@...b.com>,
        Jiri Olsa <jolsa@...hat.com>,
        Masami Hiramatsu <mhiramat@...nel.org>,
        Adrian Hunter <adrian.hunter@...el.com>,
        Wang Nan <wangnan0@...wei.com>,
        Jin Yao <yao.jin@...ux.intel.com>,
        Andi Kleen <ak@...ux.intel.com>,
        Kim Phillips <kim.phillips@....com>,
        David Ahern <dsahern@...il.com>
Subject: [PATCH/RFC 3/4] perf annotate: Fold or unfold partial disassembly lines on source code view

Suggested-by: Namhyung Kim <namhyung@...nel.org>
Cc: Milian Wolff <milian.wolff@...b.com>
Cc: Jiri Olsa <jolsa@...hat.com>
Cc: Masami Hiramatsu <mhiramat@...nel.org>
Cc: Adrian Hunter <adrian.hunter@...el.com>
Cc: Wang Nan <wangnan0@...wei.com>
Cc: Jin Yao <yao.jin@...ux.intel.com>
Cc: Andi Kleen <ak@...ux.intel.com>
Cc: Kim Phillips <kim.phillips@....com>
Cc: David Ahern <dsahern@...il.com>
Signed-off-by: Taeung Song <treeze.taeung@...il.com>
---
 tools/perf/ui/browser.h           |   1 +
 tools/perf/ui/browsers/annotate.c | 146 ++++++++++++++++++++++++++++++++++++--
 tools/perf/util/annotate.h        |   1 +
 3 files changed, 141 insertions(+), 7 deletions(-)

diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index be3b70e..7637195 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -8,6 +8,7 @@
 #define HE_COLORSET_NORMAL	52
 #define HE_COLORSET_SELECTED	53
 #define HE_COLORSET_JUMP_ARROWS	54
+#define HE_COLORSET_ASM		54
 #define HE_COLORSET_ADDR	55
 #define HE_COLORSET_ROOT	56
 
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 028febe..200ee0c 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -47,11 +47,14 @@ struct annotate_browser {
 	struct ui_browser b, cb;
 	struct rb_root	  entries;
 	struct rb_node	  *curr_hot;
+	struct code_line  *code_line_selection;
 	struct disasm_line  *selection;
 	struct disasm_line  **offsets;
 	struct arch	    *arch;
 	int		    nr_events;
 	u64		    start;
+	int		    code_line_offset;
+	int		    nr_code_entries;
 	int		    nr_asm_entries;
 	int		    nr_entries;
 	int		    max_jump_sources;
@@ -67,6 +70,8 @@ struct annotate_browser {
 	char		    search_bf[128];
 };
 
+static const char *help = "Press 'h' for help on key bindings";
+
 static inline struct browser_disasm_line *disasm_line__browser(struct disasm_line *dl)
 {
 	return (struct browser_disasm_line *)(dl + 1);
@@ -111,10 +116,10 @@ static int annotate_browser__pcnt_width(struct annotate_browser *ab)
 	return w;
 }
 
-static void annotate_code_browser__write(struct ui_browser *browser, void *entry, int row)
+static void annotate_code_browser__write(struct ui_browser *browser,
+					 struct code_line *cl, int row)
 {
 	struct annotate_browser *ab = container_of(browser, struct annotate_browser, cb);
-	struct code_line *cl = list_entry(entry, struct code_line, node);
 	bool current_entry = ui_browser__is_current_entry(browser, row);
 	int i, printed;
 	double percent, max_percent = 0.0;
@@ -147,11 +152,18 @@ static void annotate_code_browser__write(struct ui_browser *browser, void *entry
 
 	SLsmg_write_char(' ');
 
+	ui_browser__printf(browser, "%c ",
+			   cl->nr_matched_dl ? (cl->show_asm ? '-' : '+') : ' ');
 	printed = scnprintf(line, sizeof(line), "%-*d ",
 			    ab->addr_width + 2, cl->line_nr);
 
 	ui_browser__write_nstring(browser, line, printed);
 	ui_browser__write_nstring(browser, cl->line, browser->width);
+
+	if (current_entry) {
+		ab->code_line_selection = cl;
+		ab->code_line_offset = 0;
+	}
 }
 
 static void annotate_browser__write(struct ui_browser *browser, void *entry, int row)
@@ -348,15 +360,108 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
 				 from, to);
 }
 
+static int annotate_code_browser__show_matched_dl(struct ui_browser *browser,
+						   struct code_line *cl, int row)
+{
+	struct annotate_browser *ab = container_of(browser, struct annotate_browser, cb);
+	int i;
+	char line[256];
+
+	for (i = 0; i <  cl->nr_matched_dl; i++) {
+		int k;
+		bool current_entry;
+		struct disasm_line *dl = cl->matched_dl[i];
+		struct browser_disasm_line *bdl = disasm_line__browser(dl);
+
+		ui_browser__gotorc(browser, row, 0);
+		current_entry = ui_browser__is_current_entry(browser, row);
+
+		for (k = 0; k < ab->nr_events; k++) {
+			ui_browser__set_percent_color(browser, bdl->samples[k].percent,
+						      current_entry);
+			if (bdl->samples[k].percent == 0.0) {
+				ui_browser__write_nstring(browser, " ", 7);
+				continue;
+			}
+
+			if (annotate_browser__opts.show_total_period) {
+				ui_browser__printf(browser, "%6" PRIu64 " ",
+						   bdl->samples[k].nr);
+			} else {
+				ui_browser__printf(browser, "%6.2f ",
+						   bdl->samples[k].percent);
+			}
+		}
+
+		SLsmg_write_char(' ');
+
+		if (current_entry) {
+			ab->code_line_selection = cl;
+			ab->code_line_offset = i + 1;
+			ui_browser__set_percent_color(browser, 0, current_entry);
+		} else
+			ui_browser__set_color(browser, HE_COLORSET_NORMAL);
+
+		ui_browser__printf(browser, " %*s - ", ab->addr_width + 4, " ");
+
+		disasm_line__scnprintf(dl, line, sizeof(line),
+				       !annotate_browser__opts.use_offset);
+		if (!current_entry)
+			ui_browser__set_color(browser, HE_COLORSET_ASM);
+		ui_browser__write_nstring(browser, line, browser->width);
+
+		if (++row == browser->rows)
+			break;
+	}
+
+	return row;
+}
+
 static unsigned int annotate_code_browser__refresh(struct ui_browser *browser)
 {
 	struct annotate_browser *ab = container_of(browser, struct annotate_browser, cb);
-	int ret = ui_browser__list_head_refresh(browser);
-	int pcnt_width = annotate_browser__pcnt_width(ab);
+	struct list_head *pos, *head = browser->entries;
+	struct code_line *cl;
+	int row = 0, pcnt_width = annotate_browser__pcnt_width(ab);
+
+	if (browser->top == NULL)
+		browser->top = head->next;
+
+	/* Reset browser->top_idx considering folded partial disassembly lines */
+	if (browser->top_idx > 0) {
+		struct list_head *top = browser->top;
+		int top_idx = 0;
+
+		pos = head->next;
+		while (pos != top) {
+			top_idx++;
+
+			cl = list_entry(pos, struct code_line, node);
+			if (cl->show_asm)
+				top_idx += cl->nr_matched_dl;
+			pos = pos->next;
+		}
+
+		browser->top_idx = top_idx;
+	}
+
+	pos = browser->top;
+	list_for_each_from(pos, head) {
+		cl = list_entry(pos, struct code_line, node);
+
+		ui_browser__gotorc(browser, row, 0);
+		annotate_code_browser__write(browser, cl, row++);
 
+		if (cl->show_asm)
+			row = annotate_code_browser__show_matched_dl(browser, cl, row);
+
+		if (row == browser->rows)
+			break;
+	}
 	ui_browser__set_color(browser, HE_COLORSET_NORMAL);
 	__ui_browser__vline(browser, pcnt_width, 0, browser->height - 1);
-	return ret;
+	ui_helpline__puts(help);
+	return row;
 }
 
 static unsigned int annotate_browser__refresh(struct ui_browser *browser)
@@ -796,6 +901,20 @@ static void annotate_browser__update_addr_width(struct annotate_browser *browser
 		browser->addr_width += browser->jumps_width + 1;
 }
 
+static void annotate_code_browser__update_nr_entries(struct annotate_browser *browser)
+{
+	u32 nr_entries = browser->nr_code_entries;
+	struct ui_browser *cb = &browser->cb;
+	struct list_head *code_lines = cb->entries;
+	struct code_line *cl;
+
+	list_for_each_entry(cl, code_lines, node) {
+		if (cl->show_asm)
+			nr_entries += cl->nr_matched_dl;
+	}
+	ui_browser__update_nr_entries(cb, nr_entries);
+}
+
 static int annotate_code_browser__run(struct annotate_browser *browser,
 				      struct perf_evsel *evsel, int delay_secs)
 {
@@ -818,8 +937,22 @@ static int annotate_code_browser__run(struct annotate_browser *browser,
 		"UP/DOWN/PGUP\n"
 		"PGDN/SPACE    Navigate\n"
 		"q/ESC/CTRL+C  Return to dissembly view\n\n"
+		"ENTER         Toggle showing partial disassembly lines\n"
 		"t             Toggle total period view\n");
 			continue;
+		case K_ENTER:
+			if (browser->code_line_selection == NULL ||
+			    browser->code_line_selection->nr_matched_dl == 0)
+				ui_helpline__puts("No disassembly for the line");
+			else {
+				if (browser->code_line_selection->show_asm)
+					browser->cb.index -= browser->code_line_offset;
+
+				browser->code_line_selection->show_asm =
+					!browser->code_line_selection->show_asm;
+				annotate_code_browser__update_nr_entries(browser);
+			}
+			continue;
 		case 't':
 			annotate_browser__opts.show_total_period =
 				!annotate_browser__opts.show_total_period;
@@ -843,7 +976,6 @@ static int annotate_browser__run(struct annotate_browser *browser,
 	struct rb_node *nd = NULL;
 	struct map_symbol *ms = browser->b.priv;
 	struct symbol *sym = ms->sym;
-	const char *help = "Press 'h' for help on key bindings";
 	int delay_secs = hbt ? hbt->refresh : 0;
 	int key;
 	char title[SYM_TITLE_MAX_SIZE];
@@ -1251,7 +1383,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
 		browser.has_src_code = true;
 		browser.cb.refresh = annotate_code_browser__refresh;
 		browser.cb.seek = ui_browser__list_head_seek;
-		browser.cb.write = annotate_code_browser__write;
 		browser.cb.use_navkeypressed = true;
 		browser.cb.entries = &code->lines;
 
@@ -1262,6 +1393,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
 				browser.cb.width = line_len;
 			browser.cb.nr_entries++;
 		}
+		browser.nr_code_entries = browser.cb.nr_entries;
 	}
 
 	if (annotate_browser__opts.hide_src_code)
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index fb352cf..97f35ba 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -104,6 +104,7 @@ struct code_line {
 	struct list_head    node;
 	int		    line_nr;
 	char		    *line;
+	bool		    show_asm;
 	int		    nr_matched_dl;
 	struct disasm_line  **matched_dl;
 	struct disasm_line_samples *samples_sum;
-- 
2.7.4

Powered by blists - more mailing lists