diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 7dabde14ea54..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); |
@@ -915,6 +934,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) | |||
915 | return -ENOMEM; | 934 | return -ENOMEM; |
916 | } | 935 | } |
917 | goto fallback; | 936 | goto fallback; |
937 | } else if (dso__is_kcore(dso)) { | ||
938 | goto fallback; | ||
918 | } else if (readlink(symfs_filename, command, sizeof(command)) < 0 || | 939 | } else if (readlink(symfs_filename, command, sizeof(command)) < 0 || |
919 | strstr(command, "[kernel.kallsyms]") || | 940 | strstr(command, "[kernel.kallsyms]") || |
920 | access(symfs_filename, R_OK)) { | 941 | access(symfs_filename, R_OK)) { |
@@ -982,7 +1003,7 @@ fallback: | |||
982 | snprintf(command, sizeof(command), | 1003 | snprintf(command, sizeof(command), |
983 | "%s %s%s --start-address=0x%016" PRIx64 | 1004 | "%s %s%s --start-address=0x%016" PRIx64 |
984 | " --stop-address=0x%016" PRIx64 | 1005 | " --stop-address=0x%016" PRIx64 |
985 | " -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", |
986 | objdump_path ? objdump_path : "objdump", | 1007 | objdump_path ? objdump_path : "objdump", |
987 | disassembler_style ? "-M " : "", | 1008 | disassembler_style ? "-M " : "", |
988 | disassembler_style ? disassembler_style : "", | 1009 | disassembler_style ? disassembler_style : "", |
@@ -999,7 +1020,8 @@ fallback: | |||
999 | goto out_free_filename; | 1020 | goto out_free_filename; |
1000 | 1021 | ||
1001 | while (!feof(file)) | 1022 | while (!feof(file)) |
1002 | if (symbol__parse_objdump_line(sym, map, file, privsize) < 0) | 1023 | if (symbol__parse_objdump_line(sym, map, file, privsize, |
1024 | &lineno) < 0) | ||
1003 | break; | 1025 | break; |
1004 | 1026 | ||
1005 | /* | 1027 | /* |