diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 76 |
1 files changed, 36 insertions, 40 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 7eae5488ecea..cf6242c92ee2 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -825,20 +825,16 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
825 | dl->ops.target.offset = dl->ops.target.addr - | 825 | dl->ops.target.offset = dl->ops.target.addr - |
826 | map__rip_2objdump(map, sym->start); | 826 | map__rip_2objdump(map, sym->start); |
827 | 827 | ||
828 | /* | 828 | /* kcore has no symbols, so add the call target name */ |
829 | * kcore has no symbols, so add the call target name if it is on the | ||
830 | * same map. | ||
831 | */ | ||
832 | if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) { | 829 | if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) { |
833 | struct symbol *s; | 830 | struct addr_map_symbol target = { |
834 | u64 ip = dl->ops.target.addr; | 831 | .map = map, |
835 | 832 | .addr = dl->ops.target.addr, | |
836 | if (ip >= map->start && ip <= map->end) { | 833 | }; |
837 | ip = map->map_ip(map, ip); | 834 | |
838 | s = map__find_symbol(map, ip, NULL); | 835 | if (!map_groups__find_ams(&target, NULL) && |
839 | if (s && s->start == ip) | 836 | target.sym->start == target.al_addr) |
840 | dl->ops.target.name = strdup(s->name); | 837 | dl->ops.target.name = strdup(target.sym->name); |
841 | } | ||
842 | } | 838 | } |
843 | 839 | ||
844 | disasm__add(¬es->src->source, dl); | 840 | disasm__add(¬es->src->source, dl); |
@@ -879,6 +875,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) | |||
879 | FILE *file; | 875 | FILE *file; |
880 | int err = 0; | 876 | int err = 0; |
881 | char symfs_filename[PATH_MAX]; | 877 | char symfs_filename[PATH_MAX]; |
878 | struct kcore_extract kce; | ||
879 | bool delete_extract = false; | ||
882 | 880 | ||
883 | if (filename) { | 881 | if (filename) { |
884 | snprintf(symfs_filename, sizeof(symfs_filename), "%s%s", | 882 | snprintf(symfs_filename, sizeof(symfs_filename), "%s%s", |
@@ -940,6 +938,23 @@ fallback: | |||
940 | pr_debug("annotating [%p] %30s : [%p] %30s\n", | 938 | pr_debug("annotating [%p] %30s : [%p] %30s\n", |
941 | dso, dso->long_name, sym, sym->name); | 939 | dso, dso->long_name, sym, sym->name); |
942 | 940 | ||
941 | if (dso__is_kcore(dso)) { | ||
942 | kce.kcore_filename = symfs_filename; | ||
943 | kce.addr = map__rip_2objdump(map, sym->start); | ||
944 | kce.offs = sym->start; | ||
945 | kce.len = sym->end + 1 - sym->start; | ||
946 | if (!kcore_extract__create(&kce)) { | ||
947 | delete_extract = true; | ||
948 | strlcpy(symfs_filename, kce.extract_filename, | ||
949 | sizeof(symfs_filename)); | ||
950 | if (free_filename) { | ||
951 | free(filename); | ||
952 | free_filename = false; | ||
953 | } | ||
954 | filename = symfs_filename; | ||
955 | } | ||
956 | } | ||
957 | |||
943 | snprintf(command, sizeof(command), | 958 | snprintf(command, sizeof(command), |
944 | "%s %s%s --start-address=0x%016" PRIx64 | 959 | "%s %s%s --start-address=0x%016" PRIx64 |
945 | " --stop-address=0x%016" PRIx64 | 960 | " --stop-address=0x%016" PRIx64 |
@@ -972,6 +987,8 @@ fallback: | |||
972 | 987 | ||
973 | pclose(file); | 988 | pclose(file); |
974 | out_free_filename: | 989 | out_free_filename: |
990 | if (delete_extract) | ||
991 | kcore_extract__delete(&kce); | ||
975 | if (free_filename) | 992 | if (free_filename) |
976 | free(filename); | 993 | free(filename); |
977 | return err; | 994 | return err; |
@@ -1070,7 +1087,7 @@ static void symbol__free_source_line(struct symbol *sym, int len) | |||
1070 | (sizeof(src_line->p) * (src_line->nr_pcnt - 1)); | 1087 | (sizeof(src_line->p) * (src_line->nr_pcnt - 1)); |
1071 | 1088 | ||
1072 | for (i = 0; i < len; i++) { | 1089 | for (i = 0; i < len; i++) { |
1073 | free(src_line->path); | 1090 | free_srcline(src_line->path); |
1074 | src_line = (void *)src_line + sizeof_src_line; | 1091 | src_line = (void *)src_line + sizeof_src_line; |
1075 | } | 1092 | } |
1076 | 1093 | ||
@@ -1081,13 +1098,11 @@ static void symbol__free_source_line(struct symbol *sym, int len) | |||
1081 | /* Get the filename:line for the colored entries */ | 1098 | /* Get the filename:line for the colored entries */ |
1082 | static int symbol__get_source_line(struct symbol *sym, struct map *map, | 1099 | static int symbol__get_source_line(struct symbol *sym, struct map *map, |
1083 | struct perf_evsel *evsel, | 1100 | struct perf_evsel *evsel, |
1084 | struct rb_root *root, int len, | 1101 | struct rb_root *root, int len) |
1085 | const char *filename) | ||
1086 | { | 1102 | { |
1087 | u64 start; | 1103 | u64 start; |
1088 | int i, k; | 1104 | int i, k; |
1089 | int evidx = evsel->idx; | 1105 | int evidx = evsel->idx; |
1090 | char cmd[PATH_MAX * 2]; | ||
1091 | struct source_line *src_line; | 1106 | struct source_line *src_line; |
1092 | struct annotation *notes = symbol__annotation(sym); | 1107 | struct annotation *notes = symbol__annotation(sym); |
1093 | struct sym_hist *h = annotation__histogram(notes, evidx); | 1108 | struct sym_hist *h = annotation__histogram(notes, evidx); |
@@ -1115,10 +1130,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
1115 | start = map__rip_2objdump(map, sym->start); | 1130 | start = map__rip_2objdump(map, sym->start); |
1116 | 1131 | ||
1117 | for (i = 0; i < len; i++) { | 1132 | for (i = 0; i < len; i++) { |
1118 | char *path = NULL; | ||
1119 | size_t line_len; | ||
1120 | u64 offset; | 1133 | u64 offset; |
1121 | FILE *fp; | ||
1122 | double percent_max = 0.0; | 1134 | double percent_max = 0.0; |
1123 | 1135 | ||
1124 | src_line->nr_pcnt = nr_pcnt; | 1136 | src_line->nr_pcnt = nr_pcnt; |
@@ -1135,23 +1147,9 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
1135 | goto next; | 1147 | goto next; |
1136 | 1148 | ||
1137 | offset = start + i; | 1149 | offset = start + i; |
1138 | sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset); | 1150 | src_line->path = get_srcline(map->dso, offset); |
1139 | fp = popen(cmd, "r"); | ||
1140 | if (!fp) | ||
1141 | goto next; | ||
1142 | |||
1143 | if (getline(&path, &line_len, fp) < 0 || !line_len) | ||
1144 | goto next_close; | ||
1145 | |||
1146 | src_line->path = malloc(sizeof(char) * line_len + 1); | ||
1147 | if (!src_line->path) | ||
1148 | goto next_close; | ||
1149 | |||
1150 | strcpy(src_line->path, path); | ||
1151 | insert_source_line(&tmp_root, src_line); | 1151 | insert_source_line(&tmp_root, src_line); |
1152 | 1152 | ||
1153 | next_close: | ||
1154 | pclose(fp); | ||
1155 | next: | 1153 | next: |
1156 | src_line = (void *)src_line + sizeof_src_line; | 1154 | src_line = (void *)src_line + sizeof_src_line; |
1157 | } | 1155 | } |
@@ -1192,7 +1190,7 @@ static void print_summary(struct rb_root *root, const char *filename) | |||
1192 | 1190 | ||
1193 | path = src_line->path; | 1191 | path = src_line->path; |
1194 | color = get_percent_color(percent_max); | 1192 | color = get_percent_color(percent_max); |
1195 | color_fprintf(stdout, color, " %s", path); | 1193 | color_fprintf(stdout, color, " %s\n", path); |
1196 | 1194 | ||
1197 | node = rb_next(node); | 1195 | node = rb_next(node); |
1198 | } | 1196 | } |
@@ -1356,7 +1354,6 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, | |||
1356 | bool full_paths, int min_pcnt, int max_lines) | 1354 | bool full_paths, int min_pcnt, int max_lines) |
1357 | { | 1355 | { |
1358 | struct dso *dso = map->dso; | 1356 | struct dso *dso = map->dso; |
1359 | const char *filename = dso->long_name; | ||
1360 | struct rb_root source_line = RB_ROOT; | 1357 | struct rb_root source_line = RB_ROOT; |
1361 | u64 len; | 1358 | u64 len; |
1362 | 1359 | ||
@@ -1366,9 +1363,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, | |||
1366 | len = symbol__size(sym); | 1363 | len = symbol__size(sym); |
1367 | 1364 | ||
1368 | if (print_lines) { | 1365 | if (print_lines) { |
1369 | symbol__get_source_line(sym, map, evsel, &source_line, | 1366 | symbol__get_source_line(sym, map, evsel, &source_line, len); |
1370 | len, filename); | 1367 | print_summary(&source_line, dso->long_name); |
1371 | print_summary(&source_line, filename); | ||
1372 | } | 1368 | } |
1373 | 1369 | ||
1374 | symbol__annotate_printf(sym, map, evsel, full_paths, | 1370 | symbol__annotate_printf(sym, map, evsel, full_paths, |