1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/kernel.h>
10 #include "util/util.h"
11 #include "util/debug.h"
12 #include "util/callchain.h"
17 bool srcline_full_filename
;
19 static const char *dso__name(struct dso
*dso
)
23 if (dso
->symsrc_filename
)
24 dso_name
= dso
->symsrc_filename
;
26 dso_name
= dso
->long_name
;
28 if (dso_name
[0] == '[')
31 if (!strncmp(dso_name
, "/tmp/perf-", 10))
37 static int inline_list__append(struct symbol
*symbol
, char *srcline
,
38 struct inline_node
*node
)
40 struct inline_list
*ilist
;
42 ilist
= zalloc(sizeof(*ilist
));
46 ilist
->symbol
= symbol
;
47 ilist
->srcline
= srcline
;
49 if (callchain_param
.order
== ORDER_CALLEE
)
50 list_add_tail(&ilist
->list
, &node
->val
);
52 list_add(&ilist
->list
, &node
->val
);
57 /* basename version that takes a const input string */
58 static const char *gnu_basename(const char *path
)
60 const char *base
= strrchr(path
, '/');
62 return base
? base
+ 1 : path
;
65 static char *srcline_from_fileline(const char *file
, unsigned int line
)
72 if (!srcline_full_filename
)
73 file
= gnu_basename(file
);
75 if (asprintf(&srcline
, "%s:%u", file
, line
) < 0)
81 static struct symbol
*new_inline_sym(struct dso
*dso
,
82 struct symbol
*base_sym
,
85 struct symbol
*inline_sym
;
86 char *demangled
= NULL
;
89 demangled
= dso__demangle_sym(dso
, 0, funcname
);
94 if (base_sym
&& strcmp(funcname
, base_sym
->name
) == 0) {
95 /* reuse the real, existing symbol */
96 inline_sym
= base_sym
;
97 /* ensure that we don't alias an inlined symbol, which could
98 * lead to double frees in inline_node__delete
100 assert(!base_sym
->inlined
);
102 /* create a fake symbol for the inline frame */
103 inline_sym
= symbol__new(base_sym
? base_sym
->start
: 0,
104 base_sym
? base_sym
->end
: 0,
105 base_sym
? base_sym
->binding
: 0,
106 base_sym
? base_sym
->type
: 0,
109 inline_sym
->inlined
= 1;
117 #ifdef HAVE_LIBBFD_SUPPORT
120 * Implement addr2line using libbfd.
122 #define PACKAGE "perf"
130 const char *filename
;
131 const char *funcname
;
138 static int bfd_error(const char *string
)
142 errmsg
= bfd_errmsg(bfd_get_error());
146 pr_debug("%s: %s\n", string
, errmsg
);
148 pr_debug("%s\n", errmsg
);
153 static int slurp_symtab(bfd
*abfd
, struct a2l_data
*a2l
)
158 bfd_boolean dynamic
= FALSE
;
160 if ((bfd_get_file_flags(abfd
) & HAS_SYMS
) == 0)
161 return bfd_error(bfd_get_filename(abfd
));
163 storage
= bfd_get_symtab_upper_bound(abfd
);
165 storage
= bfd_get_dynamic_symtab_upper_bound(abfd
);
169 return bfd_error(bfd_get_filename(abfd
));
171 syms
= malloc(storage
);
173 symcount
= bfd_canonicalize_dynamic_symtab(abfd
, syms
);
175 symcount
= bfd_canonicalize_symtab(abfd
, syms
);
179 return bfd_error(bfd_get_filename(abfd
));
186 static void find_address_in_section(bfd
*abfd
, asection
*section
, void *data
)
190 struct a2l_data
*a2l
= data
;
195 if ((bfd_get_section_flags(abfd
, section
) & SEC_ALLOC
) == 0)
199 vma
= bfd_get_section_vma(abfd
, section
);
200 size
= bfd_get_section_size(section
);
202 if (pc
< vma
|| pc
>= vma
+ size
)
205 a2l
->found
= bfd_find_nearest_line(abfd
, section
, a2l
->syms
, pc
- vma
,
206 &a2l
->filename
, &a2l
->funcname
,
209 if (a2l
->filename
&& !strlen(a2l
->filename
))
210 a2l
->filename
= NULL
;
213 static struct a2l_data
*addr2line_init(const char *path
)
216 struct a2l_data
*a2l
= NULL
;
218 abfd
= bfd_openr(path
, NULL
);
222 if (!bfd_check_format(abfd
, bfd_object
))
225 a2l
= zalloc(sizeof(*a2l
));
230 a2l
->input
= strdup(path
);
231 if (a2l
->input
== NULL
)
234 if (slurp_symtab(abfd
, a2l
))
241 zfree((char **)&a2l
->input
);
248 static void addr2line_cleanup(struct a2l_data
*a2l
)
251 bfd_close(a2l
->abfd
);
252 zfree((char **)&a2l
->input
);
257 #define MAX_INLINE_NEST 1024
259 static int inline_list__append_dso_a2l(struct dso
*dso
,
260 struct inline_node
*node
,
263 struct a2l_data
*a2l
= dso
->a2l
;
264 struct symbol
*inline_sym
= new_inline_sym(dso
, sym
, a2l
->funcname
);
265 char *srcline
= NULL
;
268 srcline
= srcline_from_fileline(a2l
->filename
, a2l
->line
);
270 return inline_list__append(inline_sym
, srcline
, node
);
273 static int addr2line(const char *dso_name
, u64 addr
,
274 char **file
, unsigned int *line
, struct dso
*dso
,
275 bool unwind_inlines
, struct inline_node
*node
,
279 struct a2l_data
*a2l
= dso
->a2l
;
282 dso
->a2l
= addr2line_init(dso_name
);
287 pr_warning("addr2line_init failed for %s\n", dso_name
);
294 bfd_map_over_sections(a2l
->abfd
, find_address_in_section
, a2l
);
299 if (unwind_inlines
) {
302 if (node
&& inline_list__append_dso_a2l(dso
, node
, sym
))
305 while (bfd_find_inliner_info(a2l
->abfd
, &a2l
->filename
,
306 &a2l
->funcname
, &a2l
->line
) &&
307 cnt
++ < MAX_INLINE_NEST
) {
309 if (a2l
->filename
&& !strlen(a2l
->filename
))
310 a2l
->filename
= NULL
;
313 if (inline_list__append_dso_a2l(dso
, node
, sym
))
315 // found at least one inline frame
322 *file
= a2l
->filename
? strdup(a2l
->filename
) : NULL
;
332 void dso__free_a2l(struct dso
*dso
)
334 struct a2l_data
*a2l
= dso
->a2l
;
339 addr2line_cleanup(a2l
);
344 static struct inline_node
*addr2inlines(const char *dso_name
, u64 addr
,
345 struct dso
*dso
, struct symbol
*sym
)
347 struct inline_node
*node
;
349 node
= zalloc(sizeof(*node
));
351 perror("not enough memory for the inline node");
355 INIT_LIST_HEAD(&node
->val
);
358 addr2line(dso_name
, addr
, NULL
, NULL
, dso
, true, node
, sym
);
362 #else /* HAVE_LIBBFD_SUPPORT */
364 static int filename_split(char *filename
, unsigned int *line_nr
)
368 sep
= strchr(filename
, '\n');
372 if (!strcmp(filename
, "??:0"))
375 sep
= strchr(filename
, ':');
378 *line_nr
= strtoul(sep
, NULL
, 0);
385 static int addr2line(const char *dso_name
, u64 addr
,
386 char **file
, unsigned int *line_nr
,
387 struct dso
*dso __maybe_unused
,
388 bool unwind_inlines __maybe_unused
,
389 struct inline_node
*node __maybe_unused
,
390 struct symbol
*sym __maybe_unused
)
394 char *filename
= NULL
;
398 scnprintf(cmd
, sizeof(cmd
), "addr2line -e %s %016"PRIx64
,
401 fp
= popen(cmd
, "r");
403 pr_warning("popen failed for %s\n", dso_name
);
407 if (getline(&filename
, &len
, fp
) < 0 || !len
) {
408 pr_warning("addr2line has no output for %s\n", dso_name
);
412 ret
= filename_split(filename
, line_nr
);
425 void dso__free_a2l(struct dso
*dso __maybe_unused
)
429 static struct inline_node
*addr2inlines(const char *dso_name
, u64 addr
,
430 struct dso
*dso __maybe_unused
,
435 struct inline_node
*node
;
436 char *filename
= NULL
;
437 char *funcname
= NULL
;
438 size_t filelen
, funclen
;
439 unsigned int line_nr
= 0;
441 scnprintf(cmd
, sizeof(cmd
), "addr2line -e %s -i -f %016"PRIx64
,
444 fp
= popen(cmd
, "r");
446 pr_err("popen failed for %s\n", dso_name
);
450 node
= zalloc(sizeof(*node
));
452 perror("not enough memory for the inline node");
456 INIT_LIST_HEAD(&node
->val
);
459 /* addr2line -f generates two lines for each inlined functions */
460 while (getline(&funcname
, &funclen
, fp
) != -1) {
462 struct symbol
*inline_sym
;
466 if (getline(&filename
, &filelen
, fp
) == -1)
469 if (filename_split(filename
, &line_nr
) != 1)
472 srcline
= srcline_from_fileline(filename
, line_nr
);
473 inline_sym
= new_inline_sym(dso
, sym
, funcname
);
475 if (inline_list__append(inline_sym
, srcline
, node
) != 0) {
477 if (inline_sym
&& inline_sym
->inlined
)
478 symbol__delete(inline_sym
);
491 #endif /* HAVE_LIBBFD_SUPPORT */
494 * Number of addr2line failures (without success) before disabling it for that
497 #define A2L_FAIL_LIMIT 123
499 char *__get_srcline(struct dso
*dso
, u64 addr
, struct symbol
*sym
,
500 bool show_sym
, bool show_addr
, bool unwind_inlines
,
506 const char *dso_name
;
508 if (!dso
->has_srcline
)
511 dso_name
= dso__name(dso
);
512 if (dso_name
== NULL
)
515 if (!addr2line(dso_name
, addr
, &file
, &line
, dso
,
516 unwind_inlines
, NULL
, sym
))
519 srcline
= srcline_from_fileline(file
, line
);
530 if (dso
->a2l_fails
&& ++dso
->a2l_fails
> A2L_FAIL_LIMIT
) {
531 dso
->has_srcline
= 0;
536 return (show_sym
&& sym
) ?
537 strndup(sym
->name
, sym
->namelen
) : NULL
;
540 if (asprintf(&srcline
, "%s+%" PRIu64
, show_sym
? sym
->name
: "",
541 ip
- sym
->start
) < 0)
542 return SRCLINE_UNKNOWN
;
543 } else if (asprintf(&srcline
, "%s[%" PRIx64
"]", dso
->short_name
, addr
) < 0)
544 return SRCLINE_UNKNOWN
;
548 void free_srcline(char *srcline
)
550 if (srcline
&& strcmp(srcline
, SRCLINE_UNKNOWN
) != 0)
554 char *get_srcline(struct dso
*dso
, u64 addr
, struct symbol
*sym
,
555 bool show_sym
, bool show_addr
, u64 ip
)
557 return __get_srcline(dso
, addr
, sym
, show_sym
, show_addr
, false, ip
);
560 struct srcline_node
{
563 struct rb_node rb_node
;
566 void srcline__tree_insert(struct rb_root
*tree
, u64 addr
, char *srcline
)
568 struct rb_node
**p
= &tree
->rb_node
;
569 struct rb_node
*parent
= NULL
;
570 struct srcline_node
*i
, *node
;
572 node
= zalloc(sizeof(struct srcline_node
));
574 perror("not enough memory for the srcline node");
579 node
->srcline
= srcline
;
583 i
= rb_entry(parent
, struct srcline_node
, rb_node
);
589 rb_link_node(&node
->rb_node
, parent
, p
);
590 rb_insert_color(&node
->rb_node
, tree
);
593 char *srcline__tree_find(struct rb_root
*tree
, u64 addr
)
595 struct rb_node
*n
= tree
->rb_node
;
598 struct srcline_node
*i
= rb_entry(n
, struct srcline_node
,
603 else if (addr
> i
->addr
)
612 void srcline__tree_delete(struct rb_root
*tree
)
614 struct srcline_node
*pos
;
615 struct rb_node
*next
= rb_first(tree
);
618 pos
= rb_entry(next
, struct srcline_node
, rb_node
);
619 next
= rb_next(&pos
->rb_node
);
620 rb_erase(&pos
->rb_node
, tree
);
621 free_srcline(pos
->srcline
);
626 struct inline_node
*dso__parse_addr_inlines(struct dso
*dso
, u64 addr
,
629 const char *dso_name
;
631 dso_name
= dso__name(dso
);
632 if (dso_name
== NULL
)
635 return addr2inlines(dso_name
, addr
, dso
, sym
);
638 void inline_node__delete(struct inline_node
*node
)
640 struct inline_list
*ilist
, *tmp
;
642 list_for_each_entry_safe(ilist
, tmp
, &node
->val
, list
) {
643 list_del_init(&ilist
->list
);
644 free_srcline(ilist
->srcline
);
645 /* only the inlined symbols are owned by the list */
646 if (ilist
->symbol
&& ilist
->symbol
->inlined
)
647 symbol__delete(ilist
->symbol
);
654 void inlines__tree_insert(struct rb_root
*tree
, struct inline_node
*inlines
)
656 struct rb_node
**p
= &tree
->rb_node
;
657 struct rb_node
*parent
= NULL
;
658 const u64 addr
= inlines
->addr
;
659 struct inline_node
*i
;
663 i
= rb_entry(parent
, struct inline_node
, rb_node
);
669 rb_link_node(&inlines
->rb_node
, parent
, p
);
670 rb_insert_color(&inlines
->rb_node
, tree
);
673 struct inline_node
*inlines__tree_find(struct rb_root
*tree
, u64 addr
)
675 struct rb_node
*n
= tree
->rb_node
;
678 struct inline_node
*i
= rb_entry(n
, struct inline_node
,
683 else if (addr
> i
->addr
)
692 void inlines__tree_delete(struct rb_root
*tree
)
694 struct inline_node
*pos
;
695 struct rb_node
*next
= rb_first(tree
);
698 pos
= rb_entry(next
, struct inline_node
, rb_node
);
699 next
= rb_next(&pos
->rb_node
);
700 rb_erase(&pos
->rb_node
, tree
);
701 inline_node__delete(pos
);