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(char *filename
, char *funcname
, int line_nr
,
38 struct inline_node
*node
, struct dso
*dso
)
40 struct inline_list
*ilist
;
43 ilist
= zalloc(sizeof(*ilist
));
47 ilist
->filename
= filename
;
48 ilist
->line_nr
= line_nr
;
51 demangled
= dso__demangle_sym(dso
, 0, funcname
);
52 if (demangled
== NULL
) {
53 ilist
->funcname
= funcname
;
55 ilist
->funcname
= demangled
;
60 if (callchain_param
.order
== ORDER_CALLEE
)
61 list_add_tail(&ilist
->list
, &node
->val
);
63 list_add(&ilist
->list
, &node
->val
);
68 #ifdef HAVE_LIBBFD_SUPPORT
71 * Implement addr2line using libbfd.
73 #define PACKAGE "perf"
89 static int bfd_error(const char *string
)
93 errmsg
= bfd_errmsg(bfd_get_error());
97 pr_debug("%s: %s\n", string
, errmsg
);
99 pr_debug("%s\n", errmsg
);
104 static int slurp_symtab(bfd
*abfd
, struct a2l_data
*a2l
)
109 bfd_boolean dynamic
= FALSE
;
111 if ((bfd_get_file_flags(abfd
) & HAS_SYMS
) == 0)
112 return bfd_error(bfd_get_filename(abfd
));
114 storage
= bfd_get_symtab_upper_bound(abfd
);
116 storage
= bfd_get_dynamic_symtab_upper_bound(abfd
);
120 return bfd_error(bfd_get_filename(abfd
));
122 syms
= malloc(storage
);
124 symcount
= bfd_canonicalize_dynamic_symtab(abfd
, syms
);
126 symcount
= bfd_canonicalize_symtab(abfd
, syms
);
130 return bfd_error(bfd_get_filename(abfd
));
137 static void find_address_in_section(bfd
*abfd
, asection
*section
, void *data
)
141 struct a2l_data
*a2l
= data
;
146 if ((bfd_get_section_flags(abfd
, section
) & SEC_ALLOC
) == 0)
150 vma
= bfd_get_section_vma(abfd
, section
);
151 size
= bfd_get_section_size(section
);
153 if (pc
< vma
|| pc
>= vma
+ size
)
156 a2l
->found
= bfd_find_nearest_line(abfd
, section
, a2l
->syms
, pc
- vma
,
157 &a2l
->filename
, &a2l
->funcname
,
160 if (a2l
->filename
&& !strlen(a2l
->filename
))
161 a2l
->filename
= NULL
;
164 static struct a2l_data
*addr2line_init(const char *path
)
167 struct a2l_data
*a2l
= NULL
;
169 abfd
= bfd_openr(path
, NULL
);
173 if (!bfd_check_format(abfd
, bfd_object
))
176 a2l
= zalloc(sizeof(*a2l
));
181 a2l
->input
= strdup(path
);
182 if (a2l
->input
== NULL
)
185 if (slurp_symtab(abfd
, a2l
))
192 zfree((char **)&a2l
->input
);
199 static void addr2line_cleanup(struct a2l_data
*a2l
)
202 bfd_close(a2l
->abfd
);
203 zfree((char **)&a2l
->input
);
208 #define MAX_INLINE_NEST 1024
210 static int inline_list__append_dso_a2l(struct dso
*dso
,
211 struct inline_node
*node
)
213 struct a2l_data
*a2l
= dso
->a2l
;
214 char *funcname
= a2l
->funcname
? strdup(a2l
->funcname
) : NULL
;
215 char *filename
= a2l
->filename
? strdup(a2l
->filename
) : NULL
;
217 return inline_list__append(filename
, funcname
, a2l
->line
, node
, dso
);
220 static int addr2line(const char *dso_name
, u64 addr
,
221 char **file
, unsigned int *line
, struct dso
*dso
,
222 bool unwind_inlines
, struct inline_node
*node
)
225 struct a2l_data
*a2l
= dso
->a2l
;
228 dso
->a2l
= addr2line_init(dso_name
);
233 pr_warning("addr2line_init failed for %s\n", dso_name
);
240 bfd_map_over_sections(a2l
->abfd
, find_address_in_section
, a2l
);
245 if (unwind_inlines
) {
248 if (node
&& inline_list__append_dso_a2l(dso
, node
))
251 while (bfd_find_inliner_info(a2l
->abfd
, &a2l
->filename
,
252 &a2l
->funcname
, &a2l
->line
) &&
253 cnt
++ < MAX_INLINE_NEST
) {
255 if (a2l
->filename
&& !strlen(a2l
->filename
))
256 a2l
->filename
= NULL
;
259 if (inline_list__append_dso_a2l(dso
, node
))
261 // found at least one inline frame
268 *file
= a2l
->filename
? strdup(a2l
->filename
) : NULL
;
278 void dso__free_a2l(struct dso
*dso
)
280 struct a2l_data
*a2l
= dso
->a2l
;
285 addr2line_cleanup(a2l
);
290 static struct inline_node
*addr2inlines(const char *dso_name
, u64 addr
,
293 struct inline_node
*node
;
295 node
= zalloc(sizeof(*node
));
297 perror("not enough memory for the inline node");
301 INIT_LIST_HEAD(&node
->val
);
304 if (!addr2line(dso_name
, addr
, NULL
, NULL
, dso
, TRUE
, node
))
305 goto out_free_inline_node
;
307 if (list_empty(&node
->val
))
308 goto out_free_inline_node
;
312 out_free_inline_node
:
313 inline_node__delete(node
);
317 #else /* HAVE_LIBBFD_SUPPORT */
319 static int filename_split(char *filename
, unsigned int *line_nr
)
323 sep
= strchr(filename
, '\n');
327 if (!strcmp(filename
, "??:0"))
330 sep
= strchr(filename
, ':');
333 *line_nr
= strtoul(sep
, NULL
, 0);
340 static int addr2line(const char *dso_name
, u64 addr
,
341 char **file
, unsigned int *line_nr
,
342 struct dso
*dso __maybe_unused
,
343 bool unwind_inlines __maybe_unused
,
344 struct inline_node
*node __maybe_unused
)
348 char *filename
= NULL
;
352 scnprintf(cmd
, sizeof(cmd
), "addr2line -e %s %016"PRIx64
,
355 fp
= popen(cmd
, "r");
357 pr_warning("popen failed for %s\n", dso_name
);
361 if (getline(&filename
, &len
, fp
) < 0 || !len
) {
362 pr_warning("addr2line has no output for %s\n", dso_name
);
366 ret
= filename_split(filename
, line_nr
);
379 void dso__free_a2l(struct dso
*dso __maybe_unused
)
383 static struct inline_node
*addr2inlines(const char *dso_name
, u64 addr
,
384 struct dso
*dso __maybe_unused
)
388 struct inline_node
*node
;
389 char *filename
= NULL
;
391 unsigned int line_nr
= 0;
393 scnprintf(cmd
, sizeof(cmd
), "addr2line -e %s -i %016"PRIx64
,
396 fp
= popen(cmd
, "r");
398 pr_err("popen failed for %s\n", dso_name
);
402 node
= zalloc(sizeof(*node
));
404 perror("not enough memory for the inline node");
408 INIT_LIST_HEAD(&node
->val
);
411 while (getline(&filename
, &len
, fp
) != -1) {
412 if (filename_split(filename
, &line_nr
) != 1) {
417 if (inline_list__append(filename
, NULL
, line_nr
, node
,
427 if (list_empty(&node
->val
)) {
428 inline_node__delete(node
);
435 #endif /* HAVE_LIBBFD_SUPPORT */
438 * Number of addr2line failures (without success) before disabling it for that
441 #define A2L_FAIL_LIMIT 123
443 char *__get_srcline(struct dso
*dso
, u64 addr
, struct symbol
*sym
,
444 bool show_sym
, bool show_addr
, bool unwind_inlines
)
449 const char *dso_name
;
451 if (!dso
->has_srcline
)
454 dso_name
= dso__name(dso
);
455 if (dso_name
== NULL
)
458 if (!addr2line(dso_name
, addr
, &file
, &line
, dso
, unwind_inlines
, NULL
))
461 if (asprintf(&srcline
, "%s:%u",
462 srcline_full_filename
? file
: basename(file
),
474 if (dso
->a2l_fails
&& ++dso
->a2l_fails
> A2L_FAIL_LIMIT
) {
475 dso
->has_srcline
= 0;
480 return (show_sym
&& sym
) ?
481 strndup(sym
->name
, sym
->namelen
) : NULL
;
484 if (asprintf(&srcline
, "%s+%" PRIu64
, show_sym
? sym
->name
: "",
485 addr
- sym
->start
) < 0)
486 return SRCLINE_UNKNOWN
;
487 } else if (asprintf(&srcline
, "%s[%" PRIx64
"]", dso
->short_name
, addr
) < 0)
488 return SRCLINE_UNKNOWN
;
492 void free_srcline(char *srcline
)
494 if (srcline
&& strcmp(srcline
, SRCLINE_UNKNOWN
) != 0)
498 char *get_srcline(struct dso
*dso
, u64 addr
, struct symbol
*sym
,
499 bool show_sym
, bool show_addr
)
501 return __get_srcline(dso
, addr
, sym
, show_sym
, show_addr
, false);
504 struct inline_node
*dso__parse_addr_inlines(struct dso
*dso
, u64 addr
)
506 const char *dso_name
;
508 dso_name
= dso__name(dso
);
509 if (dso_name
== NULL
)
512 return addr2inlines(dso_name
, addr
, dso
);
515 void inline_node__delete(struct inline_node
*node
)
517 struct inline_list
*ilist
, *tmp
;
519 list_for_each_entry_safe(ilist
, tmp
, &node
->val
, list
) {
520 list_del_init(&ilist
->list
);
521 zfree(&ilist
->filename
);
522 zfree(&ilist
->funcname
);