aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-annotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-annotate.c')
-rw-r--r--tools/perf/builtin-annotate.c57
1 files changed, 34 insertions, 23 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6ad7148451c5..f924b4332be6 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -14,7 +14,6 @@
14#include "util/cache.h" 14#include "util/cache.h"
15#include <linux/rbtree.h> 15#include <linux/rbtree.h>
16#include "util/symbol.h" 16#include "util/symbol.h"
17#include "util/string.h"
18 17
19#include "perf.h" 18#include "perf.h"
20#include "util/debug.h" 19#include "util/debug.h"
@@ -29,11 +28,11 @@
29 28
30static char const *input_name = "perf.data"; 29static char const *input_name = "perf.data";
31 30
32static int force; 31static bool force;
33 32
34static int full_paths; 33static bool full_paths;
35 34
36static int print_line; 35static bool print_line;
37 36
38struct sym_hist { 37struct sym_hist {
39 u64 sum; 38 u64 sum;
@@ -69,13 +68,13 @@ static int sym__alloc_hist(struct symbol *self)
69static int annotate__hist_hit(struct hist_entry *he, u64 ip) 68static int annotate__hist_hit(struct hist_entry *he, u64 ip)
70{ 69{
71 unsigned int sym_size, offset; 70 unsigned int sym_size, offset;
72 struct symbol *sym = he->sym; 71 struct symbol *sym = he->ms.sym;
73 struct sym_priv *priv; 72 struct sym_priv *priv;
74 struct sym_hist *h; 73 struct sym_hist *h;
75 74
76 he->count++; 75 he->count++;
77 76
78 if (!sym || !he->map) 77 if (!sym || !he->ms.map)
79 return 0; 78 return 0;
80 79
81 priv = symbol__priv(sym); 80 priv = symbol__priv(sym);
@@ -85,7 +84,7 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip)
85 sym_size = sym->end - sym->start; 84 sym_size = sym->end - sym->start;
86 offset = ip - sym->start; 85 offset = ip - sym->start;
87 86
88 pr_debug3("%s: ip=%#Lx\n", __func__, he->map->unmap_ip(he->map, ip)); 87 pr_debug3("%s: ip=%#Lx\n", __func__, he->ms.map->unmap_ip(he->ms.map, ip));
89 88
90 if (offset >= sym_size) 89 if (offset >= sym_size)
91 return 0; 90 return 0;
@@ -94,8 +93,8 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip)
94 h->sum++; 93 h->sum++;
95 h->ip[offset]++; 94 h->ip[offset]++;
96 95
97 pr_debug3("%#Lx %s: count++ [ip: %#Lx, %#Lx] => %Ld\n", he->sym->start, 96 pr_debug3("%#Lx %s: count++ [ip: %#Lx, %#Lx] => %Ld\n", he->ms.sym->start,
98 he->sym->name, ip, ip - he->sym->start, h->ip[offset]); 97 he->ms.sym->name, ip, ip - he->ms.sym->start, h->ip[offset]);
99 return 0; 98 return 0;
100} 99}
101 100
@@ -187,7 +186,7 @@ static struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
187static int parse_line(FILE *file, struct hist_entry *he, 186static int parse_line(FILE *file, struct hist_entry *he,
188 struct list_head *head) 187 struct list_head *head)
189{ 188{
190 struct symbol *sym = he->sym; 189 struct symbol *sym = he->ms.sym;
191 struct objdump_line *objdump_line; 190 struct objdump_line *objdump_line;
192 char *line = NULL, *tmp, *tmp2; 191 char *line = NULL, *tmp, *tmp2;
193 size_t line_len; 192 size_t line_len;
@@ -226,7 +225,7 @@ static int parse_line(FILE *file, struct hist_entry *he,
226 } 225 }
227 226
228 if (line_ip != -1) { 227 if (line_ip != -1) {
229 u64 start = map__rip_2objdump(he->map, sym->start); 228 u64 start = map__rip_2objdump(he->ms.map, sym->start);
230 offset = line_ip - start; 229 offset = line_ip - start;
231 } 230 }
232 231
@@ -244,7 +243,7 @@ static int objdump_line__print(struct objdump_line *self,
244 struct list_head *head, 243 struct list_head *head,
245 struct hist_entry *he, u64 len) 244 struct hist_entry *he, u64 len)
246{ 245{
247 struct symbol *sym = he->sym; 246 struct symbol *sym = he->ms.sym;
248 static const char *prev_line; 247 static const char *prev_line;
249 static const char *prev_color; 248 static const char *prev_color;
250 249
@@ -327,7 +326,7 @@ static void insert_source_line(struct sym_ext *sym_ext)
327 326
328static void free_source_line(struct hist_entry *he, int len) 327static void free_source_line(struct hist_entry *he, int len)
329{ 328{
330 struct sym_priv *priv = symbol__priv(he->sym); 329 struct sym_priv *priv = symbol__priv(he->ms.sym);
331 struct sym_ext *sym_ext = priv->ext; 330 struct sym_ext *sym_ext = priv->ext;
332 int i; 331 int i;
333 332
@@ -346,7 +345,7 @@ static void free_source_line(struct hist_entry *he, int len)
346static void 345static void
347get_source_line(struct hist_entry *he, int len, const char *filename) 346get_source_line(struct hist_entry *he, int len, const char *filename)
348{ 347{
349 struct symbol *sym = he->sym; 348 struct symbol *sym = he->ms.sym;
350 u64 start; 349 u64 start;
351 int i; 350 int i;
352 char cmd[PATH_MAX * 2]; 351 char cmd[PATH_MAX * 2];
@@ -361,7 +360,7 @@ get_source_line(struct hist_entry *he, int len, const char *filename)
361 if (!priv->ext) 360 if (!priv->ext)
362 return; 361 return;
363 362
364 start = he->map->unmap_ip(he->map, sym->start); 363 start = he->ms.map->unmap_ip(he->ms.map, sym->start);
365 364
366 for (i = 0; i < len; i++) { 365 for (i = 0; i < len; i++) {
367 char *path = NULL; 366 char *path = NULL;
@@ -425,7 +424,7 @@ static void print_summary(const char *filename)
425 424
426static void hist_entry__print_hits(struct hist_entry *self) 425static void hist_entry__print_hits(struct hist_entry *self)
427{ 426{
428 struct symbol *sym = self->sym; 427 struct symbol *sym = self->ms.sym;
429 struct sym_priv *priv = symbol__priv(sym); 428 struct sym_priv *priv = symbol__priv(sym);
430 struct sym_hist *h = priv->hist; 429 struct sym_hist *h = priv->hist;
431 u64 len = sym->end - sym->start, offset; 430 u64 len = sym->end - sym->start, offset;
@@ -439,9 +438,9 @@ static void hist_entry__print_hits(struct hist_entry *self)
439 438
440static void annotate_sym(struct hist_entry *he) 439static void annotate_sym(struct hist_entry *he)
441{ 440{
442 struct map *map = he->map; 441 struct map *map = he->ms.map;
443 struct dso *dso = map->dso; 442 struct dso *dso = map->dso;
444 struct symbol *sym = he->sym; 443 struct symbol *sym = he->ms.sym;
445 const char *filename = dso->long_name, *d_filename; 444 const char *filename = dso->long_name, *d_filename;
446 u64 len; 445 u64 len;
447 char command[PATH_MAX*2]; 446 char command[PATH_MAX*2];
@@ -452,6 +451,16 @@ static void annotate_sym(struct hist_entry *he)
452 if (!filename) 451 if (!filename)
453 return; 452 return;
454 453
454 if (dso->origin == DSO__ORIG_KERNEL) {
455 if (dso->annotate_warned)
456 return;
457 dso->annotate_warned = 1;
458 pr_err("Can't annotate %s: No vmlinux file was found in the "
459 "path:\n", sym->name);
460 vmlinux_path__fprintf(stderr);
461 return;
462 }
463
455 pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__, 464 pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__,
456 filename, sym->name, map->unmap_ip(map, sym->start), 465 filename, sym->name, map->unmap_ip(map, sym->start),
457 map->unmap_ip(map, sym->end)); 466 map->unmap_ip(map, sym->end));
@@ -516,17 +525,17 @@ static void perf_session__find_annotations(struct perf_session *self)
516 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); 525 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
517 struct sym_priv *priv; 526 struct sym_priv *priv;
518 527
519 if (he->sym == NULL) 528 if (he->ms.sym == NULL)
520 continue; 529 continue;
521 530
522 priv = symbol__priv(he->sym); 531 priv = symbol__priv(he->ms.sym);
523 if (priv->hist == NULL) 532 if (priv->hist == NULL)
524 continue; 533 continue;
525 534
526 annotate_sym(he); 535 annotate_sym(he);
527 /* 536 /*
528 * Since we have a hist_entry per IP for the same symbol, free 537 * Since we have a hist_entry per IP for the same symbol, free
529 * he->sym->hist to signal we already processed this symbol. 538 * he->ms.sym->hist to signal we already processed this symbol.
530 */ 539 */
531 free(priv->hist); 540 free(priv->hist);
532 priv->hist = NULL; 541 priv->hist = NULL;
@@ -562,7 +571,7 @@ static int __cmd_annotate(void)
562 perf_session__fprintf(session, stdout); 571 perf_session__fprintf(session, stdout);
563 572
564 if (verbose > 2) 573 if (verbose > 2)
565 dsos__fprintf(stdout); 574 dsos__fprintf(&session->kerninfo_root, stdout);
566 575
567 perf_session__collapse_resort(&session->hists); 576 perf_session__collapse_resort(&session->hists);
568 perf_session__output_resort(&session->hists, session->event_total[0]); 577 perf_session__output_resort(&session->hists, session->event_total[0]);
@@ -581,10 +590,12 @@ static const char * const annotate_usage[] = {
581static const struct option options[] = { 590static const struct option options[] = {
582 OPT_STRING('i', "input", &input_name, "file", 591 OPT_STRING('i', "input", &input_name, "file",
583 "input file name"), 592 "input file name"),
593 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
594 "only consider symbols in these dsos"),
584 OPT_STRING('s', "symbol", &sym_hist_filter, "symbol", 595 OPT_STRING('s', "symbol", &sym_hist_filter, "symbol",
585 "symbol to annotate"), 596 "symbol to annotate"),
586 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), 597 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
587 OPT_BOOLEAN('v', "verbose", &verbose, 598 OPT_INCR('v', "verbose", &verbose,
588 "be more verbose (show symbol address, etc)"), 599 "be more verbose (show symbol address, etc)"),
589 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 600 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
590 "dump raw trace in ASCII"), 601 "dump raw trace in ASCII"),