Merge tag 'regulator-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[deliverable/linux.git] / tools / perf / util / annotate.c
index 7eae5488ecea47344cac10677104cb9e6cb2cc44..cf6242c92ee244ab45498993cab477af7950853f 100644 (file)
@@ -825,20 +825,16 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
                dl->ops.target.offset = dl->ops.target.addr -
                                        map__rip_2objdump(map, sym->start);
 
-       /*
-        * kcore has no symbols, so add the call target name if it is on the
-        * same map.
-        */
+       /* kcore has no symbols, so add the call target name */
        if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) {
-               struct symbol *s;
-               u64 ip = dl->ops.target.addr;
-
-               if (ip >= map->start && ip <= map->end) {
-                       ip = map->map_ip(map, ip);
-                       s = map__find_symbol(map, ip, NULL);
-                       if (s && s->start == ip)
-                               dl->ops.target.name = strdup(s->name);
-               }
+               struct addr_map_symbol target = {
+                       .map = map,
+                       .addr = dl->ops.target.addr,
+               };
+
+               if (!map_groups__find_ams(&target, NULL) &&
+                   target.sym->start == target.al_addr)
+                       dl->ops.target.name = strdup(target.sym->name);
        }
 
        disasm__add(&notes->src->source, dl);
@@ -879,6 +875,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
        FILE *file;
        int err = 0;
        char symfs_filename[PATH_MAX];
+       struct kcore_extract kce;
+       bool delete_extract = false;
 
        if (filename) {
                snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
@@ -940,6 +938,23 @@ fallback:
        pr_debug("annotating [%p] %30s : [%p] %30s\n",
                 dso, dso->long_name, sym, sym->name);
 
+       if (dso__is_kcore(dso)) {
+               kce.kcore_filename = symfs_filename;
+               kce.addr = map__rip_2objdump(map, sym->start);
+               kce.offs = sym->start;
+               kce.len = sym->end + 1 - sym->start;
+               if (!kcore_extract__create(&kce)) {
+                       delete_extract = true;
+                       strlcpy(symfs_filename, kce.extract_filename,
+                               sizeof(symfs_filename));
+                       if (free_filename) {
+                               free(filename);
+                               free_filename = false;
+                       }
+                       filename = symfs_filename;
+               }
+       }
+
        snprintf(command, sizeof(command),
                 "%s %s%s --start-address=0x%016" PRIx64
                 " --stop-address=0x%016" PRIx64
@@ -972,6 +987,8 @@ fallback:
 
        pclose(file);
 out_free_filename:
+       if (delete_extract)
+               kcore_extract__delete(&kce);
        if (free_filename)
                free(filename);
        return err;
@@ -1070,7 +1087,7 @@ static void symbol__free_source_line(struct symbol *sym, int len)
                          (sizeof(src_line->p) * (src_line->nr_pcnt - 1));
 
        for (i = 0; i < len; i++) {
-               free(src_line->path);
+               free_srcline(src_line->path);
                src_line = (void *)src_line + sizeof_src_line;
        }
 
@@ -1081,13 +1098,11 @@ static void symbol__free_source_line(struct symbol *sym, int len)
 /* Get the filename:line for the colored entries */
 static int symbol__get_source_line(struct symbol *sym, struct map *map,
                                   struct perf_evsel *evsel,
-                                  struct rb_root *root, int len,
-                                  const char *filename)
+                                  struct rb_root *root, int len)
 {
        u64 start;
        int i, k;
        int evidx = evsel->idx;
-       char cmd[PATH_MAX * 2];
        struct source_line *src_line;
        struct annotation *notes = symbol__annotation(sym);
        struct sym_hist *h = annotation__histogram(notes, evidx);
@@ -1115,10 +1130,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
        start = map__rip_2objdump(map, sym->start);
 
        for (i = 0; i < len; i++) {
-               char *path = NULL;
-               size_t line_len;
                u64 offset;
-               FILE *fp;
                double percent_max = 0.0;
 
                src_line->nr_pcnt = nr_pcnt;
@@ -1135,23 +1147,9 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
                        goto next;
 
                offset = start + i;
-               sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset);
-               fp = popen(cmd, "r");
-               if (!fp)
-                       goto next;
-
-               if (getline(&path, &line_len, fp) < 0 || !line_len)
-                       goto next_close;
-
-               src_line->path = malloc(sizeof(char) * line_len + 1);
-               if (!src_line->path)
-                       goto next_close;
-
-               strcpy(src_line->path, path);
+               src_line->path = get_srcline(map->dso, offset);
                insert_source_line(&tmp_root, src_line);
 
-       next_close:
-               pclose(fp);
        next:
                src_line = (void *)src_line + sizeof_src_line;
        }
@@ -1192,7 +1190,7 @@ static void print_summary(struct rb_root *root, const char *filename)
 
                path = src_line->path;
                color = get_percent_color(percent_max);
-               color_fprintf(stdout, color, " %s", path);
+               color_fprintf(stdout, color, " %s\n", path);
 
                node = rb_next(node);
        }
@@ -1356,7 +1354,6 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
                         bool full_paths, int min_pcnt, int max_lines)
 {
        struct dso *dso = map->dso;
-       const char *filename = dso->long_name;
        struct rb_root source_line = RB_ROOT;
        u64 len;
 
@@ -1366,9 +1363,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
        len = symbol__size(sym);
 
        if (print_lines) {
-               symbol__get_source_line(sym, map, evsel, &source_line,
-                                       len, filename);
-               print_summary(&source_line, filename);
+               symbol__get_source_line(sym, map, evsel, &source_line, len);
+               print_summary(&source_line, dso->long_name);
        }
 
        symbol__annotate_printf(sym, map, evsel, full_paths,
This page took 0.027942 seconds and 5 git commands to generate.