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