7 #include <linux/kernel.h> 28 if (dso_name[0] ==
'[')
31 if (!strncmp(dso_name,
"/tmp/perf-", 10))
42 ilist =
zalloc(
sizeof(*ilist));
50 list_add_tail(&ilist->
list, &node->
val);
52 list_add(&ilist->
list, &node->
val);
60 const char *base = strrchr(path,
'/');
62 return base ? base + 1 : path;
75 if (asprintf(&srcline,
"%s:%u", file, line) < 0)
86 char *demangled = NULL;
94 if (base_sym && strcmp(funcname, base_sym->
name) == 0) {
96 inline_sym = base_sym;
104 base_sym ? base_sym->
end : 0,
105 base_sym ? base_sym->
binding : 0,
106 base_sym ? base_sym->
type : 0,
117 #ifdef HAVE_LIBBFD_SUPPORT 122 #define PACKAGE "perf" 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);
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));
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,
263 struct a2l_data *a2l = dso->
a2l;
265 char *srcline = NULL;
274 char **file,
unsigned int *line,
struct dso *dso,
279 struct a2l_data *a2l = dso->
a2l;
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))
322 *file = a2l->filename ? strdup(a2l->filename) : NULL;
334 struct a2l_data *a2l = dso->
a2l;
339 addr2line_cleanup(a2l);
345 struct dso *dso,
struct symbol *sym)
349 node =
zalloc(
sizeof(*node));
351 perror(
"not enough memory for the inline node");
355 INIT_LIST_HEAD(&node->
val);
368 sep = strchr(filename,
'\n');
372 if (!strcmp(filename,
"??:0"))
375 sep = strchr(filename,
':');
378 *line_nr = strtoul(sep, NULL, 0);
386 char **file,
unsigned int *line_nr,
387 struct dso *dso __maybe_unused,
388 bool unwind_inlines __maybe_unused,
390 struct symbol *sym __maybe_unused)
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);
430 struct dso *dso __maybe_unused,
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);
460 while (getline(&funcname, &funclen, fp) != -1) {
462 struct symbol *inline_sym;
466 if (getline(&filename, &filelen, fp) == -1)
477 if (inline_sym && inline_sym->
inlined)
497 #define A2L_FAIL_LIMIT 123 500 bool show_sym,
bool show_addr,
bool unwind_inlines,
512 if (dso_name == NULL)
515 if (!
addr2line(dso_name, addr, &file, &line, dso,
516 unwind_inlines, NULL, sym))
536 return (show_sym && sym) ?
540 if (asprintf(&srcline,
"%s+%" PRIu64, show_sym ? sym->
name :
"",
541 ip - sym->
start) < 0)
543 }
else if (asprintf(&srcline,
"%s[%" PRIx64
"]", dso->
short_name, addr) < 0)
555 bool show_sym,
bool show_addr, u64 ip)
557 return __get_srcline(dso, addr, sym, show_sym, show_addr,
false, ip);
563 struct rb_node rb_node;
568 struct rb_node **p = &tree->rb_node;
569 struct rb_node *parent = NULL;
574 perror(
"not enough memory for the srcline node");
589 rb_link_node(&node->
rb_node, parent, p);
590 rb_insert_color(&node->
rb_node, tree);
595 struct rb_node *n = tree->rb_node;
603 else if (addr > i->
addr)
615 struct rb_node *next = rb_first(tree);
632 if (dso_name == NULL)
642 list_for_each_entry_safe(ilist, tmp, &node->
val,
list) {
643 list_del_init(&ilist->
list);
656 struct rb_node **p = &tree->rb_node;
657 struct rb_node *parent = NULL;
658 const u64 addr = inlines->
addr;
669 rb_link_node(&inlines->
rb_node, parent, p);
670 rb_insert_color(&inlines->
rb_node, tree);
675 struct rb_node *n = tree->
rb_node;
683 else if (addr > i->
addr)
695 struct rb_node *next = rb_first(tree);
void srcline__tree_insert(struct rb_root *tree, u64 addr, char *srcline)
char * get_srcline(struct dso *dso, u64 addr, struct symbol *sym, bool show_sym, bool show_addr, u64 ip)
static int addr2line(const char *dso_name, u64 addr, char **file, unsigned int *line_nr, struct dso *dso __maybe_unused, bool unwind_inlines __maybe_unused, struct inline_node *node __maybe_unused, struct symbol *sym __maybe_unused)
static int inline_list__append(struct symbol *symbol, char *srcline, struct inline_node *node)
char * dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
static int filename_split(char *filename, unsigned int *line_nr)
char * __get_srcline(struct dso *dso, u64 addr, struct symbol *sym, bool show_sym, bool show_addr, bool unwind_inlines, u64 ip)
static int input(yyscan_t yyscanner)
bool srcline_full_filename
struct symbol * symbol__new(u64 start, u64 len, u8 binding, u8 type, const char *name)
#define pr_debug(fmt,...)
void free_srcline(char *srcline)
void inlines__tree_insert(struct rb_root *tree, struct inline_node *inlines)
char * srcline__tree_find(struct rb_root *tree, u64 addr)
void inline_node__delete(struct inline_node *node)
void inlines__tree_delete(struct rb_root *tree)
void srcline__tree_delete(struct rb_root *tree)
struct inline_node * dso__parse_addr_inlines(struct dso *dso, u64 addr, struct symbol *sym)
static const char * gnu_basename(const char *path)
static struct inline_node * addr2inlines(const char *dso_name, u64 addr, struct dso *dso __maybe_unused, struct symbol *sym)
static int sym(yyscan_t scanner, int type, int config)
static struct symbol * new_inline_sym(struct dso *dso, struct symbol *base_sym, const char *funcname)
static char * srcline_from_fileline(const char *file, unsigned int line)
void symbol__delete(struct symbol *sym)
#define pr_warning(fmt,...)
void dso__free_a2l(struct dso *dso __maybe_unused)
static const char * dso__name(struct dso *dso)
struct inline_node * inlines__tree_find(struct rb_root *tree, u64 addr)
void static void * zalloc(size_t size)