From 058b4cc9af574c072988a38a7a5ee93df881e5aa Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 2 Apr 2012 12:59:01 -0300 Subject: [PATCH] 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/Documentation/perfconfig.example | 1 + tools/perf/util/annotate.c | 35 ++++++++++++++------- tools/perf/util/ui/browser.c | 6 ++++ tools/perf/util/ui/browser.h | 1 + tools/perf/util/ui/browsers/annotate.c | 26 ++++++++++++--- 5 files changed, 53 insertions(+), 16 deletions(-) diff --git a/tools/perf/Documentation/perfconfig.example b/tools/perf/Documentation/perfconfig.example index d1448668f4d4..42c6fd2ae85d 100644 --- a/tools/perf/Documentation/perfconfig.example +++ b/tools/perf/Documentation/perfconfig.example @@ -6,6 +6,7 @@ normal = black, lightgray selected = lightgray, magenta code = blue, lightgray + addr = magenta, lightgray [tui] diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 08c6d138a655..9fc4126e54db 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -84,10 +84,15 @@ static struct objdump_line *objdump_line__new(s64 offset, char *line, size_t pri if (self != NULL) { self->offset = offset; - self->line = line; + self->line = strdup(line); + if (self->line == NULL) + goto out_delete; } return self; +out_delete: + free(self); + return NULL; } void objdump_line__free(struct objdump_line *self) @@ -112,7 +117,7 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, } static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, - int evidx, u64 len, int min_pcnt, + u64 start, int evidx, u64 len, int min_pcnt, int printed, int max_lines, struct objdump_line *queue) { @@ -128,6 +133,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, struct source_line *src_line = notes->src->lines; struct sym_hist *h = annotation__histogram(notes, evidx); s64 offset = oline->offset; + const u64 addr = start + offset; struct objdump_line *next; next = objdump__get_next_ip_line(¬es->src->source, oline); @@ -157,7 +163,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, list_for_each_entry_from(queue, ¬es->src->source, node) { if (queue == oline) break; - objdump_line__print(queue, sym, evidx, len, + objdump_line__print(queue, sym, start, evidx, len, 0, 0, 1, NULL); } } @@ -180,6 +186,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, color_fprintf(stdout, color, " %7.2f", percent); printf(" : "); + color_fprintf(stdout, PERF_COLOR_MAGENTA, " %" PRIx64 ":", addr); color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", oline->line); } else if (max_lines && printed >= max_lines) return 1; @@ -201,7 +208,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, { struct annotation *notes = symbol__annotation(sym); struct objdump_line *objdump_line; - char *line = NULL, *tmp, *tmp2, *c; + char *line = NULL, *parsed_line, *tmp, *tmp2, *c; size_t line_len; s64 line_ip, offset = -1; @@ -246,13 +253,17 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, offset = line_ip - start; if (offset < 0 || (u64)line_ip > end) offset = -1; - } + else + parsed_line = tmp2 + 1; + } else + parsed_line = line; - objdump_line = objdump_line__new(offset, line, privsize); - if (objdump_line == NULL) { - free(line); + objdump_line = objdump_line__new(offset, parsed_line, privsize); + free(line); + + if (objdump_line == NULL) return -1; - } + objdump__add_line(¬es->src->source, objdump_line); return 0; @@ -493,6 +504,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, const char *filename = dso->long_name, *d_filename; struct annotation *notes = symbol__annotation(sym); struct objdump_line *pos, *queue = NULL; + u64 start = map__rip_2objdump(map, sym->start); int printed = 2, queue_len = 0; int more = 0; u64 len; @@ -516,8 +528,9 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, queue_len = 0; } - switch (objdump_line__print(pos, sym, evidx, len, min_pcnt, - printed, max_lines, queue)) { + switch (objdump_line__print(pos, sym, start, evidx, len, + min_pcnt, printed, max_lines, + queue)) { case 0: ++printed; if (context) { diff --git a/tools/perf/util/ui/browser.c b/tools/perf/util/ui/browser.c index 076a5ffc8f56..a1b140cf75ac 100644 --- a/tools/perf/util/ui/browser.c +++ b/tools/perf/util/ui/browser.c @@ -505,6 +505,12 @@ static struct ui_browser__colorset { .fg = "blue", .bg = "default", }, + { + .colorset = HE_COLORSET_ADDR, + .name = "addr", + .fg = "magenta", + .bg = "default", + }, { .name = NULL, } diff --git a/tools/perf/util/ui/browser.h b/tools/perf/util/ui/browser.h index 65b25921529e..2550277db9f9 100644 --- a/tools/perf/util/ui/browser.h +++ b/tools/perf/util/ui/browser.h @@ -10,6 +10,7 @@ #define HE_COLORSET_NORMAL 52 #define HE_COLORSET_SELECTED 53 #define HE_COLORSET_CODE 54 +#define HE_COLORSET_ADDR 55 struct ui_browser { u64 index, top_idx; 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;