diff --git a/libr/anal/esil_cfg.c b/libr/anal/esil_cfg.c index dd26e5b78c98e..e5c5e9642c87b 100644 --- a/libr/anal/esil_cfg.c +++ b/libr/anal/esil_cfg.c @@ -85,7 +85,7 @@ static void esil_expr_atomize(RIDStorage *atoms, char *expr) { } static void _free_bb_cb(void *data) { - REsilBB *bb = (REsilBB *)data; + RAnalEsilBB *bb = (RAnalEsilBB *)data; free (bb->expr); free (bb); } @@ -93,14 +93,14 @@ static void _free_bb_cb(void *data) { // REMINDER: generating the block content needs to prepend setting the program counter // r_anal_esil_cfg_op does this ^, use it whenever generating cfg from op -// this nasty function is an insert-compare for RGraphNodes that contain REsilBB +// this nasty function is an insert-compare for RGraphNodes that contain RAnalEsilBB static int _graphnode_esilbb_insert_cmp(void *incoming, void *in, void *user) { RGraphNode *incoming_gnode = (RGraphNode *)incoming; RGraphNode *in_gnode = (RGraphNode *)in; - REsilBB *incoming_bb = (REsilBB *)incoming_gnode->data; - REsilBB *in_bb = (REsilBB *)in_gnode->data; + RAnalEsilBB *incoming_bb = (RAnalEsilBB *)incoming_gnode->data; + RAnalEsilBB *in_bb = (RAnalEsilBB *)in_gnode->data; - // REsilBBs have the nice property, that they cannot intersect, + // RAnalEsilBBs have the nice property, that they cannot intersect, // so just comparing first and first should be fine for inserting #if 0 return incoming_bb->first - in_bb->first; @@ -118,9 +118,9 @@ static int _graphnode_esilbb_insert_cmp(void *incoming, void *in, void *user) { } static int _graphnode_esilbb_find_cmp(void *incoming, void *in, void *user) { - REsilEOffset *find_me = (REsilEOffset *)incoming; + RAnalEsilEOffset *find_me = (RAnalEsilEOffset *)incoming; RGraphNode *in_gnode = (RGraphNode *)in; - REsilBB *in_bb = (REsilBB *)in_gnode->data; + RAnalEsilBB *in_bb = (RAnalEsilBB *)in_gnode->data; // not sure if this is needed that way if (find_me->off < in_bb->first.off) { return -1; @@ -140,7 +140,7 @@ static int _graphnode_esilbb_find_cmp(void *incoming, void *in, void *user) { static int _graphnode_delete_always_0_cmp(void *incoming, void *in, void *user) { EsilCfgGen *gen = (EsilCfgGen *)user; RGraphNode *delete_me = (RGraphNode *)in; - REsilBB *delete_me_bb = (REsilBB *)delete_me->data; + RAnalEsilBB *delete_me_bb = (RAnalEsilBB *)delete_me->data; r_graph_del_node (gen->cfg->g, delete_me); ut32 id; for (id = delete_me_bb->first.idx; id <= delete_me_bb->last.idx; id++) { @@ -157,13 +157,13 @@ void _handle_if_enter (EsilCfgGen *gen, ut32 id, const bool has_next) { EsilCfgScopeCookie *cookie = R_NEW0 (EsilCfgScopeCookie); // get current bb - // REsilBB *bb = (REsilBB *)gen->cur->data; + // RAnalEsilBB *bb = (RAnalEsilBB *)gen->cur->data; // create if-enter-bb - REsilBB *entered_bb = R_NEW0 (REsilBB); + RAnalEsilBB *entered_bb = R_NEW0 (RAnalEsilBB); entered_bb->first.off = entered_bb->last.off = gen->off; entered_bb->first.idx = entered_bb->last.idx = id + 1; - entered_bb->enter = R_ESIL_BLOCK_ENTER_TRUE; + entered_bb->enter = R_ANAL_ESIL_BLOCK_ENTER_TRUE; // create if-entered-graph-node RGraphNode *entered_node = r_graph_add_node (gen->cfg->g, entered_bb); @@ -188,7 +188,7 @@ void _handle_else_enter (EsilCfgGen *gen, ut32 id, const bool has_next) { EsilCfgScopeCookie *cookie = (EsilCfgScopeCookie *)r_stack_peek (gen->ifelse); // create if-enter-bb - REsilBB *entered_bb = R_NEW0 (REsilBB); + RAnalEsilBB *entered_bb = R_NEW0 (RAnalEsilBB); entered_bb->first.off = entered_bb->last.off = gen->off; entered_bb->first.idx = entered_bb->last.idx = id + 1; @@ -198,13 +198,13 @@ void _handle_else_enter (EsilCfgGen *gen, ut32 id, const bool has_next) { r_crbtree_insert (gen->blocks, entered_node, _graphnode_esilbb_insert_cmp, NULL); if (cookie->is_else) { - entered_bb->enter = R_ESIL_BLOCK_ENTER_TRUE; + entered_bb->enter = R_ANAL_ESIL_BLOCK_ENTER_TRUE; r_graph_add_edge (gen->cfg->g, cookie->if_block, entered_node); cookie->if_block = entered_node; cookie->else_block = gen->cur; cookie->is_else = false; } else { - entered_bb->enter = R_ESIL_BLOCK_ENTER_FALSE; + entered_bb->enter = R_ANAL_ESIL_BLOCK_ENTER_FALSE; r_graph_add_edge (gen->cfg->g, cookie->else_block, entered_node); cookie->else_block = entered_node; cookie->if_block = gen->cur; @@ -220,12 +220,12 @@ void _handle_fi_leave(EsilCfgGen *gen, ut32 id, const bool has_next) { return; } - REsilBB *cur_bb = (REsilBB *)gen->cur->data; + RAnalEsilBB *cur_bb = (RAnalEsilBB *)gen->cur->data; // this block is not executed when the if or else block is empty - if (memcmp (&cur_bb->first, &cur_bb->last, sizeof (REsilEOffset))) { + if (memcmp (&cur_bb->first, &cur_bb->last, sizeof (RAnalEsilEOffset))) { // TODO: add some thoughts in comments here cur_bb->last.idx--; - REsilBB *leaving_bb = R_NEW0 (REsilBB); + RAnalEsilBB *leaving_bb = R_NEW0 (RAnalEsilBB); leaving_bb->first.off = leaving_bb->last.off = gen->off; leaving_bb->first.idx = leaving_bb->last.idx = id; RGraphNode *leaving_node = r_graph_add_node (gen->cfg->g, leaving_bb); @@ -261,7 +261,7 @@ void _handle_control_flow_ifelsefi (EsilCfgGen *gen, char *atom, ut32 id) { bool _round_0_cb (void *user, void *data, ut32 id) { EsilCfgGen *gen = (EsilCfgGen *)user; char *atom = (char *)data; - REsilBB *bb = (REsilBB *)gen->cur->data; + RAnalEsilBB *bb = (RAnalEsilBB *)gen->cur->data; REsilOp *op = esil_get_op (gen->esil, atom); bb->last.idx = (ut16)id; if (op && op->type == R_ESIL_OP_TYPE_CONTROL_FLOW) { @@ -271,11 +271,11 @@ bool _round_0_cb (void *user, void *data, ut32 id) { } RGraphNode *_common_break_goto (EsilCfgGen *gen, ut32 id) { - REsilEOffset off = { gen->off, (ut16)id }; + RAnalEsilEOffset off = { gen->off, (ut16)id }; RGraphNode *gnode = r_crbtree_find (gen->blocks, &off, _graphnode_esilbb_find_cmp, NULL); - REsilBB *bb = (REsilBB *)gnode->data; + RAnalEsilBB *bb = (RAnalEsilBB *)gnode->data; if (id != bb->last.idx) { - REsilBB *next_bb = R_NEW0 (REsilBB); + RAnalEsilBB *next_bb = R_NEW0 (RAnalEsilBB); // split blocks next_bb->first.off = gen->off; next_bb->first.idx = id + 1; @@ -302,7 +302,7 @@ void _handle_break (EsilCfgGen *gen, ut32 id) { void _handle_goto (EsilCfgGen *gen, ut32 idx) { RGraphNode *gnode = _common_break_goto (gen, idx); - REsilBB *bb = (REsilBB *)gnode->data; + RAnalEsilBB *bb = (RAnalEsilBB *)gnode->data; // so what we're doing here is emulating this block with a certain degree of abstraction: // no reg-access // no io-access @@ -348,16 +348,16 @@ void _handle_goto (EsilCfgGen *gen, ut32 idx) { } // get the node to the corresponding GOTO destination - REsilEOffset dst_off = { gen->off, (ut16)v->val }; + RAnalEsilEOffset dst_off = { gen->off, (ut16)v->val }; RGraphNode *dst_node = r_crbtree_find (gen->blocks, &dst_off, _graphnode_esilbb_find_cmp, NULL); if (!dst_node) { // out-of-bounds // check if this works dst_node = gen->cfg->end; } else { - REsilBB *dst_bb = (REsilBB *)dst_node->data; + RAnalEsilBB *dst_bb = (RAnalEsilBB *)dst_node->data; if (dst_bb->first.idx != v->val) { - REsilBB *split_bb = R_NEW0 (REsilBB); + RAnalEsilBB *split_bb = R_NEW0 (RAnalEsilBB); split_bb[0] = dst_bb[0]; dst_bb->last.idx = v->val - 1; split_bb->first.idx = v->val; @@ -390,7 +390,7 @@ bool _round_1_cb(void *user, void *data, ut32 id) { } void _round_2_cb (RGraphNode *n, RGraphVisitor *vi) { - REsilBB *bb = (REsilBB *)n->data; + RAnalEsilBB *bb = (RAnalEsilBB *)n->data; EsilCfgGen *gen = (EsilCfgGen *)vi->data; RStrBuf *buf = r_strbuf_new (n == gen->cfg->end ? NULL: (char *)r_id_storage_get (gen->atoms, bb->first.idx)); r_strbuf_append (buf, ","); @@ -417,7 +417,7 @@ static RAnalEsilCFG *esil_cfg_gen(RAnalEsilCFG *cfg, RAnal *anal, RIDStorage *at if (!_expr) { return cfg; //NULL? } - REsilBB *end_bb = R_NEW0 (REsilBB); + RAnalEsilBB *end_bb = R_NEW0 (RAnalEsilBB); if (!end_bb) { free (_expr); return cfg; @@ -441,7 +441,7 @@ static RAnalEsilCFG *esil_cfg_gen(RAnalEsilCFG *cfg, RAnal *anal, RIDStorage *at // // without information about the outside cfg, we CANNOT merge cpu-instructions - REsilBB *bb = (REsilBB *)cfg->end->data; + RAnalEsilBB *bb = (RAnalEsilBB *)cfg->end->data; end_bb->expr = bb->expr; // FIXME: use end_bb here @@ -500,7 +500,7 @@ static RAnalEsilCFG *esil_cfg_gen(RAnalEsilCFG *cfg, RAnal *anal, RIDStorage *at R_IPI RAnalEsilCFG *r_anal_esil_cfg_new(void) { RAnalEsilCFG *cf = R_NEW0 (RAnalEsilCFG); if (cf) { - REsilBB *p = R_NEW0 (REsilBB); + RAnalEsilBB *p = R_NEW0 (RAnalEsilBB); if (!p) { free (cf); return NULL; @@ -576,7 +576,7 @@ R_API RAnalEsilCFG *r_anal_esil_cfg_op(R_NULLABLE RAnalEsilCFG *cfg, RAnal *anal if (!anal->reg || !anal->esil) { return NULL; } - REsilBB *glue_bb = R_NEW0 (REsilBB); + RAnalEsilBB *glue_bb = R_NEW0 (RAnalEsilBB); if (!glue_bb) { return NULL; } @@ -593,7 +593,7 @@ R_API RAnalEsilCFG *r_anal_esil_cfg_op(R_NULLABLE RAnalEsilCFG *cfg, RAnal *anal free (glue_bb); return NULL; } - glue_bb->enter = R_ESIL_BLOCK_ENTER_GLUE; + glue_bb->enter = R_ANAL_ESIL_BLOCK_ENTER_GLUE; glue_bb->first.off = glue_bb->last.off = op->addr; glue_bb->first.idx = glue_bb->last.idx = 0; @@ -630,12 +630,13 @@ static void merge_2_blocks(RAnalEsilCFG *cfg, RGraphNode *node, RGraphNode *bloc r_list_foreach (block->in_nodes, iter, n) { r_graph_add_edge (cfg->g, n, node); } - REsilBB *block_bb, *node_bb = (REsilBB *)node->data; - block_bb = (REsilBB *)block->data; - if ((block_bb->enter == R_ESIL_BLOCK_ENTER_TRUE) || (block_bb->enter == R_ESIL_BLOCK_ENTER_FALSE)) { + RAnalEsilBB *block_bb, *node_bb = (RAnalEsilBB *)node->data; + block_bb = (RAnalEsilBB *)block->data; + if ((block_bb->enter == R_ANAL_ESIL_BLOCK_ENTER_TRUE) || + (block_bb->enter == R_ANAL_ESIL_BLOCK_ENTER_FALSE)) { node_bb->enter = block_bb->enter; } else { - node_bb->enter = R_ESIL_BLOCK_ENTER_NORMAL; + node_bb->enter = R_ANAL_ESIL_BLOCK_ENTER_NORMAL; } RStrBuf *buf = r_strbuf_new (block_bb->expr); node_bb->first = block_bb->first; @@ -657,10 +658,11 @@ R_API void r_anal_esil_cfg_merge_blocks(RAnalEsilCFG *cfg) { RGraphNode *node; r_list_foreach_safe (cfg->g->nodes, iter, ator, node) { if (r_list_length (node->in_nodes) == 1) { - REsilBB *bb = (REsilBB *)node->data; + RAnalEsilBB *bb = (RAnalEsilBB *)node->data; RGraphNode *top = (RGraphNode *)r_list_last (node->out_nodes); // segfaults here ? - if (!(top && bb->enter == R_ESIL_BLOCK_ENTER_GLUE && (r_list_length (top->in_nodes) > 1))) { + if (!(top && bb->enter == R_ANAL_ESIL_BLOCK_ENTER_GLUE && + (r_list_length (top->in_nodes) > 1))) { RGraphNode *block = (RGraphNode *)r_list_last (node->in_nodes); if (r_list_length (block->out_nodes) == 1) { merge_2_blocks (cfg, node, block); diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index 7915e089bda5b..12529c04e4f78 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -721,6 +721,26 @@ typedef struct r_anal_esil_cfg_t { RGraph *g; } RAnalEsilCFG; +// this is 80-bit offsets so we can address every piece of esil in an instruction +typedef struct r_anal_esil_expr_offset_t { + ut64 off; + ut16 idx; +} RAnalEsilEOffset; + +typedef enum { + R_ANAL_ESIL_BLOCK_ENTER_NORMAL = 0, + R_ANAL_ESIL_BLOCK_ENTER_TRUE, + R_ANAL_ESIL_BLOCK_ENTER_FALSE, + R_ANAL_ESIL_BLOCK_ENTER_GLUE, +} RAnalEsilBlockEnterType; + +typedef struct r_anal_esil_basic_block_t { + RAnalEsilEOffset first; + RAnalEsilEOffset last; + char *expr; //synthesized esil-expression for this block + RAnalEsilBlockEnterType enter; //maybe more type is needed here +} RAnalEsilBB; + enum { R_ANAL_ESIL_DFG_TAG_CONST = 1, R_ANAL_ESIL_DFG_TAG_VAR = 2, diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index d2962fe142179..3bc6cafcfe714 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -36,26 +36,6 @@ enum { R_ESIL_OP_TYPE_TRAP = 0x100 // syscall, interrupts, breakpoints, ... }; -// this is 80-bit offsets so we can address every piece of esil in an instruction -typedef struct r_esil_expr_offset_t { - ut64 off; - ut16 idx; -} REsilEOffset; - -typedef enum { - R_ESIL_BLOCK_ENTER_NORMAL = 0, - R_ESIL_BLOCK_ENTER_TRUE, - R_ESIL_BLOCK_ENTER_FALSE, - R_ESIL_BLOCK_ENTER_GLUE, -} REsilBlockEnterType; - -typedef struct r_esil_basic_block_t { - REsilEOffset first; - REsilEOffset last; - char *expr; //synthesized esil-expression for this block - REsilBlockEnterType enter; //maybe more type is needed here -} REsilBB; - typedef struct r_esil_t ESIL; typedef bool (*REsilHandlerCB)(ESIL *esil, ut32 h, void *user);