Skip to content

Commit

Permalink
Generate iword by checking HexInsnContainer
Browse files Browse the repository at this point in the history
  • Loading branch information
Rot127 committed Feb 17, 2024
1 parent dd955e6 commit 8de8541
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 18 deletions.
39 changes: 22 additions & 17 deletions librz/asm/arch/hexagon/hexagon_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -1082,7 +1082,7 @@ static void copy_asm_ana_ops(const HexState *state, RZ_BORROW HexReversedOpcode
* \return true If the decoded instruction was the last instruction in a _valid_ packet.
* \return false Otherwise.
*/
RZ_API bool hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_reverse, const ut8 *buf, const ut64 addr, const bool copy_result) {
RZ_API HexInsnContainer *hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_reverse, const ut8 *buf, const ut64 addr, const bool copy_result) {
HexState *state = hexagon_state(false);
if (!state) {
RZ_LOG_FATAL("HexState was NULL.");
Expand All @@ -1107,7 +1107,7 @@ RZ_API bool hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_re
if (copy_result) {
copy_asm_ana_ops(state, rz_reverse, hic);
}
return hic->pkt_info.last_insn;
return hic;
}

ut32 data = rz_read_le32(buf);
Expand All @@ -1117,7 +1117,7 @@ RZ_API bool hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_re
// Add to state
hic = hex_add_hic_to_state(state, &hic_new);
if (!hic) {
return false;
return NULL;
}
HexPkt *p = hex_get_pkt(state, hic->addr);

Expand All @@ -1127,7 +1127,7 @@ RZ_API bool hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_re
if (copy_result) {
copy_asm_ana_ops(state, rz_reverse, hic);
}
return hic->pkt_info.last_insn;
return hic;
}

RZ_API bool hexagon_decode_iword(RZ_OUT RzAnalysisInsnWord *iword, ut64 addr, const ut8 *buf, size_t len, size_t buf_off_iword) {
Expand All @@ -1138,32 +1138,37 @@ RZ_API bool hexagon_decode_iword(RZ_OUT RzAnalysisInsnWord *iword, ut64 addr, co
RZ_LOG_WARN("Hexagon needs at least 5 * %" PFMT32d " bytes to decode an instr. word.\n", HEX_INSN_SIZE);
return false;
}
iword->addr = addr;
RzAnalysisOp prev_op = { 0 };
HexReversedOpcode rev = { .action = HEXAGON_ANALYSIS, .ana_op = &prev_op, .asm_op = NULL };
hexagon_reverse_opcode(NULL, &rev, buf, addr - buf_off_iword, false);
if (!hexagon_reverse_opcode(NULL, &rev, buf + (buf_off_iword - 4), addr - 4, false)) {
RZ_LOG_WARN("Cannot decode an iword if the last previous instruction was not an end of a packet.\n");
return false;
}

iword->addr = addr;
ut32 buf_offset = buf_off_iword;
while (buf_offset + HEX_INSN_SIZE <= len && buf_offset <= HEX_INSN_SIZE * HEX_MAX_INSN_PER_PKT) {
const ut32 buf_ptr = rz_read_at_le32(buf, buf_offset);
if (buf_offset > 0 && (buf_ptr == HEX_INVALID_INSN_0 || buf_ptr == HEX_INVALID_INSN_F)) {
RZ_LOG_WARN("Attemt to decode an invalid instruction for a instruction word. Is the address 0x%" PFMT64x " in valid memory?\n", addr);
ut64 addr_offset = 0;
while (buf_offset + HEX_INSN_SIZE <= len) {
const ut32 insn_bytes = rz_read_at_le32(buf, buf_offset);
if (insn_bytes == HEX_INVALID_INSN_0 || insn_bytes == HEX_INVALID_INSN_F) {
RZ_LOG_WARN("Attempt to decode an invalid instruction for a instruction word. Is the address 0x%" PFMT64x " in valid memory?\n", addr);
return false;
}

RzAnalysisOp *aop = RZ_NEW0(RzAnalysisOp);
HexReversedOpcode rev = { .action = HEXAGON_ANALYSIS, .ana_op = aop, .asm_op = NULL };
bool last_insn = hexagon_reverse_opcode(NULL, &rev, buf + buf_offset, addr + buf_offset, true);
HexInsnContainer *hic = hexagon_reverse_opcode(NULL, &rev, buf + buf_offset, addr + addr_offset, true);
rz_pvector_push(iword->insns, aop);
if (aop->jump) {
if (aop->jump && aop->jump != UT64_MAX) {
rz_vector_push(iword->jump_targets, &aop->jump);
}
if (aop->fail) {
if (aop->fail && aop->fail != UT64_MAX) {
rz_vector_push(iword->jump_targets, &aop->fail);
}
rz_strbuf_appendf(iword->asm_str, "%s\n", aop->mnemonic);
rz_strbuf_appendf(iword->asm_str, "%s\n", hic->text);
iword->size_bytes += 4;
iword->size_bits += 32;
addr_offset += 4;

if (aop->type & RZ_ANALYSIS_OP_TYPE_COND) {
iword->props |= RZ_ANALYSIS_IWORD_COND;
Expand All @@ -1179,10 +1184,10 @@ RZ_API bool hexagon_decode_iword(RZ_OUT RzAnalysisInsnWord *iword, ut64 addr, co
iword->props |= RZ_ANALYSIS_IWORD_RET;
}

if (last_insn) {
if (hic->pkt_info.last_insn) {
if (!(aop->type & RZ_ANALYSIS_OP_TYPE_RET)) {
ut64 next_insn_addr = addr + iword->size_bytes;
rz_vector_push(iword->jump_targets, &next_insn_addr);
ut64 next_iword_addr = addr + iword->size_bytes;
rz_vector_push(iword->jump_targets, &next_iword_addr);
}
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion librz/asm/arch/hexagon/hexagon_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ RZ_API void hex_insn_container_free(RZ_NULLABLE HexInsnContainer *c);
RZ_API void hex_const_ext_free(RZ_NULLABLE HexConstExt *ce);
RZ_API HexState *hexagon_state(bool reset);
RZ_IPI void hexagon_state_fini(HexState *state);
RZ_API bool hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_reverse, const ut8 *buf, const ut64 addr, const bool copy_result);
RZ_API HexInsnContainer *hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_reverse, const ut8 *buf, const ut64 addr, const bool copy_result);
RZ_API bool hexagon_decode_iword(RZ_OUT RzAnalysisInsnWord *iword, ut64 addr, const ut8 *buf, size_t len, size_t buf_off_iword);
RZ_API ut8 hexagon_get_pkt_index_of_addr(const ut32 addr, const HexPkt *p);
RZ_API HexLoopAttr hex_get_loop_flag(const HexPkt *p);
Expand Down

0 comments on commit 8de8541

Please sign in to comment.