689ab462a188e2a758ec3b84a72eb8cc9846aed0
[linux-2.6.git] / tools / perf / util / probe-finder.c
1 /*
2  * probe-finder.c : C expression to kprobe event converter
3  *
4  * Written by Masami Hiramatsu <mhiramat@redhat.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  */
21
22 #include <sys/utsname.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <getopt.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdarg.h>
33 #include <ctype.h>
34 #include <dwarf-regs.h>
35
36 #include <linux/bitops.h>
37 #include "event.h"
38 #include "debug.h"
39 #include "util.h"
40 #include "symbol.h"
41 #include "probe-finder.h"
42
43 /* Kprobe tracer basic type is up to u64 */
44 #define MAX_BASIC_TYPE_BITS     64
45
46 /*
47  * Compare the tail of two strings.
48  * Return 0 if whole of either string is same as another's tail part.
49  */
50 static int strtailcmp(const char *s1, const char *s2)
51 {
52         int i1 = strlen(s1);
53         int i2 = strlen(s2);
54         while (--i1 >= 0 && --i2 >= 0) {
55                 if (s1[i1] != s2[i2])
56                         return s1[i1] - s2[i2];
57         }
58         return 0;
59 }
60
61 /* Line number list operations */
62
63 /* Add a line to line number list */
64 static int line_list__add_line(struct list_head *head, int line)
65 {
66         struct line_node *ln;
67         struct list_head *p;
68
69         /* Reverse search, because new line will be the last one */
70         list_for_each_entry_reverse(ln, head, list) {
71                 if (ln->line < line) {
72                         p = &ln->list;
73                         goto found;
74                 } else if (ln->line == line)    /* Already exist */
75                         return 1;
76         }
77         /* List is empty, or the smallest entry */
78         p = head;
79 found:
80         pr_debug("line list: add a line %u\n", line);
81         ln = zalloc(sizeof(struct line_node));
82         if (ln == NULL)
83                 return -ENOMEM;
84         ln->line = line;
85         INIT_LIST_HEAD(&ln->list);
86         list_add(&ln->list, p);
87         return 0;
88 }
89
90 /* Check if the line in line number list */
91 static int line_list__has_line(struct list_head *head, int line)
92 {
93         struct line_node *ln;
94
95         /* Reverse search, because new line will be the last one */
96         list_for_each_entry(ln, head, list)
97                 if (ln->line == line)
98                         return 1;
99
100         return 0;
101 }
102
103 /* Init line number list */
104 static void line_list__init(struct list_head *head)
105 {
106         INIT_LIST_HEAD(head);
107 }
108
109 /* Free line number list */
110 static void line_list__free(struct list_head *head)
111 {
112         struct line_node *ln;
113         while (!list_empty(head)) {
114                 ln = list_first_entry(head, struct line_node, list);
115                 list_del(&ln->list);
116                 free(ln);
117         }
118 }
119
120 /* Dwarf FL wrappers */
121 static char *debuginfo_path;    /* Currently dummy */
122
123 static const Dwfl_Callbacks offline_callbacks = {
124         .find_debuginfo = dwfl_standard_find_debuginfo,
125         .debuginfo_path = &debuginfo_path,
126
127         .section_address = dwfl_offline_section_address,
128
129         /* We use this table for core files too.  */
130         .find_elf = dwfl_build_id_find_elf,
131 };
132
133 /* Get a Dwarf from offline image */
134 static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
135 {
136         Dwfl_Module *mod;
137         Dwarf *dbg = NULL;
138
139         if (!dwflp)
140                 return NULL;
141
142         *dwflp = dwfl_begin(&offline_callbacks);
143         if (!*dwflp)
144                 return NULL;
145
146         mod = dwfl_report_offline(*dwflp, "", "", fd);
147         if (!mod)
148                 goto error;
149
150         dbg = dwfl_module_getdwarf(mod, bias);
151         if (!dbg) {
152 error:
153                 dwfl_end(*dwflp);
154                 *dwflp = NULL;
155         }
156         return dbg;
157 }
158
159 #if _ELFUTILS_PREREQ(0, 148)
160 /* This method is buggy if elfutils is older than 0.148 */
161 static int __linux_kernel_find_elf(Dwfl_Module *mod,
162                                    void **userdata,
163                                    const char *module_name,
164                                    Dwarf_Addr base,
165                                    char **file_name, Elf **elfp)
166 {
167         int fd;
168         const char *path = kernel_get_module_path(module_name);
169
170         pr_debug2("Use file %s for %s\n", path, module_name);
171         if (path) {
172                 fd = open(path, O_RDONLY);
173                 if (fd >= 0) {
174                         *file_name = strdup(path);
175                         return fd;
176                 }
177         }
178         /* If failed, try to call standard method */
179         return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
180                                           file_name, elfp);
181 }
182
183 static const Dwfl_Callbacks kernel_callbacks = {
184         .find_debuginfo = dwfl_standard_find_debuginfo,
185         .debuginfo_path = &debuginfo_path,
186
187         .find_elf = __linux_kernel_find_elf,
188         .section_address = dwfl_linux_kernel_module_section_address,
189 };
190
191 /* Get a Dwarf from live kernel image */
192 static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
193                                           Dwarf_Addr *bias)
194 {
195         Dwarf *dbg;
196
197         if (!dwflp)
198                 return NULL;
199
200         *dwflp = dwfl_begin(&kernel_callbacks);
201         if (!*dwflp)
202                 return NULL;
203
204         /* Load the kernel dwarves: Don't care the result here */
205         dwfl_linux_kernel_report_kernel(*dwflp);
206         dwfl_linux_kernel_report_modules(*dwflp);
207
208         dbg = dwfl_addrdwarf(*dwflp, addr, bias);
209         /* Here, check whether we could get a real dwarf */
210         if (!dbg) {
211                 pr_debug("Failed to find kernel dwarf at %lx\n",
212                          (unsigned long)addr);
213                 dwfl_end(*dwflp);
214                 *dwflp = NULL;
215         }
216         return dbg;
217 }
218 #else
219 /* With older elfutils, this just support kernel module... */
220 static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp,
221                                           Dwarf_Addr *bias)
222 {
223         int fd;
224         const char *path = kernel_get_module_path("kernel");
225
226         if (!path) {
227                 pr_err("Failed to find vmlinux path\n");
228                 return NULL;
229         }
230
231         pr_debug2("Use file %s for debuginfo\n", path);
232         fd = open(path, O_RDONLY);
233         if (fd < 0)
234                 return NULL;
235
236         return dwfl_init_offline_dwarf(fd, dwflp, bias);
237 }
238 #endif
239
240 /* Dwarf wrappers */
241
242 /* Find the realpath of the target file. */
243 static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
244 {
245         Dwarf_Files *files;
246         size_t nfiles, i;
247         const char *src = NULL;
248         int ret;
249
250         if (!fname)
251                 return NULL;
252
253         ret = dwarf_getsrcfiles(cu_die, &files, &nfiles);
254         if (ret != 0)
255                 return NULL;
256
257         for (i = 0; i < nfiles; i++) {
258                 src = dwarf_filesrc(files, i, NULL, NULL);
259                 if (strtailcmp(src, fname) == 0)
260                         break;
261         }
262         if (i == nfiles)
263                 return NULL;
264         return src;
265 }
266
267 /* Get DW_AT_comp_dir (should be NULL with older gcc) */
268 static const char *cu_get_comp_dir(Dwarf_Die *cu_die)
269 {
270         Dwarf_Attribute attr;
271         if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
272                 return NULL;
273         return dwarf_formstring(&attr);
274 }
275
276 /* Compare diename and tname */
277 static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
278 {
279         const char *name;
280         name = dwarf_diename(dw_die);
281         return name ? (strcmp(tname, name) == 0) : false;
282 }
283
284 /* Get callsite line number of inline-function instance */
285 static int die_get_call_lineno(Dwarf_Die *in_die)
286 {
287         Dwarf_Attribute attr;
288         Dwarf_Word ret;
289
290         if (!dwarf_attr(in_die, DW_AT_call_line, &attr))
291                 return -ENOENT;
292
293         dwarf_formudata(&attr, &ret);
294         return (int)ret;
295 }
296
297 /* Get type die */
298 static Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
299 {
300         Dwarf_Attribute attr;
301
302         if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) &&
303             dwarf_formref_die(&attr, die_mem))
304                 return die_mem;
305         else
306                 return NULL;
307 }
308
309 /* Get a type die, but skip qualifiers */
310 static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
311 {
312         int tag;
313
314         do {
315                 vr_die = die_get_type(vr_die, die_mem);
316                 if (!vr_die)
317                         break;
318                 tag = dwarf_tag(vr_die);
319         } while (tag == DW_TAG_const_type ||
320                  tag == DW_TAG_restrict_type ||
321                  tag == DW_TAG_volatile_type ||
322                  tag == DW_TAG_shared_type);
323
324         return vr_die;
325 }
326
327 /* Get a type die, but skip qualifiers and typedef */
328 static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
329 {
330         do {
331                 vr_die = __die_get_real_type(vr_die, die_mem);
332         } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef);
333
334         return vr_die;
335 }
336
337 static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
338                               Dwarf_Word *result)
339 {
340         Dwarf_Attribute attr;
341
342         if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
343             dwarf_formudata(&attr, result) != 0)
344                 return -ENOENT;
345
346         return 0;
347 }
348
349 static bool die_is_signed_type(Dwarf_Die *tp_die)
350 {
351         Dwarf_Word ret;
352
353         if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
354                 return false;
355
356         return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
357                 ret == DW_ATE_signed_fixed);
358 }
359
360 static int die_get_byte_size(Dwarf_Die *tp_die)
361 {
362         Dwarf_Word ret;
363
364         if (die_get_attr_udata(tp_die, DW_AT_byte_size, &ret))
365                 return 0;
366
367         return (int)ret;
368 }
369
370 static int die_get_bit_size(Dwarf_Die *tp_die)
371 {
372         Dwarf_Word ret;
373
374         if (die_get_attr_udata(tp_die, DW_AT_bit_size, &ret))
375                 return 0;
376
377         return (int)ret;
378 }
379
380 static int die_get_bit_offset(Dwarf_Die *tp_die)
381 {
382         Dwarf_Word ret;
383
384         if (die_get_attr_udata(tp_die, DW_AT_bit_offset, &ret))
385                 return 0;
386
387         return (int)ret;
388 }
389
390 /* Get data_member_location offset */
391 static int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
392 {
393         Dwarf_Attribute attr;
394         Dwarf_Op *expr;
395         size_t nexpr;
396         int ret;
397
398         if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
399                 return -ENOENT;
400
401         if (dwarf_formudata(&attr, offs) != 0) {
402                 /* DW_AT_data_member_location should be DW_OP_plus_uconst */
403                 ret = dwarf_getlocation(&attr, &expr, &nexpr);
404                 if (ret < 0 || nexpr == 0)
405                         return -ENOENT;
406
407                 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
408                         pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
409                                  expr[0].atom, nexpr);
410                         return -ENOTSUP;
411                 }
412                 *offs = (Dwarf_Word)expr[0].number;
413         }
414         return 0;
415 }
416
417 /* Return values for die_find callbacks */
418 enum {
419         DIE_FIND_CB_FOUND = 0,          /* End of Search */
420         DIE_FIND_CB_CHILD = 1,          /* Search only children */
421         DIE_FIND_CB_SIBLING = 2,        /* Search only siblings */
422         DIE_FIND_CB_CONTINUE = 3,       /* Search children and siblings */
423 };
424
425 /* Search a child die */
426 static Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
427                                  int (*callback)(Dwarf_Die *, void *),
428                                  void *data, Dwarf_Die *die_mem)
429 {
430         Dwarf_Die child_die;
431         int ret;
432
433         ret = dwarf_child(rt_die, die_mem);
434         if (ret != 0)
435                 return NULL;
436
437         do {
438                 ret = callback(die_mem, data);
439                 if (ret == DIE_FIND_CB_FOUND)
440                         return die_mem;
441
442                 if ((ret & DIE_FIND_CB_CHILD) &&
443                     die_find_child(die_mem, callback, data, &child_die)) {
444                         memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
445                         return die_mem;
446                 }
447         } while ((ret & DIE_FIND_CB_SIBLING) &&
448                  dwarf_siblingof(die_mem, die_mem) == 0);
449
450         return NULL;
451 }
452
453 struct __addr_die_search_param {
454         Dwarf_Addr      addr;
455         Dwarf_Die       *die_mem;
456 };
457
458 static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
459 {
460         struct __addr_die_search_param *ad = data;
461
462         if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
463             dwarf_haspc(fn_die, ad->addr)) {
464                 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
465                 return DWARF_CB_ABORT;
466         }
467         return DWARF_CB_OK;
468 }
469
470 /* Search a real subprogram including this line, */
471 static Dwarf_Die *die_find_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
472                                            Dwarf_Die *die_mem)
473 {
474         struct __addr_die_search_param ad;
475         ad.addr = addr;
476         ad.die_mem = die_mem;
477         /* dwarf_getscopes can't find subprogram. */
478         if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
479                 return NULL;
480         else
481                 return die_mem;
482 }
483
484 /* die_find callback for inline function search */
485 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
486 {
487         Dwarf_Addr *addr = data;
488
489         if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
490             dwarf_haspc(die_mem, *addr))
491                 return DIE_FIND_CB_FOUND;
492
493         return DIE_FIND_CB_CONTINUE;
494 }
495
496 /* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */
497 static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
498                                       Dwarf_Die *die_mem)
499 {
500         Dwarf_Die tmp_die;
501
502         sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
503         if (!sp_die)
504                 return NULL;
505
506         /* Inlined function could be recursive. Trace it until fail */
507         while (sp_die) {
508                 memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
509                 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
510                                         &tmp_die);
511         }
512
513         return die_mem;
514 }
515
516 /* Walker on lines (Note: line number will not be sorted) */
517 typedef int (* line_walk_handler_t) (const char *fname, int lineno,
518                                      Dwarf_Addr addr, void *data);
519
520 struct __line_walk_param {
521         const char *fname;
522         line_walk_handler_t handler;
523         void *data;
524         int retval;
525 };
526
527 static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
528 {
529         struct __line_walk_param *lw = data;
530         Dwarf_Addr addr;
531         int lineno;
532
533         if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
534                 lineno = die_get_call_lineno(in_die);
535                 if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) {
536                         lw->retval = lw->handler(lw->fname, lineno, addr,
537                                                  lw->data);
538                         if (lw->retval != 0)
539                                 return DIE_FIND_CB_FOUND;
540                 }
541         }
542         return DIE_FIND_CB_SIBLING;
543 }
544
545 /* Walk on lines of blocks included in given DIE */
546 static int __die_walk_funclines(Dwarf_Die *sp_die,
547                                 line_walk_handler_t handler, void *data)
548 {
549         struct __line_walk_param lw = {
550                 .handler = handler,
551                 .data = data,
552                 .retval = 0,
553         };
554         Dwarf_Die die_mem;
555         Dwarf_Addr addr;
556         int lineno;
557
558         /* Handle function declaration line */
559         lw.fname = dwarf_decl_file(sp_die);
560         if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
561             dwarf_entrypc(sp_die, &addr) == 0) {
562                 lw.retval = handler(lw.fname, lineno, addr, data);
563                 if (lw.retval != 0)
564                         goto done;
565         }
566         die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem);
567 done:
568         return lw.retval;
569 }
570
571 static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
572 {
573         struct __line_walk_param *lw = data;
574
575         lw->retval = __die_walk_funclines(sp_die, lw->handler, lw->data);
576         if (lw->retval != 0)
577                 return DWARF_CB_ABORT;
578
579         return DWARF_CB_OK;
580 }
581
582 /*
583  * Walk on lines inside given PDIE. If the PDIE is subprogram, walk only on
584  * the lines inside the subprogram, otherwise PDIE must be a CU DIE.
585  */
586 static int die_walk_lines(Dwarf_Die *pdie, line_walk_handler_t handler,
587                           void *data)
588 {
589         Dwarf_Lines *lines;
590         Dwarf_Line *line;
591         Dwarf_Addr addr;
592         const char *fname;
593         int lineno, ret = 0;
594         Dwarf_Die die_mem, *cu_die;
595         size_t nlines, i;
596
597         /* Get the CU die */
598         if (dwarf_tag(pdie) == DW_TAG_subprogram)
599                 cu_die = dwarf_diecu(pdie, &die_mem, NULL, NULL);
600         else
601                 cu_die = pdie;
602         if (!cu_die) {
603                 pr_debug2("Failed to get CU from subprogram\n");
604                 return -EINVAL;
605         }
606
607         /* Get lines list in the CU */
608         if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) {
609                 pr_debug2("Failed to get source lines on this CU.\n");
610                 return -ENOENT;
611         }
612         pr_debug2("Get %zd lines from this CU\n", nlines);
613
614         /* Walk on the lines on lines list */
615         for (i = 0; i < nlines; i++) {
616                 line = dwarf_onesrcline(lines, i);
617                 if (line == NULL ||
618                     dwarf_lineno(line, &lineno) != 0 ||
619                     dwarf_lineaddr(line, &addr) != 0) {
620                         pr_debug2("Failed to get line info. "
621                                   "Possible error in debuginfo.\n");
622                         continue;
623                 }
624                 /* Filter lines based on address */
625                 if (pdie != cu_die)
626                         /*
627                          * Address filtering
628                          * The line is included in given function, and
629                          * no inline block includes it.
630                          */
631                         if (!dwarf_haspc(pdie, addr) ||
632                             die_find_inlinefunc(pdie, addr, &die_mem))
633                                 continue;
634                 /* Get source line */
635                 fname = dwarf_linesrc(line, NULL, NULL);
636
637                 ret = handler(fname, lineno, addr, data);
638                 if (ret != 0)
639                         return ret;
640         }
641
642         /*
643          * Dwarf lines doesn't include function declarations and inlined
644          * subroutines. We have to check functions list or given function.
645          */
646         if (pdie != cu_die)
647                 ret = __die_walk_funclines(pdie, handler, data);
648         else {
649                 struct __line_walk_param param = {
650                         .handler = handler,
651                         .data = data,
652                         .retval = 0,
653                 };
654                 dwarf_getfuncs(cu_die, __die_walk_culines_cb, &param, 0);
655                 ret = param.retval;
656         }
657
658         return ret;
659 }
660
661 struct __find_variable_param {
662         const char *name;
663         Dwarf_Addr addr;
664 };
665
666 static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
667 {
668         struct __find_variable_param *fvp = data;
669         int tag;
670
671         tag = dwarf_tag(die_mem);
672         if ((tag == DW_TAG_formal_parameter ||
673              tag == DW_TAG_variable) &&
674             die_compare_name(die_mem, fvp->name))
675                 return DIE_FIND_CB_FOUND;
676
677         if (dwarf_haspc(die_mem, fvp->addr))
678                 return DIE_FIND_CB_CONTINUE;
679         else
680                 return DIE_FIND_CB_SIBLING;
681 }
682
683 /* Find a variable called 'name' at given address */
684 static Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
685                                        Dwarf_Addr addr, Dwarf_Die *die_mem)
686 {
687         struct __find_variable_param fvp = { .name = name, .addr = addr};
688
689         return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
690                               die_mem);
691 }
692
693 static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
694 {
695         const char *name = data;
696
697         if ((dwarf_tag(die_mem) == DW_TAG_member) &&
698             die_compare_name(die_mem, name))
699                 return DIE_FIND_CB_FOUND;
700
701         return DIE_FIND_CB_SIBLING;
702 }
703
704 /* Find a member called 'name' */
705 static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
706                                   Dwarf_Die *die_mem)
707 {
708         return die_find_child(st_die, __die_find_member_cb, (void *)name,
709                               die_mem);
710 }
711
712 /* Get the name of given variable DIE */
713 static int die_get_typename(Dwarf_Die *vr_die, char *buf, int len)
714 {
715         Dwarf_Die type;
716         int tag, ret, ret2;
717         const char *tmp = "";
718
719         if (__die_get_real_type(vr_die, &type) == NULL)
720                 return -ENOENT;
721
722         tag = dwarf_tag(&type);
723         if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)
724                 tmp = "*";
725         else if (tag == DW_TAG_subroutine_type) {
726                 /* Function pointer */
727                 ret = snprintf(buf, len, "(function_type)");
728                 return (ret >= len) ? -E2BIG : ret;
729         } else {
730                 if (!dwarf_diename(&type))
731                         return -ENOENT;
732                 if (tag == DW_TAG_union_type)
733                         tmp = "union ";
734                 else if (tag == DW_TAG_structure_type)
735                         tmp = "struct ";
736                 /* Write a base name */
737                 ret = snprintf(buf, len, "%s%s", tmp, dwarf_diename(&type));
738                 return (ret >= len) ? -E2BIG : ret;
739         }
740         ret = die_get_typename(&type, buf, len);
741         if (ret > 0) {
742                 ret2 = snprintf(buf + ret, len - ret, "%s", tmp);
743                 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
744         }
745         return ret;
746 }
747
748 /* Get the name and type of given variable DIE, stored as "type\tname" */
749 static int die_get_varname(Dwarf_Die *vr_die, char *buf, int len)
750 {
751         int ret, ret2;
752
753         ret = die_get_typename(vr_die, buf, len);
754         if (ret < 0) {
755                 pr_debug("Failed to get type, make it unknown.\n");
756                 ret = snprintf(buf, len, "(unknown_type)");
757         }
758         if (ret > 0) {
759                 ret2 = snprintf(buf + ret, len - ret, "\t%s",
760                                 dwarf_diename(vr_die));
761                 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
762         }
763         return ret;
764 }
765
766 /*
767  * Probe finder related functions
768  */
769
770 static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
771 {
772         struct probe_trace_arg_ref *ref;
773         ref = zalloc(sizeof(struct probe_trace_arg_ref));
774         if (ref != NULL)
775                 ref->offset = offs;
776         return ref;
777 }
778
779 /*
780  * Convert a location into trace_arg.
781  * If tvar == NULL, this just checks variable can be converted.
782  */
783 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
784                                      Dwarf_Op *fb_ops,
785                                      struct probe_trace_arg *tvar)
786 {
787         Dwarf_Attribute attr;
788         Dwarf_Op *op;
789         size_t nops;
790         unsigned int regn;
791         Dwarf_Word offs = 0;
792         bool ref = false;
793         const char *regs;
794         int ret;
795
796         if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL)
797                 goto static_var;
798
799         /* TODO: handle more than 1 exprs */
800         if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL ||
801             dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0 ||
802             nops == 0) {
803                 /* TODO: Support const_value */
804                 return -ENOENT;
805         }
806
807         if (op->atom == DW_OP_addr) {
808 static_var:
809                 if (!tvar)
810                         return 0;
811                 /* Static variables on memory (not stack), make @varname */
812                 ret = strlen(dwarf_diename(vr_die));
813                 tvar->value = zalloc(ret + 2);
814                 if (tvar->value == NULL)
815                         return -ENOMEM;
816                 snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die));
817                 tvar->ref = alloc_trace_arg_ref((long)offs);
818                 if (tvar->ref == NULL)
819                         return -ENOMEM;
820                 return 0;
821         }
822
823         /* If this is based on frame buffer, set the offset */
824         if (op->atom == DW_OP_fbreg) {
825                 if (fb_ops == NULL)
826                         return -ENOTSUP;
827                 ref = true;
828                 offs = op->number;
829                 op = &fb_ops[0];
830         }
831
832         if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
833                 regn = op->atom - DW_OP_breg0;
834                 offs += op->number;
835                 ref = true;
836         } else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) {
837                 regn = op->atom - DW_OP_reg0;
838         } else if (op->atom == DW_OP_bregx) {
839                 regn = op->number;
840                 offs += op->number2;
841                 ref = true;
842         } else if (op->atom == DW_OP_regx) {
843                 regn = op->number;
844         } else {
845                 pr_debug("DW_OP %x is not supported.\n", op->atom);
846                 return -ENOTSUP;
847         }
848
849         if (!tvar)
850                 return 0;
851
852         regs = get_arch_regstr(regn);
853         if (!regs) {
854                 /* This should be a bug in DWARF or this tool */
855                 pr_warning("Mapping for the register number %u "
856                            "missing on this architecture.\n", regn);
857                 return -ERANGE;
858         }
859
860         tvar->value = strdup(regs);
861         if (tvar->value == NULL)
862                 return -ENOMEM;
863
864         if (ref) {
865                 tvar->ref = alloc_trace_arg_ref((long)offs);
866                 if (tvar->ref == NULL)
867                         return -ENOMEM;
868         }
869         return 0;
870 }
871
872 #define BYTES_TO_BITS(nb)       ((nb) * BITS_PER_LONG / sizeof(long))
873
874 static int convert_variable_type(Dwarf_Die *vr_die,
875                                  struct probe_trace_arg *tvar,
876                                  const char *cast)
877 {
878         struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
879         Dwarf_Die type;
880         char buf[16];
881         int ret;
882
883         /* TODO: check all types */
884         if (cast && strcmp(cast, "string") != 0) {
885                 /* Non string type is OK */
886                 tvar->type = strdup(cast);
887                 return (tvar->type == NULL) ? -ENOMEM : 0;
888         }
889
890         if (die_get_bit_size(vr_die) != 0) {
891                 /* This is a bitfield */
892                 ret = snprintf(buf, 16, "b%d@%d/%zd", die_get_bit_size(vr_die),
893                                 die_get_bit_offset(vr_die),
894                                 BYTES_TO_BITS(die_get_byte_size(vr_die)));
895                 goto formatted;
896         }
897
898         if (die_get_real_type(vr_die, &type) == NULL) {
899                 pr_warning("Failed to get a type information of %s.\n",
900                            dwarf_diename(vr_die));
901                 return -ENOENT;
902         }
903
904         pr_debug("%s type is %s.\n",
905                  dwarf_diename(vr_die), dwarf_diename(&type));
906
907         if (cast && strcmp(cast, "string") == 0) {      /* String type */
908                 ret = dwarf_tag(&type);
909                 if (ret != DW_TAG_pointer_type &&
910                     ret != DW_TAG_array_type) {
911                         pr_warning("Failed to cast into string: "
912                                    "%s(%s) is not a pointer nor array.\n",
913                                    dwarf_diename(vr_die), dwarf_diename(&type));
914                         return -EINVAL;
915                 }
916                 if (ret == DW_TAG_pointer_type) {
917                         if (die_get_real_type(&type, &type) == NULL) {
918                                 pr_warning("Failed to get a type"
919                                            " information.\n");
920                                 return -ENOENT;
921                         }
922                         while (*ref_ptr)
923                                 ref_ptr = &(*ref_ptr)->next;
924                         /* Add new reference with offset +0 */
925                         *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref));
926                         if (*ref_ptr == NULL) {
927                                 pr_warning("Out of memory error\n");
928                                 return -ENOMEM;
929                         }
930                 }
931                 if (!die_compare_name(&type, "char") &&
932                     !die_compare_name(&type, "unsigned char")) {
933                         pr_warning("Failed to cast into string: "
934                                    "%s is not (unsigned) char *.\n",
935                                    dwarf_diename(vr_die));
936                         return -EINVAL;
937                 }
938                 tvar->type = strdup(cast);
939                 return (tvar->type == NULL) ? -ENOMEM : 0;
940         }
941
942         ret = BYTES_TO_BITS(die_get_byte_size(&type));
943         if (!ret)
944                 /* No size ... try to use default type */
945                 return 0;
946
947         /* Check the bitwidth */
948         if (ret > MAX_BASIC_TYPE_BITS) {
949                 pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n",
950                         dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
951                 ret = MAX_BASIC_TYPE_BITS;
952         }
953         ret = snprintf(buf, 16, "%c%d",
954                        die_is_signed_type(&type) ? 's' : 'u', ret);
955
956 formatted:
957         if (ret < 0 || ret >= 16) {
958                 if (ret >= 16)
959                         ret = -E2BIG;
960                 pr_warning("Failed to convert variable type: %s\n",
961                            strerror(-ret));
962                 return ret;
963         }
964         tvar->type = strdup(buf);
965         if (tvar->type == NULL)
966                 return -ENOMEM;
967         return 0;
968 }
969
970 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
971                                     struct perf_probe_arg_field *field,
972                                     struct probe_trace_arg_ref **ref_ptr,
973                                     Dwarf_Die *die_mem)
974 {
975         struct probe_trace_arg_ref *ref = *ref_ptr;
976         Dwarf_Die type;
977         Dwarf_Word offs;
978         int ret, tag;
979
980         pr_debug("converting %s in %s\n", field->name, varname);
981         if (die_get_real_type(vr_die, &type) == NULL) {
982                 pr_warning("Failed to get the type of %s.\n", varname);
983                 return -ENOENT;
984         }
985         pr_debug2("Var real type: (%x)\n", (unsigned)dwarf_dieoffset(&type));
986         tag = dwarf_tag(&type);
987
988         if (field->name[0] == '[' &&
989             (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) {
990                 if (field->next)
991                         /* Save original type for next field */
992                         memcpy(die_mem, &type, sizeof(*die_mem));
993                 /* Get the type of this array */
994                 if (die_get_real_type(&type, &type) == NULL) {
995                         pr_warning("Failed to get the type of %s.\n", varname);
996                         return -ENOENT;
997                 }
998                 pr_debug2("Array real type: (%x)\n",
999                          (unsigned)dwarf_dieoffset(&type));
1000                 if (tag == DW_TAG_pointer_type) {
1001                         ref = zalloc(sizeof(struct probe_trace_arg_ref));
1002                         if (ref == NULL)
1003                                 return -ENOMEM;
1004                         if (*ref_ptr)
1005                                 (*ref_ptr)->next = ref;
1006                         else
1007                                 *ref_ptr = ref;
1008                 }
1009                 ref->offset += die_get_byte_size(&type) * field->index;
1010                 if (!field->next)
1011                         /* Save vr_die for converting types */
1012                         memcpy(die_mem, vr_die, sizeof(*die_mem));
1013                 goto next;
1014         } else if (tag == DW_TAG_pointer_type) {
1015                 /* Check the pointer and dereference */
1016                 if (!field->ref) {
1017                         pr_err("Semantic error: %s must be referred by '->'\n",
1018                                field->name);
1019                         return -EINVAL;
1020                 }
1021                 /* Get the type pointed by this pointer */
1022                 if (die_get_real_type(&type, &type) == NULL) {
1023                         pr_warning("Failed to get the type of %s.\n", varname);
1024                         return -ENOENT;
1025                 }
1026                 /* Verify it is a data structure  */
1027                 if (dwarf_tag(&type) != DW_TAG_structure_type) {
1028                         pr_warning("%s is not a data structure.\n", varname);
1029                         return -EINVAL;
1030                 }
1031
1032                 ref = zalloc(sizeof(struct probe_trace_arg_ref));
1033                 if (ref == NULL)
1034                         return -ENOMEM;
1035                 if (*ref_ptr)
1036                         (*ref_ptr)->next = ref;
1037                 else
1038                         *ref_ptr = ref;
1039         } else {
1040                 /* Verify it is a data structure  */
1041                 if (tag != DW_TAG_structure_type) {
1042                         pr_warning("%s is not a data structure.\n", varname);
1043                         return -EINVAL;
1044                 }
1045                 if (field->name[0] == '[') {
1046                         pr_err("Semantic error: %s is not a pointor"
1047                                " nor array.\n", varname);
1048                         return -EINVAL;
1049                 }
1050                 if (field->ref) {
1051                         pr_err("Semantic error: %s must be referred by '.'\n",
1052                                field->name);
1053                         return -EINVAL;
1054                 }
1055                 if (!ref) {
1056                         pr_warning("Structure on a register is not "
1057                                    "supported yet.\n");
1058                         return -ENOTSUP;
1059                 }
1060         }
1061
1062         if (die_find_member(&type, field->name, die_mem) == NULL) {
1063                 pr_warning("%s(tyep:%s) has no member %s.\n", varname,
1064                            dwarf_diename(&type), field->name);
1065                 return -EINVAL;
1066         }
1067
1068         /* Get the offset of the field */
1069         ret = die_get_data_member_location(die_mem, &offs);
1070         if (ret < 0) {
1071                 pr_warning("Failed to get the offset of %s.\n", field->name);
1072                 return ret;
1073         }
1074         ref->offset += (long)offs;
1075
1076 next:
1077         /* Converting next field */
1078         if (field->next)
1079                 return convert_variable_fields(die_mem, field->name,
1080                                         field->next, &ref, die_mem);
1081         else
1082                 return 0;
1083 }
1084
1085 /* Show a variables in kprobe event format */
1086 static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
1087 {
1088         Dwarf_Die die_mem;
1089         int ret;
1090
1091         pr_debug("Converting variable %s into trace event.\n",
1092                  dwarf_diename(vr_die));
1093
1094         ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
1095                                         pf->tvar);
1096         if (ret == -ENOENT)
1097                 pr_err("Failed to find the location of %s at this address.\n"
1098                        " Perhaps, it has been optimized out.\n", pf->pvar->var);
1099         else if (ret == -ENOTSUP)
1100                 pr_err("Sorry, we don't support this variable location yet.\n");
1101         else if (pf->pvar->field) {
1102                 ret = convert_variable_fields(vr_die, pf->pvar->var,
1103                                               pf->pvar->field, &pf->tvar->ref,
1104                                               &die_mem);
1105                 vr_die = &die_mem;
1106         }
1107         if (ret == 0)
1108                 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type);
1109         /* *expr will be cached in libdw. Don't free it. */
1110         return ret;
1111 }
1112
1113 /* Find a variable in a subprogram die */
1114 static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
1115 {
1116         Dwarf_Die vr_die, *scopes;
1117         char buf[32], *ptr;
1118         int ret, nscopes;
1119
1120         if (!is_c_varname(pf->pvar->var)) {
1121                 /* Copy raw parameters */
1122                 pf->tvar->value = strdup(pf->pvar->var);
1123                 if (pf->tvar->value == NULL)
1124                         return -ENOMEM;
1125                 if (pf->pvar->type) {
1126                         pf->tvar->type = strdup(pf->pvar->type);
1127                         if (pf->tvar->type == NULL)
1128                                 return -ENOMEM;
1129                 }
1130                 if (pf->pvar->name) {
1131                         pf->tvar->name = strdup(pf->pvar->name);
1132                         if (pf->tvar->name == NULL)
1133                                 return -ENOMEM;
1134                 } else
1135                         pf->tvar->name = NULL;
1136                 return 0;
1137         }
1138
1139         if (pf->pvar->name)
1140                 pf->tvar->name = strdup(pf->pvar->name);
1141         else {
1142                 ret = synthesize_perf_probe_arg(pf->pvar, buf, 32);
1143                 if (ret < 0)
1144                         return ret;
1145                 ptr = strchr(buf, ':'); /* Change type separator to _ */
1146                 if (ptr)
1147                         *ptr = '_';
1148                 pf->tvar->name = strdup(buf);
1149         }
1150         if (pf->tvar->name == NULL)
1151                 return -ENOMEM;
1152
1153         pr_debug("Searching '%s' variable in context.\n",
1154                  pf->pvar->var);
1155         /* Search child die for local variables and parameters. */
1156         if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die))
1157                 ret = convert_variable(&vr_die, pf);
1158         else {
1159                 /* Search upper class */
1160                 nscopes = dwarf_getscopes_die(sp_die, &scopes);
1161                 while (nscopes-- > 1) {
1162                         pr_debug("Searching variables in %s\n",
1163                                  dwarf_diename(&scopes[nscopes]));
1164                         /* We should check this scope, so give dummy address */
1165                         if (die_find_variable_at(&scopes[nscopes],
1166                                                  pf->pvar->var, 0,
1167                                                  &vr_die)) {
1168                                 ret = convert_variable(&vr_die, pf);
1169                                 goto found;
1170                         }
1171                 }
1172                 if (scopes)
1173                         free(scopes);
1174                 ret = -ENOENT;
1175         }
1176 found:
1177         if (ret < 0)
1178                 pr_warning("Failed to find '%s' in this function.\n",
1179                            pf->pvar->var);
1180         return ret;
1181 }
1182
1183 /* Convert subprogram DIE to trace point */
1184 static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
1185                                   bool retprobe, struct probe_trace_point *tp)
1186 {
1187         Dwarf_Addr eaddr;
1188         const char *name;
1189
1190         /* Copy the name of probe point */
1191         name = dwarf_diename(sp_die);
1192         if (name) {
1193                 if (dwarf_entrypc(sp_die, &eaddr) != 0) {
1194                         pr_warning("Failed to get entry address of %s\n",
1195                                    dwarf_diename(sp_die));
1196                         return -ENOENT;
1197                 }
1198                 tp->symbol = strdup(name);
1199                 if (tp->symbol == NULL)
1200                         return -ENOMEM;
1201                 tp->offset = (unsigned long)(paddr - eaddr);
1202         } else
1203                 /* This function has no name. */
1204                 tp->offset = (unsigned long)paddr;
1205
1206         /* Return probe must be on the head of a subprogram */
1207         if (retprobe) {
1208                 if (eaddr != paddr) {
1209                         pr_warning("Return probe must be on the head of"
1210                                    " a real function.\n");
1211                         return -EINVAL;
1212                 }
1213                 tp->retprobe = true;
1214         }
1215
1216         return 0;
1217 }
1218
1219 /* Call probe_finder callback with real subprogram DIE */
1220 static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf)
1221 {
1222         Dwarf_Die die_mem;
1223         Dwarf_Attribute fb_attr;
1224         size_t nops;
1225         int ret;
1226
1227         /* If no real subprogram, find a real one */
1228         if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
1229                 sp_die = die_find_real_subprogram(&pf->cu_die,
1230                                                   pf->addr, &die_mem);
1231                 if (!sp_die) {
1232                         pr_warning("Failed to find probe point in any "
1233                                    "functions.\n");
1234                         return -ENOENT;
1235                 }
1236         }
1237
1238         /* Get the frame base attribute/ops */
1239         dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
1240         ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
1241         if (ret <= 0 || nops == 0) {
1242                 pf->fb_ops = NULL;
1243 #if _ELFUTILS_PREREQ(0, 142)
1244         } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
1245                    pf->cfi != NULL) {
1246                 Dwarf_Frame *frame;
1247                 if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
1248                     dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
1249                         pr_warning("Failed to get call frame on 0x%jx\n",
1250                                    (uintmax_t)pf->addr);
1251                         return -ENOENT;
1252                 }
1253 #endif
1254         }
1255
1256         /* Call finder's callback handler */
1257         ret = pf->callback(sp_die, pf);
1258
1259         /* *pf->fb_ops will be cached in libdw. Don't free it. */
1260         pf->fb_ops = NULL;
1261
1262         return ret;
1263 }
1264
1265 static int probe_point_line_walker(const char *fname, int lineno,
1266                                    Dwarf_Addr addr, void *data)
1267 {
1268         struct probe_finder *pf = data;
1269         int ret;
1270
1271         if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0)
1272                 return 0;
1273
1274         pf->addr = addr;
1275         ret = call_probe_finder(NULL, pf);
1276
1277         /* Continue if no error, because the line will be in inline function */
1278         return ret < 0 ? ret : 0;
1279 }
1280
1281 /* Find probe point from its line number */
1282 static int find_probe_point_by_line(struct probe_finder *pf)
1283 {
1284         return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf);
1285 }
1286
1287 /* Find lines which match lazy pattern */
1288 static int find_lazy_match_lines(struct list_head *head,
1289                                  const char *fname, const char *pat)
1290 {
1291         FILE *fp;
1292         char *line = NULL;
1293         size_t line_len;
1294         ssize_t len;
1295         int count = 0, linenum = 1;
1296
1297         fp = fopen(fname, "r");
1298         if (!fp) {
1299                 pr_warning("Failed to open %s: %s\n", fname, strerror(errno));
1300                 return -errno;
1301         }
1302
1303         while ((len = getline(&line, &line_len, fp)) > 0) {
1304
1305                 if (line[len - 1] == '\n')
1306                         line[len - 1] = '\0';
1307
1308                 if (strlazymatch(line, pat)) {
1309                         line_list__add_line(head, linenum);
1310                         count++;
1311                 }
1312                 linenum++;
1313         }
1314
1315         if (ferror(fp))
1316                 count = -errno;
1317         free(line);
1318         fclose(fp);
1319
1320         if (count == 0)
1321                 pr_debug("No matched lines found in %s.\n", fname);
1322         return count;
1323 }
1324
1325 static int probe_point_lazy_walker(const char *fname, int lineno,
1326                                    Dwarf_Addr addr, void *data)
1327 {
1328         struct probe_finder *pf = data;
1329         int ret;
1330
1331         if (!line_list__has_line(&pf->lcache, lineno) ||
1332             strtailcmp(fname, pf->fname) != 0)
1333                 return 0;
1334
1335         pr_debug("Probe line found: line:%d addr:0x%llx\n",
1336                  lineno, (unsigned long long)addr);
1337         pf->addr = addr;
1338         ret = call_probe_finder(NULL, pf);
1339
1340         /*
1341          * Continue if no error, because the lazy pattern will match
1342          * to other lines
1343          */
1344         return ret < 0 ? ret : 0;
1345 }
1346
1347 /* Find probe points from lazy pattern  */
1348 static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
1349 {
1350         int ret = 0;
1351
1352         if (list_empty(&pf->lcache)) {
1353                 /* Matching lazy line pattern */
1354                 ret = find_lazy_match_lines(&pf->lcache, pf->fname,
1355                                             pf->pev->point.lazy_line);
1356                 if (ret <= 0)
1357                         return ret;
1358         }
1359
1360         return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
1361 }
1362
1363 /* Callback parameter with return value */
1364 struct dwarf_callback_param {
1365         void *data;
1366         int retval;
1367 };
1368
1369 static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
1370 {
1371         struct dwarf_callback_param *param = data;
1372         struct probe_finder *pf = param->data;
1373         struct perf_probe_point *pp = &pf->pev->point;
1374         Dwarf_Addr addr;
1375
1376         if (pp->lazy_line)
1377                 param->retval = find_probe_point_lazy(in_die, pf);
1378         else {
1379                 /* Get probe address */
1380                 if (dwarf_entrypc(in_die, &addr) != 0) {
1381                         pr_warning("Failed to get entry address of %s.\n",
1382                                    dwarf_diename(in_die));
1383                         param->retval = -ENOENT;
1384                         return DWARF_CB_ABORT;
1385                 }
1386                 pf->addr = addr;
1387                 pf->addr += pp->offset;
1388                 pr_debug("found inline addr: 0x%jx\n",
1389                          (uintmax_t)pf->addr);
1390
1391                 param->retval = call_probe_finder(in_die, pf);
1392                 if (param->retval < 0)
1393                         return DWARF_CB_ABORT;
1394         }
1395
1396         return DWARF_CB_OK;
1397 }
1398
1399 /* Search function from function name */
1400 static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
1401 {
1402         struct dwarf_callback_param *param = data;
1403         struct probe_finder *pf = param->data;
1404         struct perf_probe_point *pp = &pf->pev->point;
1405
1406         /* Check tag and diename */
1407         if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
1408             !die_compare_name(sp_die, pp->function))
1409                 return DWARF_CB_OK;
1410
1411         /* Check declared file */
1412         if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die)))
1413                 return DWARF_CB_OK;
1414
1415         pf->fname = dwarf_decl_file(sp_die);
1416         if (pp->line) { /* Function relative line */
1417                 dwarf_decl_line(sp_die, &pf->lno);
1418                 pf->lno += pp->line;
1419                 param->retval = find_probe_point_by_line(pf);
1420         } else if (!dwarf_func_inline(sp_die)) {
1421                 /* Real function */
1422                 if (pp->lazy_line)
1423                         param->retval = find_probe_point_lazy(sp_die, pf);
1424                 else {
1425                         if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
1426                                 pr_warning("Failed to get entry address of "
1427                                            "%s.\n", dwarf_diename(sp_die));
1428                                 param->retval = -ENOENT;
1429                                 return DWARF_CB_ABORT;
1430                         }
1431                         pf->addr += pp->offset;
1432                         /* TODO: Check the address in this function */
1433                         param->retval = call_probe_finder(sp_die, pf);
1434                 }
1435         } else {
1436                 struct dwarf_callback_param _param = {.data = (void *)pf,
1437                                                       .retval = 0};
1438                 /* Inlined function: search instances */
1439                 dwarf_func_inline_instances(sp_die, probe_point_inline_cb,
1440                                             &_param);
1441                 param->retval = _param.retval;
1442         }
1443
1444         return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
1445 }
1446
1447 static int find_probe_point_by_func(struct probe_finder *pf)
1448 {
1449         struct dwarf_callback_param _param = {.data = (void *)pf,
1450                                               .retval = 0};
1451         dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
1452         return _param.retval;
1453 }
1454
1455 /* Find probe points from debuginfo */
1456 static int find_probes(int fd, struct probe_finder *pf)
1457 {
1458         struct perf_probe_point *pp = &pf->pev->point;
1459         Dwarf_Off off, noff;
1460         size_t cuhl;
1461         Dwarf_Die *diep;
1462         Dwarf *dbg = NULL;
1463         Dwfl *dwfl;
1464         Dwarf_Addr bias;        /* Currently ignored */
1465         int ret = 0;
1466
1467         dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
1468         if (!dbg) {
1469                 pr_warning("No debug information found in the vmlinux - "
1470                         "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1471                 close(fd);      /* Without dwfl_end(), fd isn't closed. */
1472                 return -EBADF;
1473         }
1474
1475 #if _ELFUTILS_PREREQ(0, 142)
1476         /* Get the call frame information from this dwarf */
1477         pf->cfi = dwarf_getcfi(dbg);
1478 #endif
1479
1480         off = 0;
1481         line_list__init(&pf->lcache);
1482         /* Loop on CUs (Compilation Unit) */
1483         while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1484                 /* Get the DIE(Debugging Information Entry) of this CU */
1485                 diep = dwarf_offdie(dbg, off + cuhl, &pf->cu_die);
1486                 if (!diep)
1487                         continue;
1488
1489                 /* Check if target file is included. */
1490                 if (pp->file)
1491                         pf->fname = cu_find_realpath(&pf->cu_die, pp->file);
1492                 else
1493                         pf->fname = NULL;
1494
1495                 if (!pp->file || pf->fname) {
1496                         if (pp->function)
1497                                 ret = find_probe_point_by_func(pf);
1498                         else if (pp->lazy_line)
1499                                 ret = find_probe_point_lazy(NULL, pf);
1500                         else {
1501                                 pf->lno = pp->line;
1502                                 ret = find_probe_point_by_line(pf);
1503                         }
1504                         if (ret < 0)
1505                                 break;
1506                 }
1507                 off = noff;
1508         }
1509         line_list__free(&pf->lcache);
1510         if (dwfl)
1511                 dwfl_end(dwfl);
1512
1513         return ret;
1514 }
1515
1516 /* Add a found probe point into trace event list */
1517 static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf)
1518 {
1519         struct trace_event_finder *tf =
1520                         container_of(pf, struct trace_event_finder, pf);
1521         struct probe_trace_event *tev;
1522         int ret, i;
1523
1524         /* Check number of tevs */
1525         if (tf->ntevs == tf->max_tevs) {
1526                 pr_warning("Too many( > %d) probe point found.\n",
1527                            tf->max_tevs);
1528                 return -ERANGE;
1529         }
1530         tev = &tf->tevs[tf->ntevs++];
1531
1532         ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe,
1533                                      &tev->point);
1534         if (ret < 0)
1535                 return ret;
1536
1537         pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
1538                  tev->point.offset);
1539
1540         /* Find each argument */
1541         tev->nargs = pf->pev->nargs;
1542         tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1543         if (tev->args == NULL)
1544                 return -ENOMEM;
1545         for (i = 0; i < pf->pev->nargs; i++) {
1546                 pf->pvar = &pf->pev->args[i];
1547                 pf->tvar = &tev->args[i];
1548                 ret = find_variable(sp_die, pf);
1549                 if (ret != 0)
1550                         return ret;
1551         }
1552
1553         return 0;
1554 }
1555
1556 /* Find probe_trace_events specified by perf_probe_event from debuginfo */
1557 int find_probe_trace_events(int fd, struct perf_probe_event *pev,
1558                             struct probe_trace_event **tevs, int max_tevs)
1559 {
1560         struct trace_event_finder tf = {
1561                         .pf = {.pev = pev, .callback = add_probe_trace_event},
1562                         .max_tevs = max_tevs};
1563         int ret;
1564
1565         /* Allocate result tevs array */
1566         *tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs);
1567         if (*tevs == NULL)
1568                 return -ENOMEM;
1569
1570         tf.tevs = *tevs;
1571         tf.ntevs = 0;
1572
1573         ret = find_probes(fd, &tf.pf);
1574         if (ret < 0) {
1575                 free(*tevs);
1576                 *tevs = NULL;
1577                 return ret;
1578         }
1579
1580         return (ret < 0) ? ret : tf.ntevs;
1581 }
1582
1583 #define MAX_VAR_LEN 64
1584
1585 /* Collect available variables in this scope */
1586 static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1587 {
1588         struct available_var_finder *af = data;
1589         struct variable_list *vl;
1590         char buf[MAX_VAR_LEN];
1591         int tag, ret;
1592
1593         vl = &af->vls[af->nvls - 1];
1594
1595         tag = dwarf_tag(die_mem);
1596         if (tag == DW_TAG_formal_parameter ||
1597             tag == DW_TAG_variable) {
1598                 ret = convert_variable_location(die_mem, af->pf.addr,
1599                                                 af->pf.fb_ops, NULL);
1600                 if (ret == 0) {
1601                         ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
1602                         pr_debug2("Add new var: %s\n", buf);
1603                         if (ret > 0)
1604                                 strlist__add(vl->vars, buf);
1605                 }
1606         }
1607
1608         if (af->child && dwarf_haspc(die_mem, af->pf.addr))
1609                 return DIE_FIND_CB_CONTINUE;
1610         else
1611                 return DIE_FIND_CB_SIBLING;
1612 }
1613
1614 /* Add a found vars into available variables list */
1615 static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf)
1616 {
1617         struct available_var_finder *af =
1618                         container_of(pf, struct available_var_finder, pf);
1619         struct variable_list *vl;
1620         Dwarf_Die die_mem, *scopes = NULL;
1621         int ret, nscopes;
1622
1623         /* Check number of tevs */
1624         if (af->nvls == af->max_vls) {
1625                 pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
1626                 return -ERANGE;
1627         }
1628         vl = &af->vls[af->nvls++];
1629
1630         ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe,
1631                                      &vl->point);
1632         if (ret < 0)
1633                 return ret;
1634
1635         pr_debug("Probe point found: %s+%lu\n", vl->point.symbol,
1636                  vl->point.offset);
1637
1638         /* Find local variables */
1639         vl->vars = strlist__new(true, NULL);
1640         if (vl->vars == NULL)
1641                 return -ENOMEM;
1642         af->child = true;
1643         die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem);
1644
1645         /* Find external variables */
1646         if (!af->externs)
1647                 goto out;
1648         /* Don't need to search child DIE for externs. */
1649         af->child = false;
1650         nscopes = dwarf_getscopes_die(sp_die, &scopes);
1651         while (nscopes-- > 1)
1652                 die_find_child(&scopes[nscopes], collect_variables_cb,
1653                                (void *)af, &die_mem);
1654         if (scopes)
1655                 free(scopes);
1656
1657 out:
1658         if (strlist__empty(vl->vars)) {
1659                 strlist__delete(vl->vars);
1660                 vl->vars = NULL;
1661         }
1662
1663         return ret;
1664 }
1665
1666 /* Find available variables at given probe point */
1667 int find_available_vars_at(int fd, struct perf_probe_event *pev,
1668                            struct variable_list **vls, int max_vls,
1669                            bool externs)
1670 {
1671         struct available_var_finder af = {
1672                         .pf = {.pev = pev, .callback = add_available_vars},
1673                         .max_vls = max_vls, .externs = externs};
1674         int ret;
1675
1676         /* Allocate result vls array */
1677         *vls = zalloc(sizeof(struct variable_list) * max_vls);
1678         if (*vls == NULL)
1679                 return -ENOMEM;
1680
1681         af.vls = *vls;
1682         af.nvls = 0;
1683
1684         ret = find_probes(fd, &af.pf);
1685         if (ret < 0) {
1686                 /* Free vlist for error */
1687                 while (af.nvls--) {
1688                         if (af.vls[af.nvls].point.symbol)
1689                                 free(af.vls[af.nvls].point.symbol);
1690                         if (af.vls[af.nvls].vars)
1691                                 strlist__delete(af.vls[af.nvls].vars);
1692                 }
1693                 free(af.vls);
1694                 *vls = NULL;
1695                 return ret;
1696         }
1697
1698         return (ret < 0) ? ret : af.nvls;
1699 }
1700
1701 /* Reverse search */
1702 int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt)
1703 {
1704         Dwarf_Die cudie, spdie, indie;
1705         Dwarf *dbg = NULL;
1706         Dwfl *dwfl = NULL;
1707         Dwarf_Line *line;
1708         Dwarf_Addr laddr, eaddr, bias = 0;
1709         const char *tmp;
1710         int lineno, ret = 0;
1711         bool found = false;
1712
1713         /* Open the live linux kernel */
1714         dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias);
1715         if (!dbg) {
1716                 pr_warning("No debug information found in the vmlinux - "
1717                         "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1718                 ret = -EINVAL;
1719                 goto end;
1720         }
1721
1722         /* Adjust address with bias */
1723         addr += bias;
1724         /* Find cu die */
1725         if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr - bias, &cudie)) {
1726                 pr_warning("Failed to find debug information for address %lx\n",
1727                            addr);
1728                 ret = -EINVAL;
1729                 goto end;
1730         }
1731
1732         /* Find a corresponding line */
1733         line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr);
1734         if (line) {
1735                 if (dwarf_lineaddr(line, &laddr) == 0 &&
1736                     (Dwarf_Addr)addr == laddr &&
1737                     dwarf_lineno(line, &lineno) == 0) {
1738                         tmp = dwarf_linesrc(line, NULL, NULL);
1739                         if (tmp) {
1740                                 ppt->line = lineno;
1741                                 ppt->file = strdup(tmp);
1742                                 if (ppt->file == NULL) {
1743                                         ret = -ENOMEM;
1744                                         goto end;
1745                                 }
1746                                 found = true;
1747                         }
1748                 }
1749         }
1750
1751         /* Find a corresponding function */
1752         if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
1753                 tmp = dwarf_diename(&spdie);
1754                 if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0)
1755                         goto end;
1756
1757                 if (ppt->line) {
1758                         if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
1759                                                 &indie)) {
1760                                 /* addr in an inline function */
1761                                 tmp = dwarf_diename(&indie);
1762                                 if (!tmp)
1763                                         goto end;
1764                                 ret = dwarf_decl_line(&indie, &lineno);
1765                         } else {
1766                                 if (eaddr == addr) {    /* Function entry */
1767                                         lineno = ppt->line;
1768                                         ret = 0;
1769                                 } else
1770                                         ret = dwarf_decl_line(&spdie, &lineno);
1771                         }
1772                         if (ret == 0) {
1773                                 /* Make a relative line number */
1774                                 ppt->line -= lineno;
1775                                 goto found;
1776                         }
1777                 }
1778                 /* We don't have a line number, let's use offset */
1779                 ppt->offset = addr - (unsigned long)eaddr;
1780 found:
1781                 ppt->function = strdup(tmp);
1782                 if (ppt->function == NULL) {
1783                         ret = -ENOMEM;
1784                         goto end;
1785                 }
1786                 found = true;
1787         }
1788
1789 end:
1790         if (dwfl)
1791                 dwfl_end(dwfl);
1792         if (ret >= 0)
1793                 ret = found ? 1 : 0;
1794         return ret;
1795 }
1796
1797 /* Add a line and store the src path */
1798 static int line_range_add_line(const char *src, unsigned int lineno,
1799                                struct line_range *lr)
1800 {
1801         /* Copy source path */
1802         if (!lr->path) {
1803                 lr->path = strdup(src);
1804                 if (lr->path == NULL)
1805                         return -ENOMEM;
1806         }
1807         return line_list__add_line(&lr->line_list, lineno);
1808 }
1809
1810 static int line_range_walk_cb(const char *fname, int lineno,
1811                               Dwarf_Addr addr __used,
1812                               void *data)
1813 {
1814         struct line_finder *lf = data;
1815
1816         if ((strtailcmp(fname, lf->fname) != 0) ||
1817             (lf->lno_s > lineno || lf->lno_e < lineno))
1818                 return 0;
1819
1820         if (line_range_add_line(fname, lineno, lf->lr) < 0)
1821                 return -EINVAL;
1822
1823         return 0;
1824 }
1825
1826 /* Find line range from its line number */
1827 static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
1828 {
1829         int ret;
1830
1831         ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf);
1832
1833         /* Update status */
1834         if (ret >= 0)
1835                 if (!list_empty(&lf->lr->line_list))
1836                         ret = lf->found = 1;
1837                 else
1838                         ret = 0;        /* Lines are not found */
1839         else {
1840                 free(lf->lr->path);
1841                 lf->lr->path = NULL;
1842         }
1843         return ret;
1844 }
1845
1846 static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
1847 {
1848         struct dwarf_callback_param *param = data;
1849
1850         param->retval = find_line_range_by_line(in_die, param->data);
1851         return DWARF_CB_ABORT;  /* No need to find other instances */
1852 }
1853
1854 /* Search function from function name */
1855 static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
1856 {
1857         struct dwarf_callback_param *param = data;
1858         struct line_finder *lf = param->data;
1859         struct line_range *lr = lf->lr;
1860
1861         /* Check declared file */
1862         if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
1863                 return DWARF_CB_OK;
1864
1865         if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
1866             die_compare_name(sp_die, lr->function)) {
1867                 lf->fname = dwarf_decl_file(sp_die);
1868                 dwarf_decl_line(sp_die, &lr->offset);
1869                 pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
1870                 lf->lno_s = lr->offset + lr->start;
1871                 if (lf->lno_s < 0)      /* Overflow */
1872                         lf->lno_s = INT_MAX;
1873                 lf->lno_e = lr->offset + lr->end;
1874                 if (lf->lno_e < 0)      /* Overflow */
1875                         lf->lno_e = INT_MAX;
1876                 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
1877                 lr->start = lf->lno_s;
1878                 lr->end = lf->lno_e;
1879                 if (dwarf_func_inline(sp_die)) {
1880                         struct dwarf_callback_param _param;
1881                         _param.data = (void *)lf;
1882                         _param.retval = 0;
1883                         dwarf_func_inline_instances(sp_die,
1884                                                     line_range_inline_cb,
1885                                                     &_param);
1886                         param->retval = _param.retval;
1887                 } else
1888                         param->retval = find_line_range_by_line(sp_die, lf);
1889                 return DWARF_CB_ABORT;
1890         }
1891         return DWARF_CB_OK;
1892 }
1893
1894 static int find_line_range_by_func(struct line_finder *lf)
1895 {
1896         struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
1897         dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0);
1898         return param.retval;
1899 }
1900
1901 int find_line_range(int fd, struct line_range *lr)
1902 {
1903         struct line_finder lf = {.lr = lr, .found = 0};
1904         int ret = 0;
1905         Dwarf_Off off = 0, noff;
1906         size_t cuhl;
1907         Dwarf_Die *diep;
1908         Dwarf *dbg = NULL;
1909         Dwfl *dwfl;
1910         Dwarf_Addr bias;        /* Currently ignored */
1911         const char *comp_dir;
1912
1913         dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
1914         if (!dbg) {
1915                 pr_warning("No debug information found in the vmlinux - "
1916                         "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1917                 close(fd);      /* Without dwfl_end(), fd isn't closed. */
1918                 return -EBADF;
1919         }
1920
1921         /* Loop on CUs (Compilation Unit) */
1922         while (!lf.found && ret >= 0) {
1923                 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
1924                         break;
1925
1926                 /* Get the DIE(Debugging Information Entry) of this CU */
1927                 diep = dwarf_offdie(dbg, off + cuhl, &lf.cu_die);
1928                 if (!diep)
1929                         continue;
1930
1931                 /* Check if target file is included. */
1932                 if (lr->file)
1933                         lf.fname = cu_find_realpath(&lf.cu_die, lr->file);
1934                 else
1935                         lf.fname = 0;
1936
1937                 if (!lr->file || lf.fname) {
1938                         if (lr->function)
1939                                 ret = find_line_range_by_func(&lf);
1940                         else {
1941                                 lf.lno_s = lr->start;
1942                                 lf.lno_e = lr->end;
1943                                 ret = find_line_range_by_line(NULL, &lf);
1944                         }
1945                 }
1946                 off = noff;
1947         }
1948
1949         /* Store comp_dir */
1950         if (lf.found) {
1951                 comp_dir = cu_get_comp_dir(&lf.cu_die);
1952                 if (comp_dir) {
1953                         lr->comp_dir = strdup(comp_dir);
1954                         if (!lr->comp_dir)
1955                                 ret = -ENOMEM;
1956                 }
1957         }
1958
1959         pr_debug("path: %s\n", lr->path);
1960         dwfl_end(dwfl);
1961         return (ret < 0) ? ret : lf.found;
1962 }
1963