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,  		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(¬es->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,  | 
