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