diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 35 |
1 files changed, 24 insertions, 11 deletions
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 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) { |