diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
| -rw-r--r-- | tools/perf/util/annotate.c | 82 |
1 files changed, 56 insertions, 26 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index cf6242c92ee2..3aa555ff9d89 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include "util.h" | 10 | #include "util.h" |
| 11 | #include "ui/ui.h" | ||
| 12 | #include "sort.h" | ||
| 11 | #include "build-id.h" | 13 | #include "build-id.h" |
| 12 | #include "color.h" | 14 | #include "color.h" |
| 13 | #include "cache.h" | 15 | #include "cache.h" |
| @@ -26,10 +28,10 @@ static int disasm_line__parse(char *line, char **namep, char **rawp); | |||
| 26 | 28 | ||
| 27 | static void ins__delete(struct ins_operands *ops) | 29 | static void ins__delete(struct ins_operands *ops) |
| 28 | { | 30 | { |
| 29 | free(ops->source.raw); | 31 | zfree(&ops->source.raw); |
| 30 | free(ops->source.name); | 32 | zfree(&ops->source.name); |
| 31 | free(ops->target.raw); | 33 | zfree(&ops->target.raw); |
| 32 | free(ops->target.name); | 34 | zfree(&ops->target.name); |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, | 37 | static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, |
| @@ -185,8 +187,7 @@ static int lock__parse(struct ins_operands *ops) | |||
| 185 | return 0; | 187 | return 0; |
| 186 | 188 | ||
| 187 | out_free_ops: | 189 | out_free_ops: |
| 188 | free(ops->locked.ops); | 190 | zfree(&ops->locked.ops); |
| 189 | ops->locked.ops = NULL; | ||
| 190 | return 0; | 191 | return 0; |
| 191 | } | 192 | } |
| 192 | 193 | ||
| @@ -205,9 +206,9 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size, | |||
| 205 | 206 | ||
| 206 | static void lock__delete(struct ins_operands *ops) | 207 | static void lock__delete(struct ins_operands *ops) |
| 207 | { | 208 | { |
| 208 | free(ops->locked.ops); | 209 | zfree(&ops->locked.ops); |
| 209 | free(ops->target.raw); | 210 | zfree(&ops->target.raw); |
| 210 | free(ops->target.name); | 211 | zfree(&ops->target.name); |
| 211 | } | 212 | } |
| 212 | 213 | ||
| 213 | static struct ins_ops lock_ops = { | 214 | static struct ins_ops lock_ops = { |
| @@ -256,8 +257,7 @@ static int mov__parse(struct ins_operands *ops) | |||
| 256 | return 0; | 257 | return 0; |
| 257 | 258 | ||
| 258 | out_free_source: | 259 | out_free_source: |
| 259 | free(ops->source.raw); | 260 | zfree(&ops->source.raw); |
| 260 | ops->source.raw = NULL; | ||
| 261 | return -1; | 261 | return -1; |
| 262 | } | 262 | } |
| 263 | 263 | ||
| @@ -464,17 +464,12 @@ void symbol__annotate_zero_histograms(struct symbol *sym) | |||
| 464 | pthread_mutex_unlock(¬es->lock); | 464 | pthread_mutex_unlock(¬es->lock); |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 467 | static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
| 468 | int evidx, u64 addr) | 468 | struct annotation *notes, int evidx, u64 addr) |
| 469 | { | 469 | { |
| 470 | unsigned offset; | 470 | unsigned offset; |
| 471 | struct annotation *notes; | ||
| 472 | struct sym_hist *h; | 471 | struct sym_hist *h; |
| 473 | 472 | ||
| 474 | notes = symbol__annotation(sym); | ||
| 475 | if (notes->src == NULL) | ||
| 476 | return -ENOMEM; | ||
| 477 | |||
| 478 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); | 473 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); |
| 479 | 474 | ||
| 480 | if (addr < sym->start || addr > sym->end) | 475 | if (addr < sym->start || addr > sym->end) |
| @@ -491,6 +486,33 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
| 491 | return 0; | 486 | return 0; |
| 492 | } | 487 | } |
| 493 | 488 | ||
| 489 | static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | ||
| 490 | int evidx, u64 addr) | ||
| 491 | { | ||
| 492 | struct annotation *notes; | ||
| 493 | |||
| 494 | if (sym == NULL) | ||
| 495 | return 0; | ||
| 496 | |||
| 497 | notes = symbol__annotation(sym); | ||
| 498 | if (notes->src == NULL) { | ||
| 499 | if (symbol__alloc_hist(sym) < 0) | ||
| 500 | return -ENOMEM; | ||
| 501 | } | ||
| 502 | |||
| 503 | return __symbol__inc_addr_samples(sym, map, notes, evidx, addr); | ||
| 504 | } | ||
| 505 | |||
| 506 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx) | ||
| 507 | { | ||
| 508 | return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr); | ||
| 509 | } | ||
| 510 | |||
| 511 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) | ||
| 512 | { | ||
| 513 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); | ||
| 514 | } | ||
| 515 | |||
| 494 | static void disasm_line__init_ins(struct disasm_line *dl) | 516 | static void disasm_line__init_ins(struct disasm_line *dl) |
| 495 | { | 517 | { |
| 496 | dl->ins = ins__find(dl->name); | 518 | dl->ins = ins__find(dl->name); |
| @@ -538,8 +560,7 @@ static int disasm_line__parse(char *line, char **namep, char **rawp) | |||
| 538 | return 0; | 560 | return 0; |
| 539 | 561 | ||
| 540 | out_free_name: | 562 | out_free_name: |
| 541 | free(*namep); | 563 | zfree(namep); |
| 542 | *namep = NULL; | ||
| 543 | return -1; | 564 | return -1; |
| 544 | } | 565 | } |
| 545 | 566 | ||
| @@ -564,7 +585,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privs | |||
| 564 | return dl; | 585 | return dl; |
| 565 | 586 | ||
| 566 | out_free_line: | 587 | out_free_line: |
| 567 | free(dl->line); | 588 | zfree(&dl->line); |
| 568 | out_delete: | 589 | out_delete: |
| 569 | free(dl); | 590 | free(dl); |
| 570 | return NULL; | 591 | return NULL; |
| @@ -572,8 +593,8 @@ out_delete: | |||
| 572 | 593 | ||
| 573 | void disasm_line__free(struct disasm_line *dl) | 594 | void disasm_line__free(struct disasm_line *dl) |
| 574 | { | 595 | { |
| 575 | free(dl->line); | 596 | zfree(&dl->line); |
| 576 | free(dl->name); | 597 | zfree(&dl->name); |
| 577 | if (dl->ins && dl->ins->ops->free) | 598 | if (dl->ins && dl->ins->ops->free) |
| 578 | dl->ins->ops->free(&dl->ops); | 599 | dl->ins->ops->free(&dl->ops); |
| 579 | else | 600 | else |
| @@ -900,7 +921,7 @@ fallback: | |||
| 900 | * cache, or is just a kallsyms file, well, lets hope that this | 921 | * cache, or is just a kallsyms file, well, lets hope that this |
| 901 | * DSO is the same as when 'perf record' ran. | 922 | * DSO is the same as when 'perf record' ran. |
| 902 | */ | 923 | */ |
| 903 | filename = dso->long_name; | 924 | filename = (char *)dso->long_name; |
| 904 | snprintf(symfs_filename, sizeof(symfs_filename), "%s%s", | 925 | snprintf(symfs_filename, sizeof(symfs_filename), "%s%s", |
| 905 | symbol_conf.symfs, filename); | 926 | symbol_conf.symfs, filename); |
| 906 | free_filename = false; | 927 | free_filename = false; |
| @@ -1091,8 +1112,7 @@ static void symbol__free_source_line(struct symbol *sym, int len) | |||
| 1091 | src_line = (void *)src_line + sizeof_src_line; | 1112 | src_line = (void *)src_line + sizeof_src_line; |
| 1092 | } | 1113 | } |
| 1093 | 1114 | ||
| 1094 | free(notes->src->lines); | 1115 | zfree(¬es->src->lines); |
| 1095 | notes->src->lines = NULL; | ||
| 1096 | } | 1116 | } |
| 1097 | 1117 | ||
| 1098 | /* Get the filename:line for the colored entries */ | 1118 | /* Get the filename:line for the colored entries */ |
| @@ -1376,3 +1396,13 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, | |||
| 1376 | 1396 | ||
| 1377 | return 0; | 1397 | return 0; |
| 1378 | } | 1398 | } |
| 1399 | |||
| 1400 | int hist_entry__annotate(struct hist_entry *he, size_t privsize) | ||
| 1401 | { | ||
| 1402 | return symbol__annotate(he->ms.sym, he->ms.map, privsize); | ||
| 1403 | } | ||
| 1404 | |||
| 1405 | bool ui__has_annotation(void) | ||
| 1406 | { | ||
| 1407 | return use_browser == 1 && sort__has_sym; | ||
| 1408 | } | ||
