rizin/librz/analysis/il/analysis_il_trace.c

99 lines
2.8 KiB
C

// SPDX-FileCopyrightText: 2021 heersin <teablearcher@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_analysis.h>
/**
* IL trace should also these info
* 1. mem.read address & data
* 2. mem.write address & data
* 3. reg.read name & data
* 4. reg.write name & data
**/
static void htup_vector_free(HtUPKv *kv) {
rz_vector_free(kv->value);
}
/**
* Create a new trace to collect infos
* \param analysis pointer to RzAnalysis
* \param rzil RZ_IL instance
* \return pointer to RzilTrace
*/
RZ_API RzAnalysisRzilTrace *rz_analysis_rzil_trace_new(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil) {
rz_return_val_if_fail(rzil, NULL);
size_t i;
RzAnalysisEsilTrace *trace = RZ_NEW0(RzAnalysisEsilTrace);
if (!trace) {
return NULL;
}
// TODO : maybe we could remove memory && register in rzil trace ?
trace->registers = ht_up_new(NULL, htup_vector_free, NULL);
if (!trace->registers) {
RZ_LOG_ERROR("rzil: Cannot allocate hasmap for trace registers\n");
goto error;
}
trace->memory = ht_up_new(NULL, htup_vector_free, NULL);
if (!trace->memory) {
RZ_LOG_ERROR("rzil: Cannot allocate hasmap for trace memory\n");
goto error;
}
trace->instructions = rz_pvector_new((RzPVectorFree)rz_analysis_il_trace_instruction_free);
if (!trace->instructions) {
RZ_LOG_ERROR("rzil: Cannot allocate vector for trace instructions\n");
goto error;
}
// TODO : Integrate with stack panel in the future
// Save initial registers arenas
for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
RzRegArena *a = analysis->reg->regset[i].arena;
RzRegArena *b = rz_reg_arena_new(a->size);
if (!b) {
RZ_LOG_ERROR("rzil: Cannot allocate register arena for trace\n");
goto error;
}
if (b->bytes && a->bytes && b->size > 0) {
memcpy(b->bytes, a->bytes, b->size);
}
trace->arena[i] = b;
}
return trace;
error:
rz_analysis_esil_trace_free(trace);
return NULL;
}
/**
* Free an IL trace
* \param trace trace to be free
*/
RZ_API void rz_analysis_rzil_trace_free(RzAnalysisEsilTrace *trace) {
size_t i;
if (!trace) {
return;
}
ht_up_free(trace->registers);
ht_up_free(trace->memory);
for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
rz_reg_arena_free(trace->arena[i]);
}
rz_pvector_free(trace->instructions);
trace->instructions = NULL;
RZ_FREE(trace);
}
/**
* This function should be called after executing the IL op
* Collect trace info (target and data of mem/reg read/write)
* \param analysis RzAnalysis
* \param rzil IL instance
* \param op RzAnalysisRzilOp, a general IL op structure (Designed for switching between different implementations of IL op struct)
*/
RZ_API void rz_analysis_rzil_trace_op(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil, RZ_NONNULL RzAnalysisLiftedILOp op) {
// TODO : rewrite this file when migrate to new op structure
}