summaryrefslogtreecommitdiff
path: root/tools/perf/util/annotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r--tools/perf/util/annotate.c151
1 files changed, 66 insertions, 85 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 469eb679fb9d..7eae5488ecea 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -26,10 +26,10 @@ static int disasm_line__parse(char *line, char **namep, char **rawp);
static void ins__delete(struct ins_operands *ops)
{
- zfree(&ops->source.raw);
- zfree(&ops->source.name);
- zfree(&ops->target.raw);
- zfree(&ops->target.name);
+ free(ops->source.raw);
+ free(ops->source.name);
+ free(ops->target.raw);
+ free(ops->target.name);
}
static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size,
@@ -185,7 +185,8 @@ static int lock__parse(struct ins_operands *ops)
return 0;
out_free_ops:
- zfree(&ops->locked.ops);
+ free(ops->locked.ops);
+ ops->locked.ops = NULL;
return 0;
}
@@ -204,9 +205,9 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
static void lock__delete(struct ins_operands *ops)
{
- zfree(&ops->locked.ops);
- zfree(&ops->target.raw);
- zfree(&ops->target.name);
+ free(ops->locked.ops);
+ free(ops->target.raw);
+ free(ops->target.name);
}
static struct ins_ops lock_ops = {
@@ -255,7 +256,8 @@ static int mov__parse(struct ins_operands *ops)
return 0;
out_free_source:
- zfree(&ops->source.raw);
+ free(ops->source.raw);
+ ops->source.raw = NULL;
return -1;
}
@@ -462,12 +464,17 @@ void symbol__annotate_zero_histograms(struct symbol *sym)
pthread_mutex_unlock(&notes->lock);
}
-static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
- struct annotation *notes, int evidx, u64 addr)
+int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
+ int evidx, u64 addr)
{
unsigned offset;
+ struct annotation *notes;
struct sym_hist *h;
+ notes = symbol__annotation(sym);
+ if (notes->src == NULL)
+ return -ENOMEM;
+
pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
if (addr < sym->start || addr > sym->end)
@@ -484,33 +491,6 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
return 0;
}
-static int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
- int evidx, u64 addr)
-{
- struct annotation *notes;
-
- if (sym == NULL || use_browser != 1 || !sort__has_sym)
- return 0;
-
- notes = symbol__annotation(sym);
- if (notes->src == NULL) {
- if (symbol__alloc_hist(sym) < 0)
- return -ENOMEM;
- }
-
- return __symbol__inc_addr_samples(sym, map, notes, evidx, addr);
-}
-
-int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx)
-{
- return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr);
-}
-
-int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
-{
- return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip);
-}
-
static void disasm_line__init_ins(struct disasm_line *dl)
{
dl->ins = ins__find(dl->name);
@@ -558,7 +538,8 @@ static int disasm_line__parse(char *line, char **namep, char **rawp)
return 0;
out_free_name:
- zfree(namep);
+ free(*namep);
+ *namep = NULL;
return -1;
}
@@ -583,7 +564,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privs
return dl;
out_free_line:
- zfree(&dl->line);
+ free(dl->line);
out_delete:
free(dl);
return NULL;
@@ -591,8 +572,8 @@ out_delete:
void disasm_line__free(struct disasm_line *dl)
{
- zfree(&dl->line);
- zfree(&dl->name);
+ free(dl->line);
+ free(dl->name);
if (dl->ins && dl->ins->ops->free)
dl->ins->ops->free(&dl->ops);
else
@@ -844,16 +825,20 @@ 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 */
+ /*
+ * kcore has no symbols, so add the call target name if it is on the
+ * same map.
+ */
if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.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);
+ 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);
+ }
}
disasm__add(&notes->src->source, dl);
@@ -894,8 +879,6 @@ 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",
@@ -919,7 +902,7 @@ fallback:
* cache, or is just a kallsyms file, well, lets hope that this
* DSO is the same as when 'perf record' ran.
*/
- filename = (char *)dso->long_name;
+ filename = dso->long_name;
snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
symbol_conf.symfs, filename);
free_filename = false;
@@ -957,23 +940,6 @@ 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
@@ -1006,8 +972,6 @@ fallback:
pclose(file);
out_free_filename:
- if (delete_extract)
- kcore_extract__delete(&kce);
if (free_filename)
free(filename);
return err;
@@ -1106,21 +1070,24 @@ 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_srcline(src_line->path);
+ free(src_line->path);
src_line = (void *)src_line + sizeof_src_line;
}
- zfree(&notes->src->lines);
+ free(notes->src->lines);
+ notes->src->lines = NULL;
}
/* 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)
+ struct rb_root *root, int len,
+ const char *filename)
{
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);
@@ -1148,7 +1115,10 @@ 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;
@@ -1165,9 +1135,23 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
goto next;
offset = start + i;
- src_line->path = get_srcline(map->dso, offset);
+ 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);
insert_source_line(&tmp_root, src_line);
+ next_close:
+ pclose(fp);
next:
src_line = (void *)src_line + sizeof_src_line;
}
@@ -1208,7 +1192,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\n", path);
+ color_fprintf(stdout, color, " %s", path);
node = rb_next(node);
}
@@ -1372,6 +1356,7 @@ 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;
@@ -1381,8 +1366,9 @@ 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);
- print_summary(&source_line, dso->long_name);
+ symbol__get_source_line(sym, map, evsel, &source_line,
+ len, filename);
+ print_summary(&source_line, filename);
}
symbol__annotate_printf(sym, map, evsel, full_paths,
@@ -1394,8 +1380,3 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
return 0;
}
-
-int hist_entry__annotate(struct hist_entry *he, size_t privsize)
-{
- return symbol__annotate(he->ms.sym, he->ms.map, privsize);
-}