diff --git a/handwritten/asm_hexagon_c/initialization.c b/handwritten/asm_hexagon_c/initialization.c index bf26da49..a816d3c0 100644 --- a/handwritten/asm_hexagon_c/initialization.c +++ b/handwritten/asm_hexagon_c/initialization.c @@ -2,25 +2,20 @@ // SPDX-License-Identifier: LGPL-3.0-only static RZ_OWN RzPVector /**/ *get_token_patterns() { - static RzPVector *pvec = NULL; - if (pvec) { - return pvec; - } - - pvec = rz_pvector_new(rz_asm_token_pattern_free); + RzPVector *pvec = rz_pvector_new(rz_asm_token_pattern_free); RzAsmTokenPattern *pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_META; pat->pattern = strdup( - "^[\\[\\?\\/\\|\\\\\\{┌│└]|" // Packet prefix - "(∎|[<\\}])[\\s:]endloop[01]{1,2}" // Endloop markers + "(^[\\[\\?\\/\\|\\\\\\{])|(┌)|(│)|(└)|" // Packet prefix + "((∎)|[<\\}])([ :])(endloop[01]{1,2})" // Endloop markers ); rz_pvector_push(pvec, pat); pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_META; pat->pattern = strdup( - "\\#{1,2}|\\}$|" // Immediate prefix, Closing packet bracket + "(#{1,2})|(\\}$)|" // Immediate prefix, Closing packet bracket "\\.new|:n?t|:raw|" // .new and jump hints ); rz_pvector_push(pvec, pat); @@ -28,7 +23,7 @@ static RZ_OWN RzPVector /**/ *get_token_patterns() { pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_REGISTER; pat->pattern = strdup( - "[CNPRMQVO]\\d{1,2}(:\\d{1,2})?(in)?" // Registers and double registers + "([CNPRMQVO][[:digit:]]{1,2}(:[[:digit:]]{1,2})?(in)?)" // Registers and double registers ); rz_pvector_push(pvec, pat); @@ -42,74 +37,57 @@ static RZ_OWN RzPVector /**/ *get_token_patterns() { pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_NUMBER; pat->pattern = strdup( - "0x(\\d|[abcdef])+" // Hexadecimal numbers + "(0x[[:digit:]abcdef]+)" // Hexadecimal numbers ); rz_pvector_push(pvec, pat); pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_MNEMONIC; pat->pattern = strdup( - "[a-zA-Z]+\\d+[a-zA-Z]*" // Mnemonics with a decimal number in the name. + "([[:alpha:]]+[[:digit:]]+[[:alpha:]]*)" // Mnemonics with a decimal number in the name. ); rz_pvector_push(pvec, pat); pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_NUMBER; pat->pattern = strdup( - "\\d+" // Decimal numbers + "([[:digit:]]+)" // Decimal numbers ); rz_pvector_push(pvec, pat); pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_SEPARATOR; pat->pattern = strdup( - "\\s+|" // Spaces and tabs - "[,;\\.\\(\\)\\{\\}:]" // Brackets and others + "([[:blank:]]+)|" // Spaces and tabs + "([,;\\.\\(\\)\\{\\}:])" // Brackets and others ); rz_pvector_push(pvec, pat); pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_OPERATOR; pat->pattern = strdup( - "[\\+=!-]" // +,-,=,],[, ! (not the packet prefix) + "(\\+)|([*&+-\\&^/]?=)|(!)|(-)" // +,-,=,],[, ! (not the packet prefix) ); rz_pvector_push(pvec, pat); pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_OPERATOR; pat->pattern = strdup( - "\\]|\\[|<{1,2}|>{1,2}" // +,-,=,],[, ! (not the packet prefix) + "(\\])|(\\[|<{1,2}|>{1,2})" // +,-,=,],[, ! (not the packet prefix) ); rz_pvector_push(pvec, pat); pat = RZ_NEW0(RzAsmTokenPattern); pat->type = RZ_ASM_TOKEN_MNEMONIC; pat->pattern = strdup( - "\\w+_\\w+|" // Mnemonics with "_" e.g dealloc_return - "\\w+" // Alphanumeric mnemonics + "([[:alnum:]]+)|" // Alphanumeric mnemonics + "([[:alnum:]]+_[[:alnum:]]+)" // Menmonics with "_" e.g dealloc_return ); rz_pvector_push(pvec, pat); return pvec; } -static void compile_token_patterns(RZ_INOUT RzPVector /**/ *patterns) { - rz_return_if_fail(patterns); - - void **it; - rz_pvector_foreach (patterns, it) { - RzAsmTokenPattern *pat = *it; - if (pat->regex) { - continue; - } - pat->regex = rz_regex_new(pat->pattern, "e"); - if (!pat->regex) { - RZ_LOG_WARN("Did not compile regex pattern %s.\n", pat->pattern); - rz_warn_if_reached(); - } - } -} - /** * \brief Setter for the plugins RzConfig nodes. * @@ -121,7 +99,7 @@ static void compile_token_patterns(RZ_INOUT RzPVector /**/ */ static bool hex_cfg_set(void *user, void *data) { rz_return_val_if_fail(user && data, false); - HexState *state = hexagon_get_state(); + HexState *state = hexagon_state(false); if (!state) { return false; } @@ -140,11 +118,26 @@ static bool hex_cfg_set(void *user, void *data) { return false; } +RZ_IPI void hexagon_state_fini(HexState *state) { + if (!state) { + return; + } + rz_config_free(state->cfg); + rz_pvector_free(state->token_patterns); + rz_list_free(state->const_ext_l); + return; +} + +static bool hexagon_fini(void *user) { + hexagon_state_fini(hexagon_state(false)); + hexagon_state(true); + return true; +} + static bool hexagon_init(void **user) { - HexState *state = hexagon_get_state(); + HexState *state = hexagon_state(false); rz_return_val_if_fail(state, false); - *user = state; // user = RzAsm.plugin_data state->cfg = rz_config_new(state); rz_return_val_if_fail(state->cfg, false); @@ -155,14 +148,16 @@ static bool hexagon_init(void **user) { SETCB("plugins.hexagon.sdk", "false", &hex_cfg_set, "Print packet syntax in objdump style."); SETCB("plugins.hexagon.reg.alias", "true", &hex_cfg_set, "Print the alias of registers (Alias from C0 = SA0)."); - state->token_patterns = get_token_patterns(); - compile_token_patterns(state->token_patterns); + if (!state->token_patterns) { + state->token_patterns = get_token_patterns(); + } + rz_asm_compile_token_patterns(state->token_patterns); return true; } RZ_API RZ_BORROW RzConfig *hexagon_get_config() { - HexState *state = hexagon_get_state(); + HexState *state = hexagon_state(false); rz_return_val_if_fail(state, NULL); return state->cfg; } @@ -209,6 +204,7 @@ RzAsmPlugin rz_asm_plugin_hexagon = { .bits = 32, .desc = "Qualcomm Hexagon (QDSP6) V6", .init = &hexagon_init, + .fini = &hexagon_fini, .disassemble = &disassemble, .get_config = &hexagon_get_config, }; diff --git a/handwritten/hexagon_arch_c/functions.c b/handwritten/hexagon_arch_c/functions.c index 381e3ddc..520ab384 100644 --- a/handwritten/hexagon_arch_c/functions.c +++ b/handwritten/hexagon_arch_c/functions.c @@ -197,7 +197,7 @@ static void hex_clear_pkt(RZ_NONNULL HexPkt *p) { p->is_valid = false; p->last_access = 0; rz_list_purge(p->bin); - rz_vector_clear(p->il_ops); + rz_pvector_clear(p->il_ops); } /** @@ -259,7 +259,7 @@ RZ_API void hex_insn_free(RZ_NULLABLE HexInsn *i) { */ RZ_API void hex_insn_container_free(RZ_NULLABLE HexInsnContainer *c) { if (c) { - // bin is a union. Just free all of them. + // bin is a uninion. Just free all of them. hex_insn_free(c->bin.sub[0]); hex_insn_free(c->bin.sub[1]); } @@ -306,11 +306,19 @@ static ut8 get_state_pkt_index(HexState *state, const HexPkt *p) { /** * \brief Initializes each packet of the state once. + * Note that this state is not thread safe. + * It requires RzArch for this. * - * \return The initialized state of the plugins. + * \param reset Reset the state to NULL. Assumes it was freed before. + * + * \return The initialized state of the plugins or NULL if \p reset = true. */ -RZ_API HexState *hexagon_get_state() { +RZ_API HexState *hexagon_state(bool reset) { static HexState *state = NULL; + if (reset) { + state = NULL; + return NULL; + } if (state) { return state; } @@ -321,13 +329,14 @@ RZ_API HexState *hexagon_get_state() { } for (int i = 0; i < HEXAGON_STATE_PKTS; ++i) { state->pkts[i].bin = rz_list_newf((RzListFree)hex_insn_container_free); - state->pkts[i].il_ops = rz_vector_new(sizeof(HexILOp), NULL, NULL); + state->pkts[i].il_ops = rz_pvector_new(NULL); if (!state->pkts[i].bin) { RZ_LOG_FATAL("Could not initialize instruction list!"); } hex_clear_pkt(&(state->pkts[i])); } state->const_ext_l = rz_list_newf((RzListFree)hex_const_ext_free); + state->token_patterns = NULL; return state; } @@ -483,7 +492,7 @@ static void hex_set_pkt_info(const RzAsm *rz_asm, RZ_INOUT HexInsnContainer *hic rz_return_if_fail(hic && pkt); bool is_first = (k == 0); HexPktInfo *hi_pi = &hic->pkt_info; - HexState *state = hexagon_get_state(); + HexState *state = hexagon_state(false); bool sdk_form = rz_config_get_b(state->cfg, "plugins.hexagon.sdk"); strncpy(hi_pi->text_postfix, "", 16); @@ -1018,17 +1027,13 @@ static void copy_asm_ana_ops(const HexState *state, RZ_BORROW HexReversedOpcode memcpy(rz_reverse->ana_op, &hic->ana_op, sizeof(RzAnalysisOp)); rz_strbuf_set(&rz_reverse->asm_op->buf_asm, hic->text); rz_reverse->asm_op->asm_toks = rz_asm_tokenize_asm_regex(&rz_reverse->asm_op->buf_asm, state->token_patterns); - if (rz_reverse->asm_op->asm_toks) { - rz_reverse->asm_op->asm_toks->op_type = hic->ana_op.type; - } + rz_reverse->asm_op->asm_toks->op_type = hic->ana_op.type; break; case HEXAGON_DISAS: memcpy(rz_reverse->asm_op, &hic->asm_op, sizeof(RzAsmOp)); rz_strbuf_set(&rz_reverse->asm_op->buf_asm, hic->text); rz_reverse->asm_op->asm_toks = rz_asm_tokenize_asm_regex(&rz_reverse->asm_op->buf_asm, state->token_patterns); - if (rz_reverse->asm_op->asm_toks) { - rz_reverse->asm_op->asm_toks->op_type = hic->ana_op.type; - } + rz_reverse->asm_op->asm_toks->op_type = hic->ana_op.type; break; case HEXAGON_ANALYSIS: memcpy(rz_reverse->ana_op, &hic->ana_op, sizeof(RzAnalysisOp)); @@ -1046,7 +1051,7 @@ static void copy_asm_ana_ops(const HexState *state, RZ_BORROW HexReversedOpcode * \param copy_result If set, it copies the result. Otherwise it only buffers it in the internal state. */ RZ_API void hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_reverse, const ut8 *buf, const ut64 addr, const bool copy_result) { - HexState *state = hexagon_get_state(); + HexState *state = hexagon_state(false); if (!state) { RZ_LOG_FATAL("HexState was NULL."); } diff --git a/handwritten/hexagon_h/typedefs.h b/handwritten/hexagon_h/typedefs.h index ebf2fa0a..c2969e41 100644 --- a/handwritten/hexagon_h/typedefs.h +++ b/handwritten/hexagon_h/typedefs.h @@ -190,7 +190,7 @@ typedef struct { ut32 pkt_addr; ///< Address of the packet. Equals the address of the first instruction. ut64 last_access; ///< Last time accessed in milliseconds RzList /**/ *bin; ///< Descending by address sorted list of instruction containers. - RzVector /**/ *il_ops; ///< Pointer to RZIL ops of the packet. If empty the il ops were not shuffled into order yet. + RzPVector /**/ *il_ops; ///< Pointer to RZIL ops of the packet. If empty the il ops were not shuffled into order yet. HexILExecData il_op_stats; ///< Meta information about the IL operations executed (register read/written etc.) } HexPkt; diff --git a/handwritten/hexagon_il_X_ops_c/non_insn_ops.c b/handwritten/hexagon_il_X_ops_c/non_insn_ops.c index 90d4dea8..4a7f38e2 100644 --- a/handwritten/hexagon_il_X_ops_c/non_insn_ops.c +++ b/handwritten/hexagon_il_X_ops_c/non_insn_ops.c @@ -46,22 +46,22 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_get_npc(const HexPkt *pkt) { } static void reset_pkt_stats(HexILExecData *stats) { - stats->ctr_written = 0; - stats->gpr_written = 0; - stats->pred_written = 0; - stats->ctr_read = 0; - stats->gpr_read = 0; - stats->pred_read = 0; - stats->ctr_tmp_read = 0; - stats->gpr_tmp_read = 0; - stats->pred_tmp_read = 0; + rz_bits_map_init_64(&stats->ctr_written); + rz_bits_map_init_64(&stats->gpr_written); + rz_bits_map_init_32(&stats->pred_written); + rz_bits_map_init_64(&stats->ctr_read); + rz_bits_map_init_64(&stats->gpr_read); + rz_bits_map_init_32(&stats->pred_read); + rz_bits_map_init_64(&stats->ctr_tmp_read); + rz_bits_map_init_64(&stats->gpr_tmp_read); + rz_bits_map_init_32(&stats->pred_tmp_read); } RZ_IPI RZ_OWN RzILOpEffect *hex_commit_packet(HexInsnPktBundle *bundle) { HexILExecData *stats = &bundle->pkt->il_op_stats; RzILOpEffect *commit_seq = EMPTY(); for (ut8 i = 0; i <= HEX_REG_CTR_REGS_C31; ++i) { - if (!(stats->ctr_written & (1 << i))) { + if (!(rz_bits_map_get_64(&stats->ctr_written, i))) { continue; } const char *dest_reg = hex_get_reg_in_class(HEX_REG_CLASS_CTR_REGS, i, false, false, false); @@ -70,7 +70,7 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_commit_packet(HexInsnPktBundle *bundle) { } for (ut8 i = 0; i <= HEX_REG_INT_REGS_R31; ++i) { - if (!(stats->gpr_written & (1 << i))) { + if (!(rz_bits_map_get_64(&stats->gpr_written, i))) { continue; } const char *dest_reg = hex_get_reg_in_class(HEX_REG_CLASS_INT_REGS, i, false, false, false); @@ -79,7 +79,7 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_commit_packet(HexInsnPktBundle *bundle) { } for (ut8 i = 0; i <= HEX_REG_PRED_REGS_P3; ++i) { - if (!(stats->pred_written & (1 << i))) { + if (!(rz_bits_map_get_32(&stats->pred_written, i))) { continue; } const char *dest_reg = hex_get_reg_in_class(HEX_REG_CLASS_PRED_REGS, i, false, false, false); @@ -97,9 +97,10 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_il_op_jump_flag_init(HexInsnPktBundle *bundle) { RZ_IPI RZ_OWN RzILOpEffect *hex_il_op_next_pkt_jmp(HexInsnPktBundle *bundle) { bool has_direct_jump = false; - HexILOp *it; - rz_vector_foreach(bundle->pkt->il_ops, it) { - if (it->attr & HEX_IL_INSN_ATTR_BRANCH && !(it->attr & HEX_IL_INSN_ATTR_COND)) { + void **it; + rz_pvector_foreach (bundle->pkt->il_ops, it) { + HexILOp *op = *it; + if (op->attr & HEX_IL_INSN_ATTR_BRANCH && !(op->attr & HEX_IL_INSN_ATTR_COND)) { has_direct_jump = true; } } @@ -109,3 +110,4 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_il_op_next_pkt_jmp(HexInsnPktBundle *bundle) { } return EMPTY(); } + diff --git a/handwritten/hexagon_il_c/functions.c b/handwritten/hexagon_il_c/functions.c index f87648f8..408b9ef2 100644 --- a/handwritten/hexagon_il_c/functions.c +++ b/handwritten/hexagon_il_c/functions.c @@ -1,6 +1,36 @@ // SPDX-FileCopyrightText: 2022 Rot127 // SPDX-License-Identifier: LGPL-3.0-only +static HexILOp hex_jump_flag_init_op = { + .attr = HEX_IL_INSN_ATTR_NONE, + .get_il_op = (HexILOpGetter)hex_il_op_jump_flag_init, +}; + +static HexILOp hex_next_jump_to_next_pkt = { + .attr = HEX_IL_INSN_ATTR_BRANCH | HEX_IL_INSN_ATTR_COND, + .get_il_op = (HexILOpGetter)hex_il_op_next_pkt_jmp, +}; + +static HexILOp hex_pkt_commit = { + .attr = HEX_IL_INSN_ATTR_NONE, + .get_il_op = (HexILOpGetter)hex_commit_packet, +}; + +static HexILOp hex_endloop0_op = { + .attr = HEX_IL_INSN_ATTR_BRANCH | HEX_IL_INSN_ATTR_COND, + .get_il_op = (HexILOpGetter)hex_il_op_j2_endloop0, +}; + +static HexILOp hex_endloop1_op = { + .attr = HEX_IL_INSN_ATTR_BRANCH | HEX_IL_INSN_ATTR_COND, + .get_il_op = (HexILOpGetter)hex_il_op_j2_endloop1, +}; + +static HexILOp hex_endloop01_op = { + .attr = HEX_IL_INSN_ATTR_BRANCH | HEX_IL_INSN_ATTR_COND, + .get_il_op = (HexILOpGetter)hex_il_op_j2_endloop01, +}; + /** * \brief Sends the IL op at \p start to the position \p newloc. * @@ -11,7 +41,7 @@ * \param start Index of the op to move. * \param newloc Position the op shall be moved to. */ -static void hex_send_insn_to_i(RzVector /**/ *ops, ut8 start, ut8 newloc) { +static void hex_send_insn_to_i(RzPVector /**/ *ops, ut8 start, ut8 newloc) { rz_return_if_fail(ops); st32 direction; @@ -26,11 +56,9 @@ static void hex_send_insn_to_i(RzVector /**/ *ops, ut8 start, ut8 newlo /* move towards beginning */ direction = -1; } - HexILOp tmp_op; for (i = start; i != newloc; i += direction) { - memcpy(&tmp_op, rz_vector_index_ptr(ops, i), sizeof(HexILOp)); - rz_vector_assign_at(ops, i, rz_vector_index_ptr(ops, i + direction)); - rz_vector_assign_at(ops, i + direction, &tmp_op); + HexILOp *tmp_op = *rz_pvector_assign_at(ops, i, (HexILOp *)*rz_pvector_index_ptr(ops, i + direction)); + rz_pvector_assign_at(ops, i + direction, tmp_op); } } @@ -55,18 +83,18 @@ RZ_IPI bool hex_shuffle_insns(RZ_INOUT HexPkt *p) { // Incomplete packets cannot be executed. return false; } - if (rz_vector_empty(p->il_ops)) { + if (rz_pvector_empty(p->il_ops)) { RZ_LOG_WARN("Valid packet without RZIL instructions encountered! pkt addr = 0x%" PFMT32x "\n", p->pkt_addr); return false; } - RzVector *ops = p->il_ops; + RzPVector *ops = p->il_ops; // Do the shuffle bool changed = false; int i; bool flag; /* flag means we've seen a non-memory instruction */ int n_mems; /* Number of memory instructions passed */ - int last_insn = rz_vector_len(p->il_ops) - 1; + int last_insn = rz_pvector_len(p->il_ops) - 1; HexILOp *op; do { @@ -81,7 +109,7 @@ RZ_IPI bool hex_shuffle_insns(RZ_INOUT HexPkt *p) { n_mems = 0; flag = false; for (flag = false, n_mems = 0, i = last_insn; i >= 0; i--) { - op = rz_vector_index_ptr(ops, i); + op = (HexILOp *)*rz_pvector_index_ptr(ops, i); if (!op) { RZ_LOG_FATAL("NULL il op at index %" PFMT32d "\n", i); } @@ -112,7 +140,7 @@ RZ_IPI bool hex_shuffle_insns(RZ_INOUT HexPkt *p) { /* Comparisons go first, may be reordered with regard to each other */ for (flag = false, i = 0; i < last_insn + 1; i++) { - op = rz_vector_index_ptr(ops, i); + op = (HexILOp *)*rz_pvector_index_ptr(ops, i); if ((op->attr & HEX_IL_INSN_ATTR_WPRED) && (op->attr & HEX_IL_INSN_ATTR_MEM_WRITE)) { /* This should be a comparison (not a store conditional) */ @@ -149,7 +177,7 @@ RZ_IPI bool hex_shuffle_insns(RZ_INOUT HexPkt *p) { * very end, past stores */ for (i = 0; i < last_insn; i++) { - op = rz_vector_index_ptr(ops, i); + op = (HexILOp *)*rz_pvector_index_ptr(ops, i); if (op->attr & HEX_IL_INSN_ATTR_NEW) { hex_send_insn_to_i(ops, i, last_insn); break; @@ -175,16 +203,16 @@ static RzILOpEffect *hex_il_op_to_effect(const HexILOp *il_op, HexPkt *pkt) { static RZ_OWN RzILOpEffect *hex_pkt_to_il_seq(HexPkt *pkt) { rz_return_val_if_fail(pkt && pkt->il_ops, NULL); - if (rz_vector_len(pkt->il_ops) == 1) { + if (rz_pvector_len(pkt->il_ops) == 1) { + rz_pvector_clear(pkt->il_ops); // We need at least the instruction op and the packet commit. // So if there aren't at least two ops something went wrong. - rz_vector_clear(pkt->il_ops); RZ_LOG_WARN("Invalid il ops sequence! There should be at least two il ops per packet.\n"); return NULL; } RzILOpEffect *complete_seq = EMPTY(); - for (ut32 i = 0; i < rz_vector_len(pkt->il_ops); ++i) { - complete_seq = SEQ2(complete_seq, hex_il_op_to_effect(rz_vector_index_ptr(pkt->il_ops, i), pkt)); + for (ut32 i = 0; i < rz_pvector_len(pkt->il_ops); ++i) { + complete_seq = SEQ2(complete_seq, hex_il_op_to_effect((HexILOp *)*rz_pvector_index_ptr(pkt->il_ops, i), pkt)); } return complete_seq; } @@ -209,12 +237,12 @@ static bool set_pkt_il_ops(RZ_INOUT HexPkt *p) { if (cur_il_insn->op0.attr == HEX_IL_INSN_ATTR_INVALID) { goto not_impl; } - rz_vector_push(p->il_ops, &cur_il_insn->op0); + rz_pvector_push(p->il_ops, &cur_il_insn->op0); // high sub operation 1 if (cur_il_insn->op1.attr != HEX_IL_INSN_ATTR_INVALID) { cur_il_insn->op1.hi = pos->bin.sub[0]; - rz_vector_push(p->il_ops, &cur_il_insn->op1); + rz_pvector_push(p->il_ops, &cur_il_insn->op1); } // Low sub-instructions @@ -225,12 +253,12 @@ static bool set_pkt_il_ops(RZ_INOUT HexPkt *p) { if (cur_il_insn->op0.attr == HEX_IL_INSN_ATTR_INVALID) { goto not_impl; } - rz_vector_push(p->il_ops, &cur_il_insn->op0); + rz_pvector_push(p->il_ops, &cur_il_insn->op0); // low sub operation 1 if (cur_il_insn->op1.attr != HEX_IL_INSN_ATTR_INVALID) { pos->bin.sub[1]->il_insn.op1.hi = pos->bin.sub[1]; - rz_vector_push(p->il_ops, &cur_il_insn->op1); + rz_pvector_push(p->il_ops, &cur_il_insn->op1); } } else { pos->bin.insn->il_insn = hex_il_getter_lt[pos->bin.insn->identifier]; @@ -240,11 +268,11 @@ static bool set_pkt_il_ops(RZ_INOUT HexPkt *p) { if (cur_il_insn->op0.attr == HEX_IL_INSN_ATTR_INVALID) { goto not_impl; } - rz_vector_push(p->il_ops, &cur_il_insn->op0); + rz_pvector_push(p->il_ops, &cur_il_insn->op0); // Insn operation 1 if (cur_il_insn->op1.attr != HEX_IL_INSN_ATTR_INVALID) { cur_il_insn->op1.hi = pos->bin.insn; - rz_vector_push(p->il_ops, &cur_il_insn->op1); + rz_pvector_push(p->il_ops, &cur_il_insn->op1); } } } @@ -256,8 +284,10 @@ static bool set_pkt_il_ops(RZ_INOUT HexPkt *p) { static void check_for_jumps(const HexPkt *p, RZ_OUT bool *jump_flag) { rz_return_if_fail(p && jump_flag); + void **it; HexILOp *op; - rz_vector_foreach(p->il_ops, op) { + rz_pvector_foreach (p->il_ops, it) { + op = *it; if (op->attr & HEX_IL_INSN_ATTR_BRANCH) { *jump_flag = true; } @@ -297,7 +327,7 @@ static inline bool pkt_at_addr_is_emu_ready(const HexPkt *pkt, const ut32 addr) */ RZ_IPI RzILOpEffect *hex_get_il_op(const ut32 addr, const bool get_pkt_op) { static bool might_has_jumped = false; - HexState *state = hexagon_get_state(); + HexState *state = hexagon_state(false); if (!state) { RZ_LOG_WARN("Failed to get hexagon plugin state data!\n"); return NULL; @@ -333,15 +363,12 @@ RZ_IPI RzILOpEffect *hex_get_il_op(const ut32 addr, const bool get_pkt_op) { return EMPTY(); } - if (!rz_vector_empty(p->il_ops)) { + if (!rz_pvector_empty(p->il_ops)) { check_for_jumps(p, &might_has_jumped); return hex_pkt_to_il_seq(p); } - HexILOp *op = RZ_NEW0(HexILOp); - op->attr = HEX_IL_INSN_ATTR_NONE; - op->get_il_op = (HexILOpGetter)hex_il_op_jump_flag_init; - rz_vector_push(p->il_ops, op); + rz_pvector_push(p->il_ops, &hex_jump_flag_init_op); if (!set_pkt_il_ops(p)) { RZ_LOG_INFO("IL ops at 0x%" PFMT32x " contain not implemented instructions.\n", addr); @@ -354,32 +381,16 @@ RZ_IPI RzILOpEffect *hex_get_il_op(const ut32 addr, const bool get_pkt_op) { } if (hex_get_loop_flag(p) == HEX_LOOP_0) { - op = RZ_NEW0(HexILOp); - op->attr = HEX_IL_INSN_ATTR_BRANCH | HEX_IL_INSN_ATTR_COND; - op->get_il_op = (HexILOpGetter)hex_il_op_j2_endloop0; - rz_vector_push(p->il_ops, op); + rz_pvector_push(p->il_ops, &hex_endloop0_op); } else if (hex_get_loop_flag(p) == HEX_LOOP_1) { - op = RZ_NEW0(HexILOp); - op->attr = HEX_IL_INSN_ATTR_BRANCH | HEX_IL_INSN_ATTR_COND; - op->get_il_op = (HexILOpGetter)hex_il_op_j2_endloop1; - rz_vector_push(p->il_ops, op); + rz_pvector_push(p->il_ops, &hex_endloop1_op); } else if (hex_get_loop_flag(p) == HEX_LOOP_01) { - op = RZ_NEW0(HexILOp); - op->attr = HEX_IL_INSN_ATTR_BRANCH | HEX_IL_INSN_ATTR_COND; - op->get_il_op = (HexILOpGetter)hex_il_op_j2_endloop01; - rz_vector_push(p->il_ops, op); + rz_pvector_push(p->il_ops, &hex_endloop01_op); } // Add a jump to the next packet. - op = RZ_NEW0(HexILOp); - op->attr = HEX_IL_INSN_ATTR_BRANCH | HEX_IL_INSN_ATTR_COND; - op->get_il_op = (HexILOpGetter)hex_il_op_next_pkt_jmp; - rz_vector_push(p->il_ops, op); - - op = RZ_NEW0(HexILOp); - op->attr = HEX_IL_INSN_ATTR_NONE; - op->get_il_op = (HexILOpGetter)hex_commit_packet; - rz_vector_push(p->il_ops, op); + rz_pvector_push(p->il_ops, &hex_next_jump_to_next_pkt); + rz_pvector_push(p->il_ops, &hex_pkt_commit); check_for_jumps(p, &might_has_jumped); @@ -400,40 +411,40 @@ static void log_reg_read(RZ_BORROW HexPkt *pkt, ut8 reg_num, HexRegClass reg_cla case HEX_REG_CLASS_DOUBLE_REGS: case HEX_REG_CLASS_GENERAL_DOUBLE_LOW8_REGS: if (tmp_reg) { - pkt->il_op_stats.gpr_tmp_read |= (1ULL << (reg_num + 1)); + rz_bits_map_set_64(&pkt->il_op_stats.gpr_tmp_read, (reg_num + 1)); } else { - pkt->il_op_stats.gpr_read |= (1ULL << (reg_num + 1)); + rz_bits_map_set_64(&pkt->il_op_stats.gpr_read, (reg_num + 1)); } // fallthrough case HEX_REG_CLASS_INT_REGS: case HEX_REG_CLASS_INT_REGS_LOW8: case HEX_REG_CLASS_GENERAL_SUB_REGS: if (tmp_reg) { - pkt->il_op_stats.gpr_tmp_read |= (1ULL << reg_num); + rz_bits_map_set_64(&pkt->il_op_stats.gpr_tmp_read, reg_num); } else { - pkt->il_op_stats.gpr_read |= (1ULL << reg_num); + rz_bits_map_set_64(&pkt->il_op_stats.gpr_read, reg_num); } break; case HEX_REG_CLASS_CTR_REGS64: if (tmp_reg) { - pkt->il_op_stats.ctr_tmp_read |= (1ULL << (reg_num + 1)); + rz_bits_map_set_64(&pkt->il_op_stats.ctr_tmp_read, (reg_num + 1)); } else { - pkt->il_op_stats.ctr_read |= (1ULL << (reg_num + 1)); + rz_bits_map_set_64(&pkt->il_op_stats.ctr_read, (reg_num + 1)); } // fallthrough case HEX_REG_CLASS_MOD_REGS: case HEX_REG_CLASS_CTR_REGS: if (tmp_reg) { - pkt->il_op_stats.ctr_tmp_read |= (1ULL << reg_num); + rz_bits_map_set_64(&pkt->il_op_stats.ctr_tmp_read, reg_num); } else { - pkt->il_op_stats.ctr_read |= (1ULL << reg_num); + rz_bits_map_set_64(&pkt->il_op_stats.ctr_read, reg_num); } break; case HEX_REG_CLASS_PRED_REGS: if (tmp_reg) { - pkt->il_op_stats.pred_tmp_read |= (1ULL << reg_num); + rz_bits_map_set_32(&pkt->il_op_stats.pred_tmp_read, reg_num); } else { - pkt->il_op_stats.pred_read |= (1ULL << reg_num); + rz_bits_map_set_32(&pkt->il_op_stats.pred_read, reg_num); } break; } @@ -442,7 +453,7 @@ static void log_reg_read(RZ_BORROW HexPkt *pkt, ut8 reg_num, HexRegClass reg_cla static inline void log_pred_write_slot(HexInsnPktBundle *bundle, ut32 pred_num) { ut32 pos = (pred_num * HEX_LOG_SLOT_LOG_WIDTH); bundle->pkt->il_op_stats.pred_written &= ~(HEX_LOG_SLOT_LOG_MASK << HEX_LOG_SLOT_BIT_OFF << pos); - bundle->pkt->il_op_stats.pred_written |= (bundle->insn->slot << HEX_LOG_SLOT_BIT_OFF << pos); + rz_bits_map_set_32(&bundle->pkt->il_op_stats.pred_written, bundle->insn->slot + HEX_LOG_SLOT_BIT_OFF + pos); } static void log_reg_write(RZ_BORROW HexInsnPktBundle *bundle, ut8 reg_num, HexRegClass reg_class, bool read, bool tmp_reg) { @@ -460,26 +471,26 @@ static void log_reg_write(RZ_BORROW HexInsnPktBundle *bundle, ut8 reg_num, HexRe break; case HEX_REG_CLASS_DOUBLE_REGS: case HEX_REG_CLASS_GENERAL_DOUBLE_LOW8_REGS: - pkt->il_op_stats.gpr_written |= (1ULL << (reg_num + 1)); + rz_bits_map_set_64(&pkt->il_op_stats.gpr_written, (reg_num + 1)); // fallthrough case HEX_REG_CLASS_INT_REGS: case HEX_REG_CLASS_INT_REGS_LOW8: case HEX_REG_CLASS_GENERAL_SUB_REGS: - pkt->il_op_stats.gpr_written |= (1ULL << reg_num); + rz_bits_map_set_64(&pkt->il_op_stats.gpr_written, reg_num); break; case HEX_REG_CLASS_CTR_REGS64: if (hex_ctr_immut_masks[reg_num + 1] != HEX_IMMUTABLE_REG) { - pkt->il_op_stats.ctr_written |= (1ULL << (reg_num + 1)); + rz_bits_map_set_64(&pkt->il_op_stats.ctr_written, (reg_num + 1)); } // fallthrough case HEX_REG_CLASS_MOD_REGS: case HEX_REG_CLASS_CTR_REGS: if (hex_ctr_immut_masks[reg_num] != HEX_IMMUTABLE_REG) { - pkt->il_op_stats.ctr_written |= (1ULL << reg_num); + rz_bits_map_set_64(&pkt->il_op_stats.ctr_written, reg_num); } break; case HEX_REG_CLASS_PRED_REGS: - pkt->il_op_stats.pred_written |= (1ULL << reg_num); + rz_bits_map_set_32(&pkt->il_op_stats.pred_written, reg_num); if (bundle->insn) { log_pred_write_slot(bundle, reg_num); } @@ -663,13 +674,13 @@ static bool x_reg_rw_overlap(const HexPkt *pkt, const HexOp *op, ut32 reg_num) { case HEX_REG_CLASS_GENERAL_SUB_REGS: case HEX_REG_CLASS_DOUBLE_REGS: case HEX_REG_CLASS_GENERAL_DOUBLE_LOW8_REGS: - return (pkt->il_op_stats.gpr_written & (1 << reg_num)) && (pkt->il_op_stats.gpr_read & (1 << reg_num)) && op->isa_id == 'x'; + return (rz_bits_map_get_64(&pkt->il_op_stats.gpr_written, reg_num)) && (rz_bits_map_get_64(&pkt->il_op_stats.gpr_read, reg_num)) && op->isa_id == 'x'; case HEX_REG_CLASS_MOD_REGS: case HEX_REG_CLASS_CTR_REGS: case HEX_REG_CLASS_CTR_REGS64: - return (pkt->il_op_stats.ctr_written & (1 << reg_num)) && (pkt->il_op_stats.ctr_read & (1 << reg_num)) && op->isa_id == 'x'; + return (rz_bits_map_get_64(&pkt->il_op_stats.ctr_written, reg_num)) && (rz_bits_map_get_64(&pkt->il_op_stats.ctr_read, reg_num)) && op->isa_id == 'x'; case HEX_REG_CLASS_PRED_REGS: - return (pkt->il_op_stats.pred_written & (1 << reg_num)) && (pkt->il_op_stats.pred_read & (1 << reg_num)) && op->isa_id == 'x'; + return (rz_bits_map_get_32(&pkt->il_op_stats.pred_written, reg_num)) && (rz_bits_map_get_32(&pkt->il_op_stats.pred_read, reg_num)) && op->isa_id == 'x'; } } @@ -800,7 +811,7 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_cancel_slot(RZ_BORROW HexPkt *pkt, ut8 slot) { rz_warn_if_reached(); RZ_LOG_WARN("Slot %d does not exist!", slot); } - pkt->il_op_stats.slot_cancelled |= (1ULL << slot); + rz_bits_map_set_32(&pkt->il_op_stats.slot_cancelled, slot); return EMPTY(); }