Skip to content

Commit

Permalink
Fix callstack_instr on MIPS
Browse files Browse the repository at this point in the history
- Add bal and balr to Capstone workaround
- Fix issue where the Capstone workaround only checked the first instruction
- Fix (always-false?) CS_GRP_INVALID check
  • Loading branch information
be32826 authored and Andrew Fasano committed Jan 8, 2024
1 parent 558d399 commit 50426f6
Showing 1 changed file with 27 additions and 25 deletions.
52 changes: 27 additions & 25 deletions panda/plugins/callstack_instr/callstack_instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,36 +276,38 @@ instr_type disas_block(CPUArchState* env, target_ulong pc, int size) {
if (count <= 0) goto done2;

for (end = insn + count - 1; end >= insn; end--) {
if (!cs_insn_group(handle, end, CS_GRP_INVALID)) {
break;
if (cs_insn_group(handle, end, CS_GRP_CALL)) {
res = INSTR_CALL;
} else if (cs_insn_group(handle, end, CS_GRP_RET)) {
res = INSTR_RET;
} else {
res = INSTR_UNKNOWN;
}
}
if (end < insn) goto done;

if (cs_insn_group(handle, end, CS_GRP_CALL)) {
res = INSTR_CALL;
} else if (cs_insn_group(handle, end, CS_GRP_RET)) {
res = INSTR_RET;
} else {
res = INSTR_UNKNOWN;
}

// Temporary workaround for https://github.com/aquynh/capstone/issues/1680
// Mnemonic/operand comparision as fallback for incorrect grouping
#if defined(TARGET_MIPS)
#define MAX_MNEMONIC_LEN 32 // CS_MNEMONIC_SIZE not imported?
if (res == INSTR_UNKNOWN) {
if (!strncasecmp(insn->mnemonic, "jal", 32)) {
res = INSTR_CALL; // Direct call
} else if (!strncasecmp(insn->mnemonic, "jalr", 32)) {
res = INSTR_CALL; // Jump table call
} else if (cs_insn_group(handle, end, CS_GRP_JUMP) && strcasestr(insn->op_str, "$ra")) {
res = INSTR_RET; // Jump to LR -> ret
// Temporary workaround for https://github.com/aquynh/capstone/issues/1680
// Mnemonic/operand comparision as fallback for incorrect grouping
#if defined(TARGET_MIPS)
#define MAX_MNEMONIC_LEN 32 // CS_MNEMONIC_SIZE not imported?
if (res == INSTR_UNKNOWN) {
if (!strncasecmp(end->mnemonic, "jal", 32)) {
res = INSTR_CALL; // Direct absolute call
} else if (!strncasecmp(end->mnemonic, "bal", 32)) {
res = INSTR_CALL; // Direct relative call
} else if (!strncasecmp(end->mnemonic, "jalr", 32)) {
res = INSTR_CALL; // Direct jump table call
} else if (!strncasecmp(end->mnemonic, "balr", 32)) {
res = INSTR_CALL; // Relative jump table call
} else if (cs_insn_group(handle, end, CS_GRP_JUMP) && strcasestr(end->op_str, "$ra")) {
res = INSTR_RET; // Jump to LR -> ret
}
}
#endif

if (res != INSTR_UNKNOWN) {
break;
}
#endif
}

done:
cs_free(insn, count);
done2:
free(buf);
Expand Down

0 comments on commit 50426f6

Please sign in to comment.