Rizin
unix-like reverse engineering framework and cli tools
analysis_8051.c File Reference
#include <string.h>
#include <rz_types.h>
#include <rz_lib.h>
#include <rz_asm.h>
#include <rz_analysis.h>
#include <8051_ops.h>
#include "../asm/arch/8051/8051_disas.c"

Go to the source code of this file.

Classes

struct  i8051_cpu_model
 
struct  i8051_map_entry
 
struct  i8051_plugin_context
 

Macros

#define e(frag)   rz_strbuf_append(&op->esil, frag)
 
#define ef(frag, ...)   rz_strbuf_appendf(&op->esil, frag, __VA_ARGS__)
 
#define flag_c   "7,$c,c,:=,"
 
#define flag_b   "8,$b,c,:=,"
 
#define flag_ac   "3,$c,ac,:=,"
 
#define flag_ab   "3,$b,ac,:=,"
 
#define flag_ov   "6,$c,ov,:=,"
 
#define flag_ob   "7,$b,6,$b,^,ov,:=,"
 
#define flag_p   "0xff,a,&=,$p,!,p,:=,"
 
#define ev_a   0
 
#define ev_bit   bitindex[buf[1] >> 3]
 
#define ev_c   0
 
#define ev_dir1   buf[1]
 
#define ev_dir2   buf[2]
 
#define ev_dp   0
 
#define ev_dpx   0
 
#define ev_imm1   buf[1]
 
#define ev_imm2   buf[2]
 
#define ev_imm16   op->val
 
#define ev_ri   (1 & buf[0])
 
#define ev_rix   (1 & buf[0])
 
#define ev_rn   (7 & buf[0])
 
#define ev_sp2   0
 
#define ev_sp1   0
 
#define xr(subject)   exr_##subject(op, ev_##subject)
 
#define xw(subject)   exw_##subject(op, ev_##subject)
 
#define xi(subject, operation)   exi_##subject(op, ev_##subject, operation)
 
#define bit_set   ef("%d,1,<<,", buf[1] & 7)
 
#define bit_mask
 
#define bit_r
 
#define bit_c   ef("%d,c,<<,", buf[1] & 7);
 
#define jmp   ef("%" PFMT64d ",pc,=", op->jump)
 
#define cjmp
 
#define call
 
#define alu_op(val, aluop, flags)
 
#define alu_op_c(val, aluop, flags)
 
#define alu_op_d(val, aluop)
 
#define template_alu4_c(base, aluop, flags)
 
#define template_alu2(base, aluop)
 
#define template_alu4(base, aluop, flags)
 

Functions

static bool i8051_reg_write (RzReg *reg, const char *regname, ut32 num)
 
static ut32 i8051_reg_read (RzReg *reg, const char *regname)
 
static void map_cpu_memory (RzAnalysis *analysis, int entry, ut32 addr, ut32 size, bool force)
 
static void set_cpu_model (RzAnalysis *analysis, bool force)
 
static void exr_a (RzAnalysisOp *op, ut8 dummy)
 
static void exr_dir1 (RzAnalysisOp *op, ut8 addr)
 
static void exr_bit (RzAnalysisOp *op, ut8 addr)
 
static void exr_dpx (RzAnalysisOp *op, ut8 dummy)
 
static void exr_imm1 (RzAnalysisOp *op, ut8 val)
 
static void exr_imm2 (RzAnalysisOp *op, ut8 val)
 
static void exr_imm16 (RzAnalysisOp *op, ut16 val)
 
static void exr_ri (RzAnalysisOp *op, ut8 reg)
 
static void exr_rix (RzAnalysisOp *op, ut8 reg)
 
static void exr_rn (RzAnalysisOp *op, ut8 reg)
 
static void exr_sp1 (RzAnalysisOp *op, ut8 dummy)
 
static void exr_sp2 (RzAnalysisOp *op, ut8 dummy)
 
static void exw_a (RzAnalysisOp *op, ut8 dummy)
 
static void exw_c (RzAnalysisOp *op, ut8 dummy)
 
static void exw_dir1 (RzAnalysisOp *op, ut8 addr)
 
static void exw_dir2 (RzAnalysisOp *op, ut8 addr)
 
static void exw_bit (RzAnalysisOp *op, ut8 addr)
 
static void exw_dp (RzAnalysisOp *op, ut8 dummy)
 
static void exw_dpx (RzAnalysisOp *op, ut8 dummy)
 
static void exw_ri (RzAnalysisOp *op, ut8 reg)
 
static void exw_rix (RzAnalysisOp *op, ut8 reg)
 
static void exw_rn (RzAnalysisOp *op, ut8 reg)
 
static void exw_sp1 (RzAnalysisOp *op, ut8 dummy)
 
static void exw_sp2 (RzAnalysisOp *op, ut8 dummy)
 
static void exi_a (RzAnalysisOp *op, ut8 dummy, const char *operation)
 
static void exi_c (RzAnalysisOp *op, ut8 dummy, const char *operation)
 
static void exi_dp (RzAnalysisOp *op, ut8 dummy, const char *operation)
 
static void exi_dir1 (RzAnalysisOp *op, ut8 addr, const char *operation)
 
static void exi_bit (RzAnalysisOp *op, ut8 addr, const char *operation)
 
static void exi_ri (RzAnalysisOp *op, ut8 reg, const char *operation)
 
static void exi_rn (RzAnalysisOp *op, ut8 reg, const char *operation)
 
static void analop_esil (RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf)
 
static int esil_i8051_init (RzAnalysisEsil *esil)
 
static int esil_i8051_fini (RzAnalysisEsil *esil)
 
static char * get_reg_profile (RzAnalysis *analysis)
 
static ut32 map_direct_addr (RzAnalysis *analysis, ut8 addr)
 
static int i8051_op (RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
 
static bool i8051_init (void **user)
 
static bool i8051_fini (void *user)
 

Variables

static const i8051_cpu_model cpu_models []
 
static const int I8051_IDATA = 0
 
static const int I8051_SFR = 1
 
static const int I8051_XDATA = 2
 
static const i8051_map_entry init_mem_map [3]
 
static const ut8 bitindex []
 
RzAnalysisPlugin rz_analysis_plugin_8051
 
RZ_API RzLibStruct rizin_plugin
 

Macro Definition Documentation

◆ alu_op

#define alu_op (   val,
  aluop,
  flags 
)
Value:
xr(val); \
e("a," aluop "=," flags)
#define xr(subject)
ut16 val
Definition: armass64_const.h:6
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123

Definition at line 411 of file analysis_8051.c.

◆ alu_op_c

#define alu_op_c (   val,
  aluop,
  flags 
)
Value:
e("c,"); \
xr(val); \
e("+,a," aluop "=," flags)
#define e(frag)

Definition at line 414 of file analysis_8051.c.

◆ alu_op_d

#define alu_op_d (   val,
  aluop 
)
Value:
xr(val); \
xi(dir1, aluop)

Definition at line 418 of file analysis_8051.c.

◆ bit_c

#define bit_c   ef("%d,c,<<,", buf[1] & 7);

Definition at line 399 of file analysis_8051.c.

◆ bit_mask

#define bit_mask
Value:
e("255,^,")
#define bit_set

Definition at line 392 of file analysis_8051.c.

◆ bit_r

#define bit_r
Value:
ef("%d,", buf[1] & 7); \
xr(bit); \
e(">>,1,&,")
#define ef(frag,...)
RzCryptoSelector bit
Definition: crypto.c:16
voidpf void * buf
Definition: ioapi.h:138

Definition at line 395 of file analysis_8051.c.

◆ bit_set

#define bit_set   ef("%d,1,<<,", buf[1] & 7)

Definition at line 391 of file analysis_8051.c.

◆ call

#define call
Value:
ef("%" PFMT64d ",", op->fail); \
xw(sp2); \
jmp
#define PFMT64d
Definition: rz_types.h:394
Definition: dis.c:32

Definition at line 406 of file analysis_8051.c.

◆ cjmp

#define cjmp
Value:
e("?{,"); \
jmp; \
e(",}")

Definition at line 402 of file analysis_8051.c.

◆ e

#define e (   frag)    rz_strbuf_append(&op->esil, frag)

Definition at line 218 of file analysis_8051.c.

◆ ef

#define ef (   frag,
  ... 
)    rz_strbuf_appendf(&op->esil, frag, __VA_ARGS__)

Definition at line 219 of file analysis_8051.c.

◆ ev_a

#define ev_a   0

Definition at line 229 of file analysis_8051.c.

◆ ev_bit

#define ev_bit   bitindex[buf[1] >> 3]

Definition at line 230 of file analysis_8051.c.

◆ ev_c

#define ev_c   0

Definition at line 231 of file analysis_8051.c.

◆ ev_dir1

#define ev_dir1   buf[1]

Definition at line 232 of file analysis_8051.c.

◆ ev_dir2

#define ev_dir2   buf[2]

Definition at line 233 of file analysis_8051.c.

◆ ev_dp

#define ev_dp   0

Definition at line 234 of file analysis_8051.c.

◆ ev_dpx

#define ev_dpx   0

Definition at line 235 of file analysis_8051.c.

◆ ev_imm1

#define ev_imm1   buf[1]

Definition at line 236 of file analysis_8051.c.

◆ ev_imm16

#define ev_imm16   op->val

Definition at line 238 of file analysis_8051.c.

◆ ev_imm2

#define ev_imm2   buf[2]

Definition at line 237 of file analysis_8051.c.

◆ ev_ri

#define ev_ri   (1 & buf[0])

Definition at line 239 of file analysis_8051.c.

◆ ev_rix

#define ev_rix   (1 & buf[0])

Definition at line 240 of file analysis_8051.c.

◆ ev_rn

#define ev_rn   (7 & buf[0])

Definition at line 241 of file analysis_8051.c.

◆ ev_sp1

#define ev_sp1   0

Definition at line 243 of file analysis_8051.c.

◆ ev_sp2

#define ev_sp2   0

Definition at line 242 of file analysis_8051.c.

◆ flag_ab

#define flag_ab   "3,$b,ac,:=,"

Definition at line 224 of file analysis_8051.c.

◆ flag_ac

#define flag_ac   "3,$c,ac,:=,"

Definition at line 223 of file analysis_8051.c.

◆ flag_b

#define flag_b   "8,$b,c,:=,"

Definition at line 222 of file analysis_8051.c.

◆ flag_c

#define flag_c   "7,$c,c,:=,"

Definition at line 221 of file analysis_8051.c.

◆ flag_ob

#define flag_ob   "7,$b,6,$b,^,ov,:=,"

Definition at line 226 of file analysis_8051.c.

◆ flag_ov

#define flag_ov   "6,$c,ov,:=,"

Definition at line 225 of file analysis_8051.c.

◆ flag_p

#define flag_p   "0xff,a,&=,$p,!,p,:=,"

Definition at line 227 of file analysis_8051.c.

◆ jmp

#define jmp   ef("%" PFMT64d ",pc,=", op->jump)

Definition at line 401 of file analysis_8051.c.

◆ template_alu2

#define template_alu2 (   base,
  aluop 
)
Value:
case base + 0x2: \
alu_op_d(a, aluop); \
break; \
case base + 0x3: \
alu_op_d(imm2, aluop); \
break;
#define a(i)
Definition: sha256.c:41

Definition at line 444 of file analysis_8051.c.

◆ template_alu4

#define template_alu4 (   base,
  aluop,
  flags 
)
Value:
case base + 0x4: \
alu_op(imm1, aluop, flags); \
break; \
case base + 0x5: \
alu_op(dir1, aluop, flags); \
break; \
case base + 0x6: \
case base + 0x7: \
alu_op(ri, aluop, flags); \
break; \
case base + 0x8: \
case base + 0x9: \
case base + 0xA: \
case base + 0xB: \
case base + 0xC: \
case base + 0xD: \
case base + 0xE: \
case base + 0xF: \
alu_op(rn, aluop, flags); \
break;

Definition at line 452 of file analysis_8051.c.

◆ template_alu4_c

#define template_alu4_c (   base,
  aluop,
  flags 
)
Value:
case base + 0x4: \
alu_op_c(imm1, aluop, flags); \
break; \
case base + 0x5: \
alu_op_c(dir1, aluop, flags); \
break; \
case base + 0x6: \
case base + 0x7: \
alu_op_c(ri, aluop, flags); \
break; \
case base + 0x8: \
case base + 0x9: \
case base + 0xA: \
case base + 0xB: \
case base + 0xC: \
case base + 0xD: \
case base + 0xE: \
case base + 0xF: \
alu_op_c(rn, aluop, flags); \
break;

Definition at line 422 of file analysis_8051.c.

◆ xi

#define xi (   subject,
  operation 
)    exi_##subject(op, ev_##subject, operation)

Definition at line 389 of file analysis_8051.c.

◆ xr

#define xr (   subject)    exr_##subject(op, ev_##subject)

Definition at line 387 of file analysis_8051.c.

◆ xw

#define xw (   subject)    exw_##subject(op, ev_##subject)

Definition at line 388 of file analysis_8051.c.

Function Documentation

◆ analop_esil()

static void analop_esil ( RzAnalysis a,
RzAnalysisOp op,
ut64  addr,
const ut8 buf 
)
static

Definition at line 474 of file analysis_8051.c.

474  {
475  rz_strbuf_init(&op->esil);
476  rz_strbuf_set(&op->esil, "");
477 
478  switch (buf[0]) {
479  // Irregulars sorted by lower nibble
480  case 0x00: /* nop */
481  e(",");
482  break;
483 
484  case 0x10: /* jbc bit, offset */
485  bit_r;
486  e("?{,");
487  bit_mask;
488  xi(bit, "&");
489  jmp;
490  e(",}");
491  break;
492  case 0x20: /* jb bit, offset */
493  bit_r;
494  cjmp;
495  break;
496  case 0x30: /* jnb bit, offset */
497  bit_r;
498  e("!,");
499  cjmp;
500  break;
501  case 0x40: /* jc offset */
502  e("c,1,&,");
503  cjmp;
504  break;
505  case 0x50: /* jnc offset */
506  e("c,1,&,!,");
507  cjmp;
508  break;
509  case 0x60: /* jz offset */
510  e("a,0,==,$z,");
511  cjmp;
512  break;
513  case 0x70: /* jnz offset */
514  e("a,0,==,$z,!,");
515  cjmp;
516  break;
517 
518  case 0x11:
519  case 0x31:
520  case 0x51:
521  case 0x71:
522  case 0x91:
523  case 0xB1:
524  case 0xD1:
525  case 0xF1: /* acall addr11 */
526  case 0x12: /* lcall addr16 */
527  call;
528  break;
529  case 0x01:
530  case 0x21:
531  case 0x41:
532  case 0x61:
533  case 0x81:
534  case 0xA1:
535  case 0xC1:
536  case 0xE1: /* ajmp addr11 */
537  case 0x02: /* ljmp addr16 */
538  case 0x80: /* sjmp offset */
539  jmp;
540  break;
541 
542  case 0x22: /* ret */
543  case 0x32: /* reti */
544  xr(sp2);
545  e("pc,=");
546  break;
547 
548  case 0x03: /* rr a */
549  e("1,a,0x101,*,>>,a,=," flag_p);
550  break;
551  case 0x04: /* inc a */
552  xi(a, "++");
553  e(flag_p);
554  break;
555  case 0x05: /* inc direct */
556  xi(dir1, "++");
557  break;
558  case 0x06:
559  case 0x07: /* inc @Ri */
560  xi(ri, "++");
561  break;
562  case 0x08:
563  case 0x09:
564  case 0x0A:
565  case 0x0B:
566  case 0x0C:
567  case 0x0D:
568  case 0x0E:
569  case 0x0F: /* inc @Rn */
570  xi(rn, "++");
571  break;
572  case 0x13: /* rrc a */
573  e("7,c,<<,1,a,&,c,=,0x7f,1,a,>>,&,+,a,=," flag_p);
574  break;
575  case 0x14: /* dec a */
576  xi(a, "--");
577  e(flag_p);
578  break;
579  case 0x15: /* dec direct */
580  xi(dir1, "--");
581  e(flag_p);
582  break;
583  case 0x16:
584  case 0x17: /* dec @Ri */
585  xi(ri, "--");
586  break;
587  case 0x18:
588  case 0x19:
589  case 0x1A:
590  case 0x1B:
591  case 0x1C:
592  case 0x1D:
593  case 0x1E:
594  case 0x1F: /* dec @Rn */
595  xi(rn, "--");
596  break;
597  case 0x23: /* rl a */
598  e("7,a,0x101,*,>>,a,=," flag_p);
599  break;
600  template_alu4(0x20, "+", flag_c flag_ac flag_ov flag_p) /* 0x24..0x2f add a,.. */
601  case 0x33 : /* rlc a */
602  e("c,1,&,a,a,+=,7,$c,c,:=,a,+=," flag_p);
603  break;
604  template_alu4_c(0x30, "+", flag_c flag_ac flag_ov flag_p) /* 0x34..0x3f addc a,.. */
605  template_alu2(0x40, "|") /* 0x42..0x43 orl direct,.. */
606  template_alu4(0x40, "|", flag_p) /* 0x44..0x4f orl a,.. */
607  template_alu2(0x50, "&") /* 0x52..0x53 anl direct,.. */
608  template_alu4(0x50, "&", flag_p) /* 0x54..0x5f anl a,.. */
609  template_alu2(0x60, "^") /* 0x62..0x63 xrl direct,.. */
610  template_alu4(0x60, "^", flag_p) /* 0x64..0x6f xrl a,.. */
611  case 0x72 : /* orl C, bit */
612  bit_r;
613  xi(c, "|");
614  break;
615  case 0x73: /* jmp @a+dptr */
616  e("dptr,a,+,pc,=");
617  break;
618  case 0x74: /* mov a, imm */
619  xr(imm1);
620  xw(a);
621  e(flag_p);
622  break;
623  case 0x75: /* mov direct, imm */
624  xr(imm2);
625  xw(dir1);
626  break;
627  case 0x76:
628  case 0x77: /* mov @Ri, imm */
629  xr(imm1);
630  xw(ri);
631  break;
632  case 0x78:
633  case 0x79:
634  case 0x7A:
635  case 0x7B:
636  case 0x7C:
637  case 0x7D:
638  case 0x7E:
639  case 0x7F: /* mov Rn, imm */
640  xr(imm1);
641  xw(rn);
642  break;
643  case 0x82: /* anl C, bit */
644  bit_r;
645  xi(c, "&");
646  break;
647  case 0x83: /* movc a, @a+pc */
648  e("a,pc,--,+,[1],a,=," flag_p);
649  break;
650  case 0x84: /* div ab */
651  // note: escape % if this becomes a format string
652  e("b,0,==,$z,ov,:=,b,a,%,b,a,/=,b,=,0,c,=," flag_p);
653  break;
654  case 0x85: /* mov direct, direct */
655  xr(dir1);
656  xw(dir2);
657  break;
658  case 0x86:
659  case 0x87: /* mov direct, @Ri */
660  xr(ri);
661  xw(dir1);
662  break;
663  case 0x88:
664  case 0x89:
665  case 0x8A:
666  case 0x8B:
667  case 0x8C:
668  case 0x8D:
669  case 0x8E:
670  case 0x8F: /* mov direct, Rn */
671  xr(rn);
672  xw(dir1);
673  break;
674  case 0x90: /* mov dptr, imm */
675  xr(imm16);
676  xw(dp);
677  break;
678  case 0x92: /* mov bit, C */
679  bit_c;
680  bit_mask;
681  xr(bit);
682  e("&,|,");
683  xw(bit);
684  break;
685  case 0x93: /* movc a, @a+dptr */
686  e("a,dptr,+,[1],a,=," flag_p);
687  break;
688  template_alu4_c(0x90, "-", flag_b flag_ab flag_ob flag_p) /* 0x94..0x9f subb a,.. */
689  case 0xA0 : /* orl C, /bit */
690  bit_r;
691  e("!,");
692  xi(c, "|");
693  break;
694  case 0xA2: /* mov C, bit */
695  bit_r;
696  xw(c);
697  break;
698  case 0xA3: /* inc dptr */
699  xi(dp, "++");
700  break;
701  case 0xA4: /* mul ab */
702  e("8,a,b,*,DUP,a,=,>>,DUP,b,=,0,==,$z,!,ov,:=,0,c,=," flag_p);
703  break;
704  case 0xA5: /* "reserved" */
705  e("0,trap");
706  break;
707  case 0xA6:
708  case 0xA7: /* mov @Ri, direct */
709  xr(dir1);
710  xw(ri);
711  break;
712  case 0xA8:
713  case 0xA9:
714  case 0xAA:
715  case 0xAB:
716  case 0xAC:
717  case 0xAD:
718  case 0xAE:
719  case 0xAF: /* mov Rn, direct */
720  xr(dir1);
721  xw(rn);
722  break;
723  case 0xB0: /* anl C, /bit */
724  bit_r;
725  e("!,");
726  xi(c, "&");
727  break;
728  case 0xB2: /* cpl bit */
729  bit_set;
730  xi(bit, "^");
731  break;
732  case 0xB3: /* cpl C */
733  e("1,");
734  xi(c, "^");
735  break;
736  case 0xB4: /* cjne a, imm, offset */
737  xr(imm1);
738  xr(a);
739  e("==,$z,!," flag_b);
740  cjmp;
741  break;
742  case 0xB5: /* cjne a, direct, offset */
743  xr(dir1);
744  xr(a);
745  e("==,$z,!," flag_b);
746  cjmp;
747  break;
748  case 0xB6:
749  case 0xB7: /* cjne @ri, imm, offset */
750  xr(imm1);
751  xr(ri);
752  e("==,$z,!," flag_b);
753  cjmp;
754  break;
755  case 0xB8:
756  case 0xB9:
757  case 0xBA:
758  case 0xBB:
759  case 0xBC:
760  case 0xBD:
761  case 0xBE:
762  case 0xBF: /* cjne Rn, imm, offset */
763  xr(imm1);
764  xr(rn);
765  e("==,$z,!," flag_b);
766  cjmp;
767  break;
768  case 0xC0: /* push direct */
769  xr(dir1);
770  xw(sp1);
771  break;
772  case 0xC2: /* clr bit */
773  bit_mask;
774  xi(bit, "&");
775  break;
776  case 0xC3: /* clr C */
777  e("0,");
778  xw(c);
779  break;
780  case 0xC4: /* swap a */
781  e("0xff,4,a,0x101,*,>>,&,a,=," flag_p);
782  break;
783  case 0xC5: /* xch a, direct */
784  xr(a);
785  e("0,+,");
786  xr(dir1);
787  xw(a);
788  xw(dir1);
789  e(flag_p);
790  break;
791  case 0xC6:
792  case 0xC7: /* xch a, @Ri */
793  xr(a);
794  e("0,+,");
795  xr(ri);
796  xw(a);
797  xw(ri);
798  e(flag_p);
799  break;
800  case 0xC8:
801  case 0xC9:
802  case 0xCA:
803  case 0xCB:
804  case 0xCC:
805  case 0xCD:
806  case 0xCE:
807  case 0xCF: /* xch a, Rn */
808  xr(a);
809  e("0,+,");
810  xr(rn);
811  xw(a);
812  xw(rn);
813  e(flag_p);
814  break;
815  case 0xD0: /* pop direct */
816  xr(sp1);
817  xw(dir1);
818  break;
819  case 0xD2: /* setb bit */
820  bit_set;
821  xi(bit, "|");
822  break;
823  case 0xD3: /* setb C */
824  e("1,");
825  xw(c);
826  break;
827  case 0xD4: /* da a */
828  // BCD adjust after add:
829  // if (lower nibble > 9) or (AC == 1) add 6
830  // if (higher nibble > 9) or (C == 1) add 0x60
831  // carry |= carry caused by this operation
832  e("a,0x0f,&,9,==,4,$b,ac,|,?{,6,a,+=,7,$c,c,|,c,:=,},a,0xf0,&,0x90,==,8,$b,c,|,?{,0x60,a,+=,7,$c,c,|,c,:=,}," flag_p);
833  break;
834  case 0xD5: /* djnz direct, offset */
835  xi(dir1, "--");
836  xr(dir1);
837  e("0,==,$z,!,");
838  cjmp;
839  break;
840  case 0xD6:
841  case 0xD7: /* xchd a, @Ri*/
842  xr(a);
843  e("0xf0,&,");
844  xr(ri);
845  e("0x0f,&,|,");
846  xr(ri);
847  e("0xf0,&,");
848  xr(a);
849  e("0x0f,&,|,");
850  xw(ri);
851  xw(a);
852  e(flag_p);
853  break;
854  case 0xD8:
855  case 0xD9:
856  case 0xDA:
857  case 0xDB:
858  case 0xDC:
859  case 0xDD:
860  case 0xDE:
861  case 0xDF: /* djnz Rn, offset */
862  xi(rn, "--");
863  xr(rn);
864  e("0,==,$z,!,");
865  cjmp;
866  break;
867  case 0xE0: /* movx a, @dptr */
868  xr(dpx);
869  xw(a);
870  e(flag_p);
871  break;
872  case 0xE2:
873  case 0xE3: /* movx a, @Ri */
874  xr(rix);
875  xw(a);
876  e(flag_p);
877  break;
878  case 0xE4: /* clr a */
879  e("0,");
880  xw(a);
881  e(flag_p);
882  break;
883  case 0xE5: /* mov a, direct */
884  xr(dir1);
885  xw(a);
886  e(flag_p);
887  break;
888  case 0xE6:
889  case 0xE7: /* mov a, @Ri */
890  xr(ri);
891  xw(a);
892  e(flag_p);
893  break;
894  case 0xE8:
895  case 0xE9:
896  case 0xEA:
897  case 0xEB:
898  case 0xEC:
899  case 0xED:
900  case 0xEE:
901  case 0xEF: /* mov a, Rn */
902  xr(rn);
903  xw(a);
904  e(flag_p);
905  break;
906  case 0xF0: /* movx @dptr, a */
907  xr(a);
908  xw(dpx);
909  break;
910  case 0xF2:
911  case 0xF3: /* movx @Ri, a */
912  xr(a);
913  xw(rix);
914  break;
915  case 0xF4: /* cpl a */
916  e("255,");
917  xi(a, "^");
918  e(flag_p);
919  break;
920  case 0xF5: /* mov direct, a */
921  xr(a);
922  xw(dir1);
923  break;
924  case 0xF6:
925  case 0xF7: /* mov @Ri, a */
926  xr(a);
927  xw(ri);
928  break;
929  case 0xF8:
930  case 0xF9:
931  case 0xFA:
932  case 0xFB:
933  case 0xFC:
934  case 0xFD:
935  case 0xFE:
936  case 0xFF: /* mov Rn, a */
937  xr(a);
938  xw(rn);
939  break;
940  default:
941  break;
942  }
943 }
#define flag_ov
#define bit_r
#define jmp
#define flag_ac
#define xi(subject, operation)
#define flag_b
#define template_alu4_c(base, aluop, flags)
#define xw(subject)
#define bit_c
#define template_alu2(base, aluop)
#define template_alu4(base, aluop, flags)
#define flag_ab
#define flag_p
#define cjmp
#define flag_ob
#define bit_mask
#define flag_c
#define call
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
@ DUP
Definition: packet.c:12
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43

References a, bit, bit_c, bit_mask, bit_r, bit_set, c, call, cjmp, e, flag_ab, flag_ac, flag_b, flag_c, flag_ob, flag_ov, flag_p, jmp, rz_strbuf_init(), rz_strbuf_set(), template_alu2, template_alu4, template_alu4_c, xi, xr, and xw.

Referenced by i8051_op().

◆ esil_i8051_fini()

static int esil_i8051_fini ( RzAnalysisEsil esil)
static

Definition at line 1037 of file analysis_8051.c.

1037  {
1038  RZ_FREE(esil->cb.user);
1039  return true;
1040 }
#define RZ_FREE(x)
Definition: rz_types.h:369
RzAnalysisEsilCallbacks cb
Definition: rz_analysis.h:1078

References rz_analysis_esil_t::cb, RZ_FREE, and rz_analysis_esil_callbacks_t::user.

◆ esil_i8051_init()

static int esil_i8051_init ( RzAnalysisEsil esil)
static

Definition at line 1015 of file analysis_8051.c.

1015  {
1016  // reset emulation control registers based on cpu
1017  set_cpu_model(esil->analysis, true);
1018 
1019  if (esil->cb.user) {
1020  return true;
1021  }
1023  if (!ocbs) {
1024  return 0;
1025  }
1026  *ocbs = esil->cb;
1027  esil->cb.user = ocbs;
1028  /* these hooks break esil emulation */
1029  /* pc is not read properly, mem mapped registers are not shown in ar, ... */
1030  /* all 8051 regs are mem mapped, and reg access via mem is very common */
1031  // disabled to make esil work, before digging deeper
1032  // esil->cb.hook_reg_read = i8051_hook_reg_read;
1033  // esil->cb.hook_reg_write = i8051_hook_reg_write;
1034  return true;
1035 }
static void set_cpu_model(RzAnalysis *analysis, bool force)
static RzAnalysisEsilCallbacks ocbs
Definition: esil_trace.c:11
#define RZ_NEW0(x)
Definition: rz_types.h:284
RzAnalysis * analysis
Definition: rz_analysis.h:1043

References rz_analysis_esil_t::analysis, rz_analysis_esil_t::cb, ocbs, RZ_NEW0, set_cpu_model(), and rz_analysis_esil_callbacks_t::user.

◆ exi_a()

static void exi_a ( RzAnalysisOp op,
ut8  dummy,
const char *  operation 
)
static

Definition at line 355 of file analysis_8051.c.

355  {
356  ef("a,%s=,", operation);
357 }

References ef.

◆ exi_bit()

static void exi_bit ( RzAnalysisOp op,
ut8  addr,
const char *  operation 
)
static

Definition at line 375 of file analysis_8051.c.

375  {
376  exi_dir1(op, addr, operation);
377 }
static void exi_dir1(RzAnalysisOp *op, ut8 addr, const char *operation)
static int addr
Definition: z80asm.c:58

References addr, and exi_dir1().

◆ exi_c()

static void exi_c ( RzAnalysisOp op,
ut8  dummy,
const char *  operation 
)
static

Definition at line 359 of file analysis_8051.c.

359  {
360  ef("c,%s=,", operation);
361 }

References ef.

◆ exi_dir1()

static void exi_dir1 ( RzAnalysisOp op,
ut8  addr,
const char *  operation 
)
static

Definition at line 367 of file analysis_8051.c.

367  {
368  if (addr < 0x80) {
369  ef("_idata,%d,+,%s=[1],", addr, operation);
370  } else {
371  ef("_sfr,%d,+,%s=[1],", addr, operation);
372  }
373 }

References addr, and ef.

Referenced by exi_bit().

◆ exi_dp()

static void exi_dp ( RzAnalysisOp op,
ut8  dummy,
const char *  operation 
)
static

Definition at line 363 of file analysis_8051.c.

363  {
364  ef("dptr,%s=,", operation);
365 }

References ef.

◆ exi_ri()

static void exi_ri ( RzAnalysisOp op,
ut8  reg,
const char *  operation 
)
static

Definition at line 379 of file analysis_8051.c.

379  {
380  ef("_idata,r%d,+,%s=[1],", reg, operation);
381 }
#define reg(n)

References ef, and reg.

◆ exi_rn()

static void exi_rn ( RzAnalysisOp op,
ut8  reg,
const char *  operation 
)
static

Definition at line 383 of file analysis_8051.c.

383  {
384  ef("r%d,%s=,", reg, operation);
385 }

References ef, and reg.

◆ exr_a()

static void exr_a ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 245 of file analysis_8051.c.

245  {
246  e("a,");
247 }

References e.

◆ exr_bit()

static void exr_bit ( RzAnalysisOp op,
ut8  addr 
)
static

Definition at line 257 of file analysis_8051.c.

257  {
258  exr_dir1(op, addr);
259 }
static void exr_dir1(RzAnalysisOp *op, ut8 addr)

References addr, and exr_dir1().

◆ exr_dir1()

static void exr_dir1 ( RzAnalysisOp op,
ut8  addr 
)
static

Definition at line 249 of file analysis_8051.c.

249  {
250  if (addr < 0x80) {
251  ef("_idata,%d,+,[1],", addr);
252  } else {
253  ef("_sfr,%d,+,[1],", addr);
254  }
255 }

References addr, and ef.

Referenced by exr_bit().

◆ exr_dpx()

static void exr_dpx ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 261 of file analysis_8051.c.

261  {
262  e("_xdata,dptr,+,[1],");
263 }

References e.

◆ exr_imm1()

static void exr_imm1 ( RzAnalysisOp op,
ut8  val 
)
static

Definition at line 265 of file analysis_8051.c.

265  {
266  ef("%d,", val);
267 }

References ef, and val.

◆ exr_imm16()

static void exr_imm16 ( RzAnalysisOp op,
ut16  val 
)
static

Definition at line 273 of file analysis_8051.c.

273  {
274  ef("%d,", val);
275 }

References ef, and val.

◆ exr_imm2()

static void exr_imm2 ( RzAnalysisOp op,
ut8  val 
)
static

Definition at line 269 of file analysis_8051.c.

269  {
270  ef("%d,", val);
271 }

References ef, and val.

◆ exr_ri()

static void exr_ri ( RzAnalysisOp op,
ut8  reg 
)
static

Definition at line 277 of file analysis_8051.c.

277  {
278  ef("_idata,r%d,+,[1],", reg);
279 }

References ef, and reg.

◆ exr_rix()

static void exr_rix ( RzAnalysisOp op,
ut8  reg 
)
static

Definition at line 281 of file analysis_8051.c.

281  {
282  ef("8,0xff,_pdata,&,<<,_xdata,+,r%d,+,[1],", reg);
283 }

References ef, and reg.

◆ exr_rn()

static void exr_rn ( RzAnalysisOp op,
ut8  reg 
)
static

Definition at line 285 of file analysis_8051.c.

285  {
286  ef("r%d,", reg);
287 }

References ef, and reg.

◆ exr_sp1()

static void exr_sp1 ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 289 of file analysis_8051.c.

289  {
290  e("_idata,sp,+,[1],");
291  e("1,sp,-=,");
292 }

References e.

◆ exr_sp2()

static void exr_sp2 ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 294 of file analysis_8051.c.

294  {
295  e("1,sp,-=,");
296  e("_idata,sp,+,[2],");
297  e("1,sp,-=,");
298 }

References e.

◆ exw_a()

static void exw_a ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 300 of file analysis_8051.c.

300  {
301  e("a,=,");
302 }

References e.

◆ exw_bit()

static void exw_bit ( RzAnalysisOp op,
ut8  addr 
)
static

Definition at line 320 of file analysis_8051.c.

320  {
321  exw_dir1(op, addr);
322 }
static void exw_dir1(RzAnalysisOp *op, ut8 addr)

References addr, and exw_dir1().

◆ exw_c()

static void exw_c ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 304 of file analysis_8051.c.

304  {
305  e("c,=,");
306 }

References e.

◆ exw_dir1()

static void exw_dir1 ( RzAnalysisOp op,
ut8  addr 
)
static

Definition at line 308 of file analysis_8051.c.

308  {
309  if (addr < 0x80) {
310  ef("_idata,%d,+,=[1],", addr);
311  } else {
312  ef("_sfr,%d,+,=[1],", addr);
313  }
314 }

References addr, and ef.

Referenced by exw_bit(), and exw_dir2().

◆ exw_dir2()

static void exw_dir2 ( RzAnalysisOp op,
ut8  addr 
)
static

Definition at line 316 of file analysis_8051.c.

316  {
317  exw_dir1(op, addr);
318 }

References addr, and exw_dir1().

◆ exw_dp()

static void exw_dp ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 324 of file analysis_8051.c.

324  {
325  e("dptr,=,");
326 }

References e.

◆ exw_dpx()

static void exw_dpx ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 328 of file analysis_8051.c.

328  {
329  e("_xdata,dptr,+,=[1],");
330 }

References e.

◆ exw_ri()

static void exw_ri ( RzAnalysisOp op,
ut8  reg 
)
static

Definition at line 332 of file analysis_8051.c.

332  {
333  ef("_idata,r%d,+,=[1],", reg);
334 }

References ef, and reg.

◆ exw_rix()

static void exw_rix ( RzAnalysisOp op,
ut8  reg 
)
static

Definition at line 336 of file analysis_8051.c.

336  {
337  ef("8,0xff,_pdata,&,<<,_xdata,+,r%d,+,=[1],", reg);
338 }

References ef, and reg.

◆ exw_rn()

static void exw_rn ( RzAnalysisOp op,
ut8  reg 
)
static

Definition at line 340 of file analysis_8051.c.

340  {
341  ef("r%d,=,", reg);
342 }

References ef, and reg.

◆ exw_sp1()

static void exw_sp1 ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 344 of file analysis_8051.c.

344  {
345  e("1,sp,+=,");
346  e("_idata,sp,+,=[1],");
347 }

References e.

◆ exw_sp2()

static void exw_sp2 ( RzAnalysisOp op,
ut8  dummy 
)
static

Definition at line 349 of file analysis_8051.c.

349  {
350  e("1,sp,+=,");
351  e("_idata,sp,+,=[2],");
352  e("1,sp,+=,");
353 }

References e.

◆ get_reg_profile()

static char* get_reg_profile ( RzAnalysis analysis)
static

Definition at line 1042 of file analysis_8051.c.

1042  {
1043  const char *p =
1044  "=PC pc\n"
1045  "=SP sp\n"
1046  "=A0 r0\n"
1047  "=A1 r1\n"
1048  "gpr r0 .8 0 0\n"
1049  "gpr r1 .8 1 0\n"
1050  "gpr r2 .8 2 0\n"
1051  "gpr r3 .8 3 0\n"
1052  "gpr r4 .8 4 0\n"
1053  "gpr r5 .8 5 0\n"
1054  "gpr r6 .8 6 0\n"
1055  "gpr r7 .8 7 0\n"
1056  "gpr a .8 8 0\n"
1057  "gpr b .8 9 0\n"
1058  "gpr dptr .16 10 0\n"
1059  "gpr dpl .8 10 0\n"
1060  "gpr dph .8 11 0\n"
1061  "gpr psw .8 12 0\n"
1062  "gpr p .1 .96 0\n"
1063  "gpr ov .1 .98 0\n"
1064  "gpr ac .1 .102 0\n"
1065  "gpr c .1 .103 0\n"
1066  "gpr sp .8 13 0\n"
1067  "gpr pc .16 15 0\n"
1068  // ---------------------------------------------------
1069  // 8051 memory emulation control registers
1070  // These registers map 8051 memory classes to r2's
1071  // linear address space. Registers contain base addr
1072  // in r2 memory space representing the memory class.
1073  // Offsets are initialized based on asm.cpu, but can
1074  // be updated with ar command.
1075  //
1076  // _code
1077  // program memory (CODE)
1078  // _idata
1079  // internal data memory (IDATA, IRAM)
1080  // _sfr
1081  // special function registers (SFR)
1082  // _xdata
1083  // external data memory (XDATA, XRAM)
1084  // _pdata
1085  // page accessed by movx @ri op (PDATA, XREG)
1086  // r2 addr = (_pdata & 0xff) << 8 + x_data
1087  // if 0xffffffnn, addr = ([SFRnn] << 8) + _xdata (TODO)
1088  "gpr _code .32 20 0\n"
1089  "gpr _idata .32 24 0\n"
1090  "gpr _sfr .32 28 0\n"
1091  "gpr _xdata .32 32 0\n"
1092  "gpr _pdata .32 36 0\n";
1093  return strdup(p);
1094 }
void * p
Definition: libc.cpp:67
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")

References p, and strdup().

◆ i8051_fini()

static bool i8051_fini ( void *  user)
static

Definition at line 1283 of file analysis_8051.c.

1283  {
1284  free(user);
1285  return true;
1286 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References free().

◆ i8051_init()

static bool i8051_init ( void **  user)
static

Definition at line 1271 of file analysis_8051.c.

1271  {
1273  if (!ctx) {
1274  return false;
1275  }
1276  ctx->mem_map[I8051_IDATA] = init_mem_map[I8051_IDATA];
1277  ctx->mem_map[I8051_SFR] = init_mem_map[I8051_SFR];
1278  ctx->mem_map[I8051_XDATA] = init_mem_map[I8051_XDATA];
1279  *user = ctx;
1280  return true;
1281 }
static const int I8051_SFR
Definition: analysis_8051.c:70
static const i8051_map_entry init_mem_map[3]
Definition: analysis_8051.c:73
static const int I8051_IDATA
Definition: analysis_8051.c:69
static const int I8051_XDATA
Definition: analysis_8051.c:71

References I8051_IDATA, I8051_SFR, I8051_XDATA, init_mem_map, and RZ_NEW0.

◆ i8051_op()

static int i8051_op ( RzAnalysis analysis,
RzAnalysisOp op,
ut64  addr,
const ut8 buf,
int  len,
RzAnalysisOpMask  mask 
)
static

Definition at line 1104 of file analysis_8051.c.

1104  {
1105  set_cpu_model(analysis, false);
1106 
1107  int i = 0;
1108  while (_8051_ops[i].string && _8051_ops[i].op != (buf[0] & ~_8051_ops[i].mask)) {
1109  i++;
1110  }
1111 
1112  ut8 arg1 = _8051_ops[i].arg1;
1113  ut8 arg2 = _8051_ops[i].arg2;
1114 
1115  op->cycles = _8051_ops[i].cycles;
1116  op->failcycles = _8051_ops[i].cycles;
1117  op->nopcode = 1;
1118  op->size = _8051_ops[i].len;
1119  op->type = _8051_ops[i].type;
1120  op->family = RZ_ANALYSIS_OP_FAMILY_CPU; // maybe also FAMILY_IO...
1121  op->id = i;
1122 
1123  switch (_8051_ops[i].instr) {
1124  default:
1125  op->cond = RZ_TYPE_COND_AL;
1126  break;
1127  case OP_CJNE:
1128  case OP_DJNZ:
1129  case OP_JB:
1130  case OP_JBC:
1131  case OP_JNZ:
1132  op->cond = RZ_TYPE_COND_NE;
1133  break;
1134  case OP_JNB:
1135  case OP_JZ:
1136  op->cond = RZ_TYPE_COND_EQ;
1137  break;
1138  case OP_JC:
1139  op->cond = RZ_TYPE_COND_HS;
1140  break;
1141  case OP_JNC:
1142  op->cond = RZ_TYPE_COND_LO;
1143  }
1144 
1145  switch (_8051_ops[i].instr) {
1146  default:
1147  op->eob = false;
1148  break;
1149  case OP_CJNE:
1150  case OP_DJNZ:
1151  case OP_JB:
1152  case OP_JBC:
1153  case OP_JC:
1154  case OP_JMP:
1155  case OP_JNB:
1156  case OP_JNC:
1157  case OP_JNZ:
1158  case OP_JZ:
1159  op->eob = true;
1160  }
1161 
1162  // TODO: op->datatype
1163 
1164  switch (arg1) {
1165  default:
1166  break;
1167  case A_DIRECT:
1168  op->ptr = map_direct_addr(analysis, buf[1]);
1169  break;
1170  case A_BIT:
1171  op->ptr = map_direct_addr(analysis, arg_bit(buf[1]));
1172  break;
1173  case A_IMMEDIATE:
1174  op->val = buf[1];
1175  break;
1176  case A_IMM16:
1177  op->val = buf[1] * 256 + buf[2];
1178  op->ptr = op->val + i8051_reg_read(analysis->reg, "_xdata"); // best guess, it's a XRAM pointer
1179  }
1180 
1181  switch (arg2) {
1182  default:
1183  break;
1184  case A_DIRECT:
1185  if (arg1 == A_RI || arg1 == A_RN) {
1186  op->ptr = map_direct_addr(analysis, buf[1]);
1187  } else if (arg1 != A_DIRECT) {
1188  op->ptr = map_direct_addr(analysis, buf[2]);
1189  }
1190  break;
1191  case A_BIT:
1192  op->ptr = arg_bit((arg1 == A_RI || arg1 == A_RN) ? buf[1] : buf[2]);
1193  op->ptr = map_direct_addr(analysis, op->ptr);
1194  break;
1195  case A_IMMEDIATE:
1196  op->val = (arg1 == A_RI || arg1 == A_RN) ? buf[1] : buf[2];
1197  }
1198 
1199  switch (_8051_ops[i].instr) {
1200  default:
1201  break;
1202  case OP_PUSH:
1203  op->stackop = RZ_ANALYSIS_STACK_INC;
1204  op->stackptr = 1;
1205  break;
1206  case OP_POP:
1207  op->stackop = RZ_ANALYSIS_STACK_INC;
1208  op->stackptr = -1;
1209  break;
1210  case OP_RET:
1211  op->stackop = RZ_ANALYSIS_STACK_INC;
1212  op->stackptr = -2;
1213  break;
1214  case OP_CALL:
1215  op->stackop = RZ_ANALYSIS_STACK_INC;
1216  op->stackptr = 2;
1217  if (arg1 == A_ADDR11) {
1218  op->jump = arg_addr11(addr, addr + op->size, buf);
1219  op->fail = addr + op->size;
1220  } else if (arg1 == A_ADDR16) {
1221  op->jump = apply_bank(addr, 0x100 * buf[1] + buf[2]);
1222  op->fail = addr + op->size;
1223  }
1224  break;
1225  case OP_JMP:
1226  if (arg1 == A_ADDR11) {
1227  op->jump = arg_addr11(addr, addr + op->size, buf);
1228  op->fail = addr + op->size;
1229  } else if (arg1 == A_ADDR16) {
1230  op->jump = apply_bank(addr, 0x100 * buf[1] + buf[2]);
1231  op->fail = addr + op->size;
1232  } else if (arg1 == A_OFFSET) {
1233  op->jump = arg_offset(addr, addr + op->size, buf[1]);
1234  op->fail = addr + op->size;
1235  }
1236  break;
1237  case OP_CJNE:
1238  case OP_DJNZ:
1239  case OP_JC:
1240  case OP_JNC:
1241  case OP_JZ:
1242  case OP_JNZ:
1243  case OP_JB:
1244  case OP_JBC:
1245  case OP_JNB:
1246  op->jump = arg_offset(addr, addr + op->size, buf[op->size - 1]);
1247  op->fail = addr + op->size;
1248  }
1249 
1250  if (op->ptr != -1 && op->refptr == 0) {
1251  op->refptr = 1;
1252  }
1253 
1255  ut8 copy[3] = { 0, 0, 0 };
1256  memcpy(copy, buf, len >= 3 ? 3 : len);
1257  analop_esil(analysis, op, addr, copy);
1258  }
1259 
1260  int olen = 0;
1261  op->mnemonic = rz_8051_disas(addr, buf, len, &olen);
1262  op->size = olen;
1263 
1265  // TODO: op->hint
1266  }
1267 
1268  return op->size;
1269 }
size_t len
Definition: 6502dis.c:15
static char * rz_8051_disas(ut64 pc, const ut8 *buf, int len, int *olen)
Definition: 8051_disas.c:69
@ A_ADDR11
Definition: 8051_ops.h:84
@ A_IMMEDIATE
Definition: 8051_ops.h:88
@ A_DIRECT
Definition: 8051_ops.h:86
@ A_RN
Definition: 8051_ops.h:83
@ A_BIT
Definition: 8051_ops.h:87
@ A_OFFSET
Definition: 8051_ops.h:90
@ A_RI
Definition: 8051_ops.h:82
@ A_ADDR16
Definition: 8051_ops.h:85
@ A_IMM16
Definition: 8051_ops.h:89
static ut64 arg_offset(ut64 bank, ut16 pc, ut8 offset)
Definition: 8051_ops.h:18
static ut64 arg_addr11(ut64 bank, ut16 pc, const ut8 *buf)
Definition: 8051_ops.h:26
static ut64 apply_bank(ut64 ref, ut16 addr)
Construct an address with the higher bits from ref (determining the bank) and the lower from addr (of...
Definition: 8051_ops.h:14
@ OP_JZ
Definition: 8051_ops.h:61
@ OP_JNC
Definition: 8051_ops.h:59
@ OP_CJNE
Definition: 8051_ops.h:46
@ OP_JBC
Definition: 8051_ops.h:55
@ OP_JC
Definition: 8051_ops.h:56
@ OP_RET
Definition: 8051_ops.h:68
@ OP_PUSH
Definition: 8051_ops.h:67
@ OP_JB
Definition: 8051_ops.h:54
@ OP_JNZ
Definition: 8051_ops.h:60
@ OP_JNB
Definition: 8051_ops.h:58
@ OP_POP
Definition: 8051_ops.h:66
@ OP_JMP
Definition: 8051_ops.h:57
@ OP_DJNZ
Definition: 8051_ops.h:52
static _8051_op_t _8051_ops[]
Definition: 8051_ops.h:113
static ut8 arg_bit(ut8 bit_addr)
Definition: 8051_ops.h:31
static ut32 map_direct_addr(RzAnalysis *analysis, ut8 addr)
static void analop_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf)
static ut32 i8051_reg_read(RzReg *reg, const char *regname)
Definition: analysis_8051.c:53
#define mask()
lzma_index ** i
Definition: index.h:629
uint8_t ut8
Definition: lh5801.h:11
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define OP_CALL
Definition: nios2.h:263
@ RZ_ANALYSIS_STACK_INC
Definition: rz_analysis.h:457
@ RZ_ANALYSIS_OP_FAMILY_CPU
Definition: rz_analysis.h:312
@ RZ_ANALYSIS_OP_MASK_ESIL
Definition: rz_analysis.h:441
@ RZ_ANALYSIS_OP_MASK_HINT
Definition: rz_analysis.h:443
@ RZ_TYPE_COND_LO
Carry clear Less than.
Definition: rz_type.h:192
@ RZ_TYPE_COND_EQ
Equal.
Definition: rz_type.h:184
@ RZ_TYPE_COND_HS
Carry set >, ==, or unordered.
Definition: rz_type.h:191
@ RZ_TYPE_COND_NE
Not equal.
Definition: rz_type.h:185
@ RZ_TYPE_COND_AL
Always executed (no condition)
Definition: rz_type.h:183
argtype8051 arg2
Definition: 8051_ops.h:109
argtype8051 arg1
Definition: 8051_ops.h:108
_RzAnalysisOpType type
Definition: 8051_ops.h:104
size_t len
Definition: 8051_ops.h:106
int cycles
Definition: 8051_ops.h:102

References _8051_ops, A_ADDR11, A_ADDR16, A_BIT, A_DIRECT, A_IMM16, A_IMMEDIATE, A_OFFSET, A_RI, A_RN, addr, analop_esil(), apply_bank(), _8051_op_t::arg1, _8051_op_t::arg2, arg_addr11(), arg_bit(), arg_offset(), _8051_op_t::cycles, i, i8051_reg_read(), len, _8051_op_t::len, map_direct_addr(), mask, memcpy(), OP_CALL, OP_CJNE, OP_DJNZ, OP_JB, OP_JBC, OP_JC, OP_JMP, OP_JNB, OP_JNC, OP_JNZ, OP_JZ, OP_POP, OP_PUSH, OP_RET, rz_analysis_t::reg, rz_8051_disas(), RZ_ANALYSIS_OP_FAMILY_CPU, RZ_ANALYSIS_OP_MASK_ESIL, RZ_ANALYSIS_OP_MASK_HINT, RZ_ANALYSIS_STACK_INC, RZ_TYPE_COND_AL, RZ_TYPE_COND_EQ, RZ_TYPE_COND_HS, RZ_TYPE_COND_LO, RZ_TYPE_COND_NE, set_cpu_model(), and _8051_op_t::type.

◆ i8051_reg_read()

static ut32 i8051_reg_read ( RzReg reg,
const char *  regname 
)
static

Definition at line 53 of file analysis_8051.c.

53  {
54  if (reg) {
56  if (item) {
57  return rz_reg_get_value(reg, item);
58  }
59  }
60  return 0;
61 }
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
RZ_API ut64 rz_reg_get_value(RzReg *reg, RzRegItem *item)
Definition: rvalue.c:114
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
static char * regname(int reg)
Definition: dis.c:71

References reg, regname(), rz_reg_get(), rz_reg_get_value(), and RZ_REG_TYPE_GPR.

Referenced by i8051_op(), map_direct_addr(), and set_cpu_model().

◆ i8051_reg_write()

static bool i8051_reg_write ( RzReg reg,
const char *  regname,
ut32  num 
)
static

Definition at line 42 of file analysis_8051.c.

42  {
43  if (reg) {
45  if (item) {
46  rz_reg_set_value(reg, item, num);
47  return true;
48  }
49  }
50  return false;
51 }
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
RZ_API bool rz_reg_set_value(RzReg *reg, RzRegItem *item, ut64 value)
Definition: rvalue.c:186

References num, reg, regname(), rz_reg_get(), rz_reg_set_value(), and RZ_REG_TYPE_GPR.

Referenced by set_cpu_model().

◆ map_cpu_memory()

static void map_cpu_memory ( RzAnalysis analysis,
int  entry,
ut32  addr,
ut32  size,
bool  force 
)
static

Definition at line 84 of file analysis_8051.c.

84  {
86  RzIODesc *desc = ctx->mem_map[entry].desc;
87  if (desc && analysis->iob.fd_get_name(analysis->iob.io, desc->fd)) {
88  if (force || addr != ctx->mem_map[entry].addr) {
89  // reallocate mapped memory if address changed
90  analysis->iob.fd_remap(analysis->iob.io, desc->fd, addr);
91  }
92  } else {
93  // allocate memory for address space
94  char *mstr = rz_str_newf("malloc://%d", size);
95  desc = analysis->iob.open_at(analysis->iob.io, mstr, RZ_PERM_RW, 0, addr, NULL);
96  free(mstr);
97  // set 8051 address space as name of mapped memory
98  if (desc && analysis->iob.fd_get_name(analysis->iob.io, desc->fd)) {
99  RzList *maps = analysis->iob.fd_get_map(analysis->iob.io, desc->fd);
100  RzIOMap *current_map;
101  RzListIter *iter;
102  rz_list_foreach (maps, iter, current_map) {
103  char *cmdstr = rz_str_newf("omni %d %s", current_map->id, ctx->mem_map[entry].name);
104  analysis->coreb.cmd(analysis->coreb.core, cmdstr);
105  free(cmdstr);
106  }
108  }
109  }
110  ctx->mem_map[entry].desc = desc;
111  ctx->mem_map[entry].addr = addr;
112 }
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
const char * desc
Definition: bin_vsf.c:19
#define cmdstr(x)
#define NULL
Definition: cris-opc.c:27
voidpf void uLong size
Definition: ioapi.h:138
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_PERM_RW
Definition: rz_types.h:96
Definition: zipcmp.c:77
void * plugin_data
Definition: rz_analysis.h:561
RzIOBind iob
Definition: rz_analysis.h:574
RzCoreBind coreb
Definition: rz_analysis.h:580
RzCoreCmd cmd
Definition: rz_bind.h:32
void * core
Definition: rz_bind.h:31
RzIOOpenAt open_at
Definition: rz_io.h:238
RzIO * io
Definition: rz_io.h:232
RzIOFdGetMap fd_get_map
Definition: rz_io.h:254
RzIOFdGetName fd_get_name
Definition: rz_io.h:253
RzIOFdRemap fd_remap
Definition: rz_io.h:255
ut32 id
Definition: rz_io.h:148

References addr, rz_core_bind_t::cmd, cmdstr, rz_core_bind_t::core, rz_analysis_t::coreb, desc, rz_io_bind_t::fd_get_map, rz_io_bind_t::fd_get_name, rz_io_bind_t::fd_remap, free(), rz_io_map_t::id, rz_io_bind_t::io, rz_analysis_t::iob, maps(), NULL, rz_io_bind_t::open_at, rz_analysis_t::plugin_data, rz_list_free(), RZ_PERM_RW, and rz_str_newf().

Referenced by set_cpu_model().

◆ map_direct_addr()

static ut32 map_direct_addr ( RzAnalysis analysis,
ut8  addr 
)
static

Definition at line 1096 of file analysis_8051.c.

1096  {
1097  if (addr < 0x80) {
1098  return addr + i8051_reg_read(analysis->reg, "_idata");
1099  } else {
1100  return addr + i8051_reg_read(analysis->reg, "_sfr");
1101  }
1102 }

References addr, i8051_reg_read(), and rz_analysis_t::reg.

Referenced by i8051_op().

◆ set_cpu_model()

static void set_cpu_model ( RzAnalysis analysis,
bool  force 
)
static

Definition at line 114 of file analysis_8051.c.

114  {
115  ut32 addr_idata, addr_sfr, addr_xdata;
116 
117  if (!analysis->reg) {
118  return;
119  }
120 
121  const char *cpu = analysis->cpu;
122  if (!cpu || !cpu[0]) {
123  cpu = cpu_models[0].name;
124  }
125  i8051_plugin_context *ctx = analysis->plugin_data;
126  // if cpu model changed, reinitialize emulation
127  if (force || !ctx->cpu_curr_model || rz_str_casecmp(cpu, ctx->cpu_curr_model->name)) {
128  // find model by name
129  int i = 0;
131  i++;
132  }
133  if (!cpu_models[i].name) {
134  i = 0; // if not found, default to generic 8051
135  }
136  ctx->cpu_curr_model = &cpu_models[i];
137 
138  // TODO: Add flags as needed - seek using pseudo registers works w/o flags
139 
140  // set memory map registers
141  addr_idata = cpu_models[i].map_idata;
142  addr_sfr = cpu_models[i].map_sfr;
143  addr_xdata = cpu_models[i].map_xdata;
144  i8051_reg_write(analysis->reg, "_code", cpu_models[i].map_code);
145  i8051_reg_write(analysis->reg, "_idata", addr_idata);
146  i8051_reg_write(analysis->reg, "_sfr", addr_sfr - 0x80);
147  i8051_reg_write(analysis->reg, "_xdata", addr_xdata);
148  i8051_reg_write(analysis->reg, "_pdata", cpu_models[i].map_pdata);
149  } else {
150  addr_idata = i8051_reg_read(analysis->reg, "_idata");
151  addr_sfr = i8051_reg_read(analysis->reg, "_sfr") + 0x80;
152  addr_xdata = i8051_reg_read(analysis->reg, "_xdata");
153  }
154 
155  // (Re)allocate memory as needed.
156  // We assume that code is allocated with firmware image
157  if (analysis->iob.fd_get_name && analysis->coreb.cmd) {
158  map_cpu_memory(analysis, I8051_IDATA, addr_idata, 0x100, force);
159  map_cpu_memory(analysis, I8051_SFR, addr_sfr, 0x80, force);
160  map_cpu_memory(analysis, I8051_XDATA, addr_xdata, 0x10000, force);
161  }
162 }
static bool i8051_reg_write(RzReg *reg, const char *regname, ut32 num)
Definition: analysis_8051.c:42
static void map_cpu_memory(RzAnalysis *analysis, int entry, ut32 addr, ut32 size, bool force)
Definition: analysis_8051.c:84
static const i8051_cpu_model cpu_models[]
Definition: analysis_8051.c:24
static ut32 cpu[32]
Definition: analysis_or1k.c:21
uint32_t ut32
RZ_API int rz_str_casecmp(const char *dst, const char *orig)
Definition: str.c:121
const char * name
Definition: analysis_8051.c:16
Definition: z80asm.h:102

References rz_core_bind_t::cmd, rz_analysis_t::coreb, cpu, rz_analysis_t::cpu, cpu_models, rz_io_bind_t::fd_get_name, i, I8051_IDATA, i8051_reg_read(), i8051_reg_write(), I8051_SFR, I8051_XDATA, rz_analysis_t::iob, i8051_cpu_model::map_code, map_cpu_memory(), i8051_cpu_model::map_idata, i8051_cpu_model::map_pdata, i8051_cpu_model::map_sfr, i8051_cpu_model::map_xdata, i8051_cpu_model::name, rz_analysis_t::plugin_data, rz_analysis_t::reg, and rz_str_casecmp().

Referenced by esil_i8051_init(), and i8051_op().

Variable Documentation

◆ bitindex

const ut8 bitindex[]
static
Initial value:
= {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x80, 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8,
0xC0, 0xC8, 0xD0, 0xD8, 0xE0, 0xE8, 0xF0, 0xF8
}

Definition at line 164 of file analysis_8051.c.

◆ cpu_models

const i8051_cpu_model cpu_models[]
static
Initial value:
= {
{ .name = "8051-generic",
.map_code = 0,
.map_idata = 0x10000000,
.map_sfr = 0x10000180,
.map_xdata = 0x20000000,
.map_pdata = 0x00000000 },
{ .name = "8051-shared-code-xdata",
.map_code = 0,
.map_idata = 0x10000000,
.map_sfr = 0x10000180,
.map_xdata = 0x00000000,
.map_pdata = 0x00000000 },
{
.name = NULL
}
}

Definition at line 24 of file analysis_8051.c.

Referenced by set_cpu_model().

◆ I8051_IDATA

const int I8051_IDATA = 0
static

Definition at line 69 of file analysis_8051.c.

Referenced by i8051_init(), and set_cpu_model().

◆ I8051_SFR

const int I8051_SFR = 1
static

Definition at line 70 of file analysis_8051.c.

Referenced by i8051_init(), and set_cpu_model().

◆ I8051_XDATA

const int I8051_XDATA = 2
static

Definition at line 71 of file analysis_8051.c.

Referenced by i8051_init(), and set_cpu_model().

◆ init_mem_map

const i8051_map_entry init_mem_map[3]
static
Initial value:
= {
{ NULL, UT32_MAX, "idata" },
{ NULL, UT32_MAX, "sfr" },
{ NULL, UT32_MAX, "xdata" }
}
#define UT32_MAX
Definition: rz_types_base.h:99

Definition at line 73 of file analysis_8051.c.

Referenced by i8051_init().

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
}
RzAnalysisPlugin rz_analysis_plugin_8051
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
#define RZ_VERSION
Definition: rz_version.h:8
const char * version
Definition: rz_analysis.h:1239

Definition at line 1304 of file analysis_8051.c.

◆ rz_analysis_plugin_8051

RzAnalysisPlugin rz_analysis_plugin_8051
Initial value:
= {
.name = "8051",
.arch = "8051",
.esil = true,
.bits = 8 | 16,
.desc = "8051 CPU code analysis plugin",
.license = "LGPL3",
.op = &i8051_op,
.get_reg_profile = &get_reg_profile,
.esil_init = esil_i8051_init,
.esil_fini = esil_i8051_fini,
.init = &i8051_init,
.fini = &i8051_fini,
}
static char * get_reg_profile(RzAnalysis *analysis)
static int esil_i8051_fini(RzAnalysisEsil *esil)
static int i8051_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
static bool i8051_init(void **user)
static int esil_i8051_init(RzAnalysisEsil *esil)
static bool i8051_fini(void *user)

Definition at line 1288 of file analysis_8051.c.