static bool analysis_path_exists(RzCore *core, ut64 from, ut64 to, RzList *bbs, int depth, HtUP *state, HtUP *avoid) {
	rz_return_val_if_fail(bbs, false);
	RzAnalysisBlock *bb = rz_analysis_find_most_relevant_block_in(core->analysis, from);
	RzListIter *iter = NULL;
	RzAnalysisXRef *xrefi;

	if (depth < 1) {
		eprintf("going too deep\n");
		return false;
	}

	if (!bb) {
		return false;
	}

	ht_up_update(state, from, bb);

	// try to find the target in the current function
	if (rz_analysis_block_contains(bb, to) ||
		((!ht_up_find(avoid, bb->jump, NULL) &&
			!ht_up_find(state, bb->jump, NULL) &&
			analysis_path_exists(core, bb->jump, to, bbs, depth - 1, state, avoid))) ||
		((!ht_up_find(avoid, bb->fail, NULL) &&
			!ht_up_find(state, bb->fail, NULL) &&
			analysis_path_exists(core, bb->fail, to, bbs, depth - 1, state, avoid)))) {
		rz_list_prepend(bbs, bb);
		return true;
	}

	// find our current function
	RzAnalysisFunction *cur_fcn = rz_analysis_get_fcn_in(core->analysis, from, 0);

	// get call refs from current basic block and find a path from them
	if (cur_fcn) {
		RzList *xrefs = rz_analysis_function_get_xrefs_from(cur_fcn);
		if (xrefs) {
			rz_list_foreach (xrefs, iter, xrefi) {
				if (xrefi->type == RZ_ANALYSIS_REF_TYPE_CALL) {
					if (rz_analysis_block_contains(bb, xrefi->from)) {
						if ((xrefi->from != xrefi->to) && !ht_up_find(state, xrefi->to, NULL) && analysis_path_exists(core, xrefi->to, to, bbs, depth - 1, state, avoid)) {
							rz_list_prepend(bbs, bb);
							rz_list_free(xrefs);
							return true;
						}
					}
				}
			}
		}
		rz_list_free(xrefs);
	}

	return false;
}
static bool analysis_path_exists(RzCore *core, ut64 from, ut64 to, RzList *bbs, int depth, HtUP *state, HtUP *avoid) {
	rz_return_val_if_fail(bbs, false);
	RzAnalysisBlock *bb = rz_analysis_find_most_relevant_block_in(core->analysis, from);
	RzListIter *iter = NULL;
	RzAnalysisXRef *xrefi;

	if (depth < 1) {
		eprintf("going too deep\n");
		return false;
	}

	if (!bb) {
		return false;
	}

	ht_up_update(state, from, bb);

	 
	if (rz_analysis_block_contains(bb, to) ||
		((!ht_up_find(avoid, bb->jump, NULL) &&
			!ht_up_find(state, bb->jump, NULL) &&
			analysis_path_exists(core, bb->jump, to, bbs, depth - 1, state, avoid))) ||
		((!ht_up_find(avoid, bb->fail, NULL) &&
			!ht_up_find(state, bb->fail, NULL) &&
			analysis_path_exists(core, bb->fail, to, bbs, depth - 1, state, avoid)))) {
		rz_list_prepend(bbs, bb);
		return true;
	}

	 
	RzAnalysisFunction *cur_fcn = rz_analysis_get_fcn_in(core->analysis, from, 0);

	 
	if (cur_fcn) {
		RzList *xrefs = rz_analysis_function_get_xrefs_from(cur_fcn);
		if (xrefs) {
			rz_list_foreach (xrefs, iter, xrefi) {
				if (xrefi->type == RZ_ANALYSIS_REF_TYPE_CALL) {
					if (rz_analysis_block_contains(bb, xrefi->from)) {
						if ((xrefi->from != xrefi->to) && !ht_up_find(state, xrefi->to, NULL) && analysis_path_exists(core, xrefi->to, to, bbs, depth - 1, state, avoid)) {
							rz_list_prepend(bbs, bb);
							rz_list_free(xrefs);
							return true;
						}
					}
				}
			}
		}
		rz_list_free(xrefs);
	}

	return false;
}