File Index
Files and directories
Sign in
FILE

probe-finder.c

File preview with syntax highlighting.

linux-6.19.14/tools/perf/util/probe-finder.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * probe-finder.c : C expression to kprobe event converter
   4 *
   5 * Written by Masami Hiramatsu <mhiramat@redhat.com>
   6 */
   7
   8#include <inttypes.h>
   9#include <sys/utsname.h>
  10#include <sys/types.h>
  11#include <sys/stat.h>
  12#include <fcntl.h>
  13#include <errno.h>
  14#include <stdio.h>
  15#include <unistd.h>
  16#include <stdlib.h>
  17#include <string.h>
  18#include <stdarg.h>
  19#include <dwarf-regs.h>
  20
  21#include <linux/bitops.h>
  22#include <linux/zalloc.h>
  23#include "event.h"
  24#include "dso.h"
  25#include "debug.h"
  26#include "debuginfo.h"
  27#include "intlist.h"
  28#include "strbuf.h"
  29#include "strlist.h"
  30#include "symbol.h"
  31#include "probe-finder.h"
  32#include "probe-file.h"
  33#include "string2.h"
  34
  35/* Kprobe tracer basic type is up to u64 */
  36#define MAX_BASIC_TYPE_BITS	64
  37
  38bool is_known_C_lang(int lang)
  39{
  40	switch (lang) {
  41	case DW_LANG_C89:
  42	case DW_LANG_C:
  43	case DW_LANG_C99:
  44	case DW_LANG_C11:
  45		return true;
  46	default:
  47		return false;
  48	}
  49}
  50
  51/*
  52 * Probe finder related functions
  53 */
  54
  55static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
  56{
  57	struct probe_trace_arg_ref *ref;
  58	ref = zalloc(sizeof(struct probe_trace_arg_ref));
  59	if (ref != NULL)
  60		ref->offset = offs;
  61	return ref;
  62}
  63
  64/*
  65 * Convert a location into trace_arg.
  66 * If tvar == NULL, this just checks variable can be converted.
  67 * If fentry == true and vr_die is a parameter, do heuristic search
  68 * for the location fuzzed by function entry mcount.
  69 */
  70static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
  71				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
  72				     const struct probe_finder *pf,
  73				     struct probe_trace_arg *tvar)
  74{
  75	Dwarf_Attribute attr;
  76	Dwarf_Addr tmp = 0;
  77	Dwarf_Op *op;
  78	size_t nops;
  79	unsigned int regn;
  80	Dwarf_Word offs = 0;
  81	bool ref = false;
  82	const char *regs;
  83	int ret, ret2 = 0;
  84
  85	if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL)
  86		goto static_var;
  87
  88	/* Constant value */
  89	if (dwarf_attr(vr_die, DW_AT_const_value, &attr) &&
  90	    immediate_value_is_supported()) {
  91		Dwarf_Sword snum;
  92
  93		if (!tvar)
  94			return 0;
  95
  96		dwarf_formsdata(&attr, &snum);
  97		ret = asprintf(&tvar->value, "\\%ld", (long)snum);
  98
  99		return ret < 0 ? -ENOMEM : 0;
 100	}
 101
 102	/* TODO: handle more than 1 exprs */
 103	if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
 104		return -EINVAL;	/* Broken DIE ? */
 105	if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) {
 106		ret = dwarf_entrypc(sp_die, &tmp);
 107		if (ret)
 108			return -ENOENT;
 109
 110		if (probe_conf.show_location_range &&
 111			(dwarf_tag(vr_die) == DW_TAG_variable)) {
 112			ret2 = -ERANGE;
 113		} else if (addr != tmp ||
 114			dwarf_tag(vr_die) != DW_TAG_formal_parameter) {
 115			return -ENOENT;
 116		}
 117
 118		ret = dwarf_highpc(sp_die, &tmp);
 119		if (ret)
 120			return -ENOENT;
 121		/*
 122		 * This is fuzzed by fentry mcount. We try to find the
 123		 * parameter location at the earliest address.
 124		 */
 125		for (addr += 1; addr <= tmp; addr++) {
 126			if (dwarf_getlocation_addr(&attr, addr, &op,
 127						   &nops, 1) > 0)
 128				goto found;
 129		}
 130		return -ENOENT;
 131	}
 132found:
 133	if (nops == 0)
 134		/* TODO: Support const_value */
 135		return -ENOENT;
 136
 137	if (op->atom == DW_OP_addr) {
 138static_var:
 139		if (!tvar)
 140			return ret2;
 141		/* Static variables on memory (not stack), make @varname */
 142		ret = strlen(dwarf_diename(vr_die));
 143		tvar->value = zalloc(ret + 2);
 144		if (tvar->value == NULL)
 145			return -ENOMEM;
 146		snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die));
 147		tvar->ref = alloc_trace_arg_ref((long)offs);
 148		if (tvar->ref == NULL)
 149			return -ENOMEM;
 150		return ret2;
 151	}
 152
 153	/* If this is based on frame buffer, set the offset */
 154	if (op->atom == DW_OP_fbreg) {
 155		if (fb_ops == NULL)
 156			return -ENOTSUP;
 157		ref = true;
 158		offs = op->number;
 159		op = &fb_ops[0];
 160	}
 161
 162	if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
 163		regn = op->atom - DW_OP_breg0;
 164		offs += op->number;
 165		ref = true;
 166	} else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) {
 167		regn = op->atom - DW_OP_reg0;
 168	} else if (op->atom == DW_OP_bregx) {
 169		regn = op->number;
 170		offs += op->number2;
 171		ref = true;
 172	} else if (op->atom == DW_OP_regx) {
 173		regn = op->number;
 174	} else {
 175		pr_debug("DW_OP %x is not supported.\n", op->atom);
 176		return -ENOTSUP;
 177	}
 178
 179	if (!tvar)
 180		return ret2;
 181
 182	regs = get_dwarf_regstr(regn, pf->e_machine, pf->e_flags);
 183	if (!regs) {
 184		/* This should be a bug in DWARF or this tool */
 185		pr_warning("Mapping for the register number %u "
 186			   "missing on this architecture.\n", regn);
 187		return -ENOTSUP;
 188	}
 189
 190	tvar->value = strdup(regs);
 191	if (tvar->value == NULL)
 192		return -ENOMEM;
 193
 194	if (ref) {
 195		tvar->ref = alloc_trace_arg_ref((long)offs);
 196		if (tvar->ref == NULL)
 197			return -ENOMEM;
 198	}
 199	return ret2;
 200}
 201
 202static int convert_variable_type(Dwarf_Die *vr_die,
 203				 struct probe_trace_arg *tvar,
 204				 const char *cast, bool user_access)
 205{
 206	struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
 207	Dwarf_Die type;
 208	char buf[16];
 209	char sbuf[STRERR_BUFSIZE];
 210	int bsize, boffs, total;
 211	int ret;
 212	char prefix;
 213
 214	/* TODO: check all types */
 215	if (cast && strcmp(cast, "string") != 0 && strcmp(cast, "ustring") &&
 216	    strcmp(cast, "x") != 0 &&
 217	    strcmp(cast, "s") != 0 && strcmp(cast, "u") != 0) {
 218		/* Non string type is OK */
 219		/* and respect signedness/hexadecimal cast */
 220		tvar->type = strdup(cast);
 221		return (tvar->type == NULL) ? -ENOMEM : 0;
 222	}
 223
 224	bsize = dwarf_bitsize(vr_die);
 225	if (bsize > 0) {
 226		/* This is a bitfield */
 227		boffs = dwarf_bitoffset(vr_die);
 228		total = dwarf_bytesize(vr_die);
 229		if (boffs < 0 || total < 0)
 230			return -ENOENT;
 231		ret = snprintf(buf, 16, "b%d@%d/%d", bsize, boffs,
 232				BYTES_TO_BITS(total));
 233		goto formatted;
 234	}
 235
 236	if (die_get_real_type(vr_die, &type) == NULL) {
 237		pr_warning("Failed to get a type information of %s.\n",
 238			   dwarf_diename(vr_die));
 239		return -ENOENT;
 240	}
 241
 242	pr_debug("%s type is %s.\n",
 243		 dwarf_diename(vr_die), dwarf_diename(&type));
 244
 245	if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) {
 246		/* String type */
 247		ret = dwarf_tag(&type);
 248		if (ret != DW_TAG_pointer_type &&
 249		    ret != DW_TAG_array_type) {
 250			pr_warning("Failed to cast into string: "
 251				   "%s(%s) is not a pointer nor array.\n",
 252				   dwarf_diename(vr_die), dwarf_diename(&type));
 253			return -EINVAL;
 254		}
 255		if (die_get_real_type(&type, &type) == NULL) {
 256			pr_warning("Failed to get a type"
 257				   " information.\n");
 258			return -ENOENT;
 259		}
 260		if (ret == DW_TAG_pointer_type) {
 261			while (*ref_ptr)
 262				ref_ptr = &(*ref_ptr)->next;
 263			/* Add new reference with offset +0 */
 264			*ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref));
 265			if (*ref_ptr == NULL) {
 266				pr_warning("Out of memory error\n");
 267				return -ENOMEM;
 268			}
 269			(*ref_ptr)->user_access = user_access;
 270		}
 271		if (!die_compare_name(&type, "char") &&
 272		    !die_compare_name(&type, "unsigned char")) {
 273			pr_warning("Failed to cast into string: "
 274				   "%s is not (unsigned) char *.\n",
 275				   dwarf_diename(vr_die));
 276			return -EINVAL;
 277		}
 278		tvar->type = strdup(cast);
 279		return (tvar->type == NULL) ? -ENOMEM : 0;
 280	}
 281
 282	if (cast && (strcmp(cast, "u") == 0))
 283		prefix = 'u';
 284	else if (cast && (strcmp(cast, "s") == 0))
 285		prefix = 's';
 286	else if (cast && (strcmp(cast, "x") == 0) &&
 287		 probe_type_is_available(PROBE_TYPE_X))
 288		prefix = 'x';
 289	else
 290		prefix = die_is_signed_type(&type) ? 's' :
 291			 probe_type_is_available(PROBE_TYPE_X) ? 'x' : 'u';
 292
 293	ret = dwarf_bytesize(&type);
 294	if (ret <= 0)
 295		/* No size ... try to use default type */
 296		return 0;
 297	ret = BYTES_TO_BITS(ret);
 298
 299	/* Check the bitwidth */
 300	if (ret > MAX_BASIC_TYPE_BITS) {
 301		pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n",
 302			dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
 303		ret = MAX_BASIC_TYPE_BITS;
 304	}
 305	ret = snprintf(buf, 16, "%c%d", prefix, ret);
 306
 307formatted:
 308	if (ret < 0 || ret >= 16) {
 309		if (ret >= 16)
 310			ret = -E2BIG;
 311		pr_warning("Failed to convert variable type: %s\n",
 312			   str_error_r(-ret, sbuf, sizeof(sbuf)));
 313		return ret;
 314	}
 315	tvar->type = strdup(buf);
 316	if (tvar->type == NULL)
 317		return -ENOMEM;
 318	return 0;
 319}
 320
 321static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 322				    struct perf_probe_arg_field *field,
 323				    struct probe_trace_arg_ref **ref_ptr,
 324				    Dwarf_Die *die_mem, bool user_access)
 325{
 326	struct probe_trace_arg_ref *ref = *ref_ptr;
 327	Dwarf_Die type;
 328	Dwarf_Word offs;
 329	int ret, tag;
 330
 331	pr_debug("converting %s in %s\n", field->name, varname);
 332	if (die_get_real_type(vr_die, &type) == NULL) {
 333		pr_warning("Failed to get the type of %s.\n", varname);
 334		return -ENOENT;
 335	}
 336	pr_debug2("Var real type: %s (%x)\n", dwarf_diename(&type),
 337		  (unsigned)dwarf_dieoffset(&type));
 338	tag = dwarf_tag(&type);
 339
 340	if (field->name[0] == '[' &&
 341	    (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) {
 342		/* Save original type for next field or type */
 343		memcpy(die_mem, &type, sizeof(*die_mem));
 344		/* Get the type of this array */
 345		if (die_get_real_type(&type, &type) == NULL) {
 346			pr_warning("Failed to get the type of %s.\n", varname);
 347			return -ENOENT;
 348		}
 349		pr_debug2("Array real type: %s (%x)\n", dwarf_diename(&type),
 350			 (unsigned)dwarf_dieoffset(&type));
 351		if (tag == DW_TAG_pointer_type) {
 352			ref = zalloc(sizeof(struct probe_trace_arg_ref));
 353			if (ref == NULL)
 354				return -ENOMEM;
 355			if (*ref_ptr)
 356				(*ref_ptr)->next = ref;
 357			else
 358				*ref_ptr = ref;
 359		}
 360		ref->offset += dwarf_bytesize(&type) * field->index;
 361		ref->user_access = user_access;
 362		goto next;
 363	} else if (tag == DW_TAG_pointer_type) {
 364		/* Check the pointer and dereference */
 365		if (!field->ref) {
 366			pr_err("Semantic error: %s must be referred by '->'\n",
 367			       field->name);
 368			return -EINVAL;
 369		}
 370		/* Get the type pointed by this pointer */
 371		if (die_get_real_type(&type, &type) == NULL) {
 372			pr_warning("Failed to get the type of %s.\n", varname);
 373			return -ENOENT;
 374		}
 375		/* Verify it is a data structure  */
 376		tag = dwarf_tag(&type);
 377		if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
 378			pr_warning("%s is not a data structure nor a union.\n",
 379				   varname);
 380			return -EINVAL;
 381		}
 382
 383		ref = zalloc(sizeof(struct probe_trace_arg_ref));
 384		if (ref == NULL)
 385			return -ENOMEM;
 386		if (*ref_ptr)
 387			(*ref_ptr)->next = ref;
 388		else
 389			*ref_ptr = ref;
 390	} else {
 391		/* Verify it is a data structure  */
 392		if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
 393			pr_warning("%s is not a data structure nor a union.\n",
 394				   varname);
 395			return -EINVAL;
 396		}
 397		if (field->name[0] == '[') {
 398			pr_err("Semantic error: %s is not a pointer"
 399			       " nor array.\n", varname);
 400			return -EINVAL;
 401		}
 402		/* While processing unnamed field, we don't care about this */
 403		if (field->ref && dwarf_diename(vr_die)) {
 404			pr_err("Semantic error: %s must be referred by '.'\n",
 405			       field->name);
 406			return -EINVAL;
 407		}
 408		if (!ref) {
 409			pr_warning("Structure on a register is not "
 410				   "supported yet.\n");
 411			return -ENOTSUP;
 412		}
 413	}
 414
 415	if (die_find_member(&type, field->name, die_mem) == NULL) {
 416		pr_warning("%s(type:%s) has no member %s.\n", varname,
 417			   dwarf_diename(&type), field->name);
 418		return -EINVAL;
 419	}
 420
 421	/* Get the offset of the field */
 422	if (tag == DW_TAG_union_type) {
 423		offs = 0;
 424	} else {
 425		ret = die_get_data_member_location(die_mem, &offs);
 426		if (ret < 0) {
 427			pr_warning("Failed to get the offset of %s.\n",
 428				   field->name);
 429			return ret;
 430		}
 431	}
 432	ref->offset += (long)offs;
 433	ref->user_access = user_access;
 434
 435	/* If this member is unnamed, we need to reuse this field */
 436	if (!dwarf_diename(die_mem))
 437		return convert_variable_fields(die_mem, varname, field,
 438						&ref, die_mem, user_access);
 439
 440next:
 441	/* Converting next field */
 442	if (field->next)
 443		return convert_variable_fields(die_mem, field->name,
 444				field->next, &ref, die_mem, user_access);
 445	else
 446		return 0;
 447}
 448
 449static void print_var_not_found(const char *varname)
 450{
 451	pr_err("Failed to find the location of the '%s' variable at this address.\n"
 452	       " Perhaps it has been optimized out.\n"
 453	       " Use -V with the --range option to show '%s' location range.\n",
 454		varname, varname);
 455}
 456
 457/* Show a variables in kprobe event format */
 458static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
 459{
 460	Dwarf_Die die_mem;
 461	int ret;
 462
 463	pr_debug("Converting variable %s into trace event.\n",
 464		 dwarf_diename(vr_die));
 465
 466	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
 467					&pf->sp_die, pf, pf->tvar);
 468	if (ret == -ENOENT && pf->skip_empty_arg)
 469		/* This can be found in other place. skip it */
 470		return 0;
 471	if (ret == -ENOENT || ret == -EINVAL) {
 472		print_var_not_found(pf->pvar->var);
 473	} else if (ret == -ENOTSUP)
 474		pr_err("Sorry, we don't support this variable location yet.\n");
 475	else if (ret == 0 && pf->pvar->field) {
 476		ret = convert_variable_fields(vr_die, pf->pvar->var,
 477					      pf->pvar->field, &pf->tvar->ref,
 478					      &die_mem, pf->pvar->user_access);
 479		vr_die = &die_mem;
 480	}
 481	if (ret == 0)
 482		ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type,
 483					    pf->pvar->user_access);
 484	/* *expr will be cached in libdw. Don't free it. */
 485	return ret;
 486}
 487
 488/* Find a variable in a scope DIE */
 489static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
 490{
 491	Dwarf_Die vr_die;
 492	char *buf, *ptr;
 493	int ret = 0;
 494
 495	/* Copy raw parameters */
 496	if (!is_c_varname(pf->pvar->var))
 497		return copy_to_probe_trace_arg(pf->tvar, pf->pvar);
 498
 499	if (pf->pvar->name)
 500		pf->tvar->name = strdup(pf->pvar->name);
 501	else {
 502		buf = synthesize_perf_probe_arg(pf->pvar);
 503		if (!buf)
 504			return -ENOMEM;
 505		ptr = strchr(buf, ':');	/* Change type separator to _ */
 506		if (ptr)
 507			*ptr = '_';
 508		pf->tvar->name = buf;
 509	}
 510	if (pf->tvar->name == NULL)
 511		return -ENOMEM;
 512
 513	pr_debug("Searching '%s' variable in context.\n", pf->pvar->var);
 514	/* Search child die for local variables and parameters. */
 515	if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
 516		/* Search again in global variables */
 517		if (!die_find_variable_at(&pf->cu_die, pf->pvar->var,
 518						0, &vr_die)) {
 519			if (pf->skip_empty_arg)
 520				return 0;
 521			pr_warning("Failed to find '%s' in this function.\n",
 522				   pf->pvar->var);
 523			ret = -ENOENT;
 524		}
 525	}
 526	if (ret >= 0)
 527		ret = convert_variable(&vr_die, pf);
 528
 529	return ret;
 530}
 531
 532/* Convert subprogram DIE to trace point */
 533static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
 534				  Dwarf_Addr paddr, bool retprobe,
 535				  const char *function,
 536				  struct probe_trace_point *tp)
 537{
 538	Dwarf_Addr eaddr;
 539	GElf_Sym sym;
 540	const char *symbol;
 541
 542	/* Verify the address is correct */
 543	if (!dwarf_haspc(sp_die, paddr)) {
 544		pr_warning("Specified offset is out of %s\n",
 545			   dwarf_diename(sp_die));
 546		return -EINVAL;
 547	}
 548
 549	if (dwarf_entrypc(sp_die, &eaddr) == 0) {
 550		/* If the DIE has entrypc, use it. */
 551		symbol = dwarf_diename(sp_die);
 552	} else {
 553		/* Try to get actual symbol name and address from symtab */
 554		symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
 555		eaddr = sym.st_value;
 556	}
 557	if (!symbol) {
 558		pr_warning("Failed to find symbol at 0x%lx\n",
 559			   (unsigned long)paddr);
 560		return -ENOENT;
 561	}
 562
 563	tp->offset = (unsigned long)(paddr - eaddr);
 564	tp->address = paddr;
 565	tp->symbol = strdup(symbol);
 566	if (!tp->symbol)
 567		return -ENOMEM;
 568
 569	/* Return probe must be on the head of a subprogram */
 570	if (retprobe) {
 571		if (eaddr != paddr) {
 572			pr_warning("Failed to find \"%s%%return\",\n"
 573				   " because %s is an inlined function and"
 574				   " has no return point.\n", function,
 575				   function);
 576			return -EINVAL;
 577		}
 578		tp->retprobe = true;
 579	}
 580
 581	return 0;
 582}
 583
 584/* Call probe_finder callback with scope DIE */
 585static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
 586{
 587	Dwarf_Attribute fb_attr;
 588	Dwarf_Frame *frame = NULL;
 589	size_t nops;
 590	int ret;
 591
 592	if (!sc_die) {
 593		pr_err("Caller must pass a scope DIE. Program error.\n");
 594		return -EINVAL;
 595	}
 596
 597	/* If not a real subprogram, find a real one */
 598	if (!die_is_func_def(sc_die)) {
 599		if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
 600			if (die_find_tailfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
 601				pr_warning("Ignoring tail call from %s\n",
 602						dwarf_diename(&pf->sp_die));
 603				return 0;
 604			} else {
 605				pr_warning("Failed to find probe point in any "
 606					   "functions.\n");
 607				return -ENOENT;
 608			}
 609		}
 610	} else
 611		memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die));
 612
 613	/* Get the frame base attribute/ops from subprogram */
 614	dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr);
 615	ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
 616	if (ret <= 0 || nops == 0) {
 617		pf->fb_ops = NULL;
 618	} else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
 619		   (pf->cfi_eh != NULL || pf->cfi_dbg != NULL)) {
 620		if ((dwarf_cfi_addrframe(pf->cfi_eh, pf->addr, &frame) != 0 &&
 621		     (dwarf_cfi_addrframe(pf->cfi_dbg, pf->addr, &frame) != 0)) ||
 622		    dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
 623			pr_warning("Failed to get call frame on 0x%jx\n",
 624				   (uintmax_t)pf->addr);
 625			free(frame);
 626			return -ENOENT;
 627		}
 628	}
 629
 630	/* Call finder's callback handler */
 631	ret = pf->callback(sc_die, pf);
 632
 633	/* Since *pf->fb_ops can be a part of frame. we should free it here. */
 634	free(frame);
 635	pf->fb_ops = NULL;
 636
 637	return ret;
 638}
 639
 640struct find_scope_param {
 641	const char *function;
 642	const char *file;
 643	int line;
 644	int diff;
 645	Dwarf_Die *die_mem;
 646	bool found;
 647};
 648
 649static int find_best_scope_cb(Dwarf_Die *fn_die, void *data)
 650{
 651	struct find_scope_param *fsp = data;
 652	const char *file;
 653	int lno;
 654
 655	/* Skip if declared file name does not match */
 656	if (fsp->file) {
 657		file = die_get_decl_file(fn_die);
 658		if (!file || strcmp(fsp->file, file) != 0)
 659			return 0;
 660	}
 661	/* If the function name is given, that's what user expects */
 662	if (fsp->function) {
 663		if (die_match_name(fn_die, fsp->function)) {
 664			memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
 665			fsp->found = true;
 666			return 1;
 667		}
 668	} else {
 669		/* With the line number, find the nearest declared DIE */
 670		dwarf_decl_line(fn_die, &lno);
 671		if (lno < fsp->line && fsp->diff > fsp->line - lno) {
 672			/* Keep a candidate and continue */
 673			fsp->diff = fsp->line - lno;
 674			memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
 675			fsp->found = true;
 676		}
 677	}
 678	return 0;
 679}
 680
 681/* Return innermost DIE */
 682static int find_inner_scope_cb(Dwarf_Die *fn_die, void *data)
 683{
 684	struct find_scope_param *fsp = data;
 685
 686	memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
 687	fsp->found = true;
 688	return 1;
 689}
 690
 691/* Find an appropriate scope fits to given conditions */
 692static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
 693{
 694	struct find_scope_param fsp = {
 695		.function = pf->pev->point.function,
 696		.file = pf->fname,
 697		.line = pf->lno,
 698		.diff = INT_MAX,
 699		.die_mem = die_mem,
 700		.found = false,
 701	};
 702	int ret;
 703
 704	ret = cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb,
 705				   &fsp);
 706	if (!ret && !fsp.found)
 707		cu_walk_functions_at(&pf->cu_die, pf->addr,
 708				     find_inner_scope_cb, &fsp);
 709
 710	return fsp.found ? die_mem : NULL;
 711}
 712
 713static int verify_representive_line(struct probe_finder *pf, const char *fname,
 714				int lineno, Dwarf_Addr addr)
 715{
 716	const char *__fname, *__func = NULL;
 717	Dwarf_Die die_mem;
 718	int __lineno;
 719
 720	/* Verify line number and address by reverse search */
 721	if (cu_find_lineinfo(&pf->cu_die, addr, &__fname, &__lineno) < 0)
 722		return 0;
 723
 724	pr_debug2("Reversed line: %s:%d\n", __fname, __lineno);
 725	if (strcmp(fname, __fname) || lineno == __lineno)
 726		return 0;
 727
 728	pr_warning("This line is sharing the address with other lines.\n");
 729
 730	if (pf->pev->point.function) {
 731		/* Find best match function name and lines */
 732		pf->addr = addr;
 733		if (find_best_scope(pf, &die_mem)
 734		    && die_match_name(&die_mem, pf->pev->point.function)
 735		    && dwarf_decl_line(&die_mem, &lineno) == 0) {
 736			__func = dwarf_diename(&die_mem);
 737			__lineno -= lineno;
 738		}
 739	}
 740	pr_warning("Please try to probe at %s:%d instead.\n",
 741		   __func ? : __fname, __lineno);
 742
 743	return -ENOENT;
 744}
 745
 746static int probe_point_line_walker(const char *fname, int lineno,
 747				   Dwarf_Addr addr, void *data)
 748{
 749	struct probe_finder *pf = data;
 750	Dwarf_Die *sc_die, die_mem;
 751	int ret;
 752
 753	if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0)
 754		return 0;
 755
 756	if (verify_representive_line(pf, fname, lineno, addr))
 757		return -ENOENT;
 758
 759	pf->addr = addr;
 760	sc_die = find_best_scope(pf, &die_mem);
 761	if (!sc_die) {
 762		pr_warning("Failed to find scope of probe point.\n");
 763		return -ENOENT;
 764	}
 765
 766	ret = call_probe_finder(sc_die, pf);
 767
 768	/* Continue if no error, because the line will be in inline function */
 769	return ret < 0 ? ret : 0;
 770}
 771
 772/* Find probe point from its line number */
 773static int find_probe_point_by_line(struct probe_finder *pf)
 774{
 775	return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf);
 776}
 777
 778/* Find lines which match lazy pattern */
 779static int find_lazy_match_lines(struct intlist *list,
 780				 const char *fname, const char *pat)
 781{
 782	FILE *fp;
 783	char *line = NULL;
 784	size_t line_len;
 785	ssize_t len;
 786	int count = 0, linenum = 1;
 787	char sbuf[STRERR_BUFSIZE];
 788
 789	fp = fopen(fname, "r");
 790	if (!fp) {
 791		pr_warning("Failed to open %s: %s\n", fname,
 792			   str_error_r(errno, sbuf, sizeof(sbuf)));
 793		return -errno;
 794	}
 795
 796	while ((len = getline(&line, &line_len, fp)) > 0) {
 797
 798		if (line[len - 1] == '\n')
 799			line[len - 1] = '\0';
 800
 801		if (strlazymatch(line, pat)) {
 802			intlist__add(list, linenum);
 803			count++;
 804		}
 805		linenum++;
 806	}
 807
 808	if (ferror(fp))
 809		count = -errno;
 810	free(line);
 811	fclose(fp);
 812
 813	if (count == 0)
 814		pr_debug("No matched lines found in %s.\n", fname);
 815	return count;
 816}
 817
 818static int probe_point_lazy_walker(const char *fname, int lineno,
 819				   Dwarf_Addr addr, void *data)
 820{
 821	struct probe_finder *pf = data;
 822	Dwarf_Die *sc_die, die_mem;
 823	int ret;
 824
 825	if (!intlist__has_entry(pf->lcache, lineno) ||
 826	    strtailcmp(fname, pf->fname) != 0)
 827		return 0;
 828
 829	pr_debug("Probe line found: line:%d addr:0x%llx\n",
 830		 lineno, (unsigned long long)addr);
 831	pf->addr = addr;
 832	pf->lno = lineno;
 833	sc_die = find_best_scope(pf, &die_mem);
 834	if (!sc_die) {
 835		pr_warning("Failed to find scope of probe point.\n");
 836		return -ENOENT;
 837	}
 838
 839	ret = call_probe_finder(sc_die, pf);
 840
 841	/*
 842	 * Continue if no error, because the lazy pattern will match
 843	 * to other lines
 844	 */
 845	return ret < 0 ? ret : 0;
 846}
 847
 848/* Find probe points from lazy pattern  */
 849static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
 850{
 851	char sbuild_id[SBUILD_ID_SIZE] = "";
 852	int ret = 0;
 853	char *fpath;
 854
 855	if (intlist__empty(pf->lcache)) {
 856		const char *comp_dir;
 857
 858		comp_dir = cu_get_comp_dir(&pf->cu_die);
 859		if (pf->dbg->build_id) {
 860			struct build_id bid;
 861
 862			build_id__init(&bid, pf->dbg->build_id, BUILD_ID_SIZE);
 863			build_id__snprintf(&bid, sbuild_id, sizeof(sbuild_id));
 864		}
 865		ret = find_source_path(pf->fname, sbuild_id, comp_dir, &fpath);
 866		if (ret < 0) {
 867			pr_warning("Failed to find source file path.\n");
 868			return ret;
 869		}
 870
 871		/* Matching lazy line pattern */
 872		ret = find_lazy_match_lines(pf->lcache, fpath,
 873					    pf->pev->point.lazy_line);
 874		free(fpath);
 875		if (ret <= 0)
 876			return ret;
 877	}
 878
 879	return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
 880}
 881
 882static void skip_prologue(Dwarf_Die *sp_die, struct probe_finder *pf)
 883{
 884	struct perf_probe_point *pp = &pf->pev->point;
 885
 886	/* Not uprobe? */
 887	if (!pf->pev->uprobes)
 888		return;
 889
 890	/* Compiled with optimization? */
 891	if (die_is_optimized_target(&pf->cu_die))
 892		return;
 893
 894	/* Don't know entrypc? */
 895	if (!pf->addr)
 896		return;
 897
 898	/* Only FUNC and FUNC@SRC are eligible. */
 899	if (!pp->function || pp->line || pp->retprobe || pp->lazy_line ||
 900	    pp->offset || pp->abs_address)
 901		return;
 902
 903	/* Not interested in func parameter? */
 904	if (!perf_probe_with_var(pf->pev))
 905		return;
 906
 907	pr_info("Target program is compiled without optimization. Skipping prologue.\n"
 908		"Probe on address 0x%" PRIx64 " to force probing at the function entry.\n\n",
 909		pf->addr);
 910
 911	die_skip_prologue(sp_die, &pf->cu_die, &pf->addr);
 912}
 913
 914static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
 915{
 916	struct probe_finder *pf = data;
 917	struct perf_probe_point *pp = &pf->pev->point;
 918	Dwarf_Addr addr;
 919	int ret;
 920
 921	if (pp->lazy_line)
 922		ret = find_probe_point_lazy(in_die, pf);
 923	else {
 924		/* Get probe address */
 925		if (die_entrypc(in_die, &addr) != 0) {
 926			pr_warning("Failed to get entry address of %s.\n",
 927				   dwarf_diename(in_die));
 928			return -ENOENT;
 929		}
 930		if (addr == 0) {
 931			pr_debug("%s has no valid entry address. skipped.\n",
 932				 dwarf_diename(in_die));
 933			return -ENOENT;
 934		}
 935		pf->addr = addr;
 936		pf->addr += pp->offset;
 937		pr_debug("found inline addr: 0x%jx\n",
 938			 (uintmax_t)pf->addr);
 939
 940		ret = call_probe_finder(in_die, pf);
 941	}
 942
 943	return ret;
 944}
 945
 946/* Callback parameter with return value for libdw */
 947struct dwarf_callback_param {
 948	void *data;
 949	int retval;
 950};
 951
 952/* Search function from function name */
 953static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 954{
 955	struct dwarf_callback_param *param = data;
 956	struct probe_finder *pf = param->data;
 957	struct perf_probe_point *pp = &pf->pev->point;
 958	const char *fname;
 959
 960	/* Check tag and diename */
 961	if (!die_is_func_def(sp_die) ||
 962	    !die_match_name(sp_die, pp->function))
 963		return DWARF_CB_OK;
 964
 965	/* Check declared file */
 966	fname = die_get_decl_file(sp_die);
 967	if (!fname) {
 968		pr_warning("A function DIE doesn't have decl_line. Maybe broken DWARF?\n");
 969		return DWARF_CB_OK;
 970	}
 971	if (pp->file && fname && strtailcmp(pp->file, fname))
 972		return DWARF_CB_OK;
 973
 974	pr_debug("Matched function: %s [%lx]\n", dwarf_diename(sp_die),
 975		 (unsigned long)dwarf_dieoffset(sp_die));
 976	pf->fname = fname;
 977	pf->abstrace_dieoffset = dwarf_dieoffset(sp_die);
 978	if (pp->line) { /* Function relative line */
 979		dwarf_decl_line(sp_die, &pf->lno);
 980		pf->lno += pp->line;
 981		param->retval = find_probe_point_by_line(pf);
 982	} else if (die_is_func_instance(sp_die)) {
 983		/* Instances always have the entry address */
 984		die_entrypc(sp_die, &pf->addr);
 985		/* But in some case the entry address is 0 */
 986		if (pf->addr == 0) {
 987			pr_debug("%s has no entry PC. Skipped\n",
 988				 dwarf_diename(sp_die));
 989			param->retval = 0;
 990		/* Real function */
 991		} else if (pp->lazy_line)
 992			param->retval = find_probe_point_lazy(sp_die, pf);
 993		else {
 994			skip_prologue(sp_die, pf);
 995			pf->addr += pp->offset;
 996			/* TODO: Check the address in this function */
 997			param->retval = call_probe_finder(sp_die, pf);
 998		}
 999	} else if (!probe_conf.no_inlines) {
1000		/* Inlined function: search instances */
1001		param->retval = die_walk_instances(sp_die,
1002					probe_point_inline_cb, (void *)pf);
1003		/* This could be a non-existed inline definition */
1004		if (param->retval == -ENOENT)
1005			param->retval = 0;
1006	}
1007
1008	/* We need to find other candidates */
1009	if (strisglob(pp->function) && param->retval >= 0) {
1010		param->retval = 0;	/* We have to clear the result */
1011		return DWARF_CB_OK;
1012	}
1013
1014	return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
1015}
1016
1017static int find_probe_point_by_func(struct probe_finder *pf)
1018{
1019	struct dwarf_callback_param _param = {.data = (void *)pf,
1020					      .retval = 0};
1021	dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
1022	return _param.retval;
1023}
1024
1025struct pubname_callback_param {
1026	char *function;
1027	char *file;
1028	Dwarf_Die *cu_die;
1029	Dwarf_Die *sp_die;
1030	int found;
1031};
1032
1033static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
1034{
1035	struct pubname_callback_param *param = data;
1036	const char *fname;
1037
1038	if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
1039		if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
1040			return DWARF_CB_OK;
1041
1042		if (die_match_name(param->sp_die, param->function)) {
1043			if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
1044				return DWARF_CB_OK;
1045
1046			if (param->file) {
1047				fname = die_get_decl_file(param->sp_die);
1048				if (!fname || strtailcmp(param->file, fname))
1049					return DWARF_CB_OK;
1050			}
1051
1052			param->found = 1;
1053			return DWARF_CB_ABORT;
1054		}
1055	}
1056
1057	return DWARF_CB_OK;
1058}
1059
1060static int debuginfo__find_probe_location(struct debuginfo *dbg,
1061				  struct probe_finder *pf)
1062{
1063	struct perf_probe_point *pp = &pf->pev->point;
1064	Dwarf_Off off, noff;
1065	size_t cuhl;
1066	Dwarf_Die *diep;
1067	int ret = 0;
1068
1069	off = 0;
1070	pf->lcache = intlist__new(NULL);
1071	if (!pf->lcache)
1072		return -ENOMEM;
1073
1074	/* Fastpath: lookup by function name from .debug_pubnames section */
1075	if (pp->function && !strisglob(pp->function)) {
1076		struct pubname_callback_param pubname_param = {
1077			.function = pp->function,
1078			.file	  = pp->file,
1079			.cu_die	  = &pf->cu_die,
1080			.sp_die	  = &pf->sp_die,
1081			.found	  = 0,
1082		};
1083		struct dwarf_callback_param probe_param = {
1084			.data = pf,
1085		};
1086
1087		dwarf_getpubnames(dbg->dbg, pubname_search_cb,
1088				  &pubname_param, 0);
1089		if (pubname_param.found) {
1090			ret = probe_point_search_cb(&pf->sp_die, &probe_param);
1091			if (ret)
1092				goto found;
1093		}
1094	}
1095
1096	/* Loop on CUs (Compilation Unit) */
1097	while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1098		/* Get the DIE(Debugging Information Entry) of this CU */
1099		diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die);
1100		if (!diep) {
1101			off = noff;
1102			continue;
1103		}
1104
1105		/* Check if target file is included. */
1106		if (pp->file)
1107			pf->fname = cu_find_realpath(&pf->cu_die, pp->file);
1108		else
1109			pf->fname = NULL;
1110
1111		if (!pp->file || pf->fname) {
1112			if (pp->function)
1113				ret = find_probe_point_by_func(pf);
1114			else if (pp->lazy_line)
1115				ret = find_probe_point_lazy(&pf->cu_die, pf);
1116			else {
1117				pf->lno = pp->line;
1118				ret = find_probe_point_by_line(pf);
1119			}
1120			if (ret < 0)
1121				break;
1122		}
1123		off = noff;
1124	}
1125
1126found:
1127	intlist__delete(pf->lcache);
1128	pf->lcache = NULL;
1129
1130	return ret;
1131}
1132
1133/* Find probe points from debuginfo */
1134static int debuginfo__find_probes(struct debuginfo *dbg,
1135				  struct probe_finder *pf)
1136{
1137	int ret = 0;
1138	Elf *elf;
1139	GElf_Ehdr ehdr;
1140
1141	if (pf->cfi_eh || pf->cfi_dbg)
1142		return debuginfo__find_probe_location(dbg, pf);
1143
1144	/* Get the call frame information from this dwarf */
1145	elf = dwarf_getelf(dbg->dbg);
1146	if (elf == NULL)
1147		return -EINVAL;
1148
1149	if (gelf_getehdr(elf, &ehdr) == NULL)
1150		return -EINVAL;
1151
1152	pf->e_machine = ehdr.e_machine;
1153	pf->e_flags = ehdr.e_flags;
1154
1155	do {
1156		GElf_Shdr shdr;
1157
1158		if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
1159		    shdr.sh_type == SHT_PROGBITS)
1160			pf->cfi_eh = dwarf_getcfi_elf(elf);
1161
1162		pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
1163	} while (0);
1164
1165	ret = debuginfo__find_probe_location(dbg, pf);
1166	return ret;
1167}
1168
1169struct local_vars_finder {
1170	struct probe_finder *pf;
1171	struct perf_probe_arg *args;
1172	bool vars;
1173	int max_args;
1174	int nargs;
1175	int ret;
1176};
1177
1178/* Collect available variables in this scope */
1179static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
1180{
1181	struct local_vars_finder *vf = data;
1182	struct probe_finder *pf = vf->pf;
1183	int tag;
1184	Dwarf_Attribute attr;
1185	Dwarf_Die var_die;
1186
1187	tag = dwarf_tag(die_mem);
1188	if (tag == DW_TAG_formal_parameter ||
1189	    (tag == DW_TAG_variable && vf->vars)) {
1190		if (convert_variable_location(die_mem, vf->pf->addr,
1191					      vf->pf->fb_ops, &pf->sp_die,
1192					      pf, /*tvar=*/NULL) == 0) {
1193			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
1194			if (vf->args[vf->nargs].var == NULL) {
1195				vf->ret = -ENOMEM;
1196				return DIE_FIND_CB_END;
1197			}
1198			pr_debug(" %s", vf->args[vf->nargs].var);
1199			vf->nargs++;
1200		}
1201	}
1202
1203	if (dwarf_haspc(die_mem, vf->pf->addr)) {
1204		/*
1205		 * when DW_AT_entry_pc contains instruction address,
1206		 * also check if the DW_AT_abstract_origin of die_mem
1207		 * points to correct die.
1208		 */
1209		if (dwarf_attr(die_mem, DW_AT_abstract_origin, &attr)) {
1210			dwarf_formref_die(&attr, &var_die);
1211			if (pf->abstrace_dieoffset != dwarf_dieoffset(&var_die))
1212				goto out;
1213		}
1214		return DIE_FIND_CB_CONTINUE;
1215	}
1216
1217out:
1218	return DIE_FIND_CB_SIBLING;
1219}
1220
1221static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
1222			     struct perf_probe_arg *args)
1223{
1224	Dwarf_Die die_mem;
1225	int i;
1226	int n = 0;
1227	struct local_vars_finder vf = {.pf = pf, .args = args, .vars = false,
1228				.max_args = MAX_PROBE_ARGS, .ret = 0};
1229
1230	for (i = 0; i < pf->pev->nargs; i++) {
1231		/* var never be NULL */
1232		if (strcmp(pf->pev->args[i].var, PROBE_ARG_VARS) == 0)
1233			vf.vars = true;
1234		else if (strcmp(pf->pev->args[i].var, PROBE_ARG_PARAMS) != 0) {
1235			/* Copy normal argument */
1236			args[n] = pf->pev->args[i];
1237			n++;
1238			continue;
1239		}
1240		pr_debug("Expanding %s into:", pf->pev->args[i].var);
1241		vf.nargs = n;
1242		/* Special local variables */
1243		die_find_child(sc_die, copy_variables_cb, (void *)&vf,
1244			       &die_mem);
1245		pr_debug(" (%d)\n", vf.nargs - n);
1246		if (vf.ret < 0)
1247			return vf.ret;
1248		n = vf.nargs;
1249	}
1250	return n;
1251}
1252
1253static bool trace_event_finder_overlap(struct trace_event_finder *tf)
1254{
1255	int i;
1256
1257	for (i = 0; i < tf->ntevs; i++) {
1258		if (tf->pf.addr == tf->tevs[i].point.address)
1259			return true;
1260	}
1261	return false;
1262}
1263
1264/* Add a found probe point into trace event list */
1265static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1266{
1267	struct trace_event_finder *tf =
1268			container_of(pf, struct trace_event_finder, pf);
1269	struct perf_probe_point *pp = &pf->pev->point;
1270	struct probe_trace_event *tev;
1271	struct perf_probe_arg *args = NULL;
1272	int ret, i;
1273
1274	/*
1275	 * For some reason (e.g. different column assigned to same address)
1276	 * This callback can be called with the address which already passed.
1277	 * Ignore it first.
1278	 */
1279	if (trace_event_finder_overlap(tf))
1280		return 0;
1281
1282	/* Check number of tevs */
1283	if (tf->ntevs == tf->max_tevs) {
1284		pr_warning("Too many( > %d) probe point found.\n",
1285			   tf->max_tevs);
1286		return -ERANGE;
1287	}
1288	tev = &tf->tevs[tf->ntevs++];
1289
1290	/* Trace point should be converted from subprogram DIE */
1291	ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
1292				     pp->retprobe, pp->function, &tev->point);
1293	if (ret < 0)
1294		goto end;
1295
1296	tev->point.realname = strdup(dwarf_diename(sc_die));
1297	if (!tev->point.realname) {
1298		ret = -ENOMEM;
1299		goto end;
1300	}
1301
1302	tev->lang = dwarf_srclang(dwarf_diecu(sc_die, &pf->cu_die, NULL, NULL));
1303
1304	pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
1305		 tev->point.offset);
1306
1307	/* Expand special probe argument if exist */
1308	args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
1309	if (args == NULL) {
1310		ret = -ENOMEM;
1311		goto end;
1312	}
1313
1314	ret = expand_probe_args(sc_die, pf, args);
1315	if (ret < 0)
1316		goto end;
1317
1318	tev->nargs = ret;
1319	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1320	if (tev->args == NULL) {
1321		ret = -ENOMEM;
1322		goto end;
1323	}
1324
1325	/* Find each argument */
1326	for (i = 0; i < tev->nargs; i++) {
1327		pf->pvar = &args[i];
1328		pf->tvar = &tev->args[i];
1329		/* Variable should be found from scope DIE */
1330		ret = find_variable(sc_die, pf);
1331		if (ret != 0)
1332			break;
1333	}
1334
1335end:
1336	if (ret) {
1337		clear_probe_trace_event(tev);
1338		tf->ntevs--;
1339	}
1340	free(args);
1341	return ret;
1342}
1343
1344static int fill_empty_trace_arg(struct perf_probe_event *pev,
1345				struct probe_trace_event *tevs, int ntevs)
1346{
1347	char **valp;
1348	char *type;
1349	int i, j, ret;
1350
1351	if (!ntevs)
1352		return -ENOENT;
1353
1354	for (i = 0; i < pev->nargs; i++) {
1355		type = NULL;
1356		for (j = 0; j < ntevs; j++) {
1357			if (tevs[j].args[i].value) {
1358				type = tevs[j].args[i].type;
1359				break;
1360			}
1361		}
1362		if (j == ntevs) {
1363			print_var_not_found(pev->args[i].var);
1364			return -ENOENT;
1365		}
1366		for (j = 0; j < ntevs; j++) {
1367			valp = &tevs[j].args[i].value;
1368			if (*valp)
1369				continue;
1370
1371			ret = asprintf(valp, "\\%lx", probe_conf.magic_num);
1372			if (ret < 0)
1373				return -ENOMEM;
1374			/* Note that type can be NULL */
1375			if (type) {
1376				tevs[j].args[i].type = strdup(type);
1377				if (!tevs[j].args[i].type)
1378					return -ENOMEM;
1379			}
1380		}
1381	}
1382	return 0;
1383}
1384
1385/* Find probe_trace_events specified by perf_probe_event from debuginfo */
1386int debuginfo__find_trace_events(struct debuginfo *dbg,
1387				 struct perf_probe_event *pev,
1388				 struct probe_trace_event **tevs)
1389{
1390	struct trace_event_finder tf = {
1391			.pf = {.pev = pev, .dbg = dbg, .callback = add_probe_trace_event},
1392			.max_tevs = probe_conf.max_probes, .mod = dbg->mod};
1393	int ret, i;
1394
1395	/* Allocate result tevs array */
1396	*tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs);
1397	if (*tevs == NULL)
1398		return -ENOMEM;
1399
1400	tf.tevs = *tevs;
1401	tf.ntevs = 0;
1402
1403	if (pev->nargs != 0 && immediate_value_is_supported())
1404		tf.pf.skip_empty_arg = true;
1405
1406	ret = debuginfo__find_probes(dbg, &tf.pf);
1407	if (ret >= 0 && tf.pf.skip_empty_arg)
1408		ret = fill_empty_trace_arg(pev, tf.tevs, tf.ntevs);
1409
1410	dwarf_cfi_end(tf.pf.cfi_eh);
1411
1412	if (ret < 0 || tf.ntevs == 0) {
1413		for (i = 0; i < tf.ntevs; i++)
1414			clear_probe_trace_event(&tf.tevs[i]);
1415		zfree(tevs);
1416		return ret;
1417	}
1418
1419	return (ret < 0) ? ret : tf.ntevs;
1420}
1421
1422/* Collect available variables in this scope */
1423static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1424{
1425	struct available_var_finder *af = data;
1426	struct variable_list *vl;
1427	struct strbuf buf = STRBUF_INIT;
1428	int tag, ret;
1429
1430	vl = &af->vls[af->nvls - 1];
1431
1432	tag = dwarf_tag(die_mem);
1433	if (tag == DW_TAG_formal_parameter ||
1434	    tag == DW_TAG_variable) {
1435		ret = convert_variable_location(die_mem, af->pf.addr,
1436						af->pf.fb_ops, &af->pf.sp_die,
1437						&af->pf, /*tvar=*/NULL);
1438		if (ret == 0 || ret == -ERANGE) {
1439			int ret2;
1440			bool externs = !af->child;
1441
1442			if (strbuf_init(&buf, 64) < 0)
1443				goto error;
1444
1445			if (probe_conf.show_location_range) {
1446				if (!externs)
1447					ret2 = strbuf_add(&buf,
1448						ret ? "[INV]\t" : "[VAL]\t", 6);
1449				else
1450					ret2 = strbuf_add(&buf, "[EXT]\t", 6);
1451				if (ret2)
1452					goto error;
1453			}
1454
1455			ret2 = die_get_varname(die_mem, &buf);
1456
1457			if (!ret2 && probe_conf.show_location_range &&
1458				!externs) {
1459				if (strbuf_addch(&buf, '\t') < 0)
1460					goto error;
1461				ret2 = die_get_var_range(&af->pf.sp_die,
1462							die_mem, &buf);
1463			}
1464
1465			pr_debug("Add new var: %s\n", buf.buf);
1466			if (ret2 == 0) {
1467				strlist__add(vl->vars,
1468					strbuf_detach(&buf, NULL));
1469			}
1470			strbuf_release(&buf);
1471		}
1472	}
1473
1474	if (af->child && dwarf_haspc(die_mem, af->pf.addr))
1475		return DIE_FIND_CB_CONTINUE;
1476	else
1477		return DIE_FIND_CB_SIBLING;
1478error:
1479	strbuf_release(&buf);
1480	pr_debug("Error in strbuf\n");
1481	return DIE_FIND_CB_END;
1482}
1483
1484static bool available_var_finder_overlap(struct available_var_finder *af)
1485{
1486	int i;
1487
1488	for (i = 0; i < af->nvls; i++) {
1489		if (af->pf.addr == af->vls[i].point.address)
1490			return true;
1491	}
1492	return false;
1493
1494}
1495
1496/* Add a found vars into available variables list */
1497static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
1498{
1499	struct available_var_finder *af =
1500			container_of(pf, struct available_var_finder, pf);
1501	struct perf_probe_point *pp = &pf->pev->point;
1502	struct variable_list *vl;
1503	Dwarf_Die die_mem;
1504	int ret;
1505
1506	/*
1507	 * For some reason (e.g. different column assigned to same address),
1508	 * this callback can be called with the address which already passed.
1509	 * Ignore it first.
1510	 */
1511	if (available_var_finder_overlap(af))
1512		return 0;
1513
1514	/* Check number of tevs */
1515	if (af->nvls == af->max_vls) {
1516		pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
1517		return -ERANGE;
1518	}
1519	vl = &af->vls[af->nvls++];
1520
1521	/* Trace point should be converted from subprogram DIE */
1522	ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
1523				     pp->retprobe, pp->function, &vl->point);
1524	if (ret < 0)
1525		return ret;
1526
1527	pr_debug("Probe point found: %s+%lu\n", vl->point.symbol,
1528		 vl->point.offset);
1529
1530	/* Find local variables */
1531	vl->vars = strlist__new(NULL, NULL);
1532	if (vl->vars == NULL)
1533		return -ENOMEM;
1534	af->child = true;
1535	die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem);
1536
1537	/* Find external variables */
1538	if (!probe_conf.show_ext_vars)
1539		goto out;
1540	/* Don't need to search child DIE for external vars. */
1541	af->child = false;
1542	die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem);
1543
1544out:
1545	if (strlist__empty(vl->vars)) {
1546		strlist__delete(vl->vars);
1547		vl->vars = NULL;
1548	}
1549
1550	return ret;
1551}
1552
1553/*
1554 * Find available variables at given probe point
1555 * Return the number of found probe points. Return 0 if there is no
1556 * matched probe point. Return <0 if an error occurs.
1557 */
1558int debuginfo__find_available_vars_at(struct debuginfo *dbg,
1559				      struct perf_probe_event *pev,
1560				      struct variable_list **vls)
1561{
1562	struct available_var_finder af = {
1563			.pf = {.pev = pev, .dbg = dbg, .callback = add_available_vars},
1564			.mod = dbg->mod,
1565			.max_vls = probe_conf.max_probes};
1566	int ret;
1567
1568	/* Allocate result vls array */
1569	*vls = zalloc(sizeof(struct variable_list) * af.max_vls);
1570	if (*vls == NULL)
1571		return -ENOMEM;
1572
1573	af.vls = *vls;
1574	af.nvls = 0;
1575
1576	ret = debuginfo__find_probes(dbg, &af.pf);
1577	if (ret < 0) {
1578		/* Free vlist for error */
1579		while (af.nvls--) {
1580			zfree(&af.vls[af.nvls].point.symbol);
1581			strlist__delete(af.vls[af.nvls].vars);
1582		}
1583		zfree(vls);
1584		return ret;
1585	}
1586
1587	return (ret < 0) ? ret : af.nvls;
1588}
1589
1590/* Reverse search */
1591int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,
1592				struct perf_probe_point *ppt)
1593{
1594	Dwarf_Die cudie, spdie, indie;
1595	Dwarf_Addr _addr = 0, baseaddr = 0;
1596	const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp;
1597	int baseline = 0, lineno = 0, ret = 0;
1598
1599	/* We always need to relocate the address for aranges */
1600	if (debuginfo__get_text_offset(dbg, &baseaddr, false) == 0)
1601		addr += baseaddr;
1602	/* Find cu die */
1603	if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr, &cudie)) {
1604		pr_warning("Failed to find debug information for address %#" PRIx64 "\n",
1605			   addr);
1606		ret = -EINVAL;
1607		goto end;
1608	}
1609
1610	/* Find a corresponding line (filename and lineno) */
1611	cu_find_lineinfo(&cudie, (Dwarf_Addr)addr, &fname, &lineno);
1612	/* Don't care whether it failed or not */
1613
1614	/* Find a corresponding function (name, baseline and baseaddr) */
1615	if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
1616		/*
1617		 * Get function entry information.
1618		 *
1619		 * As described in the document DWARF Debugging Information
1620		 * Format Version 5, section 2.22 Linkage Names, "mangled names,
1621		 * are used in various ways, ... to distinguish multiple
1622		 * entities that have the same name".
1623		 *
1624		 * Firstly try to get distinct linkage name, if fail then
1625		 * rollback to get associated name in DIE.
1626		 */
1627		func = basefunc = die_get_linkage_name(&spdie);
1628		if (!func)
1629			func = basefunc = dwarf_diename(&spdie);
1630
1631		if (!func ||
1632		    die_entrypc(&spdie, &baseaddr) != 0 ||
1633		    dwarf_decl_line(&spdie, &baseline) != 0) {
1634			lineno = 0;
1635			goto post;
1636		}
1637
1638		fname = die_get_decl_file(&spdie);
1639		if (addr == baseaddr) {
1640			/* Function entry - Relative line number is 0 */
1641			lineno = baseline;
1642			goto post;
1643		}
1644
1645		/* Track down the inline functions step by step */
1646		while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
1647						&indie)) {
1648			/* There is an inline function */
1649			if (die_entrypc(&indie, &_addr) == 0 &&
1650			    _addr == addr) {
1651				/*
1652				 * addr is at an inline function entry.
1653				 * In this case, lineno should be the call-site
1654				 * line number. (overwrite lineinfo)
1655				 */
1656				lineno = die_get_call_lineno(&indie);
1657				fname = die_get_call_file(&indie);
1658				break;
1659			} else {
1660				/*
1661				 * addr is in an inline function body.
1662				 * Since lineno points one of the lines
1663				 * of the inline function, baseline should
1664				 * be the entry line of the inline function.
1665				 */
1666				tmp = dwarf_diename(&indie);
1667				if (!tmp ||
1668				    dwarf_decl_line(&indie, &baseline) != 0)
1669					break;
1670				func = tmp;
1671				spdie = indie;
1672			}
1673		}
1674		/* Verify the lineno and baseline are in a same file */
1675		tmp = die_get_decl_file(&spdie);
1676		if (!tmp || (fname && strcmp(tmp, fname) != 0))
1677			lineno = 0;
1678	}
1679
1680post:
1681	/* Make a relative line number or an offset */
1682	if (lineno)
1683		ppt->line = lineno - baseline;
1684	else if (basefunc) {
1685		ppt->offset = addr - baseaddr;
1686		func = basefunc;
1687	}
1688
1689	/* Duplicate strings */
1690	if (func) {
1691		ppt->function = strdup(func);
1692		if (ppt->function == NULL) {
1693			ret = -ENOMEM;
1694			goto end;
1695		}
1696	}
1697	if (fname) {
1698		ppt->file = strdup(fname);
1699		if (ppt->file == NULL) {
1700			zfree(&ppt->function);
1701			ret = -ENOMEM;
1702			goto end;
1703		}
1704	}
1705end:
1706	if (ret == 0 && (fname || func))
1707		ret = 1;	/* Found a point */
1708	return ret;
1709}
1710
1711/* Add a line and store the src path */
1712static int line_range_add_line(const char *src, unsigned int lineno,
1713			       struct line_range *lr)
1714{
1715	/* Copy source path */
1716	if (!lr->path) {
1717		lr->path = strdup(src);
1718		if (lr->path == NULL)
1719			return -ENOMEM;
1720	}
1721	return intlist__add(lr->line_list, lineno);
1722}
1723
1724static int line_range_walk_cb(const char *fname, int lineno,
1725			      Dwarf_Addr addr, void *data)
1726{
1727	struct line_finder *lf = data;
1728	const char *__fname;
1729	int __lineno;
1730	int err;
1731
1732	if ((strtailcmp(fname, lf->fname) != 0) ||
1733	    (lf->lno_s > lineno || lf->lno_e < lineno))
1734		return 0;
1735
1736	/* Make sure this line can be reversible */
1737	if (cu_find_lineinfo(&lf->cu_die, addr, &__fname, &__lineno) > 0
1738	    && (lineno != __lineno || strcmp(fname, __fname)))
1739		return 0;
1740
1741	err = line_range_add_line(fname, lineno, lf->lr);
1742	if (err < 0 && err != -EEXIST)
1743		return err;
1744
1745	return 0;
1746}
1747
1748/* Find line range from its line number */
1749static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
1750{
1751	int ret;
1752
1753	ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf);
1754
1755	/* Update status */
1756	if (ret >= 0)
1757		if (!intlist__empty(lf->lr->line_list))
1758			ret = lf->found = 1;
1759		else
1760			ret = 0;	/* Lines are not found */
1761	else {
1762		zfree(&lf->lr->path);
1763	}
1764	return ret;
1765}
1766
1767static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
1768{
1769	int ret = find_line_range_by_line(in_die, data);
1770
1771	/*
1772	 * We have to check all instances of inlined function, because
1773	 * some execution paths can be optimized out depends on the
1774	 * function argument of instances. However, if an error occurs,
1775	 * it should be handled by the caller.
1776	 */
1777	return ret < 0 ? ret : 0;
1778}
1779
1780/* Search function definition from function name */
1781static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
1782{
1783	struct dwarf_callback_param *param = data;
1784	struct line_finder *lf = param->data;
1785	struct line_range *lr = lf->lr;
1786	const char *fname;
1787
1788	/* Check declared file */
1789	if (lr->file) {
1790		fname = die_get_decl_file(sp_die);
1791		if (!fname || strtailcmp(lr->file, fname))
1792			return DWARF_CB_OK;
1793	}
1794
1795	if (die_match_name(sp_die, lr->function) && die_is_func_def(sp_die)) {
1796		lf->fname = die_get_decl_file(sp_die);
1797		dwarf_decl_line(sp_die, &lr->offset);
1798		pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
1799		lf->lno_s = lr->offset + lr->start;
1800		if (lf->lno_s < 0)	/* Overflow */
1801			lf->lno_s = INT_MAX;
1802		lf->lno_e = lr->offset + lr->end;
1803		if (lf->lno_e < 0)	/* Overflow */
1804			lf->lno_e = INT_MAX;
1805		pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
1806		lr->start = lf->lno_s;
1807		lr->end = lf->lno_e;
1808		if (!die_is_func_instance(sp_die))
1809			param->retval = die_walk_instances(sp_die,
1810						line_range_inline_cb, lf);
1811		else
1812			param->retval = find_line_range_by_line(sp_die, lf);
1813		return DWARF_CB_ABORT;
1814	}
1815	return DWARF_CB_OK;
1816}
1817
1818static int find_line_range_by_func(struct line_finder *lf)
1819{
1820	struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
1821	dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0);
1822	return param.retval;
1823}
1824
1825int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
1826{
1827	struct line_finder lf = {.lr = lr, .found = 0};
1828	int ret = 0;
1829	Dwarf_Off off = 0, noff;
1830	size_t cuhl;
1831	Dwarf_Die *diep;
1832	const char *comp_dir;
1833
1834	/* Fastpath: lookup by function name from .debug_pubnames section */
1835	if (lr->function) {
1836		struct pubname_callback_param pubname_param = {
1837			.function = lr->function, .file = lr->file,
1838			.cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
1839		struct dwarf_callback_param line_range_param = {
1840			.data = (void *)&lf, .retval = 0};
1841
1842		dwarf_getpubnames(dbg->dbg, pubname_search_cb,
1843				  &pubname_param, 0);
1844		if (pubname_param.found) {
1845			line_range_search_cb(&lf.sp_die, &line_range_param);
1846			if (lf.found)
1847				goto found;
1848		}
1849	}
1850
1851	/* Loop on CUs (Compilation Unit) */
1852	while (!lf.found && ret >= 0) {
1853		if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl,
1854				 NULL, NULL, NULL) != 0)
1855			break;
1856
1857		/* Get the DIE(Debugging Information Entry) of this CU */
1858		diep = dwarf_offdie(dbg->dbg, off + cuhl, &lf.cu_die);
1859		if (!diep) {
1860			off = noff;
1861			continue;
1862		}
1863
1864		/* Check if target file is included. */
1865		if (lr->file)
1866			lf.fname = cu_find_realpath(&lf.cu_die, lr->file);
1867		else
1868			lf.fname = 0;
1869
1870		if (!lr->file || lf.fname) {
1871			if (lr->function)
1872				ret = find_line_range_by_func(&lf);
1873			else {
1874				lf.lno_s = lr->start;
1875				lf.lno_e = lr->end;
1876				ret = find_line_range_by_line(NULL, &lf);
1877			}
1878		}
1879		off = noff;
1880	}
1881
1882found:
1883	/* Store comp_dir */
1884	if (lf.found) {
1885		comp_dir = cu_get_comp_dir(&lf.cu_die);
1886		if (comp_dir) {
1887			lr->comp_dir = strdup(comp_dir);
1888			if (!lr->comp_dir)
1889				ret = -ENOMEM;
1890		}
1891	}
1892
1893	pr_debug("path: %s\n", lr->path);
1894	return (ret < 0) ? ret : lf.found;
1895}
1896
1897/*
1898 * Find a src file from a DWARF tag path. Prepend optional source path prefix
1899 * and chop off leading directories that do not exist. Result is passed back as
1900 * a newly allocated path on success.
1901 * Return 0 if file was found and readable, -errno otherwise.
1902 */
1903int find_source_path(const char *raw_path, const char *sbuild_id,
1904		const char *comp_dir, char **new_path)
1905{
1906	const char *prefix = symbol_conf.source_prefix;
1907
1908	if (sbuild_id && !prefix) {
1909		char prefixed_raw_path[PATH_MAX];
1910
1911		path__join(prefixed_raw_path, sizeof(prefixed_raw_path), comp_dir, raw_path);
1912
1913		if (!get_source_from_debuginfod(prefixed_raw_path, sbuild_id, new_path))
1914			return 0;
1915	}
1916
1917	if (!prefix) {
1918		if (raw_path[0] != '/' && comp_dir)
1919			/* If not an absolute path, try to use comp_dir */
1920			prefix = comp_dir;
1921		else {
1922			if (access(raw_path, R_OK) == 0) {
1923				*new_path = strdup(raw_path);
1924				return *new_path ? 0 : -ENOMEM;
1925			} else
1926				return -errno;
1927		}
1928	}
1929
1930	*new_path = malloc((strlen(prefix) + strlen(raw_path) + 2));
1931	if (!*new_path)
1932		return -ENOMEM;
1933
1934	for (;;) {
1935		sprintf(*new_path, "%s/%s", prefix, raw_path);
1936
1937		if (access(*new_path, R_OK) == 0)
1938			return 0;
1939
1940		if (!symbol_conf.source_prefix) {
1941			/* In case of searching comp_dir, don't retry */
1942			zfree(new_path);
1943			return -errno;
1944		}
1945
1946		switch (errno) {
1947		case ENAMETOOLONG:
1948		case ENOENT:
1949		case EROFS:
1950		case EFAULT:
1951			raw_path = strchr(++raw_path, '/');
1952			if (!raw_path) {
1953				zfree(new_path);
1954				return -ENOENT;
1955			}
1956			continue;
1957
1958		default:
1959			zfree(new_path);
1960			return -errno;
1961		}
1962	}
1963}
~/ Read-only file preview.