Skip to content

Commit 56a2986

Browse files
author
Valentin Obst
committed
libr/mips: fix USE_DS
1 parent 43c83dc commit 56a2986

File tree

2 files changed

+188
-51
lines changed

2 files changed

+188
-51
lines changed

libr/arch/p/mips/plugin_cs.c

Lines changed: 121 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,25 @@ R_IPI int mips_assemble(const char *str, ut64 pc, ut8 *out);
6464

6565

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

7070
// call without delay slot
71-
#define ES_CALL_NDR(ra, addr) "pc,"ra",=,"ES_J(addr)
71+
#define ES_CALL_NDR(ra, addr) "pc,"ra",=,"ES_J_ND(addr)
7272
#define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr)
7373

74-
#define USE_DS 0
74+
#define USE_DS 1
7575
#if USE_DS
7676
// emit ERR trap if executed in a delay slot
7777
#define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,},"
78-
// jump to address
79-
#define ES_J(addr) addr",SETJT,1,SETD"
78+
// Record jump-to-address and set delay slot flag.
79+
#define ES_J_D(addr) addr",SETJT,1,SETD"
80+
// Jump to address.
81+
#define ES_J_ND(addr) addr",pc,:="
8082
#else
8183
#define ES_TRAP_DS() ""
82-
#define ES_J(addr) addr",pc,:="
84+
#define ES_J_D(addr) addr",pc,:="
85+
#define ES_J_ND(addr) ES_J_D(addr)
8386
#endif
8487

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

245249
r_strbuf_init (&op->esil);
246250
r_strbuf_set (&op->esil, "");
@@ -314,6 +318,15 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
314318
case MIPS_INS_SLL:
315319
r_strbuf_appendf (&op->esil, "%s,%s,<<,%s,=", ARG (2), ARG (1), ARG (0));
316320
break;
321+
case MIPS_INS_BALC:
322+
// BALC address
323+
// Branch And Link, Compact. Unconditional PC relative branch to address, placing return address
324+
// in register $31.
325+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_ND ("%s"), ARG (0));
326+
#if USE_DS
327+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
328+
#endif
329+
break;
317330
case MIPS_INS_BAL:
318331
case MIPS_INS_JAL:
319332
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_D ("%s"), ARG (0));
@@ -348,48 +361,94 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
348361
break;
349362
case MIPS_INS_JRADDIUSP:
350363
// increment stackpointer in X and jump to %ra
351-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,sp,+=," ES_J ("ra"), ARG (0));
364+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,sp,+=," ES_J_D ("ra"), ARG (0));
352365
#if USE_DS
353366
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
354367
#endif
355368
break;
356-
case MIPS_INS_JR:
357369
case MIPS_INS_JRC:
370+
case MIPS_INS_BC:
371+
// JRC rt
372+
// Jump Register, Compact. Unconditional jump to address in register $rt.
373+
// BC address
374+
// Branch, Compact. Unconditional PC relative branch to address.
375+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J_ND ("%s"), ARG (0));
376+
#if USE_DS
377+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
378+
#endif
379+
break;
380+
case MIPS_INS_JR:
358381
case MIPS_INS_J:
359382
case MIPS_INS_B: // ???
360383
// jump to address with conditional
361-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J ("%s"), ARG (0));
384+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J_D ("%s"), ARG (0));
385+
#if USE_DS
386+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
387+
#endif
388+
break;
389+
case MIPS_INS_BNEC:
390+
// BNEC rs, rt, address
391+
// Branch Not Equal, Compact. PC relative branch to address if register $rs is not equal to
392+
// register $rt.
393+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J_ND ("%s") ",}",
394+
ARG (0), ARG (1), ARG (2));
362395
#if USE_DS
363396
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
364397
#endif
365398
break;
366399
case MIPS_INS_BNE: // bne $s, $t, offset
367400
case MIPS_INS_BNEL:
368-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J ("%s") ",}",
401+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J_D ("%s") ",}",
402+
ARG (0), ARG (1), ARG (2));
403+
#if USE_DS
404+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
405+
#endif
406+
break;
407+
case MIPS_INS_BEQC:
408+
// BEQC rs, rt, address
409+
// Branch if Equal, Compact. PC relative branch to address if registers $rs and $rt are are equal.
410+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J_ND ("%s") ",}",
369411
ARG (0), ARG (1), ARG (2));
370412
#if USE_DS
371413
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
372414
#endif
373415
break;
374416
case MIPS_INS_BEQ:
375417
case MIPS_INS_BEQL:
376-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J ("%s") ",}",
418+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J_D ("%s") ",}",
377419
ARG (0), ARG (1), ARG (2));
378420
#if USE_DS
379421
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
422+
#endif
423+
break;
424+
case MIPS_INS_BEQZC:
425+
// BEQZC rt, address # when rt and address are in range
426+
// Branch if Equal to Zero, Compact. PC relative branch to address if register $rt equals zero.
427+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,?{," ES_J_ND ("%s") ",}",
428+
ARG (0), ARG (1));
429+
#if USE_DS
430+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
380431
#endif
381432
break;
382433
case MIPS_INS_BZ:
383434
case MIPS_INS_BEQZ:
384-
case MIPS_INS_BEQZC:
385-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,?{," ES_J ("%s") ",}",
435+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,?{," ES_J_D ("%s") ",}",
436+
ARG (0), ARG (1));
437+
#if USE_DS
438+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
439+
#endif
440+
break;
441+
case MIPS_INS_BNEZC:
442+
// BNEZC rt, address
443+
// Branch if Not Equal to Zero, Compact. PC relative branch to address if register $rt is not equal to zero.
444+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J_ND ("%s") ",}",
386445
ARG (0), ARG (1));
387446
#if USE_DS
388447
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
389448
#endif
390449
break;
391450
case MIPS_INS_BNEZ:
392-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J ("%s") ",}",
451+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J_D ("%s") ",}",
393452
ARG (0), ARG (1));
394453
#if USE_DS
395454
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
@@ -402,21 +461,45 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
402461
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
403462
#endif
404463
break;
405-
case MIPS_INS_BLEZ:
406464
case MIPS_INS_BLEZC:
465+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{," ES_J_ND ("%s") ",BREAK,},",
466+
ARG (0), ARG (1));
467+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_ND ("%s") ",}",
468+
ARG (0), ARG (1));
469+
#if USE_DS
470+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
471+
#endif
472+
break;
473+
case MIPS_INS_BLEZ:
407474
case MIPS_INS_BLEZL:
408-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{," ES_J ("%s") ",BREAK,},",
475+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{," ES_J_D ("%s") ",BREAK,},",
409476
ARG (0), ARG (1));
410-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
477+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_D ("%s") ",}",
411478
ARG (0), ARG (1));
412479
#if USE_DS
413480
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
414481
#endif
415482
break;
416-
case MIPS_INS_BGEZ:
483+
case MIPS_INS_BGEC:
484+
// BGEC rs, rt, address
485+
// Branch if Greater than or Equal, Compact. PC relative branch to address if register $rs
486+
// is greater than or equal to register $rt.
487+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,>=,$z,?{," ES_J_ND ("%s") ",}",
488+
ARG (1), ARG (0), ARG (2));
489+
#if USE_DS
490+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
491+
#endif
492+
break;
417493
case MIPS_INS_BGEZC:
494+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_ND ("%s") ",}",
495+
ARG (0), ARG (1));
496+
#if USE_DS
497+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
498+
#endif
499+
break;
500+
case MIPS_INS_BGEZ:
418501
case MIPS_INS_BGEZL:
419-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
502+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_D ("%s") ",}",
420503
ARG (0), ARG (1));
421504
#if USE_DS
422505
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
@@ -450,33 +533,46 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
450533
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
451534
#endif
452535
break;
453-
case MIPS_INS_BLTZ:
454536
case MIPS_INS_BLTZC:
537+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_ND ("%s") ",}",
538+
ARG (0), ARG (1));
539+
#if USE_DS
540+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
541+
#endif
542+
break;
543+
case MIPS_INS_BLTZ:
455544
case MIPS_INS_BLTZL:
456-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
545+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_D ("%s") ",}",
457546
ARG (0), ARG (1));
458547
#if USE_DS
459548
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
460549
#endif
461550
break;
462-
case MIPS_INS_BGTZ:
463551
case MIPS_INS_BGTZC:
552+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{,BREAK,},", ARG (0));
553+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_ND ("%s") ",}",
554+
ARG (0), ARG (1));
555+
#if USE_DS
556+
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
557+
#endif
558+
break;
559+
case MIPS_INS_BGTZ:
464560
case MIPS_INS_BGTZL:
465561
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{,BREAK,},", ARG (0));
466-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
562+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J_D ("%s") ",}",
467563
ARG (0), ARG (1));
468564
#if USE_DS
469565
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
470566
#endif
471567
break;
472568
case MIPS_INS_BTEQZ:
473-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,t,==,$z,?{," ES_J ("%s") ",}", ARG (0));
569+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,t,==,$z,?{," ES_J_D ("%s") ",}", ARG (0));
474570
#if USE_DS
475571
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
476572
#endif
477573
break;
478574
case MIPS_INS_BTNEZ:
479-
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,t,==,$z,!,?{," ES_J ("%s") ",}", ARG (0));
575+
r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,t,==,$z,!,?{," ES_J_D ("%s") ",}", ARG (0));
480576
#if USE_DS
481577
r_strbuf_replacef (&op->esil, "$$", "0x%"PFMT64x, addr);
482578
#endif

0 commit comments

Comments
 (0)