mirror of
https://github.com/rizinorg/rizin
synced 2026-08-22 20:26:16 -04:00
Reset abstract state instead of freeing and allocating it.
This commit is contained in:
parent
8650b9fcc1
commit
3c6113cd66
3 changed files with 69 additions and 12 deletions
|
|
@ -159,11 +159,16 @@ typedef struct {
|
|||
*/
|
||||
RzInterpreterYieldKind supported_yields;
|
||||
bool (*init)(void **plugin_data);
|
||||
bool (*reset)(void *plugin_data);
|
||||
bool (*fini)(void *plugin_data);
|
||||
/**
|
||||
* \brief Initializes the abstract state.
|
||||
*/
|
||||
bool (*init_state)(RZ_BORROW RzInterpreterAbstrState *state, ut64 entry_point, void *plugin_data);
|
||||
bool (*init_state)(RZ_BORROW RzInterpreterAbstrState *state, void *plugin_data);
|
||||
/**
|
||||
* \brief Reset the abstract state.
|
||||
*/
|
||||
bool (*reset_state)(RZ_BORROW RzInterpreterAbstrState *state, ut64 entry_point, void *plugin_data);
|
||||
/**
|
||||
* \brief Closes the abstract state and frees all its abstract data and sets the pointers to NULL.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -422,18 +422,18 @@ static bool choose_next_pc(RzInterpreterSet *iset,
|
|||
return has_succsessor;
|
||||
}
|
||||
|
||||
static bool setup_intrpr_state(
|
||||
static bool reset_intrpr_state(
|
||||
RzInterpreterSet *iset,
|
||||
ut64 entry_point,
|
||||
RzVector **tmp_succ_addr,
|
||||
RzSetU **reachable_states,
|
||||
RzVector **succ_states) {
|
||||
|
||||
if (iset->plugin->init) {
|
||||
iset->plugin->init(&iset->intrpr_priv);
|
||||
if (iset->plugin->reset) {
|
||||
iset->plugin->reset(iset->intrpr_priv);
|
||||
}
|
||||
|
||||
if (!iset->plugin->init_state(iset->astate, entry_point, iset->intrpr_priv)) {
|
||||
if (!iset->plugin->reset_state(iset->astate, entry_point, iset->intrpr_priv)) {
|
||||
rz_warn_if_reached();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -485,6 +485,14 @@ RZ_API bool rz_interpreter_run(RZ_NONNULL RZ_OWN RzInterpreterSet *iset) {
|
|||
const RzInterpreterILBB *il_bb = NULL;
|
||||
ut64 astate_hash = 0;
|
||||
|
||||
if (iset->plugin->init) {
|
||||
iset->plugin->init(&iset->intrpr_priv);
|
||||
}
|
||||
if (!iset->plugin->init_state(iset->astate, iset->intrpr_priv)) {
|
||||
rz_warn_if_reached();
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: It is probably better to make the following stuff while-loops.
|
||||
// Because otherwise it doesn't make sense without the docs.
|
||||
// But while debugging and developing, I keep it this way to separate clearly
|
||||
|
|
@ -501,7 +509,7 @@ INIT: {
|
|||
}
|
||||
|
||||
// Initializes the current interpreter's private data and its state.
|
||||
if (!setup_intrpr_state(iset, il_bb->bb_addr, &tmp_succ_addr, &reachable_states, &succ_states)) {
|
||||
if (!reset_intrpr_state(iset, il_bb->bb_addr, &tmp_succ_addr, &reachable_states, &succ_states)) {
|
||||
success = false;
|
||||
goto TERM;
|
||||
}
|
||||
|
|
@ -565,10 +573,6 @@ CLEAN: {
|
|||
RZ_FREE_CUSTOM(tmp_succ_addr, rz_vector_free);
|
||||
RZ_FREE_CUSTOM(succ_states, rz_vector_free);
|
||||
RZ_FREE_CUSTOM(reachable_states, rz_set_u_free);
|
||||
iset->plugin->fini_state(iset->astate, iset->intrpr_priv);
|
||||
if (iset->plugin->fini && iset->intrpr_priv) {
|
||||
RZ_FREE_CUSTOM(iset->intrpr_priv, iset->plugin->fini);
|
||||
}
|
||||
|
||||
// Wait until RzInquiry asks to start again.
|
||||
rz_th_sem_wait(iset->run_state_sync);
|
||||
|
|
@ -580,6 +584,10 @@ CLEAN: {
|
|||
TERM: {
|
||||
RZ_LOG_DEBUG("Enter TERM\n");
|
||||
rz_intp_run_state_set(iset->run_state, RZ_INTP_RUN_STATE_TERM);
|
||||
iset->plugin->fini_state(iset->astate, iset->intrpr_priv);
|
||||
if (iset->plugin->fini && iset->intrpr_priv) {
|
||||
RZ_FREE_CUSTOM(iset->intrpr_priv, iset->plugin->fini);
|
||||
}
|
||||
|
||||
RZ_FREE_CUSTOM(tmp_succ_addr, rz_vector_free);
|
||||
RZ_FREE_CUSTOM(succ_states, rz_vector_free);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "../prototype/eval.h"
|
||||
#include "rz_util/ht_uu.h"
|
||||
#include "rz_util/rz_bitvector.h"
|
||||
|
||||
#define MAX_INVOCATIONS_PER_BB 3
|
||||
|
||||
|
|
@ -80,9 +81,9 @@ bool successors(RZ_NONNULL const RzInterpreterAbstrState *state,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool init_state(RZ_BORROW RzInterpreterAbstrState *state, ut64 entry_point, void *plugin_data) {
|
||||
static bool init_state(RZ_BORROW RzInterpreterAbstrState *state, void *plugin_data) {
|
||||
state->pc->abstr_data = RZ_NEW0(ProtoIntrprAbstrData);
|
||||
AD(state->pc->abstr_data)->bv = rz_bv_new_from_ut64(state->il_config->mem_key_size, entry_point);
|
||||
AD(state->pc->abstr_data)->bv = rz_bv_new_from_ut64(state->il_config->mem_key_size, 0);
|
||||
AD(state->pc->abstr_data)->is_concrete = true;
|
||||
RzIterator *it = ht_up_as_iter_keys(state->globals);
|
||||
ut64 *k;
|
||||
|
|
@ -117,6 +118,36 @@ static bool init_state(RZ_BORROW RzInterpreterAbstrState *state, ut64 entry_poin
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool reset_state(RZ_BORROW RzInterpreterAbstrState *state, ut64 entry_point, void *plugin_data) {
|
||||
rz_bv_set_from_ut64(AD(state->pc->abstr_data)->bv, entry_point);
|
||||
AD(state->pc->abstr_data)->is_concrete = true;
|
||||
|
||||
RzIterator *it = ht_up_as_iter_keys(state->globals);
|
||||
ut64 *k;
|
||||
rz_iterator_foreach(it, k) {
|
||||
ut64 djb2_reg_name = *k;
|
||||
RzInterpreterAbstrVal *av = ht_up_find(state->globals, djb2_reg_name, NULL);
|
||||
rz_bv_set_from_ut64(AD(av->abstr_data)->bv, 0);
|
||||
AD(av->abstr_data)->is_concrete = true;
|
||||
if (state->il_config->init_state) {
|
||||
RzAnalysisILInitStateVar *il_var;
|
||||
rz_vector_foreach (&state->il_config->init_state->vars, il_var) {
|
||||
if (rz_str_djb2_hash(il_var->name) != djb2_reg_name) {
|
||||
continue;
|
||||
}
|
||||
// The RzArch plugin defined a default value for this global.
|
||||
RzBitVector *default_val = rz_il_value_to_bv(il_var->val);
|
||||
rz_bv_copy(AD(av->abstr_data)->bv, default_val);
|
||||
rz_bv_free(default_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
rz_iterator_free(it);
|
||||
state->bb_addr = 0;
|
||||
state->bb_size = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool fini_state(RZ_BORROW RzInterpreterAbstrState *state, void *plugin_data) {
|
||||
ProtoIntrprAbstrData *ad = state->pc->abstr_data;
|
||||
if (ad && ad->bv) {
|
||||
|
|
@ -240,6 +271,17 @@ bool fini(void *plugin_data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool reset(void *plugin_data) {
|
||||
if (!plugin_data) {
|
||||
return true;
|
||||
}
|
||||
RZ_LOG_DEBUG("prototype: reset()\n");
|
||||
ProtoIntrprPluginData *pdata = plugin_data;
|
||||
ht_uu_clear(pdata->bb_invocation_count);
|
||||
memset(&pdata->call_cand, 0, sizeof(RzAnalysisCallCandidate));
|
||||
return true;
|
||||
}
|
||||
|
||||
static RzInterpreterPlugin rz_interpreter_plugin_prototype = {
|
||||
.name = "abstr_int_prototype",
|
||||
.author = "Rot127",
|
||||
|
|
@ -249,10 +291,12 @@ static RzInterpreterPlugin rz_interpreter_plugin_prototype = {
|
|||
.supported_abstractions = RZ_INTERPRETER_ABSTRACTION_CONST,
|
||||
.supported_yields = RZ_INTERPRETER_YIELD_KIND_XREF | RZ_INTERPRETER_YIELD_KIND_CALL_CANDIDATE,
|
||||
.init = init,
|
||||
.reset = reset,
|
||||
.fini = fini,
|
||||
.eval = eval,
|
||||
.successors = successors,
|
||||
.init_state = init_state,
|
||||
.reset_state = reset_state,
|
||||
.fini_state = fini_state,
|
||||
.hash_state = hash_state,
|
||||
.set_pc = set_pc,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue