xref: /linux/tools/perf/util/srcline.c (revision b38775cf7678d7715b35dded3dcfab66e244baae)
1 #include <inttypes.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 
6 #include <linux/kernel.h>
7 
8 #include "util/dso.h"
9 #include "util/util.h"
10 #include "util/debug.h"
11 #include "util/callchain.h"
12 #include "srcline.h"
13 
14 #include "symbol.h"
15 
16 bool srcline_full_filename;
17 
18 static const char *dso__name(struct dso *dso)
19 {
20 	const char *dso_name;
21 
22 	if (dso->symsrc_filename)
23 		dso_name = dso->symsrc_filename;
24 	else
25 		dso_name = dso->long_name;
26 
27 	if (dso_name[0] == '[')
28 		return NULL;
29 
30 	if (!strncmp(dso_name, "/tmp/perf-", 10))
31 		return NULL;
32 
33 	return dso_name;
34 }
35 
36 static int inline_list__append(struct symbol *symbol, char *srcline,
37 			       struct inline_node *node)
38 {
39 	struct inline_list *ilist;
40 
41 	ilist = zalloc(sizeof(*ilist));
42 	if (ilist == NULL)
43 		return -1;
44 
45 	ilist->symbol = symbol;
46 	ilist->srcline = srcline;
47 
48 	if (callchain_param.order == ORDER_CALLEE)
49 		list_add_tail(&ilist->list, &node->val);
50 	else
51 		list_add(&ilist->list, &node->val);
52 
53 	return 0;
54 }
55 
56 /* basename version that takes a const input string */
57 static const char *gnu_basename(const char *path)
58 {
59 	const char *base = strrchr(path, '/');
60 
61 	return base ? base + 1 : path;
62 }
63 
64 static char *srcline_from_fileline(const char *file, unsigned int line)
65 {
66 	char *srcline;
67 
68 	if (!file)
69 		return NULL;
70 
71 	if (!srcline_full_filename)
72 		file = gnu_basename(file);
73 
74 	if (asprintf(&srcline, "%s:%u", file, line) < 0)
75 		return NULL;
76 
77 	return srcline;
78 }
79 
80 #ifdef HAVE_LIBBFD_SUPPORT
81 
82 /*
83  * Implement addr2line using libbfd.
84  */
85 #define PACKAGE "perf"
86 #include <bfd.h>
87 
88 struct a2l_data {
89 	const char 	*input;
90 	u64	 	addr;
91 
92 	bool 		found;
93 	const char 	*filename;
94 	const char 	*funcname;
95 	unsigned 	line;
96 
97 	bfd 		*abfd;
98 	asymbol 	**syms;
99 };
100 
101 static int bfd_error(const char *string)
102 {
103 	const char *errmsg;
104 
105 	errmsg = bfd_errmsg(bfd_get_error());
106 	fflush(stdout);
107 
108 	if (string)
109 		pr_debug("%s: %s\n", string, errmsg);
110 	else
111 		pr_debug("%s\n", errmsg);
112 
113 	return -1;
114 }
115 
116 static int slurp_symtab(bfd *abfd, struct a2l_data *a2l)
117 {
118 	long storage;
119 	long symcount;
120 	asymbol **syms;
121 	bfd_boolean dynamic = FALSE;
122 
123 	if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
124 		return bfd_error(bfd_get_filename(abfd));
125 
126 	storage = bfd_get_symtab_upper_bound(abfd);
127 	if (storage == 0L) {
128 		storage = bfd_get_dynamic_symtab_upper_bound(abfd);
129 		dynamic = TRUE;
130 	}
131 	if (storage < 0L)
132 		return bfd_error(bfd_get_filename(abfd));
133 
134 	syms = malloc(storage);
135 	if (dynamic)
136 		symcount = bfd_canonicalize_dynamic_symtab(abfd, syms);
137 	else
138 		symcount = bfd_canonicalize_symtab(abfd, syms);
139 
140 	if (symcount < 0) {
141 		free(syms);
142 		return bfd_error(bfd_get_filename(abfd));
143 	}
144 
145 	a2l->syms = syms;
146 	return 0;
147 }
148 
149 static void find_address_in_section(bfd *abfd, asection *section, void *data)
150 {
151 	bfd_vma pc, vma;
152 	bfd_size_type size;
153 	struct a2l_data *a2l = data;
154 
155 	if (a2l->found)
156 		return;
157 
158 	if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
159 		return;
160 
161 	pc = a2l->addr;
162 	vma = bfd_get_section_vma(abfd, section);
163 	size = bfd_get_section_size(section);
164 
165 	if (pc < vma || pc >= vma + size)
166 		return;
167 
168 	a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma,
169 					   &a2l->filename, &a2l->funcname,
170 					   &a2l->line);
171 
172 	if (a2l->filename && !strlen(a2l->filename))
173 		a2l->filename = NULL;
174 }
175 
176 static struct a2l_data *addr2line_init(const char *path)
177 {
178 	bfd *abfd;
179 	struct a2l_data *a2l = NULL;
180 
181 	abfd = bfd_openr(path, NULL);
182 	if (abfd == NULL)
183 		return NULL;
184 
185 	if (!bfd_check_format(abfd, bfd_object))
186 		goto out;
187 
188 	a2l = zalloc(sizeof(*a2l));
189 	if (a2l == NULL)
190 		goto out;
191 
192 	a2l->abfd = abfd;
193 	a2l->input = strdup(path);
194 	if (a2l->input == NULL)
195 		goto out;
196 
197 	if (slurp_symtab(abfd, a2l))
198 		goto out;
199 
200 	return a2l;
201 
202 out:
203 	if (a2l) {
204 		zfree((char **)&a2l->input);
205 		free(a2l);
206 	}
207 	bfd_close(abfd);
208 	return NULL;
209 }
210 
211 static void addr2line_cleanup(struct a2l_data *a2l)
212 {
213 	if (a2l->abfd)
214 		bfd_close(a2l->abfd);
215 	zfree((char **)&a2l->input);
216 	zfree(&a2l->syms);
217 	free(a2l);
218 }
219 
220 #define MAX_INLINE_NEST 1024
221 
222 static struct symbol *new_inline_sym(struct dso *dso,
223 				     struct symbol *base_sym,
224 				     const char *funcname)
225 {
226 	struct symbol *inline_sym;
227 	char *demangled = NULL;
228 
229 	if (dso) {
230 		demangled = dso__demangle_sym(dso, 0, funcname);
231 		if (demangled)
232 			funcname = demangled;
233 	}
234 
235 	if (base_sym && strcmp(funcname, base_sym->name) == 0) {
236 		/* reuse the real, existing symbol */
237 		inline_sym = base_sym;
238 		/* ensure that we don't alias an inlined symbol, which could
239 		 * lead to double frees in inline_node__delete
240 		 */
241 		assert(!base_sym->inlined);
242 	} else {
243 		/* create a fake symbol for the inline frame */
244 		inline_sym = symbol__new(base_sym ? base_sym->start : 0,
245 					 base_sym ? base_sym->end : 0,
246 					 base_sym ? base_sym->binding : 0,
247 					 funcname);
248 		if (inline_sym)
249 			inline_sym->inlined = 1;
250 	}
251 
252 	free(demangled);
253 
254 	return inline_sym;
255 }
256 
257 static int inline_list__append_dso_a2l(struct dso *dso,
258 				       struct inline_node *node,
259 				       struct symbol *sym)
260 {
261 	struct a2l_data *a2l = dso->a2l;
262 	struct symbol *inline_sym = new_inline_sym(dso, sym, a2l->funcname);
263 	char *srcline = NULL;
264 
265 	if (a2l->filename)
266 		srcline = srcline_from_fileline(a2l->filename, a2l->line);
267 
268 	return inline_list__append(inline_sym, srcline, node);
269 }
270 
271 static int addr2line(const char *dso_name, u64 addr,
272 		     char **file, unsigned int *line, struct dso *dso,
273 		     bool unwind_inlines, struct inline_node *node,
274 		     struct symbol *sym)
275 {
276 	int ret = 0;
277 	struct a2l_data *a2l = dso->a2l;
278 
279 	if (!a2l) {
280 		dso->a2l = addr2line_init(dso_name);
281 		a2l = dso->a2l;
282 	}
283 
284 	if (a2l == NULL) {
285 		pr_warning("addr2line_init failed for %s\n", dso_name);
286 		return 0;
287 	}
288 
289 	a2l->addr = addr;
290 	a2l->found = false;
291 
292 	bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
293 
294 	if (!a2l->found)
295 		return 0;
296 
297 	if (unwind_inlines) {
298 		int cnt = 0;
299 
300 		if (node && inline_list__append_dso_a2l(dso, node, sym))
301 			return 0;
302 
303 		while (bfd_find_inliner_info(a2l->abfd, &a2l->filename,
304 					     &a2l->funcname, &a2l->line) &&
305 		       cnt++ < MAX_INLINE_NEST) {
306 
307 			if (a2l->filename && !strlen(a2l->filename))
308 				a2l->filename = NULL;
309 
310 			if (node != NULL) {
311 				if (inline_list__append_dso_a2l(dso, node, sym))
312 					return 0;
313 				// found at least one inline frame
314 				ret = 1;
315 			}
316 		}
317 	}
318 
319 	if (file) {
320 		*file = a2l->filename ? strdup(a2l->filename) : NULL;
321 		ret = *file ? 1 : 0;
322 	}
323 
324 	if (line)
325 		*line = a2l->line;
326 
327 	return ret;
328 }
329 
330 void dso__free_a2l(struct dso *dso)
331 {
332 	struct a2l_data *a2l = dso->a2l;
333 
334 	if (!a2l)
335 		return;
336 
337 	addr2line_cleanup(a2l);
338 
339 	dso->a2l = NULL;
340 }
341 
342 static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
343 					struct dso *dso, struct symbol *sym)
344 {
345 	struct inline_node *node;
346 
347 	node = zalloc(sizeof(*node));
348 	if (node == NULL) {
349 		perror("not enough memory for the inline node");
350 		return NULL;
351 	}
352 
353 	INIT_LIST_HEAD(&node->val);
354 	node->addr = addr;
355 
356 	addr2line(dso_name, addr, NULL, NULL, dso, true, node, sym);
357 	return node;
358 }
359 
360 #else /* HAVE_LIBBFD_SUPPORT */
361 
362 static int filename_split(char *filename, unsigned int *line_nr)
363 {
364 	char *sep;
365 
366 	sep = strchr(filename, '\n');
367 	if (sep)
368 		*sep = '\0';
369 
370 	if (!strcmp(filename, "??:0"))
371 		return 0;
372 
373 	sep = strchr(filename, ':');
374 	if (sep) {
375 		*sep++ = '\0';
376 		*line_nr = strtoul(sep, NULL, 0);
377 		return 1;
378 	}
379 
380 	return 0;
381 }
382 
383 static int addr2line(const char *dso_name, u64 addr,
384 		     char **file, unsigned int *line_nr,
385 		     struct dso *dso __maybe_unused,
386 		     bool unwind_inlines __maybe_unused,
387 		     struct inline_node *node __maybe_unused,
388 		     struct symbol *sym __maybe_unused)
389 {
390 	FILE *fp;
391 	char cmd[PATH_MAX];
392 	char *filename = NULL;
393 	size_t len;
394 	int ret = 0;
395 
396 	scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64,
397 		  dso_name, addr);
398 
399 	fp = popen(cmd, "r");
400 	if (fp == NULL) {
401 		pr_warning("popen failed for %s\n", dso_name);
402 		return 0;
403 	}
404 
405 	if (getline(&filename, &len, fp) < 0 || !len) {
406 		pr_warning("addr2line has no output for %s\n", dso_name);
407 		goto out;
408 	}
409 
410 	ret = filename_split(filename, line_nr);
411 	if (ret != 1) {
412 		free(filename);
413 		goto out;
414 	}
415 
416 	*file = filename;
417 
418 out:
419 	pclose(fp);
420 	return ret;
421 }
422 
423 void dso__free_a2l(struct dso *dso __maybe_unused)
424 {
425 }
426 
427 static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
428 					struct dso *dso __maybe_unused,
429 					struct symbol *sym)
430 {
431 	FILE *fp;
432 	char cmd[PATH_MAX];
433 	struct inline_node *node;
434 	char *filename = NULL;
435 	size_t len;
436 	unsigned int line_nr = 0;
437 
438 	scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i %016"PRIx64,
439 		  dso_name, addr);
440 
441 	fp = popen(cmd, "r");
442 	if (fp == NULL) {
443 		pr_err("popen failed for %s\n", dso_name);
444 		return NULL;
445 	}
446 
447 	node = zalloc(sizeof(*node));
448 	if (node == NULL) {
449 		perror("not enough memory for the inline node");
450 		goto out;
451 	}
452 
453 	INIT_LIST_HEAD(&node->val);
454 	node->addr = addr;
455 
456 	while (getline(&filename, &len, fp) != -1) {
457 		char *srcline;
458 
459 		if (filename_split(filename, &line_nr) != 1) {
460 			free(filename);
461 			goto out;
462 		}
463 
464 		srcline = srcline_from_fileline(filename, line_nr);
465 		if (inline_list__append(sym, srcline, node) != 0)
466 			goto out;
467 
468 		filename = NULL;
469 	}
470 
471 out:
472 	pclose(fp);
473 
474 	return node;
475 }
476 
477 #endif /* HAVE_LIBBFD_SUPPORT */
478 
479 /*
480  * Number of addr2line failures (without success) before disabling it for that
481  * dso.
482  */
483 #define A2L_FAIL_LIMIT 123
484 
485 char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
486 		  bool show_sym, bool show_addr, bool unwind_inlines)
487 {
488 	char *file = NULL;
489 	unsigned line = 0;
490 	char *srcline;
491 	const char *dso_name;
492 
493 	if (!dso->has_srcline)
494 		goto out;
495 
496 	dso_name = dso__name(dso);
497 	if (dso_name == NULL)
498 		goto out;
499 
500 	if (!addr2line(dso_name, addr, &file, &line, dso,
501 		       unwind_inlines, NULL, sym))
502 		goto out;
503 
504 	srcline = srcline_from_fileline(file, line);
505 	free(file);
506 
507 	if (!srcline)
508 		goto out;
509 
510 	dso->a2l_fails = 0;
511 
512 	return srcline;
513 
514 out:
515 	if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) {
516 		dso->has_srcline = 0;
517 		dso__free_a2l(dso);
518 	}
519 
520 	if (!show_addr)
521 		return (show_sym && sym) ?
522 			    strndup(sym->name, sym->namelen) : NULL;
523 
524 	if (sym) {
525 		if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "",
526 					addr - sym->start) < 0)
527 			return SRCLINE_UNKNOWN;
528 	} else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0)
529 		return SRCLINE_UNKNOWN;
530 	return srcline;
531 }
532 
533 void free_srcline(char *srcline)
534 {
535 	if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
536 		free(srcline);
537 }
538 
539 char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
540 		  bool show_sym, bool show_addr)
541 {
542 	return __get_srcline(dso, addr, sym, show_sym, show_addr, false);
543 }
544 
545 struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr,
546 					    struct symbol *sym)
547 {
548 	const char *dso_name;
549 
550 	dso_name = dso__name(dso);
551 	if (dso_name == NULL)
552 		return NULL;
553 
554 	return addr2inlines(dso_name, addr, dso, sym);
555 }
556 
557 void inline_node__delete(struct inline_node *node)
558 {
559 	struct inline_list *ilist, *tmp;
560 
561 	list_for_each_entry_safe(ilist, tmp, &node->val, list) {
562 		list_del_init(&ilist->list);
563 		free_srcline(ilist->srcline);
564 		/* only the inlined symbols are owned by the list */
565 		if (ilist->symbol && ilist->symbol->inlined)
566 			symbol__delete(ilist->symbol);
567 		free(ilist);
568 	}
569 
570 	free(node);
571 }
572 
573 void inlines__tree_insert(struct rb_root *tree, struct inline_node *inlines)
574 {
575 	struct rb_node **p = &tree->rb_node;
576 	struct rb_node *parent = NULL;
577 	const u64 addr = inlines->addr;
578 	struct inline_node *i;
579 
580 	while (*p != NULL) {
581 		parent = *p;
582 		i = rb_entry(parent, struct inline_node, rb_node);
583 		if (addr < i->addr)
584 			p = &(*p)->rb_left;
585 		else
586 			p = &(*p)->rb_right;
587 	}
588 	rb_link_node(&inlines->rb_node, parent, p);
589 	rb_insert_color(&inlines->rb_node, tree);
590 }
591 
592 struct inline_node *inlines__tree_find(struct rb_root *tree, u64 addr)
593 {
594 	struct rb_node *n = tree->rb_node;
595 
596 	while (n) {
597 		struct inline_node *i = rb_entry(n, struct inline_node,
598 						 rb_node);
599 
600 		if (addr < i->addr)
601 			n = n->rb_left;
602 		else if (addr > i->addr)
603 			n = n->rb_right;
604 		else
605 			return i;
606 	}
607 
608 	return NULL;
609 }
610 
611 void inlines__tree_delete(struct rb_root *tree)
612 {
613 	struct inline_node *pos;
614 	struct rb_node *next = rb_first(tree);
615 
616 	while (next) {
617 		pos = rb_entry(next, struct inline_node, rb_node);
618 		next = rb_next(&pos->rb_node);
619 		rb_erase(&pos->rb_node, tree);
620 		inline_node__delete(pos);
621 	}
622 }
623