Linux Audio

Check our new training course

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