summaryrefslogtreecommitdiffstats
path: root/kernel/tools/perf/util/srcline.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/tools/perf/util/srcline.c')
-rw-r--r--kernel/tools/perf/util/srcline.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/kernel/tools/perf/util/srcline.c b/kernel/tools/perf/util/srcline.c
index c93fb0c5b..b4db3f48e 100644
--- a/kernel/tools/perf/util/srcline.c
+++ b/kernel/tools/perf/util/srcline.c
@@ -10,6 +10,8 @@
#include "symbol.h"
+bool srcline_full_filename;
+
#ifdef HAVE_LIBBFD_SUPPORT
/*
@@ -147,8 +149,11 @@ static void addr2line_cleanup(struct a2l_data *a2l)
free(a2l);
}
+#define MAX_INLINE_NEST 1024
+
static int addr2line(const char *dso_name, u64 addr,
- char **file, unsigned int *line, struct dso *dso)
+ char **file, unsigned int *line, struct dso *dso,
+ bool unwind_inlines)
{
int ret = 0;
struct a2l_data *a2l = dso->a2l;
@@ -168,6 +173,15 @@ static int addr2line(const char *dso_name, u64 addr,
bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
+ if (a2l->found && unwind_inlines) {
+ int cnt = 0;
+
+ while (bfd_find_inliner_info(a2l->abfd, &a2l->filename,
+ &a2l->funcname, &a2l->line) &&
+ cnt++ < MAX_INLINE_NEST)
+ ;
+ }
+
if (a2l->found && a2l->filename) {
*file = strdup(a2l->filename);
*line = a2l->line;
@@ -195,7 +209,8 @@ void dso__free_a2l(struct dso *dso)
static int addr2line(const char *dso_name, u64 addr,
char **file, unsigned int *line_nr,
- struct dso *dso __maybe_unused)
+ struct dso *dso __maybe_unused,
+ bool unwind_inlines __maybe_unused)
{
FILE *fp;
char cmd[PATH_MAX];
@@ -252,8 +267,8 @@ void dso__free_a2l(struct dso *dso __maybe_unused)
*/
#define A2L_FAIL_LIMIT 123
-char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
- bool show_sym)
+char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
+ bool show_sym, bool unwind_inlines)
{
char *file = NULL;
unsigned line = 0;
@@ -274,10 +289,12 @@ char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
if (!strncmp(dso_name, "/tmp/perf-", 10))
goto out;
- if (!addr2line(dso_name, addr, &file, &line, dso))
+ if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines))
goto out;
- if (asprintf(&srcline, "%s:%u", basename(file), line) < 0) {
+ if (asprintf(&srcline, "%s:%u",
+ srcline_full_filename ? file : basename(file),
+ line) < 0) {
free(file);
goto out;
}
@@ -306,3 +323,9 @@ void free_srcline(char *srcline)
if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
free(srcline);
}
+
+char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
+ bool show_sym)
+{
+ return __get_srcline(dso, addr, sym, show_sym, false);
+}