summaryrefslogtreecommitdiff
path: root/arch/powerpc/util.cpp
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2024-03-05 19:50:13 -0500
committerRusty Wagner <rusty.wagner@gmail.com>2024-03-05 20:34:34 -0500
commite093c21ed880ac3eb72119be15093ee04f8ce299 (patch)
tree9f720ebdc0ae415734b1199ed341668c69710a94 /arch/powerpc/util.cpp
parent0609276712622908254065546102381466033141 (diff)
Move architecture modules into the API repo
Diffstat (limited to 'arch/powerpc/util.cpp')
-rw-r--r--arch/powerpc/util.cpp88
1 files changed, 88 insertions, 0 deletions
diff --git a/arch/powerpc/util.cpp b/arch/powerpc/util.cpp
new file mode 100644
index 00000000..50c3eb5b
--- /dev/null
+++ b/arch/powerpc/util.cpp
@@ -0,0 +1,88 @@
+#include "disassembler.h"
+
+#include <binaryninjaapi.h>
+#define MYLOG(...) while(0);
+//#define MYLOG BinaryNinja::LogDebug
+
+void printOperandVerbose(decomp_result *res, cs_ppc_op *op)
+{
+ (void)res;
+ if(op == NULL) {
+ MYLOG("NULL\n");
+ return;
+ }
+
+ switch(op->type) {
+ case PPC_OP_INVALID:
+ MYLOG("invalid\n");
+ break;
+ case PPC_OP_REG:
+ MYLOG("reg: %s\n", cs_reg_name(res->handle, op->reg));
+ break;
+ case PPC_OP_IMM:
+ MYLOG("imm: 0x%X\n", op->imm);
+ break;
+ case PPC_OP_MEM:
+ MYLOG("mem (%s + %d)\n", cs_reg_name(res->handle, op->mem.base),
+ op->mem.disp);
+ break;
+ case PPC_OP_CRX:
+ MYLOG("crx (scale:%d, reg:%s)\n", op->crx.scale,
+ cs_reg_name(res->handle, op->crx.reg));
+ break;
+ default:
+ MYLOG("unknown (%d)\n", op->type);
+ break;
+ }
+}
+
+void printInstructionVerbose(decomp_result *res)
+{
+ struct cs_insn *insn = &(res->insn);
+ struct cs_detail *detail = &(res->detail);
+ struct cs_ppc *ppc = &(detail->ppc);
+ (void)insn;
+
+ /* LEVEL1: id, address, size, bytes, mnemonic, op_str */
+ MYLOG("instruction id: %d \"%s %s\"\n", insn->id, insn->mnemonic,
+ insn->op_str);
+
+ MYLOG(" bytes: %02X %02X %02X %02X\n", insn->bytes[0], insn->bytes[1],
+ insn->bytes[2], insn->bytes[3]);
+
+ /* LEVEL2: regs_read, regs_write, groups */
+ MYLOG(" regs read:");
+ for(int j=0; j<detail->regs_read_count; ++j) {
+ MYLOG(" %s", cs_reg_name(res->handle, detail->regs_read[j]));
+ }
+ MYLOG("\n");
+ MYLOG(" regs write:");
+ for(int j=0; j<detail->regs_write_count; ++j) {
+ MYLOG(" %s", cs_reg_name(res->handle, detail->regs_write[j]));
+ }
+ MYLOG("\n");
+ MYLOG(" groups:");
+ for(int j=0; j<detail->groups_count; ++j) {
+ int group = detail->groups[j];
+ (void)group;
+ MYLOG(" %d(%s)", group, cs_group_name(res->handle, group));
+ }
+ MYLOG("\n");
+
+ /* LEVEL3: branch code, branch hint, update_cr0, operands */
+ if(1 /* branch instruction */) {
+ MYLOG(" branch code: %d\n", ppc->bc); // PPC_BC_LT, PPC_BC_LE, etc.
+ MYLOG(" branch hint: %d\n", ppc->bh); // PPC_BH_PLUS, PPC_BH_MINUS
+ }
+
+ MYLOG(" update_cr0: %d\n", ppc->update_cr0);
+
+ // .op_count is number of operands
+ // .operands[] is array of cs_ppc_op
+ for(int j=0; j<ppc->op_count; ++j) {
+ MYLOG(" operand%d: ", j);
+ printOperandVerbose(res, &(ppc->operands[j]));
+ }
+}
+
+