Skip to content

Commit

Permalink
libr/mips: fix USE_DS
Browse files Browse the repository at this point in the history
  • Loading branch information
Valentin Obst committed Sep 11, 2024
1 parent 43c83dc commit 56a2986
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 51 deletions.
146 changes: 121 additions & 25 deletions libr/arch/p/mips/plugin_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,25 @@ R_IPI int mips_assemble(const char *str, ut64 pc, ut8 *out);


// call with delay slot
#define ES_CALL_DR(ra, addr) "pc,4,+,"ra",=,"ES_J(addr)
#define ES_CALL_DR(ra, addr) "pc,4,+,"ra",=,"ES_J_D(addr)
#define ES_CALL_D(addr) ES_CALL_DR("ra", addr)

// call without delay slot
#define ES_CALL_NDR(ra, addr) "pc,"ra",=,"ES_J(addr)
#define ES_CALL_NDR(ra, addr) "pc,"ra",=,"ES_J_ND(addr)
#define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr)

#define USE_DS 0
#define USE_DS 1
#if USE_DS
// emit ERR trap if executed in a delay slot
#define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,},"
// jump to address
#define ES_J(addr) addr",SETJT,1,SETD"
// Record jump-to-address and set delay slot flag.
#define ES_J_D(addr) addr",SETJT,1,SETD"
// Jump to address.
#define ES_J_ND(addr) addr",pc,:="
#else
#define ES_TRAP_DS() ""
#define ES_J(addr) addr",pc,:="
#define ES_J_D(addr) addr",pc,:="
#define ES_J_ND(addr) ES_J_D(addr)
#endif

#define ES_B(x) "0xff,"x",&"
Expand Down Expand Up @@ -241,6 +244,7 @@ static const char *arg(csh *handle, cs_insn *insn, char *buf, size_t buf_sz, int
static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn) {
char str[8][32] = {{0}};
int i;
u_int64_t addr = insn->address;

r_strbuf_init (&op->esil);
r_strbuf_set (&op->esil, "");
Expand Down Expand Up @@ -314,6 +318,15 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
case MIPS_INS_SLL:
r_strbuf_appendf (&op->esil, "%s,%s,<<,%s,=", ARG (2), ARG (1), ARG (0));
break;
case MIPS_INS_BALC:
// BALC address
// Branch And Link, Compact. Unconditional PC relative branch to address, placing return address
// in register $31.
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_ND ("%s"), ARG (0));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BAL:
case MIPS_INS_JAL:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_D ("%s"), ARG (0));
Expand Down Expand Up @@ -348,48 +361,94 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
break;
case MIPS_INS_JRADDIUSP:
// increment stackpointer in X and jump to %ra
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,sp,+=," ES_J ("ra"), ARG (0));
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,sp,+=," ES_J_D ("ra"), ARG (0));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_JR:
case MIPS_INS_JRC:
case MIPS_INS_BC:
// JRC rt
// Jump Register, Compact. Unconditional jump to address in register $rt.
// BC address
// Branch, Compact. Unconditional PC relative branch to address.
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J_ND ("%s"), ARG (0));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_JR:
case MIPS_INS_J:
case MIPS_INS_B: // ???
// jump to address with conditional
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J ("%s"), ARG (0));
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J_D ("%s"), ARG (0));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BNEC:
// BNEC rs, rt, address
// Branch Not Equal, Compact. PC relative branch to address if register $rs is not equal to
// register $rt.
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J_ND ("%s") ",}",
ARG (0), ARG (1), ARG (2));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BNE: // bne $s, $t, offset
case MIPS_INS_BNEL:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J ("%s") ",}",
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J_D ("%s") ",}",
ARG (0), ARG (1), ARG (2));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BEQC:
// BEQC rs, rt, address
// Branch if Equal, Compact. PC relative branch to address if registers $rs and $rt are are equal.
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J_ND ("%s") ",}",
ARG (0), ARG (1), ARG (2));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BEQ:
case MIPS_INS_BEQL:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J ("%s") ",}",
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J_D ("%s") ",}",
ARG (0), ARG (1), ARG (2));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BEQZC:
// BEQZC rt, address # when rt and address are in range
// Branch if Equal to Zero, Compact. PC relative branch to address if register $rt equals zero.
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,?{," ES_J_ND ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BZ:
case MIPS_INS_BEQZ:
case MIPS_INS_BEQZC:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,?{," ES_J ("%s") ",}",
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,?{," ES_J_D ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BNEZC:
// BNEZC rt, address
// Branch if Not Equal to Zero, Compact. PC relative branch to address if register $rt is not equal to zero.
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J_ND ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BNEZ:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J ("%s") ",}",
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J_D ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
Expand All @@ -402,21 +461,45 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BLEZ:
case MIPS_INS_BLEZC:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{," ES_J_ND ("%s") ",BREAK,},",
ARG (0), ARG (1));
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_ND ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BLEZ:
case MIPS_INS_BLEZL:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{," ES_J ("%s") ",BREAK,},",
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{," ES_J_D ("%s") ",BREAK,},",
ARG (0), ARG (1));
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_D ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BGEZ:
case MIPS_INS_BGEC:
// BGEC rs, rt, address
// Branch if Greater than or Equal, Compact. PC relative branch to address if register $rs
// is greater than or equal to register $rt.
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,>=,$z,?{," ES_J_ND ("%s") ",}",
ARG (1), ARG (0), ARG (2));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BGEZC:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_ND ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BGEZ:
case MIPS_INS_BGEZL:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_D ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
Expand Down Expand Up @@ -450,33 +533,46 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BLTZ:
case MIPS_INS_BLTZC:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_ND ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BLTZ:
case MIPS_INS_BLTZL:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_D ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BGTZ:
case MIPS_INS_BGTZC:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{,BREAK,},", ARG (0));
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_ND ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BGTZ:
case MIPS_INS_BGTZL:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{,BREAK,},", ARG (0));
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_D ("%s") ",}",
ARG (0), ARG (1));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BTEQZ:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,t,==,$z,?{," ES_J ("%s") ",}", ARG (0));
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,t,==,$z,?{," ES_J_D ("%s") ",}", ARG (0));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
break;
case MIPS_INS_BTNEZ:
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,t,==,$z,!,?{," ES_J ("%s") ",}", ARG (0));
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,t,==,$z,!,?{," ES_J_D ("%s") ",}", ARG (0));
#if USE_DS
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
#endif
Expand Down
Loading

0 comments on commit 56a2986

Please sign in to comment.