Merge the addressed bytes in the mips unaligned loads and stores ##esil

This commit is contained in:
phix33 2026-08-21 20:39:37 +10:00 committed by pancake
parent 451bb54efb
commit faaed48879
4 changed files with 254 additions and 5 deletions

View file

@ -4,6 +4,7 @@
#define R_MIPS_UTILS_H
#include <r_endian.h>
#include <r_arch.h>
#include <r_bin.h>
static inline ut64 mips_read_ptr_at(RBin *bin, ut64 addr, bool be, int bits) {
@ -15,4 +16,31 @@ static inline ut64 mips_read_ptr_at(RBin *bin, ut64 addr, bool be, int bits) {
return ptrsz == 8 ? r_read_ble64 (v, be) : r_read_ble32 (v, be);
}
// esil for the unaligned lwl/lwr/ldl/ldr loads and swl/swr/sdl/sdr stores
static inline void mips_esil_unaligned(RStrBuf *esil, const RArchConfig *cfg, const char *addr, const char *rt, int w, bool left, bool store) {
const char *mask = (w == 8)? "0xffffffffffffffff": "0xffffffff";
const char *align = (w == 8)? "0xfffffffffffffff8": "0xfffffffffffffffc";
const bool sx = !store && w == 4 && cfg->bits == 64;
// a le cpu counts the addressed byte from the other end of the word
char *sh = (R_ARCH_CONFIG_IS_BIG_ENDIAN (cfg) == left)
? r_str_newf ("3,%s,%d,&,<<", addr, w - 1)
: r_str_newf ("3,%s,%d,&,%d,-,<<", addr, w - 1, w - 1);
char *mem = r_str_newf ("%s,%s,&,[%d]", addr, align, w);
if (store && left) {
r_strbuf_appendf (esil, "%s,%s,>>,%s,^,%s,&,%s,%s,%s,&,>>,|,%s,%s,&,=[%d]",
sh, mask, mask, mem, sh, mask, rt, addr, align, w);
} else if (store) {
r_strbuf_appendf (esil, "%s,%s,%s,&,<<,1,%s,1,<<,-,%s,&,|,%s,%s,&,=[%d]",
sh, mask, rt, sh, mem, addr, align, w);
} else if (left) {
r_strbuf_appendf (esil, "%s%s,%s,<<,%s,&,1,%s,1,<<,-,%s,&,|,%s%s,=",
sx? "32,": "", sh, mem, mask, sh, rt, sx? "~,": "", rt);
} else {
r_strbuf_appendf (esil, "%s%s,%s,>>,%s,%s,%s,>>,^,%s,&,|,%s%s,=",
sx? "32,": "", sh, mem, mask, sh, mask, rt, sx? "~,": "", rt);
}
free (sh);
free (mem);
}
#endif

View file

@ -291,11 +291,19 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
ARG (0), ARG (1));
break;
case MIPS_INS_SW:
case MIPS_INS_SWL:
case MIPS_INS_SWR:
r_strbuf_appendf (&op->esil, "%s,%s,=[4]",
ARG (0), ARG (1));
break;
case MIPS_INS_SWL:
case MIPS_INS_SWR:
case MIPS_INS_SDL:
case MIPS_INS_SDR:
{
const bool wide = insn->id == MIPS_INS_SDL || insn->id == MIPS_INS_SDR;
const bool left = insn->id == MIPS_INS_SWL || insn->id == MIPS_INS_SDL;
mips_esil_unaligned (&op->esil, as->config, ARG (1), ARG (0), wide? 8: 4, left, true);
}
break;
case MIPS_INS_SH:
r_strbuf_appendf (&op->esil, "%s,%s,=[2]",
ARG (0), ARG (1));
@ -648,13 +656,19 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
break;
case MIPS_INS_LWC1:
case MIPS_INS_LWC2:
case MIPS_INS_LWL:
case MIPS_INS_LWR:
case MIPS_INS_LWU:
ESIL_LOAD ("4");
break;
case MIPS_INS_LWL:
case MIPS_INS_LWR:
case MIPS_INS_LDL:
case MIPS_INS_LDR:
PROTECT_ZERO () {
const bool wide = insn->id == MIPS_INS_LDL || insn->id == MIPS_INS_LDR;
const bool left = insn->id == MIPS_INS_LWL || insn->id == MIPS_INS_LDL;
mips_esil_unaligned (&op->esil, as->config, ARG (1), REG (0), wide? 8: 4, left, false);
}
break;
case MIPS_INS_LDC1:
case MIPS_INS_LDC2:
case MIPS_INS_LLD:
@ -1172,6 +1186,8 @@ static bool decode(RArchSession *as, RAnalOp *op, RArchDecodeMask mask) {
case MIPS_INS_SWL:
case MIPS_INS_SWR:
case MIPS_INS_SWXC1:
case MIPS_INS_SDL:
case MIPS_INS_SDR:
op->type = R_ANAL_OP_TYPE_STORE;
break;
case MIPS_INS_NOP:

View file

@ -2206,3 +2206,121 @@ EXPECT=<<EOF
0x00001234
EOF
RUN
NAME=mips lwl and lwr merge the addressed bytes into the register
FILE=malloc://0x200
ARGS=-a mips -b 32 -e cfg.bigendian=true
CMDS=<<EOF
ar > /dev/null
wx 11223344 @ 4
aei
aeim
s 8
ar t3=4
wx 89680001 @ 8
ar t0=0xaabbccdd
ar pc=8
aes
ar t0
wx 99680001 @ 8
ar t0=0xaabbccdd
ar pc=8
aes
ar t0
wx 89680003 @ 8
ar t0=0xaabbccdd
ar pc=8
aes
ar t0
wx 99680003 @ 8
ar t0=0xaabbccdd
ar pc=8
aes
ar t0
EOF
EXPECT=<<EOF
0x223344dd
0xaabb1122
0x44bbccdd
0x11223344
EOF
RUN
NAME=mips swl and swr write only the addressed bytes
FILE=malloc://0x200
ARGS=-a mips -b 32 -e cfg.bigendian=true
CMDS=<<EOF
ar > /dev/null
aei
aeim
s 8
ar t3=4
ar t1=0x55667788
wx 11223344 @ 4
wx a9690001 @ 8
ar pc=8
aes
p8 4 @ 4
wx 11223344 @ 4
wx b9690001 @ 8
ar pc=8
aes
p8 4 @ 4
wx 11223344 @ 4
wx a9690003 @ 8
ar pc=8
aes
p8 4 @ 4
wx 11223344 @ 4
wx b9690003 @ 8
ar pc=8
aes
p8 4 @ 4
EOF
EXPECT=<<EOF
11556677
77883344
11223355
55667788
EOF
RUN
NAME=mips counts the unaligned bytes from the other end when little endian
FILE=malloc://0x200
ARGS=-a mips -b 32
CMDS=<<EOF
ar > /dev/null
wx 11223344 @ 4
aei
aeim
s 8
ar t3=4
ar t1=0x55667788
wx 01006889 @ 8
ar t0=0xaabbccdd
ar pc=8
aes
ar t0
wx 01006899 @ 8
ar t0=0xaabbccdd
ar pc=8
aes
ar t0
wx 11223344 @ 4
wx 010069a9 @ 8
ar pc=8
aes
p8 4 @ 4
wx 11223344 @ 4
wx 010069b9 @ 8
ar pc=8
aes
p8 4 @ 4
EOF
EXPECT=<<EOF
0x2211ccdd
0xaa443322
66553344
11887766
EOF
RUN

View file

@ -226,3 +226,90 @@ EXPECT=<<EOF
0x7fffffff
EOF
RUN
NAME=mips64 ldl and ldr merge the addressed bytes into the register
FILE=malloc://0x200
ARGS=-a mips -b 64 -e cfg.bigendian=true
CMDS=<<EOF
ar > /dev/null
wx 1122334455667788 @ 8
aei
aeim
s 0x20
ar t3=8
wx 69680001 @ 0x20
ar t0=0xa1a2a3a4a5a6a7a8
ar pc=0x20
aes
ar t0
wx 6d680001 @ 0x20
ar t0=0xa1a2a3a4a5a6a7a8
ar pc=0x20
aes
ar t0
EOF
EXPECT=<<EOF
0x22334455667788a8
0xa1a2a3a4a5a61122
EOF
RUN
NAME=mips64 sdl and sdr write only the addressed bytes
FILE=malloc://0x200
ARGS=-a mips -b 64 -e cfg.bigendian=true
CMDS=<<EOF
ar > /dev/null
aei
aeim
s 0x20
ar t3=8
ar t1=0xf1f2f3f4f5f6f7f8
wx 1122334455667788 @ 8
wx b1690001 @ 0x20
ar pc=0x20
aes
p8 8 @ 8
wx 1122334455667788 @ 8
wx b5690001 @ 0x20
ar pc=0x20
aes
p8 8 @ 8
EOF
EXPECT=<<EOF
11f1f2f3f4f5f6f7
f7f8334455667788
EOF
RUN
NAME=mips64 lwl and lwr sign-extend the merged word
FILE=malloc://0x200
ARGS=-a mips -b 64 -e cfg.bigendian=true
CMDS=<<EOF
ar > /dev/null
wx 80223344 @ 4
aei
aeim
s 0x20
ar t3=4
wx 89680000 @ 0x20
ar t0=0xa1a2a3a4a5a6a7a8
ar pc=0x20
aes
ar t0
wx 99680003 @ 0x20
ar t0=0xa1a2a3a4a5a6a7a8
ar pc=0x20
aes
ar t0
wx 89680002 @ 0x20
ar t0=0xa1a2a3a4a5a6a7a8
ar pc=0x20
aes
ar t0
EOF
EXPECT=<<EOF
0xffffffff80223344
0xffffffff80223344
0x3344a7a8
EOF
RUN