From 58e817d997d162682717dcaae39393dcadf5f296 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 23 Feb 2012 17:46:20 +0900 Subject: perf annotate: Print asm code as blue when source code is displayed Print unselected asm code lines as blue. This is what we do now for --stdio. Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1329986784-4916-2-git-send-email-namhyung.kim@lge.com Signed-off-by: Namhyung Kim Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 295a9c93f945..76caae95df39 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -69,14 +69,17 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro if (!self->navkeypressed) width += 1; + if (!ab->hide_src_code && ol->offset != -1) + if (!current_entry || (self->use_navkeypressed && + !self->navkeypressed)) + ui_browser__set_color(self, HE_COLORSET_CODE); + if (!*ol->line) slsmg_write_nstring(" ", width - 18); else slsmg_write_nstring(ol->line, width - 18); - if (!current_entry) - ui_browser__set_color(self, HE_COLORSET_CODE); - else + if (current_entry) ab->selection = ol; } -- cgit v1.2.3 From ef7c537221160c285704997a913fb66ddc1fe6bc Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 23 Feb 2012 17:46:21 +0900 Subject: perf annotate: Handle lower case key code in annotate_browser__run() Accepting upper case character only is unconvenient since it requires SHIFT key too. Why not change to it accept a simple key stroke? Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1329986784-4916-3-git-send-email-namhyung.kim@lge.com Signed-off-by: Namhyung Kim Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 76caae95df39..374d3bc570b2 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -287,9 +287,11 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, nd = self->curr_hot; break; case 'H': + case 'h': nd = self->curr_hot; break; case 'S': + case 's': if (annotate_browser__toggle_source(self)) ui_helpline__puts(help); continue; -- cgit v1.2.3 From 142cfbd0a0353bbcf4ce62f1d4b4ffaa5fe228f9 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 23 Feb 2012 17:46:22 +0900 Subject: perf annotate: Restore title when came back to original symbol On tui annotation, the title was set to name of the target symbol if user selects the target. However it remained after returning to original symbol from the target. Fix it. Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1329986784-4916-4-git-send-email-namhyung.kim@lge.com Signed-off-by: Namhyung Kim Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 374d3bc570b2..e73357770d5d 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -343,6 +343,7 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, pthread_mutex_unlock(¬es->lock); symbol__tui_annotate(target, ms->map, evidx, timer, arg, delay_secs); + ui_browser__show_title(&self->b, sym->name); } continue; case K_LEFT: -- cgit v1.2.3 From 824ac0e9838aadf5a398850c80ec2a43b9d0ca49 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 23 Feb 2012 17:46:23 +0900 Subject: perf annotate: Fix help string on tui Separate multiple binding using /, capitalize descriptions, add missing key binding. Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1329986784-4916-5-git-send-email-namhyung.kim@lge.com Signed-off-by: Namhyung Kim Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index e73357770d5d..57a4c6ef3fd2 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -233,9 +233,9 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, struct rb_node *nd = NULL; struct map_symbol *ms = self->b.priv; struct symbol *sym = ms->sym; - const char *help = "<-, ESC: exit, TAB/shift+TAB: cycle hottest lines, " - "H: Hottest, -> Line action, S -> Toggle source " - "code view"; + const char *help = "<-/ESC: Exit, TAB/shift+TAB: Cycle hot lines, " + "H: Go to hottest line, ->/ENTER: Line action, " + "S: Toggle source code view"; int key; if (ui_browser__show(&self->b, sym->name, help) < 0) -- cgit v1.2.3 From 058b4cc9af574c072988a38a7a5ee93df881e5aa Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 2 Apr 2012 12:59:01 -0300 Subject: perf annotate: Allow printing objdump line addr in different color And by default use "magenta" for it. Both the --stdio and --tui routines follow the same semantics. Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ede5zkaf7oorwvbqjezb4yg4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 57a4c6ef3fd2..7ac7dd04d5c6 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -16,6 +16,7 @@ struct annotate_browser { struct rb_root entries; struct rb_node *curr_hot; struct objdump_line *selection; + u64 start; int nr_asm_entries; int nr_entries; bool hide_src_code; @@ -51,6 +52,9 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro struct annotate_browser *ab = container_of(self, struct annotate_browser, b); struct objdump_line *ol = list_entry(entry, struct objdump_line, node); bool current_entry = ui_browser__is_current_entry(self, row); + bool change_color = (!ab->hide_src_code && + (!current_entry || (self->use_navkeypressed && + !self->navkeypressed))); int width = self->width; if (ol->offset != -1) { @@ -69,15 +73,26 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro if (!self->navkeypressed) width += 1; - if (!ab->hide_src_code && ol->offset != -1) - if (!current_entry || (self->use_navkeypressed && - !self->navkeypressed)) - ui_browser__set_color(self, HE_COLORSET_CODE); + if (ol->offset != -1 && change_color) + ui_browser__set_color(self, HE_COLORSET_CODE); if (!*ol->line) slsmg_write_nstring(" ", width - 18); - else + else if (ol->offset == -1) slsmg_write_nstring(ol->line, width - 18); + else { + char bf[64]; + u64 addr = ab->start + ol->offset; + int printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr); + int color = -1; + + if (change_color) + color = ui_browser__set_color(self, HE_COLORSET_ADDR); + slsmg_write_nstring(bf, printed); + if (change_color) + ui_browser__set_color(self, color); + slsmg_write_nstring(ol->line, width - 18 - printed); + } if (current_entry) ab->selection = ol; @@ -406,6 +421,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, ui_helpline__push("Press <- or ESC to exit"); notes = symbol__annotation(sym); + browser.start = map__rip_2objdump(map, sym->start); list_for_each_entry(pos, ¬es->src->source, node) { struct objdump_line_rb_node *rbpos; -- cgit v1.2.3 From e235f3f3bf238eb092ad2fe7c35c6d7fd5dc2aeb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 2 Apr 2012 13:21:55 -0300 Subject: perf ui annotate browser: Allow toggling addr offset view The lines in objdump have this format: ffffffff8126543f: jne ffffffff81265494 <__list_del_entry+0x84> ffffffff81265494: mov %rdi,%rcx Since we now have objdump_line allowing tools to print the offset independently from the rest of the line, allow toggling a view where just offsets from the start of the function are shown: 2f: jne ffffffff81265494 <__list_del_entry+0x84> 84: mov %rdi,%rcx The offset view will be the default as soon as operations that deal with offsets in a function are handled accodringly, i.e. in offset view the above will become: 2f: jne __list_del_entry+0x84 84: mov %rdi,%rcx And then a follow up patch will allow navigating thru jumps, just like we handle callq instructions. Suggested-by: Linus Torvalds Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-4zpgimmz8xv7b5c920el7s45@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 7ac7dd04d5c6..5cf9b78682aa 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -20,6 +20,7 @@ struct annotate_browser { int nr_asm_entries; int nr_entries; bool hide_src_code; + bool use_offset; }; struct objdump_line_rb_node { @@ -82,10 +83,13 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro slsmg_write_nstring(ol->line, width - 18); else { char bf[64]; - u64 addr = ab->start + ol->offset; - int printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr); - int color = -1; + u64 addr = ol->offset; + int printed, color = -1; + if (!ab->use_offset) + addr += ab->start; + + printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr); if (change_color) color = ui_browser__set_color(self, HE_COLORSET_ADDR); slsmg_write_nstring(bf, printed); @@ -250,6 +254,7 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, struct symbol *sym = ms->sym; const char *help = "<-/ESC: Exit, TAB/shift+TAB: Cycle hot lines, " "H: Go to hottest line, ->/ENTER: Line action, " + "O: Toggle offset view, " "S: Toggle source code view"; int key; @@ -310,6 +315,10 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, if (annotate_browser__toggle_source(self)) ui_helpline__puts(help); continue; + case 'O': + case 'o': + self->use_offset = !self->use_offset; + continue; case K_ENTER: case K_RIGHT: if (self->selection == NULL) { -- cgit v1.2.3 From 6052170249d6696bc297d61e83b78fcfe64532d8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 2 Apr 2012 13:58:33 -0300 Subject: perf ui annotate browser: Move callq handling to separate function So that we can as well handle jumps. Later we'll move this to a proper intruction table, etc. Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-i98elvmix2cw6t8stu1iagfd@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 94 +++++++++++++++++----------------- 1 file changed, 48 insertions(+), 46 deletions(-) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 5cf9b78682aa..dbf8d3f6b567 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -245,6 +245,50 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser) return true; } +static bool annotate_browser__callq(struct annotate_browser *browser, + int evidx, void (*timer)(void *arg), + void *arg, int delay_secs) +{ + struct map_symbol *ms = browser->b.priv; + struct symbol *sym = ms->sym; + struct annotation *notes; + struct symbol *target; + char *s = strstr(browser->selection->line, "callq "); + u64 ip; + + if (s == NULL) + return false; + + s = strchr(s, ' '); + if (s++ == NULL) { + ui_helpline__puts("Invallid callq instruction."); + return true; + } + + ip = strtoull(s, NULL, 16); + ip = ms->map->map_ip(ms->map, ip); + target = map__find_symbol(ms->map, ip, NULL); + if (target == NULL) { + ui_helpline__puts("The called function was not found."); + return true; + } + + notes = symbol__annotation(target); + pthread_mutex_lock(¬es->lock); + + if (notes->src == NULL && symbol__alloc_hist(target) < 0) { + pthread_mutex_unlock(¬es->lock); + ui__warning("Not enough memory for annotating '%s' symbol!\n", + target->name); + return true; + } + + pthread_mutex_unlock(¬es->lock); + symbol__tui_annotate(target, ms->map, evidx, timer, arg, delay_secs); + ui_browser__show_title(&browser->b, sym->name); + return true; +} + static int annotate_browser__run(struct annotate_browser *self, int evidx, void(*timer)(void *arg), void *arg, int delay_secs) @@ -321,54 +365,12 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, continue; case K_ENTER: case K_RIGHT: - if (self->selection == NULL) { + if (self->selection == NULL) ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); - continue; - } - - if (self->selection->offset == -1) { + else if (self->selection->offset == -1) ui_helpline__puts("Actions are only available for assembly lines."); - continue; - } else { - char *s = strstr(self->selection->line, "callq "); - struct annotation *notes; - struct symbol *target; - u64 ip; - - if (s == NULL) { - ui_helpline__puts("Actions are only available for the 'callq' instruction."); - continue; - } - - s = strchr(s, ' '); - if (s++ == NULL) { - ui_helpline__puts("Invallid callq instruction."); - continue; - } - - ip = strtoull(s, NULL, 16); - ip = ms->map->map_ip(ms->map, ip); - target = map__find_symbol(ms->map, ip, NULL); - if (target == NULL) { - ui_helpline__puts("The called function was not found."); - continue; - } - - notes = symbol__annotation(target); - pthread_mutex_lock(¬es->lock); - - if (notes->src == NULL && symbol__alloc_hist(target) < 0) { - pthread_mutex_unlock(¬es->lock); - ui__warning("Not enough memory for annotating '%s' symbol!\n", - target->name); - continue; - } - - pthread_mutex_unlock(¬es->lock); - symbol__tui_annotate(target, ms->map, evidx, - timer, arg, delay_secs); - ui_browser__show_title(&self->b, sym->name); - } + else if (!annotate_browser__callq(self, evidx, timer, arg, delay_secs)) + ui_helpline__puts("Actions are only available for the 'callq' instruction."); continue; case K_LEFT: case K_ESC: -- cgit v1.2.3 From b0ffb2c48a924fdacb65a2320554ddc779a65eb2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Apr 2012 15:32:45 -0300 Subject: perf ui annotate browser: Add list based search for addr offset From the hit sorted rb_tree, so that we can use it in the upcoming jump instruction support. Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-44a7kl2atf9jxlg9npmotzdg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index dbf8d3f6b567..c52543c69ae0 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -157,17 +157,13 @@ static void objdump__insert_line(struct rb_root *self, } static void annotate_browser__set_top(struct annotate_browser *self, - struct rb_node *nd) + struct objdump_line *pos, u32 idx) { - struct objdump_line_rb_node *rbpos; - struct objdump_line *pos; unsigned back; ui_browser__refresh_dimensions(&self->b); back = self->b.height / 2; - rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node); - pos = ((struct objdump_line *)rbpos) - 1; - self->b.top_idx = self->b.index = rbpos->idx; + self->b.top_idx = self->b.index = idx; while (self->b.top_idx != 0 && back != 0) { pos = list_entry(pos->node.prev, struct objdump_line, node); @@ -177,7 +173,18 @@ static void annotate_browser__set_top(struct annotate_browser *self, } self->b.top = pos; - self->curr_hot = nd; +} + +static void annotate_browser__set_rb_top(struct annotate_browser *browser, + struct rb_node *nd) +{ + struct objdump_line_rb_node *rbpos; + struct objdump_line *pos; + + rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node); + pos = ((struct objdump_line *)rbpos) - 1; + annotate_browser__set_top(browser, pos, rbpos->idx); + browser->curr_hot = nd; } static void annotate_browser__calc_percent(struct annotate_browser *browser, @@ -308,7 +315,7 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, annotate_browser__calc_percent(self, evidx); if (self->curr_hot) - annotate_browser__set_top(self, self->curr_hot); + annotate_browser__set_rb_top(self, self->curr_hot); nd = self->curr_hot; @@ -382,7 +389,7 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, } if (nd != NULL) - annotate_browser__set_top(self, nd); + annotate_browser__set_rb_top(self, nd); } out: ui_browser__hide(&self->b); -- cgit v1.2.3 From 08be4eeda40ea813fa326036fdaf8fa7667eb021 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Apr 2012 21:35:35 -0300 Subject: perf annotate browser: Initial support for navigating jump instructions Now it is possible to press ENTER or -> (right arrow) on jump instructions to navigate to the offset it points to. More work needed to support <- to go back, i.e. a jump history. This is done just like the callq case, i.e. parsing objdump output lines, but should move to use Masami's disassembler at some point. Suggested-by: Linus Torvalds Cc: David Ahern Cc: Frederic Weisbecker Cc: Masami Hiramatsu Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-706qqe2xibeiocuabp39mby7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 63 ++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index c52543c69ae0..752d8d0e480c 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -168,6 +168,9 @@ static void annotate_browser__set_top(struct annotate_browser *self, while (self->b.top_idx != 0 && back != 0) { pos = list_entry(pos->node.prev, struct objdump_line, node); + if (objdump_line__filter(&self->b, &pos->node)) + continue; + --self->b.top_idx; --back; } @@ -296,6 +299,61 @@ static bool annotate_browser__callq(struct annotate_browser *browser, return true; } +static struct objdump_line * + annotate_browser__find_offset(struct annotate_browser *browser, + s64 offset, s64 *idx) +{ + struct map_symbol *ms = browser->b.priv; + struct symbol *sym = ms->sym; + struct annotation *notes = symbol__annotation(sym); + struct objdump_line *pos; + + *idx = 0; + list_for_each_entry(pos, ¬es->src->source, node) { + if (pos->offset == offset) + return pos; + if (!objdump_line__filter(&browser->b, &pos->node)) + ++*idx; + } + + return NULL; +} + +static bool annotate_browser__jump(struct annotate_browser *browser) +{ + const char *jumps[] = { "je ", "jne ", "ja ", "jmpq ", "js ", "jmp ", NULL }; + struct objdump_line *line; + s64 idx, offset; + char *s = NULL; + int i = 0; + + while (jumps[i]) { + s = strstr(browser->selection->line, jumps[i++]); + if (s) + break; + } + + if (s == NULL) + return false; + + s = strchr(s, '+'); + if (s++ == NULL) { + ui_helpline__puts("Invallid jump instruction."); + return true; + } + + offset = strtoll(s, NULL, 16); + line = annotate_browser__find_offset(browser, offset, &idx); + if (line == NULL) { + ui_helpline__puts("Invallid jump offset"); + return true; + } + + annotate_browser__set_top(browser, line, idx); + + return true; +} + static int annotate_browser__run(struct annotate_browser *self, int evidx, void(*timer)(void *arg), void *arg, int delay_secs) @@ -376,8 +434,9 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); else if (self->selection->offset == -1) ui_helpline__puts("Actions are only available for assembly lines."); - else if (!annotate_browser__callq(self, evidx, timer, arg, delay_secs)) - ui_helpline__puts("Actions are only available for the 'callq' instruction."); + else if (!(annotate_browser__jump(self) || + annotate_browser__callq(self, evidx, timer, arg, delay_secs))) + ui_helpline__puts("Actions are only available for the 'callq' and jump instructions."); continue; case K_LEFT: case K_ESC: -- cgit v1.2.3 From d3d1f61acf62204bb7b2b4509329247bffaedd7c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 7 Apr 2012 17:10:30 -0300 Subject: perf annotate browser: string search: /?n Using the same keystrokes as vim: / = search forward n = search next forward/backwards ? = search backwards Still needs to continue from start/end when not found, use HOME + / or END + ? for now. At some point we need a keybindings file to support ones favourite mode, erm, like EMACS, etc. Also we now need a 'h' window with all these keybindings. Requested-by: Andi Kleen Cc: Andi Kleen Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-rv30xj2i258n0gwkzlu0c0bc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 149 ++++++++++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 1 deletion(-) (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 752d8d0e480c..c2cfeed3af19 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -21,6 +21,8 @@ struct annotate_browser { int nr_entries; bool hide_src_code; bool use_offset; + bool searching_backwards; + char search_bf[128]; }; struct objdump_line_rb_node { @@ -176,6 +178,7 @@ static void annotate_browser__set_top(struct annotate_browser *self, } self->b.top = pos; + self->b.navkeypressed = true; } static void annotate_browser__set_rb_top(struct annotate_browser *browser, @@ -354,6 +357,132 @@ static bool annotate_browser__jump(struct annotate_browser *browser) return true; } +static struct objdump_line * + annotate_browser__find_string(struct annotate_browser *browser, + char *s, s64 *idx) +{ + struct map_symbol *ms = browser->b.priv; + struct symbol *sym = ms->sym; + struct annotation *notes = symbol__annotation(sym); + struct objdump_line *pos = browser->selection; + + *idx = browser->b.index; + list_for_each_entry_continue(pos, ¬es->src->source, node) { + if (objdump_line__filter(&browser->b, &pos->node)) + continue; + + ++*idx; + + if (pos->line && strstr(pos->line, s) != NULL) + return pos; + } + + return NULL; +} + +static bool __annotate_browser__search(struct annotate_browser *browser) +{ + struct objdump_line *line; + s64 idx; + + line = annotate_browser__find_string(browser, browser->search_bf, &idx); + if (line == NULL) { + ui_helpline__puts("String not found!"); + return false; + } + + annotate_browser__set_top(browser, line, idx); + browser->searching_backwards = false; + return true; +} + +static struct objdump_line * + annotate_browser__find_string_reverse(struct annotate_browser *browser, + char *s, s64 *idx) +{ + struct map_symbol *ms = browser->b.priv; + struct symbol *sym = ms->sym; + struct annotation *notes = symbol__annotation(sym); + struct objdump_line *pos = browser->selection; + + *idx = browser->b.index; + list_for_each_entry_continue_reverse(pos, ¬es->src->source, node) { + if (objdump_line__filter(&browser->b, &pos->node)) + continue; + + --*idx; + + if (pos->line && strstr(pos->line, s) != NULL) + return pos; + } + + return NULL; +} + +static bool __annotate_browser__search_reverse(struct annotate_browser *browser) +{ + struct objdump_line *line; + s64 idx; + + line = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx); + if (line == NULL) { + ui_helpline__puts("String not found!"); + return false; + } + + annotate_browser__set_top(browser, line, idx); + browser->searching_backwards = true; + return true; +} + +static bool annotate_browser__search_window(struct annotate_browser *browser, + int delay_secs) +{ + if (ui_browser__input_window("Search", "String: ", browser->search_bf, + "ENTER: OK, ESC: Cancel", + delay_secs * 2) != K_ENTER || + !*browser->search_bf) + return false; + + return true; +} + +static bool annotate_browser__search(struct annotate_browser *browser, int delay_secs) +{ + if (annotate_browser__search_window(browser, delay_secs)) + return __annotate_browser__search(browser); + + return false; +} + +static bool annotate_browser__continue_search(struct annotate_browser *browser, + int delay_secs) +{ + if (!*browser->search_bf) + return annotate_browser__search(browser, delay_secs); + + return __annotate_browser__search(browser); +} + +static bool annotate_browser__search_reverse(struct annotate_browser *browser, + int delay_secs) +{ + if (annotate_browser__search_window(browser, delay_secs)) + return __annotate_browser__search_reverse(browser); + + return false; +} + +static +bool annotate_browser__continue_search_reverse(struct annotate_browser *browser, + int delay_secs) +{ + if (!*browser->search_bf) + return annotate_browser__search_reverse(browser, delay_secs); + + return __annotate_browser__search_reverse(browser); +} + static int annotate_browser__run(struct annotate_browser *self, int evidx, void(*timer)(void *arg), void *arg, int delay_secs) @@ -372,8 +501,10 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, annotate_browser__calc_percent(self, evidx); - if (self->curr_hot) + if (self->curr_hot) { annotate_browser__set_rb_top(self, self->curr_hot); + self->b.navkeypressed = false; + } nd = self->curr_hot; @@ -428,6 +559,22 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, case 'o': self->use_offset = !self->use_offset; continue; + case '/': + if (annotate_browser__search(self, delay_secs)) { +show_help: + ui_helpline__puts(help); + } + continue; + case 'n': + if (self->searching_backwards ? + annotate_browser__continue_search_reverse(self, delay_secs) : + annotate_browser__continue_search(self, delay_secs)) + goto show_help; + continue; + case '?': + if (annotate_browser__search_reverse(self, delay_secs)) + goto show_help; + continue; case K_ENTER: case K_RIGHT: if (self->selection == NULL) -- cgit v1.2.3 From aca7a94d6a59d6bf2600768e752f971c6cc0ab57 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 4 Apr 2012 00:14:26 -0700 Subject: perf tools: Move UI bits to tools/perf/ui directory Move those files to new directory in order to be prepared to further UI work. Makefile and header file pathes are adjusted accordingly. Signed-off-by: Namhyung Kim Suggested-by: Arnaldo Carvalho de Melo Acked-by: Pekka Enberg Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra --- tools/perf/util/ui/browsers/annotate.c | 673 --------------------------------- 1 file changed, 673 deletions(-) delete mode 100644 tools/perf/util/ui/browsers/annotate.c (limited to 'tools/perf/util/ui/browsers/annotate.c') diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c deleted file mode 100644 index c2cfeed3af19..000000000000 --- a/tools/perf/util/ui/browsers/annotate.c +++ /dev/null @@ -1,673 +0,0 @@ -#include "../../util.h" -#include "../browser.h" -#include "../helpline.h" -#include "../libslang.h" -#include "../ui.h" -#include "../util.h" -#include "../../annotate.h" -#include "../../hist.h" -#include "../../sort.h" -#include "../../symbol.h" -#include -#include - -struct annotate_browser { - struct ui_browser b; - struct rb_root entries; - struct rb_node *curr_hot; - struct objdump_line *selection; - u64 start; - int nr_asm_entries; - int nr_entries; - bool hide_src_code; - bool use_offset; - bool searching_backwards; - char search_bf[128]; -}; - -struct objdump_line_rb_node { - struct rb_node rb_node; - double percent; - u32 idx; - int idx_asm; -}; - -static inline -struct objdump_line_rb_node *objdump_line__rb(struct objdump_line *self) -{ - return (struct objdump_line_rb_node *)(self + 1); -} - -static bool objdump_line__filter(struct ui_browser *browser, void *entry) -{ - struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); - - if (ab->hide_src_code) { - struct objdump_line *ol = list_entry(entry, struct objdump_line, node); - return ol->offset == -1; - } - - return false; -} - -static void annotate_browser__write(struct ui_browser *self, void *entry, int row) -{ - struct annotate_browser *ab = container_of(self, struct annotate_browser, b); - struct objdump_line *ol = list_entry(entry, struct objdump_line, node); - bool current_entry = ui_browser__is_current_entry(self, row); - bool change_color = (!ab->hide_src_code && - (!current_entry || (self->use_navkeypressed && - !self->navkeypressed))); - int width = self->width; - - if (ol->offset != -1) { - struct objdump_line_rb_node *olrb = objdump_line__rb(ol); - ui_browser__set_percent_color(self, olrb->percent, current_entry); - slsmg_printf(" %7.2f ", olrb->percent); - } else { - ui_browser__set_percent_color(self, 0, current_entry); - slsmg_write_nstring(" ", 9); - } - - SLsmg_write_char(':'); - slsmg_write_nstring(" ", 8); - - /* The scroll bar isn't being used */ - if (!self->navkeypressed) - width += 1; - - if (ol->offset != -1 && change_color) - ui_browser__set_color(self, HE_COLORSET_CODE); - - if (!*ol->line) - slsmg_write_nstring(" ", width - 18); - else if (ol->offset == -1) - slsmg_write_nstring(ol->line, width - 18); - else { - char bf[64]; - u64 addr = ol->offset; - int printed, color = -1; - - if (!ab->use_offset) - addr += ab->start; - - printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr); - if (change_color) - color = ui_browser__set_color(self, HE_COLORSET_ADDR); - slsmg_write_nstring(bf, printed); - if (change_color) - ui_browser__set_color(self, color); - slsmg_write_nstring(ol->line, width - 18 - printed); - } - - if (current_entry) - ab->selection = ol; -} - -static double objdump_line__calc_percent(struct objdump_line *self, - struct symbol *sym, int evidx) -{ - double percent = 0.0; - - if (self->offset != -1) { - int len = sym->end - sym->start; - unsigned int hits = 0; - struct annotation *notes = symbol__annotation(sym); - struct source_line *src_line = notes->src->lines; - struct sym_hist *h = annotation__histogram(notes, evidx); - s64 offset = self->offset; - struct objdump_line *next; - - next = objdump__get_next_ip_line(¬es->src->source, self); - while (offset < (s64)len && - (next == NULL || offset < next->offset)) { - if (src_line) { - percent += src_line[offset].percent; - } else - hits += h->addr[offset]; - - ++offset; - } - /* - * If the percentage wasn't already calculated in - * symbol__get_source_line, do it now: - */ - if (src_line == NULL && h->sum) - percent = 100.0 * hits / h->sum; - } - - return percent; -} - -static void objdump__insert_line(struct rb_root *self, - struct objdump_line_rb_node *line) -{ - struct rb_node **p = &self->rb_node; - struct rb_node *parent = NULL; - struct objdump_line_rb_node *l; - - while (*p != NULL) { - parent = *p; - l = rb_entry(parent, struct objdump_line_rb_node, rb_node); - if (line->percent < l->percent) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } - rb_link_node(&line->rb_node, parent, p); - rb_insert_color(&line->rb_node, self); -} - -static void annotate_browser__set_top(struct annotate_browser *self, - struct objdump_line *pos, u32 idx) -{ - unsigned back; - - ui_browser__refresh_dimensions(&self->b); - back = self->b.height / 2; - self->b.top_idx = self->b.index = idx; - - while (self->b.top_idx != 0 && back != 0) { - pos = list_entry(pos->node.prev, struct objdump_line, node); - - if (objdump_line__filter(&self->b, &pos->node)) - continue; - - --self->b.top_idx; - --back; - } - - self->b.top = pos; - self->b.navkeypressed = true; -} - -static void annotate_browser__set_rb_top(struct annotate_browser *browser, - struct rb_node *nd) -{ - struct objdump_line_rb_node *rbpos; - struct objdump_line *pos; - - rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node); - pos = ((struct objdump_line *)rbpos) - 1; - annotate_browser__set_top(browser, pos, rbpos->idx); - browser->curr_hot = nd; -} - -static void annotate_browser__calc_percent(struct annotate_browser *browser, - int evidx) -{ - struct map_symbol *ms = browser->b.priv; - struct symbol *sym = ms->sym; - struct annotation *notes = symbol__annotation(sym); - struct objdump_line *pos; - - browser->entries = RB_ROOT; - - pthread_mutex_lock(¬es->lock); - - list_for_each_entry(pos, ¬es->src->source, node) { - struct objdump_line_rb_node *rbpos = objdump_line__rb(pos); - rbpos->percent = objdump_line__calc_percent(pos, sym, evidx); - if (rbpos->percent < 0.01) { - RB_CLEAR_NODE(&rbpos->rb_node); - continue; - } - objdump__insert_line(&browser->entries, rbpos); - } - pthread_mutex_unlock(¬es->lock); - - browser->curr_hot = rb_last(&browser->entries); -} - -static bool annotate_browser__toggle_source(struct annotate_browser *browser) -{ - struct objdump_line *ol; - struct objdump_line_rb_node *olrb; - off_t offset = browser->b.index - browser->b.top_idx; - - browser->b.seek(&browser->b, offset, SEEK_CUR); - ol = list_entry(browser->b.top, struct objdump_line, node); - olrb = objdump_line__rb(ol); - - if (browser->hide_src_code) { - if (olrb->idx_asm < offset) - offset = olrb->idx; - - browser->b.nr_entries = browser->nr_entries; - browser->hide_src_code = false; - browser->b.seek(&browser->b, -offset, SEEK_CUR); - browser->b.top_idx = olrb->idx - offset; - browser->b.index = olrb->idx; - } else { - if (olrb->idx_asm < 0) { - ui_helpline__puts("Only available for assembly lines."); - browser->b.seek(&browser->b, -offset, SEEK_CUR); - return false; - } - - if (olrb->idx_asm < offset) - offset = olrb->idx_asm; - - browser->b.nr_entries = browser->nr_asm_entries; - browser->hide_src_code = true; - browser->b.seek(&browser->b, -offset, SEEK_CUR); - browser->b.top_idx = olrb->idx_asm - offset; - browser->b.index = olrb->idx_asm; - } - - return true; -} - -static bool annotate_browser__callq(struct annotate_browser *browser, - int evidx, void (*timer)(void *arg), - void *arg, int delay_secs) -{ - struct map_symbol *ms = browser->b.priv; - struct symbol *sym = ms->sym; - struct annotation *notes; - struct symbol *target; - char *s = strstr(browser->selection->line, "callq "); - u64 ip; - - if (s == NULL) - return false; - - s = strchr(s, ' '); - if (s++ == NULL) { - ui_helpline__puts("Invallid callq instruction."); - return true; - } - - ip = strtoull(s, NULL, 16); - ip = ms->map->map_ip(ms->map, ip); - target = map__find_symbol(ms->map, ip, NULL); - if (target == NULL) { - ui_helpline__puts("The called function was not found."); - return true; - } - - notes = symbol__annotation(target); - pthread_mutex_lock(¬es->lock); - - if (notes->src == NULL && symbol__alloc_hist(target) < 0) { - pthread_mutex_unlock(¬es->lock); - ui__warning("Not enough memory for annotating '%s' symbol!\n", - target->name); - return true; - } - - pthread_mutex_unlock(¬es->lock); - symbol__tui_annotate(target, ms->map, evidx, timer, arg, delay_secs); - ui_browser__show_title(&browser->b, sym->name); - return true; -} - -static struct objdump_line * - annotate_browser__find_offset(struct annotate_browser *browser, - s64 offset, s64 *idx) -{ - struct map_symbol *ms = browser->b.priv; - struct symbol *sym = ms->sym; - struct annotation *notes = symbol__annotation(sym); - struct objdump_line *pos; - - *idx = 0; - list_for_each_entry(pos, ¬es->src->source, node) { - if (pos->offset == offset) - return pos; - if (!objdump_line__filter(&browser->b, &pos->node)) - ++*idx; - } - - return NULL; -} - -static bool annotate_browser__jump(struct annotate_browser *browser) -{ - const char *jumps[] = { "je ", "jne ", "ja ", "jmpq ", "js ", "jmp ", NULL }; - struct objdump_line *line; - s64 idx, offset; - char *s = NULL; - int i = 0; - - while (jumps[i]) { - s = strstr(browser->selection->line, jumps[i++]); - if (s) - break; - } - - if (s == NULL) - return false; - - s = strchr(s, '+'); - if (s++ == NULL) { - ui_helpline__puts("Invallid jump instruction."); - return true; - } - - offset = strtoll(s, NULL, 16); - line = annotate_browser__find_offset(browser, offset, &idx); - if (line == NULL) { - ui_helpline__puts("Invallid jump offset"); - return true; - } - - annotate_browser__set_top(browser, line, idx); - - return true; -} - -static struct objdump_line * - annotate_browser__find_string(struct annotate_browser *browser, - char *s, s64 *idx) -{ - struct map_symbol *ms = browser->b.priv; - struct symbol *sym = ms->sym; - struct annotation *notes = symbol__annotation(sym); - struct objdump_line *pos = browser->selection; - - *idx = browser->b.index; - list_for_each_entry_continue(pos, ¬es->src->source, node) { - if (objdump_line__filter(&browser->b, &pos->node)) - continue; - - ++*idx; - - if (pos->line && strstr(pos->line, s) != NULL) - return pos; - } - - return NULL; -} - -static bool __annotate_browser__search(struct annotate_browser *browser) -{ - struct objdump_line *line; - s64 idx; - - line = annotate_browser__find_string(browser, browser->search_bf, &idx); - if (line == NULL) { - ui_helpline__puts("String not found!"); - return false; - } - - annotate_browser__set_top(browser, line, idx); - browser->searching_backwards = false; - return true; -} - -static struct objdump_line * - annotate_browser__find_string_reverse(struct annotate_browser *browser, - char *s, s64 *idx) -{ - struct map_symbol *ms = browser->b.priv; - struct symbol *sym = ms->sym; - struct annotation *notes = symbol__annotation(sym); - struct objdump_line *pos = browser->selection; - - *idx = browser->b.index; - list_for_each_entry_continue_reverse(pos, ¬es->src->source, node) { - if (objdump_line__filter(&browser->b, &pos->node)) - continue; - - --*idx; - - if (pos->line && strstr(pos->line, s) != NULL) - return pos; - } - - return NULL; -} - -static bool __annotate_browser__search_reverse(struct annotate_browser *browser) -{ - struct objdump_line *line; - s64 idx; - - line = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx); - if (line == NULL) { - ui_helpline__puts("String not found!"); - return false; - } - - annotate_browser__set_top(browser, line, idx); - browser->searching_backwards = true; - return true; -} - -static bool annotate_browser__search_window(struct annotate_browser *browser, - int delay_secs) -{ - if (ui_browser__input_window("Search", "String: ", browser->search_bf, - "ENTER: OK, ESC: Cancel", - delay_secs * 2) != K_ENTER || - !*browser->search_bf) - return false; - - return true; -} - -static bool annotate_browser__search(struct annotate_browser *browser, int delay_secs) -{ - if (annotate_browser__search_window(browser, delay_secs)) - return __annotate_browser__search(browser); - - return false; -} - -static bool annotate_browser__continue_search(struct annotate_browser *browser, - int delay_secs) -{ - if (!*browser->search_bf) - return annotate_browser__search(browser, delay_secs); - - return __annotate_browser__search(browser); -} - -static bool annotate_browser__search_reverse(struct annotate_browser *browser, - int delay_secs) -{ - if (annotate_browser__search_window(browser, delay_secs)) - return __annotate_browser__search_reverse(browser); - - return false; -} - -static -bool annotate_browser__continue_search_reverse(struct annotate_browser *browser, - int delay_secs) -{ - if (!*browser->search_bf) - return annotate_browser__search_reverse(browser, delay_secs); - - return __annotate_browser__search_reverse(browser); -} - -static int annotate_browser__run(struct annotate_browser *self, int evidx, - void(*timer)(void *arg), - void *arg, int delay_secs) -{ - struct rb_node *nd = NULL; - struct map_symbol *ms = self->b.priv; - struct symbol *sym = ms->sym; - const char *help = "<-/ESC: Exit, TAB/shift+TAB: Cycle hot lines, " - "H: Go to hottest line, ->/ENTER: Line action, " - "O: Toggle offset view, " - "S: Toggle source code view"; - int key; - - if (ui_browser__show(&self->b, sym->name, help) < 0) - return -1; - - annotate_browser__calc_percent(self, evidx); - - if (self->curr_hot) { - annotate_browser__set_rb_top(self, self->curr_hot); - self->b.navkeypressed = false; - } - - nd = self->curr_hot; - - while (1) { - key = ui_browser__run(&self->b, delay_secs); - - if (delay_secs != 0) { - annotate_browser__calc_percent(self, evidx); - /* - * Current line focus got out of the list of most active - * lines, NULL it so that if TAB|UNTAB is pressed, we - * move to curr_hot (current hottest line). - */ - if (nd != NULL && RB_EMPTY_NODE(nd)) - nd = NULL; - } - - switch (key) { - case K_TIMER: - if (timer != NULL) - timer(arg); - - if (delay_secs != 0) - symbol__annotate_decay_histogram(sym, evidx); - continue; - case K_TAB: - if (nd != NULL) { - nd = rb_prev(nd); - if (nd == NULL) - nd = rb_last(&self->entries); - } else - nd = self->curr_hot; - break; - case K_UNTAB: - if (nd != NULL) - nd = rb_next(nd); - if (nd == NULL) - nd = rb_first(&self->entries); - else - nd = self->curr_hot; - break; - case 'H': - case 'h': - nd = self->curr_hot; - break; - case 'S': - case 's': - if (annotate_browser__toggle_source(self)) - ui_helpline__puts(help); - continue; - case 'O': - case 'o': - self->use_offset = !self->use_offset; - continue; - case '/': - if (annotate_browser__search(self, delay_secs)) { -show_help: - ui_helpline__puts(help); - } - continue; - case 'n': - if (self->searching_backwards ? - annotate_browser__continue_search_reverse(self, delay_secs) : - annotate_browser__continue_search(self, delay_secs)) - goto show_help; - continue; - case '?': - if (annotate_browser__search_reverse(self, delay_secs)) - goto show_help; - continue; - case K_ENTER: - case K_RIGHT: - if (self->selection == NULL) - ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); - else if (self->selection->offset == -1) - ui_helpline__puts("Actions are only available for assembly lines."); - else if (!(annotate_browser__jump(self) || - annotate_browser__callq(self, evidx, timer, arg, delay_secs))) - ui_helpline__puts("Actions are only available for the 'callq' and jump instructions."); - continue; - case K_LEFT: - case K_ESC: - case 'q': - case CTRL('c'): - goto out; - default: - continue; - } - - if (nd != NULL) - annotate_browser__set_rb_top(self, nd); - } -out: - ui_browser__hide(&self->b); - return key; -} - -int hist_entry__tui_annotate(struct hist_entry *he, int evidx, - void(*timer)(void *arg), void *arg, int delay_secs) -{ - return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, - timer, arg, delay_secs); -} - -int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, - void(*timer)(void *arg), void *arg, - int delay_secs) -{ - struct objdump_line *pos, *n; - struct annotation *notes; - struct map_symbol ms = { - .map = map, - .sym = sym, - }; - struct annotate_browser browser = { - .b = { - .refresh = ui_browser__list_head_refresh, - .seek = ui_browser__list_head_seek, - .write = annotate_browser__write, - .filter = objdump_line__filter, - .priv = &ms, - .use_navkeypressed = true, - }, - }; - int ret; - - if (sym == NULL) - return -1; - - if (map->dso->annotate_warned) - return -1; - - if (symbol__annotate(sym, map, sizeof(struct objdump_line_rb_node)) < 0) { - ui__error("%s", ui_helpline__last_msg); - return -1; - } - - ui_helpline__push("Press <- or ESC to exit"); - - notes = symbol__annotation(sym); - browser.start = map__rip_2objdump(map, sym->start); - - list_for_each_entry(pos, ¬es->src->source, node) { - struct objdump_line_rb_node *rbpos; - size_t line_len = strlen(pos->line); - - if (browser.b.width < line_len) - browser.b.width = line_len; - rbpos = objdump_line__rb(pos); - rbpos->idx = browser.nr_entries++; - if (pos->offset != -1) - rbpos->idx_asm = browser.nr_asm_entries++; - else - rbpos->idx_asm = -1; - } - - browser.b.nr_entries = browser.nr_entries; - browser.b.entries = ¬es->src->source, - browser.b.width += 18; /* Percentage */ - ret = annotate_browser__run(&browser, evidx, timer, arg, delay_secs); - list_for_each_entry_safe(pos, n, ¬es->src->source, node) { - list_del(&pos->node); - objdump_line__free(pos); - } - return ret; -} -- cgit v1.2.3