diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-04-02 11:59:01 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-04-07 15:09:05 -0400 |
commit | 058b4cc9af574c072988a38a7a5ee93df881e5aa (patch) | |
tree | b43317d17d667aa54b20e0b363f1d2fb288e07e7 /tools | |
parent | 087091652bf8b351432a3f3fb50996ee3582d5e4 (diff) |
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 <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-ede5zkaf7oorwvbqjezb4yg4@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Documentation/perfconfig.example | 1 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 35 | ||||
-rw-r--r-- | tools/perf/util/ui/browser.c | 6 | ||||
-rw-r--r-- | tools/perf/util/ui/browser.h | 1 | ||||
-rw-r--r-- | 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 d1448668f4d..42c6fd2ae85 100644 --- a/tools/perf/Documentation/perfconfig.example +++ b/tools/perf/Documentation/perfconfig.example | |||
@@ -6,6 +6,7 @@ | |||
6 | normal = black, lightgray | 6 | normal = black, lightgray |
7 | selected = lightgray, magenta | 7 | selected = lightgray, magenta |
8 | code = blue, lightgray | 8 | code = blue, lightgray |
9 | addr = magenta, lightgray | ||
9 | 10 | ||
10 | [tui] | 11 | [tui] |
11 | 12 | ||
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 08c6d138a65..9fc4126e54d 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 | |||
84 | 84 | ||
85 | if (self != NULL) { | 85 | if (self != NULL) { |
86 | self->offset = offset; | 86 | self->offset = offset; |
87 | self->line = line; | 87 | self->line = strdup(line); |
88 | if (self->line == NULL) | ||
89 | goto out_delete; | ||
88 | } | 90 | } |
89 | 91 | ||
90 | return self; | 92 | return self; |
93 | out_delete: | ||
94 | free(self); | ||
95 | return NULL; | ||
91 | } | 96 | } |
92 | 97 | ||
93 | void objdump_line__free(struct objdump_line *self) | 98 | void objdump_line__free(struct objdump_line *self) |
@@ -112,7 +117,7 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, | |||
112 | } | 117 | } |
113 | 118 | ||
114 | static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, | 119 | static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, |
115 | int evidx, u64 len, int min_pcnt, | 120 | u64 start, int evidx, u64 len, int min_pcnt, |
116 | int printed, int max_lines, | 121 | int printed, int max_lines, |
117 | struct objdump_line *queue) | 122 | struct objdump_line *queue) |
118 | { | 123 | { |
@@ -128,6 +133,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, | |||
128 | struct source_line *src_line = notes->src->lines; | 133 | struct source_line *src_line = notes->src->lines; |
129 | struct sym_hist *h = annotation__histogram(notes, evidx); | 134 | struct sym_hist *h = annotation__histogram(notes, evidx); |
130 | s64 offset = oline->offset; | 135 | s64 offset = oline->offset; |
136 | const u64 addr = start + offset; | ||
131 | struct objdump_line *next; | 137 | struct objdump_line *next; |
132 | 138 | ||
133 | next = objdump__get_next_ip_line(¬es->src->source, oline); | 139 | 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, | |||
157 | list_for_each_entry_from(queue, ¬es->src->source, node) { | 163 | list_for_each_entry_from(queue, ¬es->src->source, node) { |
158 | if (queue == oline) | 164 | if (queue == oline) |
159 | break; | 165 | break; |
160 | objdump_line__print(queue, sym, evidx, len, | 166 | objdump_line__print(queue, sym, start, evidx, len, |
161 | 0, 0, 1, NULL); | 167 | 0, 0, 1, NULL); |
162 | } | 168 | } |
163 | } | 169 | } |
@@ -180,6 +186,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, | |||
180 | 186 | ||
181 | color_fprintf(stdout, color, " %7.2f", percent); | 187 | color_fprintf(stdout, color, " %7.2f", percent); |
182 | printf(" : "); | 188 | printf(" : "); |
189 | color_fprintf(stdout, PERF_COLOR_MAGENTA, " %" PRIx64 ":", addr); | ||
183 | color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", oline->line); | 190 | color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", oline->line); |
184 | } else if (max_lines && printed >= max_lines) | 191 | } else if (max_lines && printed >= max_lines) |
185 | return 1; | 192 | return 1; |
@@ -201,7 +208,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
201 | { | 208 | { |
202 | struct annotation *notes = symbol__annotation(sym); | 209 | struct annotation *notes = symbol__annotation(sym); |
203 | struct objdump_line *objdump_line; | 210 | struct objdump_line *objdump_line; |
204 | char *line = NULL, *tmp, *tmp2, *c; | 211 | char *line = NULL, *parsed_line, *tmp, *tmp2, *c; |
205 | size_t line_len; | 212 | size_t line_len; |
206 | s64 line_ip, offset = -1; | 213 | s64 line_ip, offset = -1; |
207 | 214 | ||
@@ -246,13 +253,17 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
246 | offset = line_ip - start; | 253 | offset = line_ip - start; |
247 | if (offset < 0 || (u64)line_ip > end) | 254 | if (offset < 0 || (u64)line_ip > end) |
248 | offset = -1; | 255 | offset = -1; |
249 | } | 256 | else |
257 | parsed_line = tmp2 + 1; | ||
258 | } else | ||
259 | parsed_line = line; | ||
250 | 260 | ||
251 | objdump_line = objdump_line__new(offset, line, privsize); | 261 | objdump_line = objdump_line__new(offset, parsed_line, privsize); |
252 | if (objdump_line == NULL) { | 262 | free(line); |
253 | free(line); | 263 | |
264 | if (objdump_line == NULL) | ||
254 | return -1; | 265 | return -1; |
255 | } | 266 | |
256 | objdump__add_line(¬es->src->source, objdump_line); | 267 | objdump__add_line(¬es->src->source, objdump_line); |
257 | 268 | ||
258 | return 0; | 269 | return 0; |
@@ -493,6 +504,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, | |||
493 | const char *filename = dso->long_name, *d_filename; | 504 | const char *filename = dso->long_name, *d_filename; |
494 | struct annotation *notes = symbol__annotation(sym); | 505 | struct annotation *notes = symbol__annotation(sym); |
495 | struct objdump_line *pos, *queue = NULL; | 506 | struct objdump_line *pos, *queue = NULL; |
507 | u64 start = map__rip_2objdump(map, sym->start); | ||
496 | int printed = 2, queue_len = 0; | 508 | int printed = 2, queue_len = 0; |
497 | int more = 0; | 509 | int more = 0; |
498 | u64 len; | 510 | u64 len; |
@@ -516,8 +528,9 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, | |||
516 | queue_len = 0; | 528 | queue_len = 0; |
517 | } | 529 | } |
518 | 530 | ||
519 | switch (objdump_line__print(pos, sym, evidx, len, min_pcnt, | 531 | switch (objdump_line__print(pos, sym, start, evidx, len, |
520 | printed, max_lines, queue)) { | 532 | min_pcnt, printed, max_lines, |
533 | queue)) { | ||
521 | case 0: | 534 | case 0: |
522 | ++printed; | 535 | ++printed; |
523 | if (context) { | 536 | if (context) { |
diff --git a/tools/perf/util/ui/browser.c b/tools/perf/util/ui/browser.c index 076a5ffc8f5..a1b140cf75a 100644 --- a/tools/perf/util/ui/browser.c +++ b/tools/perf/util/ui/browser.c | |||
@@ -506,6 +506,12 @@ static struct ui_browser__colorset { | |||
506 | .bg = "default", | 506 | .bg = "default", |
507 | }, | 507 | }, |
508 | { | 508 | { |
509 | .colorset = HE_COLORSET_ADDR, | ||
510 | .name = "addr", | ||
511 | .fg = "magenta", | ||
512 | .bg = "default", | ||
513 | }, | ||
514 | { | ||
509 | .name = NULL, | 515 | .name = NULL, |
510 | } | 516 | } |
511 | }; | 517 | }; |
diff --git a/tools/perf/util/ui/browser.h b/tools/perf/util/ui/browser.h index 65b25921529..2550277db9f 100644 --- a/tools/perf/util/ui/browser.h +++ b/tools/perf/util/ui/browser.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #define HE_COLORSET_NORMAL 52 | 10 | #define HE_COLORSET_NORMAL 52 |
11 | #define HE_COLORSET_SELECTED 53 | 11 | #define HE_COLORSET_SELECTED 53 |
12 | #define HE_COLORSET_CODE 54 | 12 | #define HE_COLORSET_CODE 54 |
13 | #define HE_COLORSET_ADDR 55 | ||
13 | 14 | ||
14 | struct ui_browser { | 15 | struct ui_browser { |
15 | u64 index, top_idx; | 16 | u64 index, top_idx; |
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 57a4c6ef3fd..7ac7dd04d5c 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c | |||
@@ -16,6 +16,7 @@ struct annotate_browser { | |||
16 | struct rb_root entries; | 16 | struct rb_root entries; |
17 | struct rb_node *curr_hot; | 17 | struct rb_node *curr_hot; |
18 | struct objdump_line *selection; | 18 | struct objdump_line *selection; |
19 | u64 start; | ||
19 | int nr_asm_entries; | 20 | int nr_asm_entries; |
20 | int nr_entries; | 21 | int nr_entries; |
21 | bool hide_src_code; | 22 | bool hide_src_code; |
@@ -51,6 +52,9 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
51 | struct annotate_browser *ab = container_of(self, struct annotate_browser, b); | 52 | struct annotate_browser *ab = container_of(self, struct annotate_browser, b); |
52 | struct objdump_line *ol = list_entry(entry, struct objdump_line, node); | 53 | struct objdump_line *ol = list_entry(entry, struct objdump_line, node); |
53 | bool current_entry = ui_browser__is_current_entry(self, row); | 54 | bool current_entry = ui_browser__is_current_entry(self, row); |
55 | bool change_color = (!ab->hide_src_code && | ||
56 | (!current_entry || (self->use_navkeypressed && | ||
57 | !self->navkeypressed))); | ||
54 | int width = self->width; | 58 | int width = self->width; |
55 | 59 | ||
56 | if (ol->offset != -1) { | 60 | if (ol->offset != -1) { |
@@ -69,15 +73,26 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
69 | if (!self->navkeypressed) | 73 | if (!self->navkeypressed) |
70 | width += 1; | 74 | width += 1; |
71 | 75 | ||
72 | if (!ab->hide_src_code && ol->offset != -1) | 76 | if (ol->offset != -1 && change_color) |
73 | if (!current_entry || (self->use_navkeypressed && | 77 | ui_browser__set_color(self, HE_COLORSET_CODE); |
74 | !self->navkeypressed)) | ||
75 | ui_browser__set_color(self, HE_COLORSET_CODE); | ||
76 | 78 | ||
77 | if (!*ol->line) | 79 | if (!*ol->line) |
78 | slsmg_write_nstring(" ", width - 18); | 80 | slsmg_write_nstring(" ", width - 18); |
79 | else | 81 | else if (ol->offset == -1) |
80 | slsmg_write_nstring(ol->line, width - 18); | 82 | slsmg_write_nstring(ol->line, width - 18); |
83 | else { | ||
84 | char bf[64]; | ||
85 | u64 addr = ab->start + ol->offset; | ||
86 | int printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr); | ||
87 | int color = -1; | ||
88 | |||
89 | if (change_color) | ||
90 | color = ui_browser__set_color(self, HE_COLORSET_ADDR); | ||
91 | slsmg_write_nstring(bf, printed); | ||
92 | if (change_color) | ||
93 | ui_browser__set_color(self, color); | ||
94 | slsmg_write_nstring(ol->line, width - 18 - printed); | ||
95 | } | ||
81 | 96 | ||
82 | if (current_entry) | 97 | if (current_entry) |
83 | ab->selection = ol; | 98 | ab->selection = ol; |
@@ -406,6 +421,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
406 | ui_helpline__push("Press <- or ESC to exit"); | 421 | ui_helpline__push("Press <- or ESC to exit"); |
407 | 422 | ||
408 | notes = symbol__annotation(sym); | 423 | notes = symbol__annotation(sym); |
424 | browser.start = map__rip_2objdump(map, sym->start); | ||
409 | 425 | ||
410 | list_for_each_entry(pos, ¬es->src->source, node) { | 426 | list_for_each_entry(pos, ¬es->src->source, node) { |
411 | struct objdump_line_rb_node *rbpos; | 427 | struct objdump_line_rb_node *rbpos; |