diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/perf/ui/browsers/annotate.c | 13 | ||||
| -rw-r--r-- | tools/perf/util/annotate.c | 30 | ||||
| -rw-r--r-- | tools/perf/util/annotate.h | 1 |
3 files changed, 38 insertions, 6 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index f0697a3aede0..1e0a2fd80115 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
| @@ -27,6 +27,7 @@ static struct annotate_browser_opt { | |||
| 27 | bool hide_src_code, | 27 | bool hide_src_code, |
| 28 | use_offset, | 28 | use_offset, |
| 29 | jump_arrows, | 29 | jump_arrows, |
| 30 | show_linenr, | ||
| 30 | show_nr_jumps; | 31 | show_nr_jumps; |
| 31 | } annotate_browser__opts = { | 32 | } annotate_browser__opts = { |
| 32 | .use_offset = true, | 33 | .use_offset = true, |
| @@ -128,7 +129,11 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
| 128 | if (!*dl->line) | 129 | if (!*dl->line) |
| 129 | slsmg_write_nstring(" ", width - pcnt_width); | 130 | slsmg_write_nstring(" ", width - pcnt_width); |
| 130 | else if (dl->offset == -1) { | 131 | else if (dl->offset == -1) { |
| 131 | printed = scnprintf(bf, sizeof(bf), "%*s ", | 132 | if (dl->line_nr && annotate_browser__opts.show_linenr) |
| 133 | printed = scnprintf(bf, sizeof(bf), "%-*d ", | ||
| 134 | ab->addr_width + 1, dl->line_nr); | ||
| 135 | else | ||
| 136 | printed = scnprintf(bf, sizeof(bf), "%*s ", | ||
| 132 | ab->addr_width, " "); | 137 | ab->addr_width, " "); |
| 133 | slsmg_write_nstring(bf, printed); | 138 | slsmg_write_nstring(bf, printed); |
| 134 | slsmg_write_nstring(dl->line, width - printed - pcnt_width + 1); | 139 | slsmg_write_nstring(dl->line, width - printed - pcnt_width + 1); |
| @@ -733,6 +738,7 @@ static int annotate_browser__run(struct annotate_browser *browser, | |||
| 733 | "o Toggle disassembler output/simplified view\n" | 738 | "o Toggle disassembler output/simplified view\n" |
| 734 | "s Toggle source code view\n" | 739 | "s Toggle source code view\n" |
| 735 | "/ Search string\n" | 740 | "/ Search string\n" |
| 741 | "k Toggle line numbers\n" | ||
| 736 | "r Run available scripts\n" | 742 | "r Run available scripts\n" |
| 737 | "? Search string backwards\n"); | 743 | "? Search string backwards\n"); |
| 738 | continue; | 744 | continue; |
| @@ -741,6 +747,10 @@ static int annotate_browser__run(struct annotate_browser *browser, | |||
| 741 | script_browse(NULL); | 747 | script_browse(NULL); |
| 742 | continue; | 748 | continue; |
| 743 | } | 749 | } |
| 750 | case 'k': | ||
| 751 | annotate_browser__opts.show_linenr = | ||
| 752 | !annotate_browser__opts.show_linenr; | ||
| 753 | break; | ||
| 744 | case 'H': | 754 | case 'H': |
| 745 | nd = browser->curr_hot; | 755 | nd = browser->curr_hot; |
| 746 | break; | 756 | break; |
| @@ -984,6 +994,7 @@ static struct annotate_config { | |||
| 984 | } annotate__configs[] = { | 994 | } annotate__configs[] = { |
| 985 | ANNOTATE_CFG(hide_src_code), | 995 | ANNOTATE_CFG(hide_src_code), |
| 986 | ANNOTATE_CFG(jump_arrows), | 996 | ANNOTATE_CFG(jump_arrows), |
| 997 | ANNOTATE_CFG(show_linenr), | ||
| 987 | ANNOTATE_CFG(show_nr_jumps), | 998 | ANNOTATE_CFG(show_nr_jumps), |
| 988 | ANNOTATE_CFG(use_offset), | 999 | ANNOTATE_CFG(use_offset), |
| 989 | }; | 1000 | }; |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 873c8778db20..e5670f1af737 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
| @@ -17,11 +17,13 @@ | |||
| 17 | #include "debug.h" | 17 | #include "debug.h" |
| 18 | #include "annotate.h" | 18 | #include "annotate.h" |
| 19 | #include "evsel.h" | 19 | #include "evsel.h" |
| 20 | #include <regex.h> | ||
| 20 | #include <pthread.h> | 21 | #include <pthread.h> |
| 21 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
| 22 | 23 | ||
| 23 | const char *disassembler_style; | 24 | const char *disassembler_style; |
| 24 | const char *objdump_path; | 25 | const char *objdump_path; |
| 26 | static regex_t file_lineno; | ||
| 25 | 27 | ||
| 26 | static struct ins *ins__find(const char *name); | 28 | static struct ins *ins__find(const char *name); |
| 27 | static int disasm_line__parse(char *line, char **namep, char **rawp); | 29 | static int disasm_line__parse(char *line, char **namep, char **rawp); |
| @@ -570,13 +572,15 @@ out_free_name: | |||
| 570 | return -1; | 572 | return -1; |
| 571 | } | 573 | } |
| 572 | 574 | ||
| 573 | static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privsize) | 575 | static struct disasm_line *disasm_line__new(s64 offset, char *line, |
| 576 | size_t privsize, int line_nr) | ||
| 574 | { | 577 | { |
| 575 | struct disasm_line *dl = zalloc(sizeof(*dl) + privsize); | 578 | struct disasm_line *dl = zalloc(sizeof(*dl) + privsize); |
| 576 | 579 | ||
| 577 | if (dl != NULL) { | 580 | if (dl != NULL) { |
| 578 | dl->offset = offset; | 581 | dl->offset = offset; |
| 579 | dl->line = strdup(line); | 582 | dl->line = strdup(line); |
| 583 | dl->line_nr = line_nr; | ||
| 580 | if (dl->line == NULL) | 584 | if (dl->line == NULL) |
| 581 | goto out_delete; | 585 | goto out_delete; |
| 582 | 586 | ||
| @@ -788,13 +792,15 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
| 788 | * The ops.raw part will be parsed further according to type of the instruction. | 792 | * The ops.raw part will be parsed further according to type of the instruction. |
| 789 | */ | 793 | */ |
| 790 | static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | 794 | static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, |
| 791 | FILE *file, size_t privsize) | 795 | FILE *file, size_t privsize, |
| 796 | int *line_nr) | ||
| 792 | { | 797 | { |
| 793 | struct annotation *notes = symbol__annotation(sym); | 798 | struct annotation *notes = symbol__annotation(sym); |
| 794 | struct disasm_line *dl; | 799 | struct disasm_line *dl; |
| 795 | char *line = NULL, *parsed_line, *tmp, *tmp2, *c; | 800 | char *line = NULL, *parsed_line, *tmp, *tmp2, *c; |
| 796 | size_t line_len; | 801 | size_t line_len; |
| 797 | s64 line_ip, offset = -1; | 802 | s64 line_ip, offset = -1; |
| 803 | regmatch_t match[2]; | ||
| 798 | 804 | ||
| 799 | if (getline(&line, &line_len, file) < 0) | 805 | if (getline(&line, &line_len, file) < 0) |
| 800 | return -1; | 806 | return -1; |
| @@ -812,6 +818,12 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
| 812 | line_ip = -1; | 818 | line_ip = -1; |
| 813 | parsed_line = line; | 819 | parsed_line = line; |
| 814 | 820 | ||
| 821 | /* /filename:linenr ? Save line number and ignore. */ | ||
| 822 | if (regexec(&file_lineno, line, 2, match, 0) == 0) { | ||
| 823 | *line_nr = atoi(line + match[1].rm_so); | ||
| 824 | return 0; | ||
| 825 | } | ||
| 826 | |||
| 815 | /* | 827 | /* |
| 816 | * Strip leading spaces: | 828 | * Strip leading spaces: |
| 817 | */ | 829 | */ |
| @@ -842,8 +854,9 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
| 842 | parsed_line = tmp2 + 1; | 854 | parsed_line = tmp2 + 1; |
| 843 | } | 855 | } |
| 844 | 856 | ||
| 845 | dl = disasm_line__new(offset, parsed_line, privsize); | 857 | dl = disasm_line__new(offset, parsed_line, privsize, *line_nr); |
| 846 | free(line); | 858 | free(line); |
| 859 | (*line_nr)++; | ||
| 847 | 860 | ||
| 848 | if (dl == NULL) | 861 | if (dl == NULL) |
| 849 | return -1; | 862 | return -1; |
| @@ -869,6 +882,11 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
| 869 | return 0; | 882 | return 0; |
| 870 | } | 883 | } |
| 871 | 884 | ||
| 885 | static __attribute__((constructor)) void symbol__init_regexpr(void) | ||
| 886 | { | ||
| 887 | regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED); | ||
| 888 | } | ||
| 889 | |||
| 872 | static void delete_last_nop(struct symbol *sym) | 890 | static void delete_last_nop(struct symbol *sym) |
| 873 | { | 891 | { |
| 874 | struct annotation *notes = symbol__annotation(sym); | 892 | struct annotation *notes = symbol__annotation(sym); |
| @@ -904,6 +922,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) | |||
| 904 | char symfs_filename[PATH_MAX]; | 922 | char symfs_filename[PATH_MAX]; |
| 905 | struct kcore_extract kce; | 923 | struct kcore_extract kce; |
| 906 | bool delete_extract = false; | 924 | bool delete_extract = false; |
| 925 | int lineno = 0; | ||
| 907 | 926 | ||
| 908 | if (filename) | 927 | if (filename) |
| 909 | symbol__join_symfs(symfs_filename, filename); | 928 | symbol__join_symfs(symfs_filename, filename); |
| @@ -984,7 +1003,7 @@ fallback: | |||
| 984 | snprintf(command, sizeof(command), | 1003 | snprintf(command, sizeof(command), |
| 985 | "%s %s%s --start-address=0x%016" PRIx64 | 1004 | "%s %s%s --start-address=0x%016" PRIx64 |
| 986 | " --stop-address=0x%016" PRIx64 | 1005 | " --stop-address=0x%016" PRIx64 |
| 987 | " -d %s %s -C %s 2>/dev/null|grep -v %s|expand", | 1006 | " -l -d %s %s -C %s 2>/dev/null|grep -v %s|expand", |
| 988 | objdump_path ? objdump_path : "objdump", | 1007 | objdump_path ? objdump_path : "objdump", |
| 989 | disassembler_style ? "-M " : "", | 1008 | disassembler_style ? "-M " : "", |
| 990 | disassembler_style ? disassembler_style : "", | 1009 | disassembler_style ? disassembler_style : "", |
| @@ -1001,7 +1020,8 @@ fallback: | |||
| 1001 | goto out_free_filename; | 1020 | goto out_free_filename; |
| 1002 | 1021 | ||
| 1003 | while (!feof(file)) | 1022 | while (!feof(file)) |
| 1004 | if (symbol__parse_objdump_line(sym, map, file, privsize) < 0) | 1023 | if (symbol__parse_objdump_line(sym, map, file, privsize, |
| 1024 | &lineno) < 0) | ||
| 1005 | break; | 1025 | break; |
| 1006 | 1026 | ||
| 1007 | /* | 1027 | /* |
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 112d6e268150..0784a9420528 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
| @@ -58,6 +58,7 @@ struct disasm_line { | |||
| 58 | char *line; | 58 | char *line; |
| 59 | char *name; | 59 | char *name; |
| 60 | struct ins *ins; | 60 | struct ins *ins; |
| 61 | int line_nr; | ||
| 61 | struct ins_operands ops; | 62 | struct ins_operands ops; |
| 62 | }; | 63 | }; |
| 63 | 64 | ||
