Merge branch 'fixes-v5.7' into fixes
[linux-2.6-microblaze.git] / tools / perf / util / srcline.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <inttypes.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include <linux/kernel.h>
8 #include <linux/string.h>
9 #include <linux/zalloc.h>
10
11 #include "util/dso.h"
12 #include "util/debug.h"
13 #include "util/callchain.h"
14 #include "util/symbol_conf.h"
15 #include "srcline.h"
16 #include "string2.h"
17 #include "symbol.h"
18
19 bool srcline_full_filename;
20
21 static const char *dso__name(struct dso *dso)
22 {
23         const char *dso_name;
24
25         if (dso->symsrc_filename)
26                 dso_name = dso->symsrc_filename;
27         else
28                 dso_name = dso->long_name;
29
30         if (dso_name[0] == '[')
31                 return NULL;
32
33         if (!strncmp(dso_name, "/tmp/perf-", 10))
34                 return NULL;
35
36         return dso_name;
37 }
38
39 static int inline_list__append(struct symbol *symbol, char *srcline,
40                                struct inline_node *node)
41 {
42         struct inline_list *ilist;
43
44         ilist = zalloc(sizeof(*ilist));
45         if (ilist == NULL)
46                 return -1;
47
48         ilist->symbol = symbol;
49         ilist->srcline = srcline;
50
51         if (callchain_param.order == ORDER_CALLEE)
52                 list_add_tail(&ilist->list, &node->val);
53         else
54                 list_add(&ilist->list, &node->val);
55
56         return 0;
57 }
58
59 /* basename version that takes a const input string */
60 static const char *gnu_basename(const char *path)
61 {
62         const char *base = strrchr(path, '/');
63
64         return base ? base + 1 : path;
65 }
66
67 static char *srcline_from_fileline(const char *file, unsigned int line)
68 {
69         char *srcline;
70
71         if (!file)
72                 return NULL;
73
74         if (!srcline_full_filename)
75                 file = gnu_basename(file);
76
77         if (asprintf(&srcline, "%s:%u", file, line) < 0)
78                 return NULL;
79
80         return srcline;
81 }
82
83 static struct symbol *new_inline_sym(struct dso *dso,
84                                      struct symbol *base_sym,
85                                      const char *funcname)
86 {
87         struct symbol *inline_sym;
88         char *demangled = NULL;
89
90         if (!funcname)
91                 funcname = "??";
92
93         if (dso) {
94                 demangled = dso__demangle_sym(dso, 0, funcname);
95                 if (demangled)
96                         funcname = demangled;
97         }
98
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
104                  */
105                 assert(!base_sym->inlined);
106         } else {
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,
112                                          funcname);
113                 if (inline_sym)
114                         inline_sym->inlined = 1;
115         }
116
117         free(demangled);
118
119         return inline_sym;
120 }
121
122 #ifdef HAVE_LIBBFD_SUPPORT
123
124 /*
125  * Implement addr2line using libbfd.
126  */
127 #define PACKAGE "perf"
128 #include <bfd.h>
129
130 struct a2l_data {
131         const char      *input;
132         u64             addr;
133
134         bool            found;
135         const char      *filename;
136         const char      *funcname;
137         unsigned        line;
138
139         bfd             *abfd;
140         asymbol         **syms;
141 };
142
143 static int bfd_error(const char *string)
144 {
145         const char *errmsg;
146
147         errmsg = bfd_errmsg(bfd_get_error());
148         fflush(stdout);
149
150         if (string)
151                 pr_debug("%s: %s\n", string, errmsg);
152         else
153                 pr_debug("%s\n", errmsg);
154
155         return -1;
156 }
157
158 static int slurp_symtab(bfd *abfd, struct a2l_data *a2l)
159 {
160         long storage;
161         long symcount;
162         asymbol **syms;
163         bfd_boolean dynamic = FALSE;
164
165         if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
166                 return bfd_error(bfd_get_filename(abfd));
167
168         storage = bfd_get_symtab_upper_bound(abfd);
169         if (storage == 0L) {
170                 storage = bfd_get_dynamic_symtab_upper_bound(abfd);
171                 dynamic = TRUE;
172         }
173         if (storage < 0L)
174                 return bfd_error(bfd_get_filename(abfd));
175
176         syms = malloc(storage);
177         if (dynamic)
178                 symcount = bfd_canonicalize_dynamic_symtab(abfd, syms);
179         else
180                 symcount = bfd_canonicalize_symtab(abfd, syms);
181
182         if (symcount < 0) {
183                 free(syms);
184                 return bfd_error(bfd_get_filename(abfd));
185         }
186
187         a2l->syms = syms;
188         return 0;
189 }
190
191 static void find_address_in_section(bfd *abfd, asection *section, void *data)
192 {
193         bfd_vma pc, vma;
194         bfd_size_type size;
195         struct a2l_data *a2l = data;
196         flagword flags;
197
198         if (a2l->found)
199                 return;
200
201 #ifdef bfd_get_section_flags
202         flags = bfd_get_section_flags(abfd, section);
203 #else
204         flags = bfd_section_flags(section);
205 #endif
206         if ((flags & SEC_ALLOC) == 0)
207                 return;
208
209         pc = a2l->addr;
210 #ifdef bfd_get_section_vma
211         vma = bfd_get_section_vma(abfd, section);
212 #else
213         vma = bfd_section_vma(section);
214 #endif
215 #ifdef bfd_get_section_size
216         size = bfd_get_section_size(section);
217 #else
218         size = bfd_section_size(section);
219 #endif
220
221         if (pc < vma || pc >= vma + size)
222                 return;
223
224         a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma,
225                                            &a2l->filename, &a2l->funcname,
226                                            &a2l->line);
227
228         if (a2l->filename && !strlen(a2l->filename))
229                 a2l->filename = NULL;
230 }
231
232 static struct a2l_data *addr2line_init(const char *path)
233 {
234         bfd *abfd;
235         struct a2l_data *a2l = NULL;
236
237         abfd = bfd_openr(path, NULL);
238         if (abfd == NULL)
239                 return NULL;
240
241         if (!bfd_check_format(abfd, bfd_object))
242                 goto out;
243
244         a2l = zalloc(sizeof(*a2l));
245         if (a2l == NULL)
246                 goto out;
247
248         a2l->abfd = abfd;
249         a2l->input = strdup(path);
250         if (a2l->input == NULL)
251                 goto out;
252
253         if (slurp_symtab(abfd, a2l))
254                 goto out;
255
256         return a2l;
257
258 out:
259         if (a2l) {
260                 zfree((char **)&a2l->input);
261                 free(a2l);
262         }
263         bfd_close(abfd);
264         return NULL;
265 }
266
267 static void addr2line_cleanup(struct a2l_data *a2l)
268 {
269         if (a2l->abfd)
270                 bfd_close(a2l->abfd);
271         zfree((char **)&a2l->input);
272         zfree(&a2l->syms);
273         free(a2l);
274 }
275
276 #define MAX_INLINE_NEST 1024
277
278 static int inline_list__append_dso_a2l(struct dso *dso,
279                                        struct inline_node *node,
280                                        struct symbol *sym)
281 {
282         struct a2l_data *a2l = dso->a2l;
283         struct symbol *inline_sym = new_inline_sym(dso, sym, a2l->funcname);
284         char *srcline = NULL;
285
286         if (a2l->filename)
287                 srcline = srcline_from_fileline(a2l->filename, a2l->line);
288
289         return inline_list__append(inline_sym, srcline, node);
290 }
291
292 static int addr2line(const char *dso_name, u64 addr,
293                      char **file, unsigned int *line, struct dso *dso,
294                      bool unwind_inlines, struct inline_node *node,
295                      struct symbol *sym)
296 {
297         int ret = 0;
298         struct a2l_data *a2l = dso->a2l;
299
300         if (!a2l) {
301                 dso->a2l = addr2line_init(dso_name);
302                 a2l = dso->a2l;
303         }
304
305         if (a2l == NULL) {
306                 if (!symbol_conf.disable_add2line_warn)
307                         pr_warning("addr2line_init failed for %s\n", dso_name);
308                 return 0;
309         }
310
311         a2l->addr = addr;
312         a2l->found = false;
313
314         bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
315
316         if (!a2l->found)
317                 return 0;
318
319         if (unwind_inlines) {
320                 int cnt = 0;
321
322                 if (node && inline_list__append_dso_a2l(dso, node, sym))
323                         return 0;
324
325                 while (bfd_find_inliner_info(a2l->abfd, &a2l->filename,
326                                              &a2l->funcname, &a2l->line) &&
327                        cnt++ < MAX_INLINE_NEST) {
328
329                         if (a2l->filename && !strlen(a2l->filename))
330                                 a2l->filename = NULL;
331
332                         if (node != NULL) {
333                                 if (inline_list__append_dso_a2l(dso, node, sym))
334                                         return 0;
335                                 // found at least one inline frame
336                                 ret = 1;
337                         }
338                 }
339         }
340
341         if (file) {
342                 *file = a2l->filename ? strdup(a2l->filename) : NULL;
343                 ret = *file ? 1 : 0;
344         }
345
346         if (line)
347                 *line = a2l->line;
348
349         return ret;
350 }
351
352 void dso__free_a2l(struct dso *dso)
353 {
354         struct a2l_data *a2l = dso->a2l;
355
356         if (!a2l)
357                 return;
358
359         addr2line_cleanup(a2l);
360
361         dso->a2l = NULL;
362 }
363
364 static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
365                                         struct dso *dso, struct symbol *sym)
366 {
367         struct inline_node *node;
368
369         node = zalloc(sizeof(*node));
370         if (node == NULL) {
371                 perror("not enough memory for the inline node");
372                 return NULL;
373         }
374
375         INIT_LIST_HEAD(&node->val);
376         node->addr = addr;
377
378         addr2line(dso_name, addr, NULL, NULL, dso, true, node, sym);
379         return node;
380 }
381
382 #else /* HAVE_LIBBFD_SUPPORT */
383
384 static int filename_split(char *filename, unsigned int *line_nr)
385 {
386         char *sep;
387
388         sep = strchr(filename, '\n');
389         if (sep)
390                 *sep = '\0';
391
392         if (!strcmp(filename, "??:0"))
393                 return 0;
394
395         sep = strchr(filename, ':');
396         if (sep) {
397                 *sep++ = '\0';
398                 *line_nr = strtoul(sep, NULL, 0);
399                 return 1;
400         }
401
402         return 0;
403 }
404
405 static int addr2line(const char *dso_name, u64 addr,
406                      char **file, unsigned int *line_nr,
407                      struct dso *dso __maybe_unused,
408                      bool unwind_inlines __maybe_unused,
409                      struct inline_node *node __maybe_unused,
410                      struct symbol *sym __maybe_unused)
411 {
412         FILE *fp;
413         char cmd[PATH_MAX];
414         char *filename = NULL;
415         size_t len;
416         int ret = 0;
417
418         scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64,
419                   dso_name, addr);
420
421         fp = popen(cmd, "r");
422         if (fp == NULL) {
423                 pr_warning("popen failed for %s\n", dso_name);
424                 return 0;
425         }
426
427         if (getline(&filename, &len, fp) < 0 || !len) {
428                 pr_warning("addr2line has no output for %s\n", dso_name);
429                 goto out;
430         }
431
432         ret = filename_split(filename, line_nr);
433         if (ret != 1) {
434                 free(filename);
435                 goto out;
436         }
437
438         *file = filename;
439
440 out:
441         pclose(fp);
442         return ret;
443 }
444
445 void dso__free_a2l(struct dso *dso __maybe_unused)
446 {
447 }
448
449 static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
450                                         struct dso *dso __maybe_unused,
451                                         struct symbol *sym)
452 {
453         FILE *fp;
454         char cmd[PATH_MAX];
455         struct inline_node *node;
456         char *filename = NULL;
457         char *funcname = NULL;
458         size_t filelen, funclen;
459         unsigned int line_nr = 0;
460
461         scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i -f %016"PRIx64,
462                   dso_name, addr);
463
464         fp = popen(cmd, "r");
465         if (fp == NULL) {
466                 pr_err("popen failed for %s\n", dso_name);
467                 return NULL;
468         }
469
470         node = zalloc(sizeof(*node));
471         if (node == NULL) {
472                 perror("not enough memory for the inline node");
473                 goto out;
474         }
475
476         INIT_LIST_HEAD(&node->val);
477         node->addr = addr;
478
479         /* addr2line -f generates two lines for each inlined functions */
480         while (getline(&funcname, &funclen, fp) != -1) {
481                 char *srcline;
482                 struct symbol *inline_sym;
483
484                 strim(funcname);
485
486                 if (getline(&filename, &filelen, fp) == -1)
487                         goto out;
488
489                 if (filename_split(filename, &line_nr) != 1)
490                         goto out;
491
492                 srcline = srcline_from_fileline(filename, line_nr);
493                 inline_sym = new_inline_sym(dso, sym, funcname);
494
495                 if (inline_list__append(inline_sym, srcline, node) != 0) {
496                         free(srcline);
497                         if (inline_sym && inline_sym->inlined)
498                                 symbol__delete(inline_sym);
499                         goto out;
500                 }
501         }
502
503 out:
504         pclose(fp);
505         free(filename);
506         free(funcname);
507
508         return node;
509 }
510
511 #endif /* HAVE_LIBBFD_SUPPORT */
512
513 /*
514  * Number of addr2line failures (without success) before disabling it for that
515  * dso.
516  */
517 #define A2L_FAIL_LIMIT 123
518
519 char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
520                   bool show_sym, bool show_addr, bool unwind_inlines,
521                   u64 ip)
522 {
523         char *file = NULL;
524         unsigned line = 0;
525         char *srcline;
526         const char *dso_name;
527
528         if (!dso->has_srcline)
529                 goto out;
530
531         dso_name = dso__name(dso);
532         if (dso_name == NULL)
533                 goto out;
534
535         if (!addr2line(dso_name, addr, &file, &line, dso,
536                        unwind_inlines, NULL, sym))
537                 goto out;
538
539         srcline = srcline_from_fileline(file, line);
540         free(file);
541
542         if (!srcline)
543                 goto out;
544
545         dso->a2l_fails = 0;
546
547         return srcline;
548
549 out:
550         if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) {
551                 dso->has_srcline = 0;
552                 dso__free_a2l(dso);
553         }
554
555         if (!show_addr)
556                 return (show_sym && sym) ?
557                             strndup(sym->name, sym->namelen) : NULL;
558
559         if (sym) {
560                 if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "",
561                                         ip - sym->start) < 0)
562                         return SRCLINE_UNKNOWN;
563         } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0)
564                 return SRCLINE_UNKNOWN;
565         return srcline;
566 }
567
568 /* Returns filename and fills in line number in line */
569 char *get_srcline_split(struct dso *dso, u64 addr, unsigned *line)
570 {
571         char *file = NULL;
572         const char *dso_name;
573
574         if (!dso->has_srcline)
575                 goto out;
576
577         dso_name = dso__name(dso);
578         if (dso_name == NULL)
579                 goto out;
580
581         if (!addr2line(dso_name, addr, &file, line, dso, true, NULL, NULL))
582                 goto out;
583
584         dso->a2l_fails = 0;
585         return file;
586
587 out:
588         if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) {
589                 dso->has_srcline = 0;
590                 dso__free_a2l(dso);
591         }
592
593         return NULL;
594 }
595
596 void free_srcline(char *srcline)
597 {
598         if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
599                 free(srcline);
600 }
601
602 char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
603                   bool show_sym, bool show_addr, u64 ip)
604 {
605         return __get_srcline(dso, addr, sym, show_sym, show_addr, false, ip);
606 }
607
608 struct srcline_node {
609         u64                     addr;
610         char                    *srcline;
611         struct rb_node          rb_node;
612 };
613
614 void srcline__tree_insert(struct rb_root_cached *tree, u64 addr, char *srcline)
615 {
616         struct rb_node **p = &tree->rb_root.rb_node;
617         struct rb_node *parent = NULL;
618         struct srcline_node *i, *node;
619         bool leftmost = true;
620
621         node = zalloc(sizeof(struct srcline_node));
622         if (!node) {
623                 perror("not enough memory for the srcline node");
624                 return;
625         }
626
627         node->addr = addr;
628         node->srcline = srcline;
629
630         while (*p != NULL) {
631                 parent = *p;
632                 i = rb_entry(parent, struct srcline_node, rb_node);
633                 if (addr < i->addr)
634                         p = &(*p)->rb_left;
635                 else {
636                         p = &(*p)->rb_right;
637                         leftmost = false;
638                 }
639         }
640         rb_link_node(&node->rb_node, parent, p);
641         rb_insert_color_cached(&node->rb_node, tree, leftmost);
642 }
643
644 char *srcline__tree_find(struct rb_root_cached *tree, u64 addr)
645 {
646         struct rb_node *n = tree->rb_root.rb_node;
647
648         while (n) {
649                 struct srcline_node *i = rb_entry(n, struct srcline_node,
650                                                   rb_node);
651
652                 if (addr < i->addr)
653                         n = n->rb_left;
654                 else if (addr > i->addr)
655                         n = n->rb_right;
656                 else
657                         return i->srcline;
658         }
659
660         return NULL;
661 }
662
663 void srcline__tree_delete(struct rb_root_cached *tree)
664 {
665         struct srcline_node *pos;
666         struct rb_node *next = rb_first_cached(tree);
667
668         while (next) {
669                 pos = rb_entry(next, struct srcline_node, rb_node);
670                 next = rb_next(&pos->rb_node);
671                 rb_erase_cached(&pos->rb_node, tree);
672                 free_srcline(pos->srcline);
673                 zfree(&pos);
674         }
675 }
676
677 struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr,
678                                             struct symbol *sym)
679 {
680         const char *dso_name;
681
682         dso_name = dso__name(dso);
683         if (dso_name == NULL)
684                 return NULL;
685
686         return addr2inlines(dso_name, addr, dso, sym);
687 }
688
689 void inline_node__delete(struct inline_node *node)
690 {
691         struct inline_list *ilist, *tmp;
692
693         list_for_each_entry_safe(ilist, tmp, &node->val, list) {
694                 list_del_init(&ilist->list);
695                 free_srcline(ilist->srcline);
696                 /* only the inlined symbols are owned by the list */
697                 if (ilist->symbol && ilist->symbol->inlined)
698                         symbol__delete(ilist->symbol);
699                 free(ilist);
700         }
701
702         free(node);
703 }
704
705 void inlines__tree_insert(struct rb_root_cached *tree,
706                           struct inline_node *inlines)
707 {
708         struct rb_node **p = &tree->rb_root.rb_node;
709         struct rb_node *parent = NULL;
710         const u64 addr = inlines->addr;
711         struct inline_node *i;
712         bool leftmost = true;
713
714         while (*p != NULL) {
715                 parent = *p;
716                 i = rb_entry(parent, struct inline_node, rb_node);
717                 if (addr < i->addr)
718                         p = &(*p)->rb_left;
719                 else {
720                         p = &(*p)->rb_right;
721                         leftmost = false;
722                 }
723         }
724         rb_link_node(&inlines->rb_node, parent, p);
725         rb_insert_color_cached(&inlines->rb_node, tree, leftmost);
726 }
727
728 struct inline_node *inlines__tree_find(struct rb_root_cached *tree, u64 addr)
729 {
730         struct rb_node *n = tree->rb_root.rb_node;
731
732         while (n) {
733                 struct inline_node *i = rb_entry(n, struct inline_node,
734                                                  rb_node);
735
736                 if (addr < i->addr)
737                         n = n->rb_left;
738                 else if (addr > i->addr)
739                         n = n->rb_right;
740                 else
741                         return i;
742         }
743
744         return NULL;
745 }
746
747 void inlines__tree_delete(struct rb_root_cached *tree)
748 {
749         struct inline_node *pos;
750         struct rb_node *next = rb_first_cached(tree);
751
752         while (next) {
753                 pos = rb_entry(next, struct inline_node, rb_node);
754                 next = rb_next(&pos->rb_node);
755                 rb_erase_cached(&pos->rb_node, tree);
756                 inline_node__delete(pos);
757         }
758 }