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