static int esilbreak_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len) {
	RzCore *core = esil->analysis->coreb.core;
	ut8 str[128];
	if (addr != UT64_MAX) {
		esilbreak_last_read = addr;
	}
	handle_var_stack_access(esil, addr, RZ_ANALYSIS_VAR_ACCESS_TYPE_READ, len);
	if (myvalid(core->io, addr) && rz_io_read_at(core->io, addr, (ut8 *)buf, len)) {
		ut64 refptr;
		bool trace = true;
		switch (len) {
		case 2:
			esilbreak_last_data = refptr = (ut64)rz_read_ble16(buf, esil->analysis->big_endian);
			break;
		case 4:
			esilbreak_last_data = refptr = (ut64)rz_read_ble32(buf, esil->analysis->big_endian);
			break;
		case 8:
			esilbreak_last_data = refptr = rz_read_ble64(buf, esil->analysis->big_endian);
			break;
		default:
			trace = false;
			rz_io_read_at(core->io, addr, (ut8 *)buf, len);
			break;
		}
		// TODO incorrect
		bool validRef = false;
		if (trace && myvalid(core->io, refptr)) {
			if (ntarget == UT64_MAX || ntarget == refptr) {
				str[0] = 0;
				if (rz_io_read_at(core->io, refptr, str, sizeof(str)) < 1) {
					//eprintf ("Invalid read\n");
					str[0] = 0;
					validRef = false;
				} else {
					rz_analysis_xrefs_set(core->analysis, esil->address, refptr, RZ_ANALYSIS_REF_TYPE_DATA);
					str[sizeof(str) - 1] = 0;
					add_string_ref(core, esil->address, refptr);
					esilbreak_last_data = UT64_MAX;
					validRef = true;
				}
			}
		}

		/** resolve ptr */
		if (ntarget == UT64_MAX || ntarget == addr || (ntarget == UT64_MAX && !validRef)) {
			rz_analysis_xrefs_set(core->analysis, esil->address, addr, RZ_ANALYSIS_REF_TYPE_DATA);
		}
	}
	return 0; // fallback
}
static int esilbreak_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len) {
	RzCore *core = esil->analysis->coreb.core;
	ut8 str[128];
	if (addr != UT64_MAX) {
		esilbreak_last_read = addr;
	}
	handle_var_stack_access(esil, addr, RZ_ANALYSIS_VAR_ACCESS_TYPE_READ, len);
	if (myvalid(core->io, addr) && rz_io_read_at(core->io, addr, (ut8 *)buf, len)) {
		ut64 refptr;
		bool trace = true;
		switch (len) {
		case 2:
			esilbreak_last_data = refptr = (ut64)rz_read_ble16(buf, esil->analysis->big_endian);
			break;
		case 4:
			esilbreak_last_data = refptr = (ut64)rz_read_ble32(buf, esil->analysis->big_endian);
			break;
		case 8:
			esilbreak_last_data = refptr = rz_read_ble64(buf, esil->analysis->big_endian);
			break;
		default:
			trace = false;
			rz_io_read_at(core->io, addr, (ut8 *)buf, len);
			break;
		}
		 
		bool validRef = false;
		if (trace && myvalid(core->io, refptr)) {
			if (ntarget == UT64_MAX || ntarget == refptr) {
				str[0] = 0;
				if (rz_io_read_at(core->io, refptr, str, sizeof(str)) < 1) {
					 
					str[0] = 0;
					validRef = false;
				} else {
					rz_analysis_xrefs_set(core->analysis, esil->address, refptr, RZ_ANALYSIS_REF_TYPE_DATA);
					str[sizeof(str) - 1] = 0;
					add_string_ref(core, esil->address, refptr);
					esilbreak_last_data = UT64_MAX;
					validRef = true;
				}
			}
		}

		 
		if (ntarget == UT64_MAX || ntarget == addr || (ntarget == UT64_MAX && !validRef)) {
			rz_analysis_xrefs_set(core->analysis, esil->address, addr, RZ_ANALYSIS_REF_TYPE_DATA);
		}
	}
	return 0;  
}