1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/kernel.h>
8 #include <linux/string.h>
9 #include <linux/zalloc.h>
12 #include "util/debug.h"
13 #include "util/callchain.h"
14 #include "util/symbol_conf.h"
19 bool srcline_full_filename
;
21 static const char *dso__name(struct dso
*dso
)
25 if (dso
->symsrc_filename
)
26 dso_name
= dso
->symsrc_filename
;
28 dso_name
= dso
->long_name
;
30 if (dso_name
[0] == '[')
33 if (!strncmp(dso_name
, "/tmp/perf-", 10))
39 static int inline_list__append(struct symbol
*symbol
, char *srcline
,
40 struct inline_node
*node
)
42 struct inline_list
*ilist
;
44 ilist
= zalloc(sizeof(*ilist
));
48 ilist
->symbol
= symbol
;
49 ilist
->srcline
= srcline
;
51 if (callchain_param
.order
== ORDER_CALLEE
)
52 list_add_tail(&ilist
->list
, &node
->val
);
54 list_add(&ilist
->list
, &node
->val
);
59 /* basename version that takes a const input string */
60 static const char *gnu_basename(const char *path
)
62 const char *base
= strrchr(path
, '/');
64 return base
? base
+ 1 : path
;
67 static char *srcline_from_fileline(const char *file
, unsigned int line
)
74 if (!srcline_full_filename
)
75 file
= gnu_basename(file
);
77 if (asprintf(&srcline
, "%s:%u", file
, line
) < 0)
83 static struct symbol
*new_inline_sym(struct dso
*dso
,
84 struct symbol
*base_sym
,
87 struct symbol
*inline_sym
;
88 char *demangled
= NULL
;
94 demangled
= dso__demangle_sym(dso
, 0, funcname
);
99 if (base_sym
&& strcmp(funcname
, base_sym
->name
) == 0) {
100 /* reuse the real, existing symbol */
101 inline_sym
= base_sym
;
102 /* ensure that we don't alias an inlined symbol, which could
103 * lead to double frees in inline_node__delete
105 assert(!base_sym
->inlined
);
107 /* create a fake symbol for the inline frame */
108 inline_sym
= symbol__new(base_sym
? base_sym
->start
: 0,
109 base_sym
? (base_sym
->end
- base_sym
->start
) : 0,
110 base_sym
? base_sym
->binding
: 0,
111 base_sym
? base_sym
->type
: 0,
114 inline_sym
->inlined
= 1;
122 #ifdef HAVE_LIBBFD_SUPPORT
125 * Implement addr2line using libbfd.
127 #define PACKAGE "perf"
135 const char *filename
;
136 const char *funcname
;
143 static int bfd_error(const char *string
)
147 errmsg
= bfd_errmsg(bfd_get_error());
151 pr_debug("%s: %s\n", string
, errmsg
);
153 pr_debug("%s\n", errmsg
);
158 static int slurp_symtab(bfd
*abfd
, struct a2l_data
*a2l
)
163 bfd_boolean dynamic
= FALSE
;
165 if ((bfd_get_file_flags(abfd
) & HAS_SYMS
) == 0)
166 return bfd_error(bfd_get_filename(abfd
));
168 storage
= bfd_get_symtab_upper_bound(abfd
);
170 storage
= bfd_get_dynamic_symtab_upper_bound(abfd
);
174 return bfd_error(bfd_get_filename(abfd
));
176 syms
= malloc(storage
);
178 symcount
= bfd_canonicalize_dynamic_symtab(abfd
, syms
);
180 symcount
= bfd_canonicalize_symtab(abfd
, syms
);
184 return bfd_error(bfd_get_filename(abfd
));
191 static void find_address_in_section(bfd
*abfd
, asection
*section
, void *data
)
195 struct a2l_data
*a2l
= data
;
200 if ((bfd_get_section_flags(abfd
, section
) & SEC_ALLOC
) == 0)
204 vma
= bfd_get_section_vma(abfd
, section
);
205 size
= bfd_get_section_size(section
);
207 if (pc
< vma
|| pc
>= vma
+ size
)
210 a2l
->found
= bfd_find_nearest_line(abfd
, section
, a2l
->syms
, pc
- vma
,
211 &a2l
->filename
, &a2l
->funcname
,
214 if (a2l
->filename
&& !strlen(a2l
->filename
))
215 a2l
->filename
= NULL
;
218 static struct a2l_data
*addr2line_init(const char *path
)
221 struct a2l_data
*a2l
= NULL
;
223 abfd
= bfd_openr(path
, NULL
);
227 if (!bfd_check_format(abfd
, bfd_object
))
230 a2l
= zalloc(sizeof(*a2l
));
235 a2l
->input
= strdup(path
);
236 if (a2l
->input
== NULL
)
239 if (slurp_symtab(abfd
, a2l
))
246 zfree((char **)&a2l
->input
);
253 static void addr2line_cleanup(struct a2l_data
*a2l
)
256 bfd_close(a2l
->abfd
);
257 zfree((char **)&a2l
->input
);
262 #define MAX_INLINE_NEST 1024
264 static int inline_list__append_dso_a2l(struct dso
*dso
,
265 struct inline_node
*node
,
268 struct a2l_data
*a2l
= dso
->a2l
;
269 struct symbol
*inline_sym
= new_inline_sym(dso
, sym
, a2l
->funcname
);
270 char *srcline
= NULL
;
273 srcline
= srcline_from_fileline(a2l
->filename
, a2l
->line
);
275 return inline_list__append(inline_sym
, srcline
, node
);
278 static int addr2line(const char *dso_name
, u64 addr
,
279 char **file
, unsigned int *line
, struct dso
*dso
,
280 bool unwind_inlines
, struct inline_node
*node
,
284 struct a2l_data
*a2l
= dso
->a2l
;
287 dso
->a2l
= addr2line_init(dso_name
);
292 if (!symbol_conf
.disable_add2line_warn
)
293 pr_warning("addr2line_init failed for %s\n", dso_name
);
300 bfd_map_over_sections(a2l
->abfd
, find_address_in_section
, a2l
);
305 if (unwind_inlines
) {
308 if (node
&& inline_list__append_dso_a2l(dso
, node
, sym
))
311 while (bfd_find_inliner_info(a2l
->abfd
, &a2l
->filename
,
312 &a2l
->funcname
, &a2l
->line
) &&
313 cnt
++ < MAX_INLINE_NEST
) {
315 if (a2l
->filename
&& !strlen(a2l
->filename
))
316 a2l
->filename
= NULL
;
319 if (inline_list__append_dso_a2l(dso
, node
, sym
))
321 // found at least one inline frame
328 *file
= a2l
->filename
? strdup(a2l
->filename
) : NULL
;
338 void dso__free_a2l(struct dso
*dso
)
340 struct a2l_data
*a2l
= dso
->a2l
;
345 addr2line_cleanup(a2l
);
350 static struct inline_node
*addr2inlines(const char *dso_name
, u64 addr
,
351 struct dso
*dso
, struct symbol
*sym
)
353 struct inline_node
*node
;
355 node
= zalloc(sizeof(*node
));
357 perror("not enough memory for the inline node");
361 INIT_LIST_HEAD(&node
->val
);
364 addr2line(dso_name
, addr
, NULL
, NULL
, dso
, true, node
, sym
);
368 #else /* HAVE_LIBBFD_SUPPORT */
370 static int filename_split(char *filename
, unsigned int *line_nr
)
374 sep
= strchr(filename
, '\n');
378 if (!strcmp(filename
, "??:0"))
381 sep
= strchr(filename
, ':');
384 *line_nr
= strtoul(sep
, NULL
, 0);
391 static int addr2line(const char *dso_name
, u64 addr
,
392 char **file
, unsigned int *line_nr
,
393 struct dso
*dso __maybe_unused
,
394 bool unwind_inlines __maybe_unused
,
395 struct inline_node
*node __maybe_unused
,
396 struct symbol
*sym __maybe_unused
)
400 char *filename
= NULL
;
404 scnprintf(cmd
, sizeof(cmd
), "addr2line -e %s %016"PRIx64
,
407 fp
= popen(cmd
, "r");
409 pr_warning("popen failed for %s\n", dso_name
);
413 if (getline(&filename
, &len
, fp
) < 0 || !len
) {
414 pr_warning("addr2line has no output for %s\n", dso_name
);
418 ret
= filename_split(filename
, line_nr
);
431 void dso__free_a2l(struct dso
*dso __maybe_unused
)
435 static struct inline_node
*addr2inlines(const char *dso_name
, u64 addr
,
436 struct dso
*dso __maybe_unused
,
441 struct inline_node
*node
;
442 char *filename
= NULL
;
443 char *funcname
= NULL
;
444 size_t filelen
, funclen
;
445 unsigned int line_nr
= 0;
447 scnprintf(cmd
, sizeof(cmd
), "addr2line -e %s -i -f %016"PRIx64
,
450 fp
= popen(cmd
, "r");
452 pr_err("popen failed for %s\n", dso_name
);
456 node
= zalloc(sizeof(*node
));
458 perror("not enough memory for the inline node");
462 INIT_LIST_HEAD(&node
->val
);
465 /* addr2line -f generates two lines for each inlined functions */
466 while (getline(&funcname
, &funclen
, fp
) != -1) {
468 struct symbol
*inline_sym
;
472 if (getline(&filename
, &filelen
, fp
) == -1)
475 if (filename_split(filename
, &line_nr
) != 1)
478 srcline
= srcline_from_fileline(filename
, line_nr
);
479 inline_sym
= new_inline_sym(dso
, sym
, funcname
);
481 if (inline_list__append(inline_sym
, srcline
, node
) != 0) {
483 if (inline_sym
&& inline_sym
->inlined
)
484 symbol__delete(inline_sym
);
497 #endif /* HAVE_LIBBFD_SUPPORT */
500 * Number of addr2line failures (without success) before disabling it for that
503 #define A2L_FAIL_LIMIT 123
505 char *__get_srcline(struct dso
*dso
, u64 addr
, struct symbol
*sym
,
506 bool show_sym
, bool show_addr
, bool unwind_inlines
,
512 const char *dso_name
;
514 if (!dso
->has_srcline
)
517 dso_name
= dso__name(dso
);
518 if (dso_name
== NULL
)
521 if (!addr2line(dso_name
, addr
, &file
, &line
, dso
,
522 unwind_inlines
, NULL
, sym
))
525 srcline
= srcline_from_fileline(file
, line
);
536 if (dso
->a2l_fails
&& ++dso
->a2l_fails
> A2L_FAIL_LIMIT
) {
537 dso
->has_srcline
= 0;
542 return (show_sym
&& sym
) ?
543 strndup(sym
->name
, sym
->namelen
) : NULL
;
546 if (asprintf(&srcline
, "%s+%" PRIu64
, show_sym
? sym
->name
: "",
547 ip
- sym
->start
) < 0)
548 return SRCLINE_UNKNOWN
;
549 } else if (asprintf(&srcline
, "%s[%" PRIx64
"]", dso
->short_name
, addr
) < 0)
550 return SRCLINE_UNKNOWN
;
554 /* Returns filename and fills in line number in line */
555 char *get_srcline_split(struct dso
*dso
, u64 addr
, unsigned *line
)
558 const char *dso_name
;
560 if (!dso
->has_srcline
)
563 dso_name
= dso__name(dso
);
564 if (dso_name
== NULL
)
567 if (!addr2line(dso_name
, addr
, &file
, line
, dso
, true, NULL
, NULL
))
574 if (dso
->a2l_fails
&& ++dso
->a2l_fails
> A2L_FAIL_LIMIT
) {
575 dso
->has_srcline
= 0;
582 void free_srcline(char *srcline
)
584 if (srcline
&& strcmp(srcline
, SRCLINE_UNKNOWN
) != 0)
588 char *get_srcline(struct dso
*dso
, u64 addr
, struct symbol
*sym
,
589 bool show_sym
, bool show_addr
, u64 ip
)
591 return __get_srcline(dso
, addr
, sym
, show_sym
, show_addr
, false, ip
);
594 struct srcline_node
{
597 struct rb_node rb_node
;
600 void srcline__tree_insert(struct rb_root_cached
*tree
, u64 addr
, char *srcline
)
602 struct rb_node
**p
= &tree
->rb_root
.rb_node
;
603 struct rb_node
*parent
= NULL
;
604 struct srcline_node
*i
, *node
;
605 bool leftmost
= true;
607 node
= zalloc(sizeof(struct srcline_node
));
609 perror("not enough memory for the srcline node");
614 node
->srcline
= srcline
;
618 i
= rb_entry(parent
, struct srcline_node
, rb_node
);
626 rb_link_node(&node
->rb_node
, parent
, p
);
627 rb_insert_color_cached(&node
->rb_node
, tree
, leftmost
);
630 char *srcline__tree_find(struct rb_root_cached
*tree
, u64 addr
)
632 struct rb_node
*n
= tree
->rb_root
.rb_node
;
635 struct srcline_node
*i
= rb_entry(n
, struct srcline_node
,
640 else if (addr
> i
->addr
)
649 void srcline__tree_delete(struct rb_root_cached
*tree
)
651 struct srcline_node
*pos
;
652 struct rb_node
*next
= rb_first_cached(tree
);
655 pos
= rb_entry(next
, struct srcline_node
, rb_node
);
656 next
= rb_next(&pos
->rb_node
);
657 rb_erase_cached(&pos
->rb_node
, tree
);
658 free_srcline(pos
->srcline
);
663 struct inline_node
*dso__parse_addr_inlines(struct dso
*dso
, u64 addr
,
666 const char *dso_name
;
668 dso_name
= dso__name(dso
);
669 if (dso_name
== NULL
)
672 return addr2inlines(dso_name
, addr
, dso
, sym
);
675 void inline_node__delete(struct inline_node
*node
)
677 struct inline_list
*ilist
, *tmp
;
679 list_for_each_entry_safe(ilist
, tmp
, &node
->val
, list
) {
680 list_del_init(&ilist
->list
);
681 free_srcline(ilist
->srcline
);
682 /* only the inlined symbols are owned by the list */
683 if (ilist
->symbol
&& ilist
->symbol
->inlined
)
684 symbol__delete(ilist
->symbol
);
691 void inlines__tree_insert(struct rb_root_cached
*tree
,
692 struct inline_node
*inlines
)
694 struct rb_node
**p
= &tree
->rb_root
.rb_node
;
695 struct rb_node
*parent
= NULL
;
696 const u64 addr
= inlines
->addr
;
697 struct inline_node
*i
;
698 bool leftmost
= true;
702 i
= rb_entry(parent
, struct inline_node
, rb_node
);
710 rb_link_node(&inlines
->rb_node
, parent
, p
);
711 rb_insert_color_cached(&inlines
->rb_node
, tree
, leftmost
);
714 struct inline_node
*inlines__tree_find(struct rb_root_cached
*tree
, u64 addr
)
716 struct rb_node
*n
= tree
->rb_root
.rb_node
;
719 struct inline_node
*i
= rb_entry(n
, struct inline_node
,
724 else if (addr
> i
->addr
)
733 void inlines__tree_delete(struct rb_root_cached
*tree
)
735 struct inline_node
*pos
;
736 struct rb_node
*next
= rb_first_cached(tree
);
739 pos
= rb_entry(next
, struct inline_node
, rb_node
);
740 next
= rb_next(&pos
->rb_node
);
741 rb_erase_cached(&pos
->rb_node
, tree
);
742 inline_node__delete(pos
);