// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * probe-finder.c : C expression to kprobe event converter
 *
 * Written by Masami Hiramatsu <mhiramat@redhat.com>
 */

#include <inttypes.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <dwarf-regs.h>

#include <linux/bitops.h>
#include <linux/zalloc.h>
#include "event.h"
#include "dso.h"
#include "debug.h"
#include "debuginfo.h"
#include "intlist.h"
#include "strbuf.h"
#include "strlist.h"
#include "symbol.h"
#include "probe-finder.h"
#include "probe-file.h"
#include "string2.h"

/* Kprobe tracer basic type is up to u64 */
#define MAX_BASIC_TYPE_BITS	64

bool is_known_C_lang(int lang)
{
	switch (lang) {
	case DW_LANG_C89:
	case DW_LANG_C:
	case DW_LANG_C99:
	case DW_LANG_C11:
		return true;
	default:
		return false;
	}
}

/*
 * Probe finder related functions
 */

static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
{
	struct probe_trace_arg_ref *ref;
	ref = zalloc(sizeof(struct probe_trace_arg_ref));
	if (ref != NULL)
		ref->offset = offs;
	return ref;
}

/*
 * Convert a location into trace_arg.
 * If tvar == NULL, this just checks variable can be converted.
 * If fentry == true and vr_die is a parameter, do heuristic search
 * for the location fuzzed by function entry mcount.
 */
static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
				     const struct probe_finder *pf,
				     struct probe_trace_arg *tvar)
{
	Dwarf_Attribute attr;
	Dwarf_Addr tmp = 0;
	Dwarf_Op *op;
	size_t nops;
	unsigned int regn;
	Dwarf_Word offs = 0;
	bool ref = false;
	const char *regs;
	int ret, ret2 = 0;

	if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL)
		goto static_var;

	/* Constant value */
	if (dwarf_attr(vr_die, DW_AT_const_value, &attr) &&
	    immediate_value_is_supported()) {
		Dwarf_Sword snum;

		if (!tvar)
			return 0;

		dwarf_formsdata(&attr, &snum);
		ret = asprintf(&tvar->value, "\\%ld", (long)snum);

		return ret < 0 ? -ENOMEM : 0;
	}

	/* TODO: handle more than 1 exprs */
	if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
		return -EINVAL;	/* Broken DIE ? */
	if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) {
		ret = dwarf_entrypc(sp_die, &tmp);
		if (ret)
			return -ENOENT;

		if (probe_conf.show_location_range &&
			(dwarf_tag(vr_die) == DW_TAG_variable)) {
			ret2 = -ERANGE;
		} else if (addr != tmp ||
			dwarf_tag(vr_die) != DW_TAG_formal_parameter) {
			return -ENOENT;
		}

		ret = dwarf_highpc(sp_die, &tmp);
		if (ret)
			return -ENOENT;
		/*
		 * This is fuzzed by fentry mcount. We try to find the
		 * parameter location at the earliest address.
		 */
		for (addr += 1; addr <= tmp; addr++) {
			if (dwarf_getlocation_addr(&attr, addr, &op,
						   &nops, 1) > 0)
				goto found;
		}
		return -ENOENT;
	}
found:
	if (nops == 0)
		/* TODO: Support const_value */
		return -ENOENT;

	if (op->atom == DW_OP_addr) {
static_var:
		if (!tvar)
			return ret2;
		/* Static variables on memory (not stack), make @varname */
		ret = strlen(dwarf_diename(vr_die));
		tvar->value = zalloc(ret + 2);
		if (tvar->value == NULL)
			return -ENOMEM;
		snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die));
		tvar->ref = alloc_trace_arg_ref((long)offs);
		if (tvar->ref == NULL)
			return -ENOMEM;
		return ret2;
	}

	/* If this is based on frame buffer, set the offset */
	if (op->atom == DW_OP_fbreg) {
		if (fb_ops == NULL)
			return -ENOTSUP;
		ref = true;
		offs = op->number;
		op = &fb_ops[0];
	}

	if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
		regn = op->atom - DW_OP_breg0;
		offs += op->number;
		ref = true;
	} else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) {
		regn = op->atom - DW_OP_reg0;
	} else if (op->atom == DW_OP_bregx) {
		regn = op->number;
		offs += op->number2;
		ref = true;
	} else if (op->atom == DW_OP_regx) {
		regn = op->number;
	} else {
		pr_debug("DW_OP %x is not supported.\n", op->atom);
		return -ENOTSUP;
	}

	if (!tvar)
		return ret2;

	regs = get_dwarf_regstr(regn, pf->e_machine, pf->e_flags);
	if (!regs) {
		/* This should be a bug in DWARF or this tool */
		pr_warning("Mapping for the register number %u "
			   "missing on this architecture.\n", regn);
		return -ENOTSUP;
	}

	tvar->value = strdup(regs);
	if (tvar->value == NULL)
		return -ENOMEM;

	if (ref) {
		tvar->ref = alloc_trace_arg_ref((long)offs);
		if (tvar->ref == NULL)
			return -ENOMEM;
	}
	return ret2;
}

static int convert_variable_type(Dwarf_Die *vr_die,
				 struct probe_trace_arg *tvar,
				 const char *cast, bool user_access)
{
	struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
	Dwarf_Die type;
	char buf[16];
	char sbuf[STRERR_BUFSIZE];
	int bsize, boffs, total;
	int ret;
	char prefix;

	/* TODO: check all types */
	if (cast && strcmp(cast, "string") != 0 && strcmp(cast, "ustring") &&
	    strcmp(cast, "x") != 0 &&
	    strcmp(cast, "s") != 0 && strcmp(cast, "u") != 0) {
		/* Non string type is OK */
		/* and respect signedness/hexadecimal cast */
		tvar->type = strdup(cast);
		return (tvar->type == NULL) ? -ENOMEM : 0;
	}

	bsize = dwarf_bitsize(vr_die);
	if (bsize > 0) {
		/* This is a bitfield */
		boffs = dwarf_bitoffset(vr_die);
		total = dwarf_bytesize(vr_die);
		if (boffs < 0 || total < 0)
			return -ENOENT;
		ret = snprintf(buf, 16, "b%d@%d/%d", bsize, boffs,
				BYTES_TO_BITS(total));
		goto formatted;
	}

	if (die_get_real_type(vr_die, &type) == NULL) {
		pr_warning("Failed to get a type information of %s.\n",
			   dwarf_diename(vr_die));
		return -ENOENT;
	}

	pr_debug("%s type is %s.\n",
		 dwarf_diename(vr_die), dwarf_diename(&type));

	if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) {
		/* String type */
		ret = dwarf_tag(&type);
		if (ret != DW_TAG_pointer_type &&
		    ret != DW_TAG_array_type) {
			pr_warning("Failed to cast into string: "
				   "%s(%s) is not a pointer nor array.\n",
				   dwarf_diename(vr_die), dwarf_diename(&type));
			return -EINVAL;
		}
		if (die_get_real_type(&type, &type) == NULL) {
			pr_warning("Failed to get a type"
				   " information.\n");
			return -ENOENT;
		}
		if (ret == DW_TAG_pointer_type) {
			while (*ref_ptr)
				ref_ptr = &(*ref_ptr)->next;
			/* Add new reference with offset +0 */
			*ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref));
			if (*ref_ptr == NULL) {
				pr_warning("Out of memory error\n");
				return -ENOMEM;
			}
			(*ref_ptr)->user_access = user_access;
		}
		if (!die_compare_name(&type, "char") &&
		    !die_compare_name(&type, "unsigned char")) {
			pr_warning("Failed to cast into string: "
				   "%s is not (unsigned) char *.\n",
				   dwarf_diename(vr_die));
			return -EINVAL;
		}
		tvar->type = strdup(cast);
		return (tvar->type == NULL) ? -ENOMEM : 0;
	}

	if (cast && (strcmp(cast, "u") == 0))
		prefix = 'u';
	else if (cast && (strcmp(cast, "s") == 0))
		prefix = 's';
	else if (cast && (strcmp(cast, "x") == 0) &&
		 probe_type_is_available(PROBE_TYPE_X))
		prefix = 'x';
	else
		prefix = die_is_signed_type(&type) ? 's' :
			 probe_type_is_available(PROBE_TYPE_X) ? 'x' : 'u';

	ret = dwarf_bytesize(&type);
	if (ret <= 0)
		/* No size ... try to use default type */
		return 0;
	ret = BYTES_TO_BITS(ret);

	/* Check the bitwidth */
	if (ret > MAX_BASIC_TYPE_BITS) {
		pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n",
			dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
		ret = MAX_BASIC_TYPE_BITS;
	}
	ret = snprintf(buf, 16, "%c%d", prefix, ret);

formatted:
	if (ret < 0 || ret >= 16) {
		if (ret >= 16)
			ret = -E2BIG;
		pr_warning("Failed to convert variable type: %s\n",
			   str_error_r(-ret, sbuf, sizeof(sbuf)));
		return ret;
	}
	tvar->type = strdup(buf);
	if (tvar->type == NULL)
		return -ENOMEM;
	return 0;
}

static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
				    struct perf_probe_arg_field *field,
				    struct probe_trace_arg_ref **ref_ptr,
				    Dwarf_Die *die_mem, bool user_access)
{
	struct probe_trace_arg_ref *ref = *ref_ptr;
	Dwarf_Die type;
	Dwarf_Word offs;
	int ret, tag;

	pr_debug("converting %s in %s\n", field->name, varname);
	if (die_get_real_type(vr_die, &type) == NULL) {
		pr_warning("Failed to get the type of %s.\n", varname);
		return -ENOENT;
	}
	pr_debug2("Var real type: %s (%x)\n", dwarf_diename(&type),
		  (unsigned)dwarf_dieoffset(&type));
	tag = dwarf_tag(&type);

	if (field->name[0] == '[' &&
	    (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) {
		/* Save original type for next field or type */
		memcpy(die_mem, &type, sizeof(*die_mem));
		/* Get the type of this array */
		if (die_get_real_type(&type, &type) == NULL) {
			pr_warning("Failed to get the type of %s.\n", varname);
			return -ENOENT;
		}
		pr_debug2("Array real type: %s (%x)\n", dwarf_diename(&type),
			 (unsigned)dwarf_dieoffset(&type));
		if (tag == DW_TAG_pointer_type) {
			ref = zalloc(sizeof(struct probe_trace_arg_ref));
			if (ref == NULL)
				return -ENOMEM;
			if (*ref_ptr)
				(*ref_ptr)->next = ref;
			else
				*ref_ptr = ref;
		}
		ref->offset += dwarf_bytesize(&type) * field->index;
		ref->user_access = user_access;
		goto next;
	} else if (tag == DW_TAG_pointer_type) {
		/* Check the pointer and dereference */
		if (!field->ref) {
			pr_err("Semantic error: %s must be referred by '->'\n",
			       field->name);
			return -EINVAL;
		}
		/* Get the type pointed by this pointer */
		if (die_get_real_type(&type, &type) == NULL) {
			pr_warning("Failed to get the type of %s.\n", varname);
			return -ENOENT;
		}
		/* Verify it is a data structure  */
		tag = dwarf_tag(&type);
		if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
			pr_warning("%s is not a data structure nor a union.\n",
				   varname);
			return -EINVAL;
		}

		ref = zalloc(sizeof(struct probe_trace_arg_ref));
		if (ref == NULL)
			return -ENOMEM;
		if (*ref_ptr)
			(*ref_ptr)->next = ref;
		else
			*ref_ptr = ref;
	} else {
		/* Verify it is a data structure  */
		if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
			pr_warning("%s is not a data structure nor a union.\n",
				   varname);
			return -EINVAL;
		}
		if (field->name[0] == '[') {
			pr_err("Semantic error: %s is not a pointer"
			       " nor array.\n", varname);
			return -EINVAL;
		}
		/* While processing unnamed field, we don't care about this */
		if (field->ref && dwarf_diename(vr_die)) {
			pr_err("Semantic error: %s must be referred by '.'\n",
			       field->name);
			return -EINVAL;
		}
		if (!ref) {
			pr_warning("Structure on a register is not "
				   "supported yet.\n");
			return -ENOTSUP;
		}
	}

	if (die_find_member(&type, field->name, die_mem) == NULL) {
		pr_warning("%s(type:%s) has no member %s.\n", varname,
			   dwarf_diename(&type), field->name);
		return -EINVAL;
	}

	/* Get the offset of the field */
	if (tag == DW_TAG_union_type) {
		offs = 0;
	} else {
		ret = die_get_data_member_location(die_mem, &offs);
		if (ret < 0) {
			pr_warning("Failed to get the offset of %s.\n",
				   field->name);
			return ret;
		}
	}
	ref->offset += (long)offs;
	ref->user_access = user_access;

	/* If this member is unnamed, we need to reuse this field */
	if (!dwarf_diename(die_mem))
		return convert_variable_fields(die_mem, varname, field,
						&ref, die_mem, user_access);

next:
	/* Converting next field */
	if (field->next)
		return convert_variable_fields(die_mem, field->name,
				field->next, &ref, die_mem, user_access);
	else
		return 0;
}

static void print_var_not_found(const char *varname)
{
	pr_err("Failed to find the location of the '%s' variable at this address.\n"
	       " Perhaps it has been optimized out.\n"
	       " Use -V with the --range option to show '%s' location range.\n",
		varname, varname);
}

/* Show a variables in kprobe event format */
static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
{
	Dwarf_Die die_mem;
	int ret;

	pr_debug("Converting variable %s into trace event.\n",
		 dwarf_diename(vr_die));

	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
					&pf->sp_die, pf, pf->tvar);
	if (ret == -ENOENT && pf->skip_empty_arg)
		/* This can be found in other place. skip it */
		return 0;
	if (ret == -ENOENT || ret == -EINVAL) {
		print_var_not_found(pf->pvar->var);
	} else if (ret == -ENOTSUP)
		pr_err("Sorry, we don't support this variable location yet.\n");
	else if (ret == 0 && pf->pvar->field) {
		ret = convert_variable_fields(vr_die, pf->pvar->var,
					      pf->pvar->field, &pf->tvar->ref,
					      &die_mem, pf->pvar->user_access);
		vr_die = &die_mem;
	}
	if (ret == 0)
		ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type,
					    pf->pvar->user_access);
	/* *expr will be cached in libdw. Don't free it. */
	return ret;
}

/* Find a variable in a scope DIE */
static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	Dwarf_Die vr_die;
	char *buf, *ptr;
	int ret = 0;

	/* Copy raw parameters */
	if (!is_c_varname(pf->pvar->var))
		return copy_to_probe_trace_arg(pf->tvar, pf->pvar);

	if (pf->pvar->name)
		pf->tvar->name = strdup(pf->pvar->name);
	else {
		buf = synthesize_perf_probe_arg(pf->pvar);
		if (!buf)
			return -ENOMEM;
		ptr = strchr(buf, ':');	/* Change type separator to _ */
		if (ptr)
			*ptr = '_';
		pf->tvar->name = buf;
	}
	if (pf->tvar->name == NULL)
		return -ENOMEM;

	pr_debug("Searching '%s' variable in context.\n", pf->pvar->var);
	/* Search child die for local variables and parameters. */
	if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
		/* Search again in global variables */
		if (!die_find_variable_at(&pf->cu_die, pf->pvar->var,
						0, &vr_die)) {
			if (pf->skip_empty_arg)
				return 0;
			pr_warning("Failed to find '%s' in this function.\n",
				   pf->pvar->var);
			ret = -ENOENT;
		}
	}
	if (ret >= 0)
		ret = convert_variable(&vr_die, pf);

	return ret;
}

/* Convert subprogram DIE to trace point */
static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
				  Dwarf_Addr paddr, bool retprobe,
				  const char *function,
				  struct probe_trace_point *tp)
{
	Dwarf_Addr eaddr;
	GElf_Sym sym;
	const char *symbol;

	/* Verify the address is correct */
	if (!dwarf_haspc(sp_die, paddr)) {
		pr_warning("Specified offset is out of %s\n",
			   dwarf_diename(sp_die));
		return -EINVAL;
	}

	if (dwarf_entrypc(sp_die, &eaddr) == 0) {
		/* If the DIE has entrypc, use it. */
		symbol = dwarf_diename(sp_die);
	} else {
		/* Try to get actual symbol name and address from symtab */
		symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
		eaddr = sym.st_value;
	}
	if (!symbol) {
		pr_warning("Failed to find symbol at 0x%lx\n",
			   (unsigned long)paddr);
		return -ENOENT;
	}

	tp->offset = (unsigned long)(paddr - eaddr);
	tp->address = paddr;
	tp->symbol = strdup(symbol);
	if (!tp->symbol)
		return -ENOMEM;

	/* Return probe must be on the head of a subprogram */
	if (retprobe) {
		if (eaddr != paddr) {
			pr_warning("Failed to find \"%s%%return\",\n"
				   " because %s is an inlined function and"
				   " has no return point.\n", function,
				   function);
			return -EINVAL;
		}
		tp->retprobe = true;
	}

	return 0;
}

/* Call probe_finder callback with scope DIE */
static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	Dwarf_Attribute fb_attr;
	Dwarf_Frame *frame = NULL;
	size_t nops;
	int ret;

	if (!sc_die) {
		pr_err("Caller must pass a scope DIE. Program error.\n");
		return -EINVAL;
	}

	/* If not a real subprogram, find a real one */
	if (!die_is_func_def(sc_die)) {
		if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
			if (die_find_tailfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
				pr_warning("Ignoring tail call from %s\n",
						dwarf_diename(&pf->sp_die));
				return 0;
			} else {
				pr_warning("Failed to find probe point in any "
					   "functions.\n");
				return -ENOENT;
			}
		}
	} else
		memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die));

	/* Get the frame base attribute/ops from subprogram */
	dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr);
	ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
	if (ret <= 0 || nops == 0) {
		pf->fb_ops = NULL;
	} else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
		   (pf->cfi_eh != NULL || pf->cfi_dbg != NULL)) {
		if ((dwarf_cfi_addrframe(pf->cfi_eh, pf->addr, &frame) != 0 &&
		     (dwarf_cfi_addrframe(pf->cfi_dbg, pf->addr, &frame) != 0)) ||
		    dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
			pr_warning("Failed to get call frame on 0x%jx\n",
				   (uintmax_t)pf->addr);
			free(frame);
			return -ENOENT;
		}
	}

	/* Call finder's callback handler */
	ret = pf->callback(sc_die, pf);

	/* Since *pf->fb_ops can be a part of frame. we should free it here. */
	free(frame);
	pf->fb_ops = NULL;

	return ret;
}

struct find_scope_param {
	const char *function;
	const char *file;
	int line;
	int diff;
	Dwarf_Die *die_mem;
	bool found;
};

static int find_best_scope_cb(Dwarf_Die *fn_die, void *data)
{
	struct find_scope_param *fsp = data;
	const char *file;
	int lno;

	/* Skip if declared file name does not match */
	if (fsp->file) {
		file = die_get_decl_file(fn_die);
		if (!file || strcmp(fsp->file, file) != 0)
			return 0;
	}
	/* If the function name is given, that's what user expects */
	if (fsp->function) {
		if (die_match_name(fn_die, fsp->function)) {
			memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
			fsp->found = true;
			return 1;
		}
	} else {
		/* With the line number, find the nearest declared DIE */
		dwarf_decl_line(fn_die, &lno);
		if (lno < fsp->line && fsp->diff > fsp->line - lno) {
			/* Keep a candidate and continue */
			fsp->diff = fsp->line - lno;
			memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
			fsp->found = true;
		}
	}
	return 0;
}

/* Return innermost DIE */
static int find_inner_scope_cb(Dwarf_Die *fn_die, void *data)
{
	struct find_scope_param *fsp = data;

	memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
	fsp->found = true;
	return 1;
}

/* Find an appropriate scope fits to given conditions */
static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
{
	struct find_scope_param fsp = {
		.function = pf->pev->point.function,
		.file = pf->fname,
		.line = pf->lno,
		.diff = INT_MAX,
		.die_mem = die_mem,
		.found = false,
	};
	int ret;

	ret = cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb,
				   &fsp);
	if (!ret && !fsp.found)
		cu_walk_functions_at(&pf->cu_die, pf->addr,
				     find_inner_scope_cb, &fsp);

	return fsp.found ? die_mem : NULL;
}

static int verify_representive_line(struct probe_finder *pf, const char *fname,
				int lineno, Dwarf_Addr addr)
{
	const char *__fname, *__func = NULL;
	Dwarf_Die die_mem;
	int __lineno;

	/* Verify line number and address by reverse search */
	if (cu_find_lineinfo(&pf->cu_die, addr, &__fname, &__lineno) < 0)
		return 0;

	pr_debug2("Reversed line: %s:%d\n", __fname, __lineno);
	if (strcmp(fname, __fname) || lineno == __lineno)
		return 0;

	pr_warning("This line is sharing the address with other lines.\n");

	if (pf->pev->point.function) {
		/* Find best match function name and lines */
		pf->addr = addr;
		if (find_best_scope(pf, &die_mem)
		    && die_match_name(&die_mem, pf->pev->point.function)
		    && dwarf_decl_line(&die_mem, &lineno) == 0) {
			__func = dwarf_diename(&die_mem);
			__lineno -= lineno;
		}
	}
	pr_warning("Please try to probe at %s:%d instead.\n",
		   __func ? : __fname, __lineno);

	return -ENOENT;
}

static int probe_point_line_walker(const char *fname, int lineno,
				   Dwarf_Addr addr, void *data)
{
	struct probe_finder *pf = data;
	Dwarf_Die *sc_die, die_mem;
	int ret;

	if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0)
		return 0;

	if (verify_representive_line(pf, fname, lineno, addr))
		return -ENOENT;

	pf->addr = addr;
	sc_die = find_best_scope(pf, &die_mem);
	if (!sc_die) {
		pr_warning("Failed to find scope of probe point.\n");
		return -ENOENT;
	}

	ret = call_probe_finder(sc_die, pf);

	/* Continue if no error, because the line will be in inline function */
	return ret < 0 ? ret : 0;
}

/* Find probe point from its line number */
static int find_probe_point_by_line(struct probe_finder *pf)
{
	return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf);
}

/* Find lines which match lazy pattern */
static int find_lazy_match_lines(struct intlist *list,
				 const char *fname, const char *pat)
{
	FILE *fp;
	char *line = NULL;
	size_t line_len;
	ssize_t len;
	int count = 0, linenum = 1;
	char sbuf[STRERR_BUFSIZE];

	fp = fopen(fname, "r");
	if (!fp) {
		pr_warning("Failed to open %s: %s\n", fname,
			   str_error_r(errno, sbuf, sizeof(sbuf)));
		return -errno;
	}

	while ((len = getline(&line, &line_len, fp)) > 0) {

		if (line[len - 1] == '\n')
			line[len - 1] = '\0';

		if (strlazymatch(line, pat)) {
			intlist__add(list, linenum);
			count++;
		}
		linenum++;
	}

	if (ferror(fp))
		count = -errno;
	free(line);
	fclose(fp);

	if (count == 0)
		pr_debug("No matched lines found in %s.\n", fname);
	return count;
}

static int probe_point_lazy_walker(const char *fname, int lineno,
				   Dwarf_Addr addr, void *data)
{
	struct probe_finder *pf = data;
	Dwarf_Die *sc_die, die_mem;
	int ret;

	if (!intlist__has_entry(pf->lcache, lineno) ||
	    strtailcmp(fname, pf->fname) != 0)
		return 0;

	pr_debug("Probe line found: line:%d addr:0x%llx\n",
		 lineno, (unsigned long long)addr);
	pf->addr = addr;
	pf->lno = lineno;
	sc_die = find_best_scope(pf, &die_mem);
	if (!sc_die) {
		pr_warning("Failed to find scope of probe point.\n");
		return -ENOENT;
	}

	ret = call_probe_finder(sc_die, pf);

	/*
	 * Continue if no error, because the lazy pattern will match
	 * to other lines
	 */
	return ret < 0 ? ret : 0;
}

/* Find probe points from lazy pattern  */
static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
{
	struct build_id bid;
	char sbuild_id[SBUILD_ID_SIZE] = "";
	int ret = 0;
	char *fpath;

	if (intlist__empty(pf->lcache)) {
		const char *comp_dir;

		comp_dir = cu_get_comp_dir(&pf->cu_die);
		if (pf->dbg->build_id) {
			build_id__init(&bid, pf->dbg->build_id, BUILD_ID_SIZE);
			build_id__sprintf(&bid, sbuild_id);
		}
		ret = find_source_path(pf->fname, sbuild_id, comp_dir, &fpath);
		if (ret < 0) {
			pr_warning("Failed to find source file path.\n");
			return ret;
		}

		/* Matching lazy line pattern */
		ret = find_lazy_match_lines(pf->lcache, fpath,
					    pf->pev->point.lazy_line);
		free(fpath);
		if (ret <= 0)
			return ret;
	}

	return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
}

static void skip_prologue(Dwarf_Die *sp_die, struct probe_finder *pf)
{
	struct perf_probe_point *pp = &pf->pev->point;

	/* Not uprobe? */
	if (!pf->pev->uprobes)
		return;

	/* Compiled with optimization? */
	if (die_is_optimized_target(&pf->cu_die))
		return;

	/* Don't know entrypc? */
	if (!pf->addr)
		return;

	/* Only FUNC and FUNC@SRC are eligible. */
	if (!pp->function || pp->line || pp->retprobe || pp->lazy_line ||
	    pp->offset || pp->abs_address)
		return;

	/* Not interested in func parameter? */
	if (!perf_probe_with_var(pf->pev))
		return;

	pr_info("Target program is compiled without optimization. Skipping prologue.\n"
		"Probe on address 0x%" PRIx64 " to force probing at the function entry.\n\n",
		pf->addr);

	die_skip_prologue(sp_die, &pf->cu_die, &pf->addr);
}

static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
{
	struct probe_finder *pf = data;
	struct perf_probe_point *pp = &pf->pev->point;
	Dwarf_Addr addr;
	int ret;

	if (pp->lazy_line)
		ret = find_probe_point_lazy(in_die, pf);
	else {
		/* Get probe address */
		if (die_entrypc(in_die, &addr) != 0) {
			pr_warning("Failed to get entry address of %s.\n",
				   dwarf_diename(in_die));
			return -ENOENT;
		}
		if (addr == 0) {
			pr_debug("%s has no valid entry address. skipped.\n",
				 dwarf_diename(in_die));
			return -ENOENT;
		}
		pf->addr = addr;
		pf->addr += pp->offset;
		pr_debug("found inline addr: 0x%jx\n",
			 (uintmax_t)pf->addr);

		ret = call_probe_finder(in_die, pf);
	}

	return ret;
}

/* Callback parameter with return value for libdw */
struct dwarf_callback_param {
	void *data;
	int retval;
};

/* Search function from function name */
static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
{
	struct dwarf_callback_param *param = data;
	struct probe_finder *pf = param->data;
	struct perf_probe_point *pp = &pf->pev->point;
	const char *fname;

	/* Check tag and diename */
	if (!die_is_func_def(sp_die) ||
	    !die_match_name(sp_die, pp->function))
		return DWARF_CB_OK;

	/* Check declared file */
	fname = die_get_decl_file(sp_die);
	if (!fname) {
		pr_warning("A function DIE doesn't have decl_line. Maybe broken DWARF?\n");
		return DWARF_CB_OK;
	}
	if (pp->file && fname && strtailcmp(pp->file, fname))
		return DWARF_CB_OK;

	pr_debug("Matched function: %s [%lx]\n", dwarf_diename(sp_die),
		 (unsigned long)dwarf_dieoffset(sp_die));
	pf->fname = fname;
	if (pp->line) { /* Function relative line */
		dwarf_decl_line(sp_die, &pf->lno);
		pf->lno += pp->line;
		param->retval = find_probe_point_by_line(pf);
	} else if (die_is_func_instance(sp_die)) {
		/* Instances always have the entry address */
		die_entrypc(sp_die, &pf->addr);
		/* But in some case the entry address is 0 */
		if (pf->addr == 0) {
			pr_debug("%s has no entry PC. Skipped\n",
				 dwarf_diename(sp_die));
			param->retval = 0;
		/* Real function */
		} else if (pp->lazy_line)
			param->retval = find_probe_point_lazy(sp_die, pf);
		else {
			skip_prologue(sp_die, pf);
			pf->addr += pp->offset;
			/* TODO: Check the address in this function */
			param->retval = call_probe_finder(sp_die, pf);
		}
	} else if (!probe_conf.no_inlines) {
		/* Inlined function: search instances */
		param->retval = die_walk_instances(sp_die,
					probe_point_inline_cb, (void *)pf);
		/* This could be a non-existed inline definition */
		if (param->retval == -ENOENT)
			param->retval = 0;
	}

	/* We need to find other candidates */
	if (strisglob(pp->function) && param->retval >= 0) {
		param->retval = 0;	/* We have to clear the result */
		return DWARF_CB_OK;
	}

	return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
}

static int find_probe_point_by_func(struct probe_finder *pf)
{
	struct dwarf_callback_param _param = {.data = (void *)pf,
					      .retval = 0};
	dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
	return _param.retval;
}

struct pubname_callback_param {
	char *function;
	char *file;
	Dwarf_Die *cu_die;
	Dwarf_Die *sp_die;
	int found;
};

static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
{
	struct pubname_callback_param *param = data;
	const char *fname;

	if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
		if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
			return DWARF_CB_OK;

		if (die_match_name(param->sp_die, param->function)) {
			if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
				return DWARF_CB_OK;

			if (param->file) {
				fname = die_get_decl_file(param->sp_die);
				if (!fname || strtailcmp(param->file, fname))
					return DWARF_CB_OK;
			}

			param->found = 1;
			return DWARF_CB_ABORT;
		}
	}

	return DWARF_CB_OK;
}

static int debuginfo__find_probe_location(struct debuginfo *dbg,
				  struct probe_finder *pf)
{
	struct perf_probe_point *pp = &pf->pev->point;
	Dwarf_Off off, noff;
	size_t cuhl;
	Dwarf_Die *diep;
	int ret = 0;

	off = 0;
	pf->lcache = intlist__new(NULL);
	if (!pf->lcache)
		return -ENOMEM;

	/* Fastpath: lookup by function name from .debug_pubnames section */
	if (pp->function && !strisglob(pp->function)) {
		struct pubname_callback_param pubname_param = {
			.function = pp->function,
			.file	  = pp->file,
			.cu_die	  = &pf->cu_die,
			.sp_die	  = &pf->sp_die,
			.found	  = 0,
		};
		struct dwarf_callback_param probe_param = {
			.data = pf,
		};

		dwarf_getpubnames(dbg->dbg, pubname_search_cb,
				  &pubname_param, 0);
		if (pubname_param.found) {
			ret = probe_point_search_cb(&pf->sp_die, &probe_param);
			if (ret)
				goto found;
		}
	}

	/* Loop on CUs (Compilation Unit) */
	while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
		/* Get the DIE(Debugging Information Entry) of this CU */
		diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die);
		if (!diep) {
			off = noff;
			continue;
		}

		/* Check if target file is included. */
		if (pp->file)
			pf->fname = cu_find_realpath(&pf->cu_die, pp->file);
		else
			pf->fname = NULL;

		if (!pp->file || pf->fname) {
			if (pp->function)
				ret = find_probe_point_by_func(pf);
			else if (pp->lazy_line)
				ret = find_probe_point_lazy(&pf->cu_die, pf);
			else {
				pf->lno = pp->line;
				ret = find_probe_point_by_line(pf);
			}
			if (ret < 0)
				break;
		}
		off = noff;
	}

found:
	intlist__delete(pf->lcache);
	pf->lcache = NULL;

	return ret;
}

/* Find probe points from debuginfo */
static int debuginfo__find_probes(struct debuginfo *dbg,
				  struct probe_finder *pf)
{
	int ret = 0;
	Elf *elf;
	GElf_Ehdr ehdr;

	if (pf->cfi_eh || pf->cfi_dbg)
		return debuginfo__find_probe_location(dbg, pf);

	/* Get the call frame information from this dwarf */
	elf = dwarf_getelf(dbg->dbg);
	if (elf == NULL)
		return -EINVAL;

	if (gelf_getehdr(elf, &ehdr) == NULL)
		return -EINVAL;

	pf->e_machine = ehdr.e_machine;
	pf->e_flags = ehdr.e_flags;

	do {
		GElf_Shdr shdr;

		if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
		    shdr.sh_type == SHT_PROGBITS)
			pf->cfi_eh = dwarf_getcfi_elf(elf);

		pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
	} while (0);

	ret = debuginfo__find_probe_location(dbg, pf);
	return ret;
}

struct local_vars_finder {
	struct probe_finder *pf;
	struct perf_probe_arg *args;
	bool vars;
	int max_args;
	int nargs;
	int ret;
};

/* Collect available variables in this scope */
static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
{
	struct local_vars_finder *vf = data;
	struct probe_finder *pf = vf->pf;
	int tag;

	tag = dwarf_tag(die_mem);
	if (tag == DW_TAG_formal_parameter ||
	    (tag == DW_TAG_variable && vf->vars)) {
		if (convert_variable_location(die_mem, vf->pf->addr,
					      vf->pf->fb_ops, &pf->sp_die,
					      pf, /*tvar=*/NULL) == 0) {
			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
			if (vf->args[vf->nargs].var == NULL) {
				vf->ret = -ENOMEM;
				return DIE_FIND_CB_END;
			}
			pr_debug(" %s", vf->args[vf->nargs].var);
			vf->nargs++;
		}
	}

	if (dwarf_haspc(die_mem, vf->pf->addr))
		return DIE_FIND_CB_CONTINUE;
	else
		return DIE_FIND_CB_SIBLING;
}

static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
			     struct perf_probe_arg *args)
{
	Dwarf_Die die_mem;
	int i;
	int n = 0;
	struct local_vars_finder vf = {.pf = pf, .args = args, .vars = false,
				.max_args = MAX_PROBE_ARGS, .ret = 0};

	for (i = 0; i < pf->pev->nargs; i++) {
		/* var never be NULL */
		if (strcmp(pf->pev->args[i].var, PROBE_ARG_VARS) == 0)
			vf.vars = true;
		else if (strcmp(pf->pev->args[i].var, PROBE_ARG_PARAMS) != 0) {
			/* Copy normal argument */
			args[n] = pf->pev->args[i];
			n++;
			continue;
		}
		pr_debug("Expanding %s into:", pf->pev->args[i].var);
		vf.nargs = n;
		/* Special local variables */
		die_find_child(sc_die, copy_variables_cb, (void *)&vf,
			       &die_mem);
		pr_debug(" (%d)\n", vf.nargs - n);
		if (vf.ret < 0)
			return vf.ret;
		n = vf.nargs;
	}
	return n;
}

static bool trace_event_finder_overlap(struct trace_event_finder *tf)
{
	int i;

	for (i = 0; i < tf->ntevs; i++) {
		if (tf->pf.addr == tf->tevs[i].point.address)
			return true;
	}
	return false;
}

/* Add a found probe point into trace event list */
static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	struct trace_event_finder *tf =
			container_of(pf, struct trace_event_finder, pf);
	struct perf_probe_point *pp = &pf->pev->point;
	struct probe_trace_event *tev;
	struct perf_probe_arg *args = NULL;
	int ret, i;

	/*
	 * For some reason (e.g. different column assigned to same address)
	 * This callback can be called with the address which already passed.
	 * Ignore it first.
	 */
	if (trace_event_finder_overlap(tf))
		return 0;

	/* Check number of tevs */
	if (tf->ntevs == tf->max_tevs) {
		pr_warning("Too many( > %d) probe point found.\n",
			   tf->max_tevs);
		return -ERANGE;
	}
	tev = &tf->tevs[tf->ntevs++];

	/* Trace point should be converted from subprogram DIE */
	ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
				     pp->retprobe, pp->function, &tev->point);
	if (ret < 0)
		goto end;

	tev->point.realname = strdup(dwarf_diename(sc_die));
	if (!tev->point.realname) {
		ret = -ENOMEM;
		goto end;
	}

	tev->lang = dwarf_srclang(dwarf_diecu(sc_die, &pf->cu_die, NULL, NULL));

	pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
		 tev->point.offset);

	/* Expand special probe argument if exist */
	args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
	if (args == NULL) {
		ret = -ENOMEM;
		goto end;
	}

	ret = expand_probe_args(sc_die, pf, args);
	if (ret < 0)
		goto end;

	tev->nargs = ret;
	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
	if (tev->args == NULL) {
		ret = -ENOMEM;
		goto end;
	}

	/* Find each argument */
	for (i = 0; i < tev->nargs; i++) {
		pf->pvar = &args[i];
		pf->tvar = &tev->args[i];
		/* Variable should be found from scope DIE */
		ret = find_variable(sc_die, pf);
		if (ret != 0)
			break;
	}

end:
	if (ret) {
		clear_probe_trace_event(tev);
		tf->ntevs--;
	}
	free(args);
	return ret;
}

static int fill_empty_trace_arg(struct perf_probe_event *pev,
				struct probe_trace_event *tevs, int ntevs)
{
	char **valp;
	char *type;
	int i, j, ret;

	if (!ntevs)
		return -ENOENT;

	for (i = 0; i < pev->nargs; i++) {
		type = NULL;
		for (j = 0; j < ntevs; j++) {
			if (tevs[j].args[i].value) {
				type = tevs[j].args[i].type;
				break;
			}
		}
		if (j == ntevs) {
			print_var_not_found(pev->args[i].var);
			return -ENOENT;
		}
		for (j = 0; j < ntevs; j++) {
			valp = &tevs[j].args[i].value;
			if (*valp)
				continue;

			ret = asprintf(valp, "\\%lx", probe_conf.magic_num);
			if (ret < 0)
				return -ENOMEM;
			/* Note that type can be NULL */
			if (type) {
				tevs[j].args[i].type = strdup(type);
				if (!tevs[j].args[i].type)
					return -ENOMEM;
			}
		}
	}
	return 0;
}

/* Find probe_trace_events specified by perf_probe_event from debuginfo */
int debuginfo__find_trace_events(struct debuginfo *dbg,
				 struct perf_probe_event *pev,
				 struct probe_trace_event **tevs)
{
	struct trace_event_finder tf = {
			.pf = {.pev = pev, .dbg = dbg, .callback = add_probe_trace_event},
			.max_tevs = probe_conf.max_probes, .mod = dbg->mod};
	int ret, i;

	/* Allocate result tevs array */
	*tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs);
	if (*tevs == NULL)
		return -ENOMEM;

	tf.tevs = *tevs;
	tf.ntevs = 0;

	if (pev->nargs != 0 && immediate_value_is_supported())
		tf.pf.skip_empty_arg = true;

	ret = debuginfo__find_probes(dbg, &tf.pf);
	if (ret >= 0 && tf.pf.skip_empty_arg)
		ret = fill_empty_trace_arg(pev, tf.tevs, tf.ntevs);

	dwarf_cfi_end(tf.pf.cfi_eh);

	if (ret < 0 || tf.ntevs == 0) {
		for (i = 0; i < tf.ntevs; i++)
			clear_probe_trace_event(&tf.tevs[i]);
		zfree(tevs);
		return ret;
	}

	return (ret < 0) ? ret : tf.ntevs;
}

/* Collect available variables in this scope */
static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
{
	struct available_var_finder *af = data;
	struct variable_list *vl;
	struct strbuf buf = STRBUF_INIT;
	int tag, ret;

	vl = &af->vls[af->nvls - 1];

	tag = dwarf_tag(die_mem);
	if (tag == DW_TAG_formal_parameter ||
	    tag == DW_TAG_variable) {
		ret = convert_variable_location(die_mem, af->pf.addr,
						af->pf.fb_ops, &af->pf.sp_die,
						&af->pf, /*tvar=*/NULL);
		if (ret == 0 || ret == -ERANGE) {
			int ret2;
			bool externs = !af->child;

			if (strbuf_init(&buf, 64) < 0)
				goto error;

			if (probe_conf.show_location_range) {
				if (!externs)
					ret2 = strbuf_add(&buf,
						ret ? "[INV]\t" : "[VAL]\t", 6);
				else
					ret2 = strbuf_add(&buf, "[EXT]\t", 6);
				if (ret2)
					goto error;
			}

			ret2 = die_get_varname(die_mem, &buf);

			if (!ret2 && probe_conf.show_location_range &&
				!externs) {
				if (strbuf_addch(&buf, '\t') < 0)
					goto error;
				ret2 = die_get_var_range(&af->pf.sp_die,
							die_mem, &buf);
			}

			pr_debug("Add new var: %s\n", buf.buf);
			if (ret2 == 0) {
				strlist__add(vl->vars,
					strbuf_detach(&buf, NULL));
			}
			strbuf_release(&buf);
		}
	}

	if (af->child && dwarf_haspc(die_mem, af->pf.addr))
		return DIE_FIND_CB_CONTINUE;
	else
		return DIE_FIND_CB_SIBLING;
error:
	strbuf_release(&buf);
	pr_debug("Error in strbuf\n");
	return DIE_FIND_CB_END;
}

static bool available_var_finder_overlap(struct available_var_finder *af)
{
	int i;

	for (i = 0; i < af->nvls; i++) {
		if (af->pf.addr == af->vls[i].point.address)
			return true;
	}
	return false;

}

/* Add a found vars into available variables list */
static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	struct available_var_finder *af =
			container_of(pf, struct available_var_finder, pf);
	struct perf_probe_point *pp = &pf->pev->point;
	struct variable_list *vl;
	Dwarf_Die die_mem;
	int ret;

	/*
	 * For some reason (e.g. different column assigned to same address),
	 * this callback can be called with the address which already passed.
	 * Ignore it first.
	 */
	if (available_var_finder_overlap(af))
		return 0;

	/* Check number of tevs */
	if (af->nvls == af->max_vls) {
		pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
		return -ERANGE;
	}
	vl = &af->vls[af->nvls++];

	/* Trace point should be converted from subprogram DIE */
	ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
				     pp->retprobe, pp->function, &vl->point);
	if (ret < 0)
		return ret;

	pr_debug("Probe point found: %s+%lu\n", vl->point.symbol,
		 vl->point.offset);

	/* Find local variables */
	vl->vars = strlist__new(NULL, NULL);
	if (vl->vars == NULL)
		return -ENOMEM;
	af->child = true;
	die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem);

	/* Find external variables */
	if (!probe_conf.show_ext_vars)
		goto out;
	/* Don't need to search child DIE for external vars. */
	af->child = false;
	die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem);

out:
	if (strlist__empty(vl->vars)) {
		strlist__delete(vl->vars);
		vl->vars = NULL;
	}

	return ret;
}

/*
 * Find available variables at given probe point
 * Return the number of found probe points. Return 0 if there is no
 * matched probe point. Return <0 if an error occurs.
 */
int debuginfo__find_available_vars_at(struct debuginfo *dbg,
				      struct perf_probe_event *pev,
				      struct variable_list **vls)
{
	struct available_var_finder af = {
			.pf = {.pev = pev, .dbg = dbg, .callback = add_available_vars},
			.mod = dbg->mod,
			.max_vls = probe_conf.max_probes};
	int ret;

	/* Allocate result vls array */
	*vls = zalloc(sizeof(struct variable_list) * af.max_vls);
	if (*vls == NULL)
		return -ENOMEM;

	af.vls = *vls;
	af.nvls = 0;

	ret = debuginfo__find_probes(dbg, &af.pf);
	if (ret < 0) {
		/* Free vlist for error */
		while (af.nvls--) {
			zfree(&af.vls[af.nvls].point.symbol);
			strlist__delete(af.vls[af.nvls].vars);
		}
		zfree(vls);
		return ret;
	}

	return (ret < 0) ? ret : af.nvls;
}

/* Reverse search */
int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,
				struct perf_probe_point *ppt)
{
	Dwarf_Die cudie, spdie, indie;
	Dwarf_Addr _addr = 0, baseaddr = 0;
	const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp;
	int baseline = 0, lineno = 0, ret = 0;

	/* We always need to relocate the address for aranges */
	if (debuginfo__get_text_offset(dbg, &baseaddr, false) == 0)
		addr += baseaddr;
	/* Find cu die */
	if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr, &cudie)) {
		pr_warning("Failed to find debug information for address %#" PRIx64 "\n",
			   addr);
		ret = -EINVAL;
		goto end;
	}

	/* Find a corresponding line (filename and lineno) */
	cu_find_lineinfo(&cudie, (Dwarf_Addr)addr, &fname, &lineno);
	/* Don't care whether it failed or not */

	/* Find a corresponding function (name, baseline and baseaddr) */
	if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
		/*
		 * Get function entry information.
		 *
		 * As described in the document DWARF Debugging Information
		 * Format Version 5, section 2.22 Linkage Names, "mangled names,
		 * are used in various ways, ... to distinguish multiple
		 * entities that have the same name".
		 *
		 * Firstly try to get distinct linkage name, if fail then
		 * rollback to get associated name in DIE.
		 */
		func = basefunc = die_get_linkage_name(&spdie);
		if (!func)
			func = basefunc = dwarf_diename(&spdie);

		if (!func ||
		    die_entrypc(&spdie, &baseaddr) != 0 ||
		    dwarf_decl_line(&spdie, &baseline) != 0) {
			lineno = 0;
			goto post;
		}

		fname = die_get_decl_file(&spdie);
		if (addr == baseaddr) {
			/* Function entry - Relative line number is 0 */
			lineno = baseline;
			goto post;
		}

		/* Track down the inline functions step by step */
		while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
						&indie)) {
			/* There is an inline function */
			if (die_entrypc(&indie, &_addr) == 0 &&
			    _addr == addr) {
				/*
				 * addr is at an inline function entry.
				 * In this case, lineno should be the call-site
				 * line number. (overwrite lineinfo)
				 */
				lineno = die_get_call_lineno(&indie);
				fname = die_get_call_file(&indie);
				break;
			} else {
				/*
				 * addr is in an inline function body.
				 * Since lineno points one of the lines
				 * of the inline function, baseline should
				 * be the entry line of the inline function.
				 */
				tmp = dwarf_diename(&indie);
				if (!tmp ||
				    dwarf_decl_line(&indie, &baseline) != 0)
					break;
				func = tmp;
				spdie = indie;
			}
		}
		/* Verify the lineno and baseline are in a same file */
		tmp = die_get_decl_file(&spdie);
		if (!tmp || (fname && strcmp(tmp, fname) != 0))
			lineno = 0;
	}

post:
	/* Make a relative line number or an offset */
	if (lineno)
		ppt->line = lineno - baseline;
	else if (basefunc) {
		ppt->offset = addr - baseaddr;
		func = basefunc;
	}

	/* Duplicate strings */
	if (func) {
		ppt->function = strdup(func);
		if (ppt->function == NULL) {
			ret = -ENOMEM;
			goto end;
		}
	}
	if (fname) {
		ppt->file = strdup(fname);
		if (ppt->file == NULL) {
			zfree(&ppt->function);
			ret = -ENOMEM;
			goto end;
		}
	}
end:
	if (ret == 0 && (fname || func))
		ret = 1;	/* Found a point */
	return ret;
}

/* Add a line and store the src path */
static int line_range_add_line(const char *src, unsigned int lineno,
			       struct line_range *lr)
{
	/* Copy source path */
	if (!lr->path) {
		lr->path = strdup(src);
		if (lr->path == NULL)
			return -ENOMEM;
	}
	return intlist__add(lr->line_list, lineno);
}

static int line_range_walk_cb(const char *fname, int lineno,
			      Dwarf_Addr addr, void *data)
{
	struct line_finder *lf = data;
	const char *__fname;
	int __lineno;
	int err;

	if ((strtailcmp(fname, lf->fname) != 0) ||
	    (lf->lno_s > lineno || lf->lno_e < lineno))
		return 0;

	/* Make sure this line can be reversible */
	if (cu_find_lineinfo(&lf->cu_die, addr, &__fname, &__lineno) > 0
	    && (lineno != __lineno || strcmp(fname, __fname)))
		return 0;

	err = line_range_add_line(fname, lineno, lf->lr);
	if (err < 0 && err != -EEXIST)
		return err;

	return 0;
}

/* Find line range from its line number */
static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
{
	int ret;

	ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf);

	/* Update status */
	if (ret >= 0)
		if (!intlist__empty(lf->lr->line_list))
			ret = lf->found = 1;
		else
			ret = 0;	/* Lines are not found */
	else {
		zfree(&lf->lr->path);
	}
	return ret;
}

static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
{
	int ret = find_line_range_by_line(in_die, data);

	/*
	 * We have to check all instances of inlined function, because
	 * some execution paths can be optimized out depends on the
	 * function argument of instances. However, if an error occurs,
	 * it should be handled by the caller.
	 */
	return ret < 0 ? ret : 0;
}

/* Search function definition from function name */
static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
{
	struct dwarf_callback_param *param = data;
	struct line_finder *lf = param->data;
	struct line_range *lr = lf->lr;
	const char *fname;

	/* Check declared file */
	if (lr->file) {
		fname = die_get_decl_file(sp_die);
		if (!fname || strtailcmp(lr->file, fname))
			return DWARF_CB_OK;
	}

	if (die_match_name(sp_die, lr->function) && die_is_func_def(sp_die)) {
		lf->fname = die_get_decl_file(sp_die);
		dwarf_decl_line(sp_die, &lr->offset);
		pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
		lf->lno_s = lr->offset + lr->start;
		if (lf->lno_s < 0)	/* Overflow */
			lf->lno_s = INT_MAX;
		lf->lno_e = lr->offset + lr->end;
		if (lf->lno_e < 0)	/* Overflow */
			lf->lno_e = INT_MAX;
		pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
		lr->start = lf->lno_s;
		lr->end = lf->lno_e;
		if (!die_is_func_instance(sp_die))
			param->retval = die_walk_instances(sp_die,
						line_range_inline_cb, lf);
		else
			param->retval = find_line_range_by_line(sp_die, lf);
		return DWARF_CB_ABORT;
	}
	return DWARF_CB_OK;
}

static int find_line_range_by_func(struct line_finder *lf)
{
	struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
	dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0);
	return param.retval;
}

int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
{
	struct line_finder lf = {.lr = lr, .found = 0};
	int ret = 0;
	Dwarf_Off off = 0, noff;
	size_t cuhl;
	Dwarf_Die *diep;
	const char *comp_dir;

	/* Fastpath: lookup by function name from .debug_pubnames section */
	if (lr->function) {
		struct pubname_callback_param pubname_param = {
			.function = lr->function, .file = lr->file,
			.cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
		struct dwarf_callback_param line_range_param = {
			.data = (void *)&lf, .retval = 0};

		dwarf_getpubnames(dbg->dbg, pubname_search_cb,
				  &pubname_param, 0);
		if (pubname_param.found) {
			line_range_search_cb(&lf.sp_die, &line_range_param);
			if (lf.found)
				goto found;
		}
	}

	/* Loop on CUs (Compilation Unit) */
	while (!lf.found && ret >= 0) {
		if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl,
				 NULL, NULL, NULL) != 0)
			break;

		/* Get the DIE(Debugging Information Entry) of this CU */
		diep = dwarf_offdie(dbg->dbg, off + cuhl, &lf.cu_die);
		if (!diep) {
			off = noff;
			continue;
		}

		/* Check if target file is included. */
		if (lr->file)
			lf.fname = cu_find_realpath(&lf.cu_die, lr->file);
		else
			lf.fname = 0;

		if (!lr->file || lf.fname) {
			if (lr->function)
				ret = find_line_range_by_func(&lf);
			else {
				lf.lno_s = lr->start;
				lf.lno_e = lr->end;
				ret = find_line_range_by_line(NULL, &lf);
			}
		}
		off = noff;
	}

found:
	/* Store comp_dir */
	if (lf.found) {
		comp_dir = cu_get_comp_dir(&lf.cu_die);
		if (comp_dir) {
			lr->comp_dir = strdup(comp_dir);
			if (!lr->comp_dir)
				ret = -ENOMEM;
		}
	}

	pr_debug("path: %s\n", lr->path);
	return (ret < 0) ? ret : lf.found;
}

/*
 * Find a src file from a DWARF tag path. Prepend optional source path prefix
 * and chop off leading directories that do not exist. Result is passed back as
 * a newly allocated path on success.
 * Return 0 if file was found and readable, -errno otherwise.
 */
int find_source_path(const char *raw_path, const char *sbuild_id,
		const char *comp_dir, char **new_path)
{
	const char *prefix = symbol_conf.source_prefix;

	if (sbuild_id && !prefix) {
		char prefixed_raw_path[PATH_MAX];

		path__join(prefixed_raw_path, sizeof(prefixed_raw_path), comp_dir, raw_path);

		if (!get_source_from_debuginfod(prefixed_raw_path, sbuild_id, new_path))
			return 0;
	}

	if (!prefix) {
		if (raw_path[0] != '/' && comp_dir)
			/* If not an absolute path, try to use comp_dir */
			prefix = comp_dir;
		else {
			if (access(raw_path, R_OK) == 0) {
				*new_path = strdup(raw_path);
				return *new_path ? 0 : -ENOMEM;
			} else
				return -errno;
		}
	}

	*new_path = malloc((strlen(prefix) + strlen(raw_path) + 2));
	if (!*new_path)
		return -ENOMEM;

	for (;;) {
		sprintf(*new_path, "%s/%s", prefix, raw_path);

		if (access(*new_path, R_OK) == 0)
			return 0;

		if (!symbol_conf.source_prefix) {
			/* In case of searching comp_dir, don't retry */
			zfree(new_path);
			return -errno;
		}

		switch (errno) {
		case ENAMETOOLONG:
		case ENOENT:
		case EROFS:
		case EFAULT:
			raw_path = strchr(++raw_path, '/');
			if (!raw_path) {
				zfree(new_path);
				return -ENOENT;
			}
			continue;

		default:
			zfree(new_path);
			return -errno;
		}
	}
}
