Update source files

This commit is contained in:
Rot127 authored and Rot127 committed 2026-07-28 12:26:25 +00:00
1 parent 0f77404990
commit 1d1500c267
2 files changed
+132 -40

No files matched your search

+26 -10
View File
@@ -75,33 +75,49 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_commit_packet(HexInsnPktBundle *bundle) {
commit_seq = SEQ2(commit_seq, SETG(dest_reg, VARG(src_reg)));
}
hex_reset_il_pkt_stats(stats);
hex_il_pkt_stats_reset(stats);
return commit_seq;
}
RZ_IPI RZ_OWN RzILOpEffect *hex_il_op_jump_flag_init(HexInsnPktBundle *bundle) {
return SEQ3(SETL(bundle->jmp_flags[0], IL_FALSE),
SETL(bundle->jmp_flags[1], IL_FALSE),
SETL("next_pkt", U32(bundle->pkt->pkt_addr + (HEX_INSN_SIZE * rz_list_length(bundle->pkt->bin)))));
return SEQ2(SETL(bundle->jmp_flags[0], IL_FALSE),
SETL(bundle->jmp_flags[1], IL_FALSE));
}
RZ_IPI RZ_OWN RzILOpEffect *hex_il_op_set_jmp_target_0(HexInsnPktBundle *bundle) {
if (bundle->jmp_cnt < 1) {
rz_warn_if_reached();
return NULL;
}
return bundle->jmp_set_addr[0];
}
RZ_IPI RZ_OWN RzILOpEffect *hex_il_op_set_jmp_target_1(HexInsnPktBundle *bundle) {
if (bundle->jmp_cnt != 2) {
rz_warn_if_reached();
return NULL;
}
return bundle->jmp_set_addr[1];
}
RZ_IPI RZ_OWN RzILOpEffect *hex_il_op_next_pkt_jmp(HexInsnPktBundle *bundle) {
RzILOpPure *next_pkt_addr = U32(bundle->pkt->pkt_addr + (HEX_INSN_SIZE * rz_list_length(bundle->pkt->bin)));
switch (bundle->jmp_cnt) {
case 0:
// No jump/call was lifted.
return JMP(VARL("next_pkt"));
return JMP(next_pkt_addr);
case 1:
// One jump/call was lifted.
return BRANCH(VARL("jump_flag_0"),
return BRANCH(VARL(bundle->jmp_flags[0]),
JMP(VARL(bundle->jmp_targets[0])),
JMP(VARL("next_pkt")));
JMP(next_pkt_addr));
case 2:
// Two jumps/calls were lifted.
return BRANCH(VARL("jump_flag_0"),
return BRANCH(VARL(bundle->jmp_flags[0]),
JMP(VARL(bundle->jmp_targets[0])),
BRANCH(VARL("jump_flag_1"),
BRANCH(VARL(bundle->jmp_flags[1]),
JMP(VARL(bundle->jmp_targets[1])),
JMP(VARL("next_pkt"))));
JMP(next_pkt_addr)));
default:
break;
}
+106 -30
View File
@@ -6,11 +6,21 @@ static HexILOp hex_jump_flag_init_op = {
.get_il_op = (HexILOpGetter)hex_il_op_jump_flag_init,
};
static HexILOp hex_next_jump_to_next_pkt = {
static HexILOp hex_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_set_jmp_target_0 = {
.attr = HEX_IL_INSN_ATTR_NONE,
.get_il_op = (HexILOpGetter)hex_il_op_set_jmp_target_0,
};
static HexILOp hex_pkt_set_jmp_target_1 = {
.attr = HEX_IL_INSN_ATTR_NONE,
.get_il_op = (HexILOpGetter)hex_il_op_set_jmp_target_1,
};
static HexILOp hex_pkt_commit = {
.attr = HEX_IL_INSN_ATTR_NONE,
.get_il_op = (HexILOpGetter)hex_commit_packet,
@@ -34,7 +44,7 @@ static HexILOp hex_endloop01_op = {
/**
* \brief Sends the IL op at \p start to the position \p newloc.
*
* Note: THis is a copy of the same function implemented by Qualcomm in QEMU.
* Note: This is a copy of the same function implemented by Qualcomm in QEMU.
* See: https://gitlab.com/qemu-project/qemu/-/blob/master/target/hexagon/decode.c :: decode_send_insn_to
*
* \param ops The IL ops list.
@@ -42,10 +52,9 @@ static HexILOp hex_endloop01_op = {
* \param newloc Position the op shall be moved to.
*/
static void hex_send_insn_to_i(RzPVector /*<HexILOp *>*/ *ops, ut8 start, ut8 newloc) {
rz_return_if_fail(ops);
rz_return_if_fail(ops && newloc < rz_pvector_len(ops));
st32 direction;
st32 i;
if (start == newloc) {
return;
}
@@ -56,9 +65,11 @@ static void hex_send_insn_to_i(RzPVector /*<HexILOp *>*/ *ops, ut8 start, ut8 ne
/* move towards beginning */
direction = -1;
}
for (i = start; i != newloc; i += direction) {
HexILOp *tmp_op = *rz_pvector_assign_at(ops, i, (HexILOp *)rz_pvector_at(ops, i + direction));
rz_pvector_assign_at(ops, i + direction, tmp_op);
for (st32 i = start; i != newloc; i += direction) {
HexILOp *neighbor_op = (HexILOp *)rz_pvector_at(ops, i + direction);
HexILOp *to_move_op = (HexILOp *)rz_pvector_at(ops, i);
rz_pvector_set(ops, i, neighbor_op);
rz_pvector_set(ops, i + direction, to_move_op);
}
}
@@ -112,6 +123,7 @@ RZ_IPI bool hex_shuffle_insns(RZ_INOUT HexPkt *p) {
op = (HexILOp *)rz_pvector_at(ops, i);
if (!op) {
RZ_LOG_FATAL("NULL il op at index %" PFMT32d "\n", i);
return false;
}
if (flag && (op->attr & HEX_IL_INSN_ATTR_MEM_WRITE)) {
hex_send_insn_to_i(ops, i, last_insn - n_mems);
@@ -186,12 +198,23 @@ RZ_IPI bool hex_shuffle_insns(RZ_INOUT HexPkt *p) {
return true;
}
static RzILOpEffect *hex_il_op_to_effect(const HexILOp *il_op, HexPkt *pkt) {
rz_return_val_if_fail(il_op, NULL);
HexInsnPktBundle bundle = { 0 };
bundle.insn = (HexInsn *)il_op->hi;
bundle.pkt = pkt;
return il_op->get_il_op ? il_op->get_il_op(&bundle) : EMPTY();
static inline void bundle_init(HexInsnPktBundle *bundle) {
memset(bundle, 0, sizeof(HexInsnPktBundle));
bundle->jmp_targets[0] = "jump_target_0";
bundle->jmp_targets[1] = "jump_target_1";
bundle->jmp_flags[0] = "jump_flag_0";
bundle->jmp_flags[1] = "jump_flag_1";
}
static inline void bundle_update(HexInsnPktBundle *bundle, HexInsn *insn, HexPkt *pkt) {
bundle->insn = insn;
bundle->pkt = pkt;
}
static RzILOpEffect *hex_il_op_to_effect(const HexILOp *il_op, HexPkt *pkt, HexInsnPktBundle *bundle) {
rz_return_val_if_fail(bundle && il_op && il_op->get_il_op, NULL);
bundle_update(bundle, il_op->hi, pkt);
return il_op->get_il_op(bundle);
}
/**
@@ -210,16 +233,18 @@ static RZ_OWN RzILOpEffect *hex_pkt_to_il_seq(HexPkt *pkt) {
RZ_LOG_WARN("Invalid il ops sequence! There should be at least two il ops per packet.\n");
return NULL;
}
HexInsnPktBundle bundle;
bundle_init(&bundle);
RzILOpEffect *complete_seq = EMPTY();
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_at(pkt->il_ops, i), pkt));
complete_seq = SEQ2(complete_seq, hex_il_op_to_effect((HexILOp *)rz_pvector_at(pkt->il_ops, i), pkt, &bundle));
}
return complete_seq;
}
static bool set_pkt_il_ops(RZ_INOUT HexPkt *p) {
rz_return_val_if_fail(p, false);
hex_reset_il_pkt_stats(&p->il_op_stats);
hex_il_pkt_stats_reset(&p->il_op_stats);
// This function is a lot of unnecessary overhead so:
// TODO The assignment of IL instructions to their actual instructions should be done in the instruction template.
// But with the current separation between Asm and Analysis plugins this is not possible.
@@ -315,6 +340,41 @@ static inline bool pkt_at_addr_is_emu_ready(const HexPkt *pkt, const ut32 addr)
return addr == pkt->pkt_addr && pkt->is_valid && pkt->last_instr_present;
}
/**
* \brief Inserts the `SETL(jmp_target_X, PURE)` effects after the respective
* jump effects.
*/
static bool insert_set_jmp_addr_effects(HexPkt *pkt) {
size_t idx[2] = { 0 };
size_t c = 0;
size_t i;
void **it;
rz_pvector_enumerate (pkt->il_ops, it, i) {
HexILOp *op = *it;
if (!(op->attr & HEX_IL_INSN_ATTR_BRANCH)) {
continue;
}
if (c >= 2) {
RZ_LOG_ERROR("Packet 0x%" PFMT32x " contains more than two branch instructions.\n", pkt->pkt_addr);
return false;
}
idx[c] = i + c + 1;
c++;
}
for (size_t k = 0; k < c; k++) {
rz_pvector_insert(pkt->il_ops, idx[k], k == 0 ? &hex_pkt_set_jmp_target_0 : &hex_pkt_set_jmp_target_1);
if (rz_pvector_at(pkt->il_ops, idx[k] - 1) == &hex_endloop01_op) {
// Edge case:
// The endloop01 effect has two jumps in it (one for each loop).
// but it is logged only once above.
// So we have to insert the second set_jmp_target_1 effect as well.
rz_pvector_insert(pkt->il_ops, idx[k] + 1, &hex_pkt_set_jmp_target_1);
break;
}
}
return true;
}
/**
* \brief Returns the IL operation of the instruction at \p addr. This will always be EMPTY().
* Except for last instructions in a packet. Those will always return the complete IL operation
@@ -326,13 +386,8 @@ static inline bool pkt_at_addr_is_emu_ready(const HexPkt *pkt, const ut32 addr)
* If false, the behavior is as documented above.
* \return RzILOpEffect* Sequence of operations to emulate the packet.
*/
RZ_IPI RzILOpEffect *hex_get_il_op(const ut32 addr, const bool get_pkt_op) {
static bool might_has_jumped = false;
HexState *state = hexagon_state(false);
if (!state) {
RZ_LOG_WARN("Failed to get hexagon plugin state data!\n");
return NULL;
}
RZ_IPI RZ_OWN RzILOpEffect *hex_get_il_op(const ut32 addr, bool get_pkt_op, RZ_NONNULL HexState *state) {
rz_return_val_if_fail(state, NULL);
HexPkt *p = hex_get_pkt(state, addr);
if (!p) {
RZ_LOG_WARN("Packet was NULL although it should have been disassembled at this point.\n");
@@ -345,13 +400,14 @@ RZ_IPI RzILOpEffect *hex_get_il_op(const ut32 addr, const bool get_pkt_op) {
if (hic->identifier == HEX_INS_INVALID_DECODE) {
return NULL;
}
if (state->just_init || might_has_jumped) {
if (state->just_init || state->might_have_jumped) {
// Assume that the instruction at the address the VM was initialized is the first instruction.
// Also make it valid if a jump let to this packet.
p->is_valid = true;
get_pkt_op = true;
hic->pkt_info.first_insn = true;
state->just_init = false;
might_has_jumped = false;
state->might_have_jumped = false;
}
if (!get_pkt_op && !hic->pkt_info.last_insn) {
@@ -365,7 +421,7 @@ RZ_IPI RzILOpEffect *hex_get_il_op(const ut32 addr, const bool get_pkt_op) {
}
if (!rz_pvector_empty(p->il_ops)) {
check_for_jumps(p, &might_has_jumped);
check_for_jumps(p, &state->might_have_jumped);
return hex_pkt_to_il_seq(p);
}
@@ -389,12 +445,16 @@ RZ_IPI RzILOpEffect *hex_get_il_op(const ut32 addr, const bool get_pkt_op) {
rz_pvector_push(p->il_ops, &hex_endloop01_op);
}
if (!insert_set_jmp_addr_effects(p)) {
rz_warn_if_reached();
return NULL;
}
rz_pvector_push(p->il_ops, &hex_pkt_commit);
// Add a jump to the next packet. This always has to come last.
rz_pvector_push(p->il_ops, &hex_next_jump_to_next_pkt);
// Add a jump to the next packet.
rz_pvector_push(p->il_ops, &hex_jump_to_next_pkt);
check_for_jumps(p, &might_has_jumped);
check_for_jumps(p, &state->might_have_jumped);
return hex_pkt_to_il_seq(p);
}
@@ -572,6 +632,7 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_write_reg(RZ_BORROW HexInsnPktBundle *bundle, co
case HEX_REG_CLASS_GENERAL_SUB_REGS:
low_name = hex_get_reg_in_class(HEX_REG_CLASS_INT_REGS, reg_num, false, true, true);
if (!low_name) {
rz_il_op_pure_free(high_val);
return NULL;
}
low_val = CAST(HEX_GPR_WIDTH, IL_FALSE, val);
@@ -593,6 +654,7 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_write_reg(RZ_BORROW HexInsnPktBundle *bundle, co
if (hex_ctr_immut_masks[reg_num] != HEX_IMMUTABLE_REG) {
low_name = hex_get_reg_in_class(HEX_REG_CLASS_CTR_REGS, reg_num, false, true, true);
if (!low_name) {
rz_il_op_pure_free(high_val);
return NULL;
}
low_val = CAST(HEX_GPR_WIDTH, IL_FALSE, val);
@@ -797,6 +859,8 @@ RZ_IPI RZ_OWN RzILOpPure *hex_read_reg(RZ_BORROW HexPkt *pkt, const HexOp *op, b
}
if (read_cond_faulty(low_val, high_val, val_width)) {
rz_warn_if_reached();
rz_il_op_pure_free(high_val);
rz_il_op_pure_free(low_val);
return NULL;
}
log_reg_read(pkt, reg_num, op->class, tmp_reg);
@@ -835,7 +899,10 @@ RzILOpPure *hex_get_corresponding_cs(RZ_BORROW HexPkt *pkt, const HexOp *Mu) {
return NULL;
}
RZ_IPI void hex_reset_il_pkt_stats(HexILExecData *stats) {
RZ_IPI void hex_il_pkt_stats_fini(HexILExecData *stats) {
if (!stats) {
return;
}
rz_bv_free(stats->slot_cancelled);
rz_bv_free(stats->ctr_written);
rz_bv_free(stats->gpr_written);
@@ -846,6 +913,10 @@ RZ_IPI void hex_reset_il_pkt_stats(HexILExecData *stats) {
rz_bv_free(stats->ctr_tmp_read);
rz_bv_free(stats->gpr_tmp_read);
rz_bv_free(stats->pred_tmp_read);
}
RZ_IPI void hex_il_pkt_stats_init(HexILExecData *stats) {
rz_return_if_fail(stats);
stats->slot_cancelled = rz_bv_new(64);
stats->ctr_written = rz_bv_new(64);
stats->gpr_written = rz_bv_new(64);
@@ -857,3 +928,8 @@ RZ_IPI void hex_reset_il_pkt_stats(HexILExecData *stats) {
stats->gpr_tmp_read = rz_bv_new(64);
stats->pred_tmp_read = rz_bv_new(32);
}
RZ_IPI void hex_il_pkt_stats_reset(HexILExecData *stats) {
hex_il_pkt_stats_fini(stats);
hex_il_pkt_stats_init(stats);
}