Rizin
unix-like reverse engineering framework and cli tools
analysis_mips_gnu.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2010-2015 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <string.h>
5 #include <rz_types.h>
6 #include <rz_lib.h>
7 #include <rz_asm.h>
8 #include <rz_analysis.h>
9 
10 static ut64 t9_pre = UT64_MAX;
11 #define REG_BUF_MAX 32
12 // ESIL macros:
13 
14 // put the sign bit on the stack
15 #define ES_IS_NEGATIVE(arg) "1," arg ",<<<,1,&"
16 
17 #define ES_B(x) "0xff," x ",&"
18 #define ES_H(x) "0xffff," x ",&"
19 #define ES_W(x) "0xffffffff," x ",&"
20 // call with delay slot
21 #define ES_CALL_DR(ra, addr) "pc,4,+," ra ",=," ES_J(addr)
22 #define ES_CALL_D(addr) ES_CALL_DR("ra", addr)
23 
24 // call without delay slot
25 #define ES_CALL_NDR(ra, addr) "pc," ra ",=," ES_J(addr)
26 #define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr)
27 
28 #define USE_DS 0
29 #if USE_DS
30 // emit ERR trap if executed in a delay slot
31 #define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,},"
32 // jump to address
33 #define ES_J(addr) addr ",SETJT,1,SETD"
34 #else
35 #define ES_TRAP_DS() ""
36 #define ES_J(addr) addr ",pc,="
37 #endif
38 
39 #define ES_SIGN32_64(arg) es_sign_n_64(a, op, arg, 32)
40 #define ES_SIGN16_64(arg) es_sign_n_64(a, op, arg, 16)
41 
42 #define ES_ADD_CK32_OVERF(x, y, z) es_add_ck(op, x, y, z, 32)
43 #define ES_ADD_CK64_OVERF(x, y, z) es_add_ck(op, x, y, z, 64)
44 
45 static inline void es_sign_n_64(RzAnalysis *a, RzAnalysisOp *op, const char *arg, int bit) {
46  if (a->bits == 64) {
47  rz_strbuf_appendf(&op->esil, ",%d,%s,~,%s,=,", bit, arg, arg);
48  } else {
49  rz_strbuf_append(&op->esil, ",");
50  }
51 }
52 
53 static inline void es_add_ck(RzAnalysisOp *op, const char *a1, const char *a2, const char *re, int bit) {
54  ut64 mask = 1ULL << (bit - 1);
55  rz_strbuf_appendf(&op->esil,
56  "%d,0x%" PFMT64x ",%s,%s,^,&,>>,%d,0x%" PFMT64x ",%s,%s,+,&,>>,|,1,==,$z,?{,$$,1,TRAP,}{,%s,%s,+,%s,=,}",
57  bit - 2, mask, a1, a2, bit - 1, mask, a1, a2, a1, a2, re);
58 }
59 // MIPS instruction
60 typedef enum mips_insn {
62 
684 
685  //> some alias instructions
688 
689  //> special instructions
690  MIPS_INS_JALR_HB, // jump and link with Hazard Barrier
691  MIPS_INS_JR_HB, // jump register with Hazard Barrier
692 
695 
696 struct gnu_rreg {
697  const char *rs;
698  const char *rt;
699  const char *rd;
701 };
702 
703 struct gnu_jreg {
705 };
706 
707 struct gnu_ireg {
708  const char *rs;
709  const char *rt;
710  union {
713  };
714 };
715 
716 typedef struct gnu_insn {
719  union {
720  struct gnu_rreg r_reg;
721  struct gnu_ireg i_reg;
722  struct gnu_jreg j_reg;
723  };
725 
726 #define R_REG(x) ((const char *)insn->r_reg.x)
727 #define I_REG(x) ((const char *)insn->i_reg.x)
728 #define J_REG(x) ((const char *)insn->j_reg.x)
729 
730 /* Return a mapping from the register number i.e. $0 .. $31 to string name */
731 static const char *mips_reg_decode(ut32 reg_num) {
732  /* See page 36 of "See Mips Run Linux, 2e, D. Sweetman, 2007"*/
733  static const char *REGISTERS[32] = {
734  "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
735  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
736  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
737  "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
738  };
739  if (reg_num < 32) {
740  return REGISTERS[reg_num];
741  }
742  return NULL;
743 }
744 
746 
747  switch (insn->id) {
748  case MIPS_INS_NOP:
749  rz_strbuf_setf(&op->esil, ",");
750  break;
751  case MIPS_INS_BREAK:
752  // rz_strbuf_setf (&op->esil, "%d,%d,TRAP", IMM (0), IMM (0));
753  break;
754  case MIPS_INS_SD:
755  rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,=[8]",
756  I_REG(rt), I_REG(imm), I_REG(rs));
757  break;
758  case MIPS_INS_SW:
759  case MIPS_INS_SWL:
760  case MIPS_INS_SWR:
761  rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,=[4]",
762  I_REG(rt), I_REG(imm), I_REG(rs));
763  break;
764  case MIPS_INS_SH:
765  rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,=[2]",
766  I_REG(rt), I_REG(imm), I_REG(rs));
767  break;
768  case MIPS_INS_SWC1:
769  case MIPS_INS_SWC2:
770  break;
771  case MIPS_INS_SB:
772  rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,=[1]",
773  I_REG(rt), I_REG(imm), I_REG(rs));
774  break;
775  case MIPS_INS_CMP:
776  case MIPS_INS_CMPU:
777  case MIPS_INS_CMPGU:
778  case MIPS_INS_CMPGDU:
779  case MIPS_INS_CMPI:
780  break;
781  case MIPS_INS_SHRAV:
782  case MIPS_INS_SHRAV_R:
783  case MIPS_INS_SHRA:
784  case MIPS_INS_SHRA_R:
785  break;
786  case MIPS_INS_SRA:
787  rz_strbuf_appendf(&op->esil,
788  ES_W("%s,%s") ",>>,31,%s,>>,?{,%s,32,-,0xffffffff,<<,0xffffffff,&,}{,0,},|,%s,=",
789  R_REG(sa), R_REG(rt), R_REG(rt), R_REG(sa), R_REG(rd));
790  break;
791  case MIPS_INS_DSRA:
792  rz_strbuf_appendf(&op->esil,
793  "%s,%s,>>,31,%s,>>,?{,32,%s,32,-,0xffffffff,<<,0xffffffff,&,<<,}{,0,},|,%s,=",
794  R_REG(sa), R_REG(rt), R_REG(rt), R_REG(sa), R_REG(rd));
795  break;
796  case MIPS_INS_SHRL:
797  // suffix 'S' forces conditional flag to be updated
798  break;
799  case MIPS_INS_SRLV:
800  case MIPS_INS_SRL:
801  rz_strbuf_appendf(&op->esil, "%s,%s,>>,%s,=",
802  R_REG(rs) ? R_REG(rs) : R_REG(sa), R_REG(rt), R_REG(rd));
803  break;
804  case MIPS_INS_SLLV:
805  case MIPS_INS_SLL:
806  rz_strbuf_appendf(&op->esil, "%s,%s,<<,%s,=",
807  R_REG(rs) ? R_REG(rs) : R_REG(sa), R_REG(rt), R_REG(rd));
808  break;
809  case MIPS_INS_BAL:
810  case MIPS_INS_JAL:
811  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_D("%s"), I_REG(jump));
812  break;
813  case MIPS_INS_JALR:
814  case MIPS_INS_JALRS:
815  if (strcmp(R_REG(rd), "rd") == 0) {
816  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_D("%s"), R_REG(rs));
817  } else {
818  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_DR("%s", "%s"), R_REG(rd), R_REG(rs));
819  }
820  break;
821  case MIPS_INS_JR:
822  case MIPS_INS_JRC:
823  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_J("%s"), R_REG(rs));
824  break;
825  case MIPS_INS_J:
826  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_J("%s"), J_REG(jump));
827  break;
828  case MIPS_INS_B:
829  // jump to address with conditional
830  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_J("%s"), I_REG(jump));
831  break;
832  case MIPS_INS_BNE: // bne $s, $t, offset
833  case MIPS_INS_BNEL:
834  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,%s,==,$z,!,?{," ES_J("%s") ",}",
835  I_REG(rs), I_REG(rt), I_REG(jump));
836  break;
837  case MIPS_INS_BEQ:
838  case MIPS_INS_BEQL:
839  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,%s,==,$z,?{," ES_J("%s") ",}",
840  I_REG(rs), I_REG(rt), I_REG(jump));
841  break;
842  case MIPS_INS_BZ:
843  case MIPS_INS_BEQZ:
844  case MIPS_INS_BEQZC:
845  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,?{," ES_J("%s") ",}",
846  I_REG(rs), I_REG(jump));
847  break;
848  case MIPS_INS_BNEZ:
849  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,!,?{," ES_J("%s") ",}",
850  I_REG(rs), I_REG(jump));
851  break;
852  case MIPS_INS_BLEZ:
853  case MIPS_INS_BLEZC:
854  case MIPS_INS_BLEZL:
855  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{," ES_J("%s") ",BREAK,},",
856  I_REG(rs), I_REG(jump));
857  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}",
858  I_REG(rs), I_REG(jump));
859  break;
860  case MIPS_INS_BGEZ:
861  case MIPS_INS_BGEZC:
862  case MIPS_INS_BGEZL:
863  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}",
864  I_REG(rs), I_REG(jump));
865  break;
866  case MIPS_INS_BGEZAL:
867  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_D("%s") ",}",
868  I_REG(rs), I_REG(jump));
869  break;
870  case MIPS_INS_BLTZAL:
871  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_D("%s") ",}",
872  I_REG(rs), I_REG(jump));
873  break;
874  case MIPS_INS_BLTZ:
875  case MIPS_INS_BLTZC:
876  case MIPS_INS_BLTZL:
877  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}",
878  I_REG(rs), I_REG(jump));
879  break;
880  case MIPS_INS_BGTZ:
881  case MIPS_INS_BGTZC:
882  case MIPS_INS_BGTZL:
883  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{,BREAK,},", I_REG(rs));
884  rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}",
885  I_REG(rs), I_REG(jump));
886  break;
887  case MIPS_INS_BTEQZ:
888  break;
889  case MIPS_INS_BTNEZ:
890  break;
891  case MIPS_INS_MOV:
892  case MIPS_INS_MOVE:
893  rz_strbuf_appendf(&op->esil, "%s,%s,=", R_REG(rs), R_REG(rd));
894  break;
895  case MIPS_INS_MOVZ:
896  case MIPS_INS_MOVF:
897  rz_strbuf_appendf(&op->esil, "0,%s,==,$z,?{,%s,%s,=,}",
898  R_REG(rt), R_REG(rs), R_REG(rd));
899  break;
900  case MIPS_INS_MOVT:
901  rz_strbuf_appendf(&op->esil, "1,%s,==,$z,?{,%s,%s,=,}",
902  R_REG(rt), R_REG(rs), R_REG(rd));
903  break;
904  case MIPS_INS_FSUB:
905  case MIPS_INS_SUB:
906  case MIPS_INS_SUBU:
907  case MIPS_INS_DSUB:
908  case MIPS_INS_DSUBU:
909  rz_strbuf_appendf(&op->esil, "%s,%s,-,%s,=",
910  R_REG(rt), R_REG(rs), R_REG(rd));
911  break;
912  case MIPS_INS_NEG:
913  case MIPS_INS_NEGU:
914  break;
916  case MIPS_INS_ADD:
918  break;
919  case MIPS_INS_ADDI:
921  break;
922  case MIPS_INS_DADD:
924  break;
925  case MIPS_INS_DADDU:
926  case MIPS_INS_ADDU:
927  rz_strbuf_appendf(&op->esil, "%s,%s,+,%s,=",
928  R_REG(rt), R_REG(rs), R_REG(rd));
929  break;
930  case MIPS_INS_DADDI:
932  break;
933  case MIPS_INS_ADDIU:
934  case MIPS_INS_DADDIU:
935  rz_strbuf_appendf(&op->esil, "%s,%s,+,%s,=",
936  I_REG(imm), I_REG(rs), I_REG(rt));
937  ES_SIGN32_64(I_REG(rt));
938  break;
939  case MIPS_INS_LI:
940  case MIPS_INS_LDI:
941  rz_strbuf_appendf(&op->esil, "%s,%s,=", I_REG(imm), I_REG(rt));
942  break;
943  case MIPS_INS_LUI:
944  rz_strbuf_appendf(&op->esil, "%s0000,%s,=", I_REG(imm), I_REG(rt));
945  break;
946  case MIPS_INS_LB:
947  op->sign = true; // To load a byte from memory as a signed value
948  /* fallthrough */
949  case MIPS_INS_LBU:
950  // one of these is wrong
951  rz_strbuf_appendf(&op->esil, "%s,%s,+,[1],%s,=",
952  I_REG(imm), I_REG(rs), I_REG(rt));
953  break;
954  case MIPS_INS_LW:
955  case MIPS_INS_LWC1:
956  case MIPS_INS_LWC2:
957  case MIPS_INS_LWL:
958  case MIPS_INS_LWR:
959  case MIPS_INS_LWU:
960  case MIPS_INS_LL:
961  rz_strbuf_appendf(&op->esil, "%s,%s,+,[4],%s,=",
962  I_REG(imm), I_REG(rs), I_REG(rt));
963  break;
964  case MIPS_INS_LDL:
965  case MIPS_INS_LDC1:
966  case MIPS_INS_LDC2:
967  case MIPS_INS_LLD:
968  case MIPS_INS_LD:
969  rz_strbuf_appendf(&op->esil, "%s,%s,+,[8],%s,=",
970  I_REG(imm), I_REG(rs), I_REG(rt));
971  break;
972  case MIPS_INS_LH:
973  op->sign = true; // To load a byte from memory as a signed value
974  /* fallthrough */
975  case MIPS_INS_LHU:
976  rz_strbuf_appendf(&op->esil, "%s,%s,+,[2],%s,=",
977  I_REG(imm), I_REG(rs), I_REG(rt));
978  break;
979  case MIPS_INS_LHX:
980  case MIPS_INS_LWX:
981  break;
982  case MIPS_INS_AND:
983  rz_strbuf_appendf(&op->esil, "%s,%s,&,%s,=", R_REG(rt), R_REG(rs), R_REG(rd));
984  break;
985  case MIPS_INS_ANDI:
986  rz_strbuf_appendf(&op->esil, "%s,%s,&,%s,=", I_REG(imm), I_REG(rs), I_REG(rt));
987  break;
988  case MIPS_INS_OR:
989  rz_strbuf_appendf(&op->esil, "%s,%s,|,%s,=", R_REG(rt), R_REG(rs), R_REG(rd));
990  break;
991  case MIPS_INS_ORI:
992  rz_strbuf_appendf(&op->esil, "%s,%s,|,%s,=", I_REG(imm), I_REG(rs), I_REG(rt));
993  break;
994  case MIPS_INS_XOR:
995  rz_strbuf_appendf(&op->esil, "%s,%s,^,%s,=", R_REG(rt), R_REG(rs), R_REG(rd));
996  break;
997  case MIPS_INS_XORI:
998  rz_strbuf_appendf(&op->esil, "%s,%s,^,%s,=", I_REG(imm), I_REG(rs), I_REG(rt));
999  break;
1000  case MIPS_INS_NOR:
1001  rz_strbuf_appendf(&op->esil, "%s,%s,|,0xffffffff,^,%s,=", R_REG(rs), R_REG(rt), R_REG(rd));
1002  break;
1003  case MIPS_INS_SLT:
1004  rz_strbuf_appendf(&op->esil, "%s,%s,<,t,=", R_REG(rs), R_REG(rt));
1005  break;
1006  case MIPS_INS_SLTI:
1007  rz_strbuf_appendf(&op->esil, "%s,%s,<,%s,=", I_REG(imm), I_REG(rs), I_REG(rt));
1008  break;
1009  case MIPS_INS_SLTU:
1010  rz_strbuf_appendf(&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,t,=",
1011  R_REG(rs), R_REG(rt));
1012  break;
1013  case MIPS_INS_SLTIU:
1014  rz_strbuf_appendf(&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,%s,=",
1015  I_REG(imm), I_REG(rs), I_REG(rt));
1016  break;
1017  case MIPS_INS_MUL:
1018  rz_strbuf_appendf(&op->esil, ES_W("%s,%s,*") ",%s,=", R_REG(rs), R_REG(rt), R_REG(rd));
1019  ES_SIGN32_64(R_REG(rd));
1020  break;
1021  case MIPS_INS_MULT:
1022  case MIPS_INS_MULTU:
1023  rz_strbuf_appendf(&op->esil, ES_W("%s,%s,*") ",lo,=", R_REG(rs), R_REG(rt));
1024  ES_SIGN32_64("lo");
1025  rz_strbuf_appendf(&op->esil, ES_W("32,%s,%s,*,>>") ",hi,=", R_REG(rs), R_REG(rt));
1026  ES_SIGN32_64("hi");
1027  break;
1028  case MIPS_INS_MFLO:
1029  rz_strbuf_appendf(&op->esil, "lo,%s,=", R_REG(rd));
1030  break;
1031  case MIPS_INS_MFHI:
1032  rz_strbuf_appendf(&op->esil, "hi,%s,=", R_REG(rd));
1033  break;
1034  case MIPS_INS_MTLO:
1035  rz_strbuf_appendf(&op->esil, "%s,lo,=,", R_REG(rs));
1036  ES_SIGN32_64("lo");
1037  break;
1038  case MIPS_INS_MTHI:
1039  rz_strbuf_appendf(&op->esil, "%s,hi,=,", R_REG(rs));
1040  ES_SIGN32_64("hi");
1041  break;
1042  default:
1043  return -1;
1044  }
1045 
1046  return 0;
1047 }
1048 
1049 static int mips_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *b, int len, RzAnalysisOpMask mask) {
1050  ut32 opcode;
1051  // WIP char buf[10]; int reg; int family;
1052  int optype, oplen = (analysis->bits == 16) ? 2 : 4;
1053  const ut8 *buf;
1054  gnu_insn insn;
1055 
1056  if (!op) {
1057  return oplen;
1058  }
1059 
1060  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
1061  op->size = oplen;
1062  op->addr = addr;
1063  // Be endian aware
1064  opcode = rz_read_ble32(b, analysis->big_endian);
1065 
1066  // RZ_LOG_DEBUG("MIPS: %02x %02x %02x %02x (after endian: big=%d)\n", buf[0], buf[1], buf[2], buf[3], analysis->big_endian);
1067  if (opcode == 0) {
1068  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
1069  return oplen;
1070  }
1071 
1072  opcode = rz_swap_ut32(opcode);
1073  buf = (ut8 *)&opcode;
1074 
1075  optype = (buf[0] >> 2);
1076  insn.optype = optype;
1077  insn.id = 0;
1078 
1079  if (optype == 0) {
1080  /*
1081  R-TYPE
1082  ======
1083  opcode (6) rs (5) rt (5) rd (5) sa (5) function (6)
1084  rs = register source
1085  rt = register target
1086  rd = register destination
1087  sa =
1088  fu =
1089  |--[0]--| |--[1]--| |--[2]--| |--[3]--|
1090  1111 1111 1111 1111 1111 1111 1111 1111
1091  \_op__/\_rs__/\_rt_/ \_rd_/\_sa__/\_fun_/
1092  | | | | | |
1093  buf[0]>>2 | (buf[1]&31) | | buf[3]&63
1094  | (buf[2]>>3) |
1095  (buf[0]&3)<<3)+(buf[1]>>5) (buf[2]&7)+(buf[3]>>6)
1096 */
1097  int rs = ((buf[0] & 3) << 3) + (buf[1] >> 5);
1098  int rt = buf[1] & 31;
1099  int rd = buf[2] >> 3;
1100  int sa = ((buf[2] & 7) << 2) + (buf[3] >> 6);
1101  int fun = buf[3] & 63;
1102 
1103  insn.r_reg.rs = mips_reg_decode(rs);
1104  insn.r_reg.rd = mips_reg_decode(rd);
1105  insn.r_reg.rt = mips_reg_decode(rt);
1106  snprintf((char *)insn.r_reg.sa, REG_BUF_MAX, "%" PFMT32d, sa);
1107 
1108  switch (fun) {
1109  case 0: // sll
1110  insn.id = MIPS_INS_SLL;
1111  insn.r_reg.rs = NULL;
1112  op->val = sa;
1113  // fallthrough
1114  case 4: // sllv
1115  insn.id = MIPS_INS_SLLV;
1116  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
1117  break;
1118  case 2: // srl
1119  insn.id = MIPS_INS_SRL;
1120  insn.r_reg.rs = NULL;
1121  op->val = sa;
1122  // fallthrough
1123  case 6: // srlv
1124  insn.id = MIPS_INS_SRLV;
1125  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
1126  break;
1127  case 3: // sra
1128  insn.id = MIPS_INS_SRA;
1129  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
1130  break;
1131  case 7: // srav
1132  insn.id = MIPS_INS_SRAV;
1133  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
1134  break;
1135  case 59: // dsra
1136  insn.id = MIPS_INS_DSRA; // TODO double
1137  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
1138  break;
1139  case 63: // dsra32
1140  insn.id = MIPS_INS_DSRA32;
1141  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
1142  break;
1143  case 8: // jr
1144  // RZ_LOG_DEBUG("%" PFMT64x " jr\n", addr);
1145  // TODO: check return value
1146  op->delay = 1;
1147  insn.id = MIPS_INS_JR;
1148  if (rs == 31) {
1149  op->type = RZ_ANALYSIS_OP_TYPE_RET;
1150  } else if (rs == 25) {
1151  op->type = RZ_ANALYSIS_OP_TYPE_RJMP;
1152  op->jump = t9_pre;
1153  break;
1154  } else {
1155  op->type = RZ_ANALYSIS_OP_TYPE_RJMP;
1156  }
1157  break;
1158  case 9: // jalr
1159  // RZ_LOG_DEBUG("%" PFMT64x " jalr\n", addr);
1160  op->delay = 1;
1161  insn.id = MIPS_INS_JALR;
1162  if (rs == 25) {
1163  op->type = RZ_ANALYSIS_OP_TYPE_RCALL;
1164  op->jump = t9_pre;
1165  break;
1166  }
1167  op->type = RZ_ANALYSIS_OP_TYPE_UCALL;
1168  break;
1169  case 10: // movz
1170  insn.id = MIPS_INS_MOVZ;
1171  break;
1172  case 12: // syscall
1173  op->type = RZ_ANALYSIS_OP_TYPE_SWI;
1174  break;
1175  case 13: // break
1176  op->type = RZ_ANALYSIS_OP_TYPE_TRAP;
1177  break;
1178  case 16: // mfhi
1179  insn.id = MIPS_INS_MFHI;
1180  break;
1181  case 18: // mflo
1182  insn.id = MIPS_INS_MFLO;
1183  break;
1184  case 17: // mthi
1185  insn.id = MIPS_INS_MTHI;
1186  break;
1187  case 19: // mtlo
1188  insn.id = MIPS_INS_MTLO;
1189  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
1190  break;
1191  case 24: // mult
1192  insn.id = MIPS_INS_MULT;
1193  // fallthrough
1194  case 25: // multu
1195  insn.id = MIPS_INS_MULTU;
1196  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
1197  break;
1198  case 26: // div
1199  case 27: // divu
1200  op->type = RZ_ANALYSIS_OP_TYPE_DIV;
1201  insn.id = MIPS_INS_DIV;
1202  break;
1203  case 32: // add
1204  insn.id = MIPS_INS_ADD;
1205  // fallthrough
1206  case 33: // addu //TODO:表明位数
1207  insn.id = MIPS_INS_ADDU;
1208  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
1209  break;
1210  case 44: // dadd
1211  insn.id = MIPS_INS_DADD;
1212  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
1213  break;
1214  case 45: // daddu move
1215  if (rt == 0) {
1216  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
1217  insn.id = MIPS_INS_MOV;
1218  break;
1219  }
1220  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
1221  insn.id = MIPS_INS_DADDU;
1222  break;
1223  case 34: // sub
1224  case 35: // subu
1225  insn.id = MIPS_INS_SUB;
1226  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
1227  break;
1228  case 46: // dsub
1229  insn.id = MIPS_INS_SUB;
1230  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
1231  break;
1232  case 47: // dsubu
1233  insn.id = MIPS_INS_SUB;
1234  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
1235  break;
1236  case 36: // and
1237  insn.id = MIPS_INS_AND;
1238  op->type = RZ_ANALYSIS_OP_TYPE_AND;
1239  break;
1240  case 37: // or
1241  insn.id = MIPS_INS_OR;
1242  op->type = RZ_ANALYSIS_OP_TYPE_OR;
1243  break;
1244  case 38: // xor
1245  insn.id = MIPS_INS_XOR;
1246  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
1247  break;
1248  case 39: // nor
1249  insn.id = MIPS_INS_NOR;
1250  op->type = RZ_ANALYSIS_OP_TYPE_NOR;
1251  break;
1252  case 42: // slt
1253  insn.id = MIPS_INS_SLT;
1254  break;
1255  case 43: // sltu
1256  insn.id = MIPS_INS_SLTU;
1257  break;
1258  default:
1259  // RZ_LOG_DEBUG("%" PFMT64x " %d\n", addr, optype);
1260  break;
1261  }
1262  // family = 'R';
1263  } else if ((optype & 0x3e) == 2) {
1264  /*
1265  // J-TYPE
1266  |--[0]--| |--[1]--| |--[2]--| |--[3]--|
1267  1111 1111 1111 1111 1111 1111 1111 1111
1268  \_op__/\______address____________________/
1269  | |
1270  (buf[0]>>2) ((buf[0]&3)<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3]
1271 */
1272  // FIXME: what happens when addr is using a virtual map?
1273  // ANS: address will be E 0x000000..0x0ffffffc
1274  // but addr could be anywhere
1275  // so address needs to be adjusted for that, somehow...
1276  // MIPS is strange. For example, the same code memory may be
1277  // mapped simultaneously to 0x00600000 and 0x80600000. The program is
1278  // executing at 0x80600000 if we are operating in 'KSEG0' space
1279  // (unmapped cached mode) vs 0x00600000 (KUSEG or user space)
1280  // An immediate jump can only reach within 2^28 bits.
1281  // HACK: if the user specified a mapping for the program
1282  // then assume that they know which MIPS segment they
1283  // are analysing in, and use the high order bits of addr
1284  // to be add to the jump.
1285  // WARNING: it is possible that this may not be the case
1286  // in all situations!
1287  // Maybe better solution: use a cfg. variable to do
1288  // the offset... but I dont yet know how to get to that
1289  // from this static function
1290  int address = (((buf[0] & 3) << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]) << 2;
1291  ut64 page_hack = addr & 0xf0000000;
1292 
1293  switch (optype) {
1294  case 2: // j
1295  insn.id = MIPS_INS_J;
1296  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
1297  op->jump = page_hack + address;
1298  op->delay = 1;
1299  snprintf((char *)insn.j_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump);
1300  break;
1301  case 3: // jal
1302  insn.id = MIPS_INS_JAL;
1303  op->type = RZ_ANALYSIS_OP_TYPE_CALL;
1304  op->jump = page_hack + address;
1305  op->fail = addr + 8;
1306  op->delay = 1;
1307  snprintf((char *)insn.j_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump);
1308  break;
1309  }
1310  // family = 'J';
1311  } else if ((optype & 0x3c) == 0x10) {
1312 /*
1313  C-TYPE
1314  ======
1315  opcode (6) format (5) ft (5) fs (5) fd (5) function (6)
1316 
1317  |--[0]--| |--[1]--| |--[2]--| |--[3]--|
1318  1111 1111 1111 1111 1111 1111 1111 1111
1319  \_op__/\_fmt_/\_ft_/ \_fs_/\_fd__/\_fun_/
1320  | | | | | |
1321  buf[0]>>2 | (buf[1]&31) | | buf[3]&63
1322  | (buf[2]>>3) |
1323  (buf[0]&3)<<3)+(buf[1]>>5) (buf[2]&7)+(buf[3]>>6)
1324 */
1325 #if WIP
1326  int fmt = ((buf[0] & 3) << 3) + (buf[1] >> 5);
1327  int ft = (buf[1] & 31);
1328  int fs = (buf[2] >> 3);
1329  int fd = (buf[2] & 7) + (buf[3] >> 6);
1330 #endif
1331  int fun = (buf[3] & 63);
1332  // family = 'C';
1333  switch (fun) {
1334  case 0: // mtc1
1335  break;
1336  case 1: // sub.s
1337  break;
1338  case 2: // mul.s
1339  break;
1340  case 3: // div.s
1341  break;
1342  // ....
1343  }
1344  } else {
1345  /*
1346  I-TYPE
1347  ======
1348  all opcodes but 000000 000001x and 0100xx
1349  opcode (6) rs (5) rt (5) immediate (16)
1350 
1351  |--[0]--| |--[1]--| |--[2]--| |--[3]--|
1352  1111 1111 1111 1111 1111 1111 1111 1111
1353  \_op__/\_rs__/\_rt_/ \_______imm________/
1354  | | | |
1355  buf[0]>>2 | (buf[1]&31) |
1356  | |
1357  ((buf[0]&3)<<3)+(buf[1]>>5) (buf[2]<<8)+buf[3]
1358 */
1359  op->refptr = 0;
1360  int rs = ((buf[0] & 3) << 3) + (buf[1] >> 5);
1361  int rt = buf[1] & 31;
1362  int imm = (buf[2] << 8) + buf[3];
1363  if (((optype >> 2) ^ 0x3) && (imm & 0x8000)) {
1364  imm = 0 - (0x10000 - imm);
1365  }
1366 
1367  insn.i_reg.rs = mips_reg_decode(rs);
1368  insn.i_reg.rt = mips_reg_decode(rt);
1369  snprintf((char *)insn.i_reg.imm, REG_BUF_MAX, "%" PFMT32d, imm);
1370 
1371  switch (optype) {
1372  case 1:
1373  switch (rt) {
1374  case 0: // bltz
1375  insn.id = MIPS_INS_BLTZ;
1376  break;
1377  case 1: // bgez
1378  insn.id = MIPS_INS_BGEZ;
1379  break;
1380  case 17: // bal bgezal
1381  if (rs == 0) {
1382  op->jump = addr + (imm << 2) + 4;
1383  snprintf((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump);
1384  insn.id = MIPS_INS_BAL;
1385  } else {
1386  op->fail = addr + 8;
1387  insn.id = MIPS_INS_BGEZAL;
1388  }
1389  op->delay = 1;
1390  op->type = RZ_ANALYSIS_OP_TYPE_CALL;
1391  break;
1392  default:
1393  op->delay = 1;
1394  op->fail = addr + 8;
1395  break;
1396  }
1397  break;
1398  case 4: // beq
1399  if (!insn.id) {
1400  insn.id = MIPS_INS_BEQ;
1401  if (rt == 0) {
1402  insn.id = MIPS_INS_BEQZ;
1403  }
1404  }
1405  // fallthrough
1406  case 5: // bne // also bnez
1407  if (!insn.id) {
1408  insn.id = MIPS_INS_BNE;
1409  if (rt == 0) {
1410  insn.id = MIPS_INS_BNEZ;
1411  }
1412  }
1413  // fallthrough
1414  case 6: // blez
1415  if (!insn.id) {
1416  insn.id = MIPS_INS_BLEZ;
1417  }
1418  // fallthrough
1419  case 7: // bgtz
1420  // XXX: use imm here
1421  if (!insn.id) {
1422  insn.id = MIPS_INS_BGTZ;
1423  }
1424  op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
1425  op->jump = addr + (imm << 2) + 4;
1426  op->fail = addr + 8;
1427  op->delay = 1;
1428 
1429  snprintf((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump);
1430  break;
1431  // The following idiom is very common in mips 32 bit:
1432  //
1433  // lui a0,0x8123
1434  // ; maybe other opcodes
1435  // ; maybe even a jump with branch delay
1436  // addui a0,a0,-12345
1437  //
1438  // Here, a0 might typically be any a0 or s0 register, and -12345 is a signed 16-bit number
1439  // This is used to address const or static data in a 64kb page
1440  // 0x8123 is the upper 16 bits of the register
1441  // The net result: a0 := 0x8122cfc7
1442  // The cases vary, so for now leave the smarts in a human generated macro to decide
1443  // but the macro needs the opcode values as input
1444  //
1445  // TODO: this is a stop-gap. Really we need some smarts in here to tie this into the
1446  // flags directly, as suggested here: https://github.com/rizinorg/rizin/issues/949#issuecomment-43654922
1447  case 15: // lui
1448  insn.id = MIPS_INS_LUI;
1449  snprintf((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%" PFMT32x, imm);
1450  op->dst = rz_analysis_value_new();
1451  op->dst->reg = rz_reg_get(analysis->reg, mips_reg_decode(rt), RZ_REG_TYPE_GPR);
1452  // TODO: currently there is no way for the macro to get access to this register
1453  op->val = imm;
1454  break;
1455  case 9: // addiu
1456  insn.id = MIPS_INS_ADDIU;
1457  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
1458  op->dst = rz_analysis_value_new();
1459  op->dst->reg = rz_reg_get(analysis->reg, mips_reg_decode(rt), RZ_REG_TYPE_GPR);
1460  // TODO: currently there is no way for the macro to get access to this register
1461  op->src[0] = rz_analysis_value_new();
1462  op->src[0]->reg = rz_reg_get(analysis->reg, mips_reg_decode(rs), RZ_REG_TYPE_GPR);
1463  op->val = imm; // Beware: this one is signed... use `?vi $v`
1464  if (rs == 0) {
1465  insn.id = MIPS_INS_LI;
1466  snprintf((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%" PFMT32x, imm);
1467  }
1468  break;
1469  case 8: // addi
1470  insn.id = MIPS_INS_ADDI;
1471  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
1472  break;
1473  case 10: // slti
1474  insn.id = MIPS_INS_SLTI;
1475  break;
1476  case 11: // sltiu
1477  insn.id = MIPS_INS_SLTIU;
1478  break;
1479  case 12: // andi
1480  insn.id = MIPS_INS_ANDI;
1481  op->type = RZ_ANALYSIS_OP_TYPE_AND;
1482  break;
1483  case 13: // ori
1484  insn.id = MIPS_INS_ORI;
1485  op->type = RZ_ANALYSIS_OP_TYPE_OR;
1486  break;
1487  case 14: // xori
1488  insn.id = MIPS_INS_XORI;
1489  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
1490  break;
1491  case 24: // daddi
1492  insn.id = MIPS_INS_DADDI;
1493  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
1494  break;
1495  case 25: // daddiu
1496  insn.id = MIPS_INS_DADDIU;
1497  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
1498  if (rs == 0) {
1499  insn.id = MIPS_INS_LDI;
1500  snprintf((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%" PFMT32x, imm);
1501  }
1502  break;
1503  case 32: // lb
1504  op->refptr = 1;
1505  insn.id = MIPS_INS_LB;
1506  /* fallthrough */
1507  case 33: // lh
1508  if (!op->refptr) {
1509  op->refptr = 2;
1510  insn.id = MIPS_INS_LB;
1511  }
1512  /* fallthrough */
1513  case 35: // lw
1514  if (!op->refptr) {
1515  op->refptr = 4;
1516  insn.id = MIPS_INS_LW;
1517  }
1518  /* fallthrough */
1519  case 55: // ld
1520  if (!op->refptr) {
1521  op->refptr = 8;
1522  insn.id = MIPS_INS_LD;
1523  }
1524 
1525  if (rs == 28) {
1526  op->ptr = analysis->gp + imm;
1527  } else {
1528  op->ptr = imm;
1529  }
1530  if (rt == 25) {
1531  t9_pre = op->ptr;
1532  }
1533  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
1534  break;
1535  case 36: // lbu
1536  insn.id = MIPS_INS_LBU;
1537  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
1538  break;
1539  case 37: // lhu
1540  insn.id = MIPS_INS_LHU;
1541  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
1542  break;
1543  case 40: // sb
1544  insn.id = MIPS_INS_SB;
1545  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
1546  break;
1547  case 41: // sh
1548  insn.id = MIPS_INS_SH;
1549  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
1550  break;
1551  case 43: // sw
1552  insn.id = MIPS_INS_SW;
1553  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
1554  break;
1555  case 63: // sd
1556  insn.id = MIPS_INS_SD;
1557  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
1558  break;
1559  case 49: // lwc1
1560  case 57: // swc1
1561  break;
1562  case 29: // jalx
1563  insn.id = MIPS_INS_JALX;
1564  op->type = RZ_ANALYSIS_OP_TYPE_CALL;
1565  op->jump = addr + 4 * ((buf[3] | buf[2] << 8 | buf[1] << 16));
1566  op->fail = addr + 8;
1567  op->delay = 1;
1568  snprintf((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump);
1569 
1570  break;
1571  }
1572  // family = 'I';
1573  }
1574 
1576  if (analop_esil(analysis, op, addr, &insn)) {
1577  rz_strbuf_fini(&op->esil);
1578  }
1579  }
1580  if (mask & RZ_ANALYSIS_OP_MASK_VAL) {
1581  // TODO: add op_fillval (analysis, op, &insn);
1582  }
1583  return oplen;
1584 }
1585 
1586 /*
1587  R - all instructions that only take registers as arguments (jalr, jr)
1588  opcode 000000
1589  opcode (6) rs (5) rt (5) rd (5) sa (5) function (6)
1590  add rd, rs, rt 100000
1591  addu rd, rs, rt 100001
1592  and rd, rs, rt 100100
1593  break 001101
1594  div rs, rt 011010
1595  divu rs, rt 011011
1596  jalr rd, rs 001001
1597  jr rs 001000
1598 
1599  mfhi rd 010000
1600  mflo rd 010010
1601  mthi rs 010001
1602  mtlo rs 010011
1603  mult rs, rt 011000
1604  multu rs, rt 011001
1605 
1606  nor rd, rs, rt 100111
1607  or rd, rs, rt 100101
1608  sll rd, rt, sa 000000
1609  sllv rd, rt, rs 000100
1610  slt rd, rs, rt 101010
1611  sltu rd, rs, rt 101011
1612 
1613  sra rd, rt, sa 000011
1614  srav rd, rt, rs 000111
1615 
1616  srl rd, rt, sa 000010
1617  srlv rd, rt, rs 000110
1618 
1619  sub rd, rs, rt 100010
1620  subu rd, rs, rt 100011
1621  syscall 001100
1622  xor rd, rs, rt 100110
1623  I - instructions with immediate operand, load/store/..
1624  all opcodes but 000000 000001x and 0100xx
1625  opcode (6) rs (5) rt (5) immediate (16)
1626  addi rt, rs, immediate 001000
1627  addiu rt, rs, immediate 001001
1628  andi rt, rs, immediate 001100
1629  beq rs, rt, label 000100
1630 
1631  bgez rs, label 000001 rt = 00001
1632 
1633  bgtz rs, label 000111 rt = 00000
1634  blez rs, label 000110 rt = 00000
1635 
1636  bltz rs, label 000001 rt = 00000
1637  bne rs, rt, label 000101
1638  lb rt, immediate(rs) 100000
1639  lbu rt, immediate(rs) 100100
1640 
1641  lh rt, immediate(rs) 100001
1642  lhu rt, immediate(rs) 100101
1643 
1644  lui rt, immediate 001111
1645 
1646  lw rt, immediate(rs) 100011
1647  lwc1 rt, immediate(rs) 110001
1648 
1649  ori rt, rs, immediate 001101
1650  sb rt, immediate(rs) 101000
1651 
1652  slti rt, rs, immediate 001010
1653  sltiu rt, rs, immediate 001011
1654  sh rt, immediate(rs) 101001
1655  sw rt, immediate(rs) 101011
1656  swc1 rt, immediate(rs) 111001
1657  xori rt, rs, immediate 001110
1658  J - require memory address like j, jal
1659  00001x
1660  opcode (6) target (26)
1661  j label 000010 coded address of label
1662  jal label 000011 coded address of label
1663  C - coprocessor insutrctions that use cp0, cp1, ..
1664  0100xx
1665  opcode (6) format (5) ft (5) fs (5) fd (5) function (6)
1666  add.s fd, fs, ft 000000 10000
1667  cvt.s.w fd, fs, ft 100000 10100
1668  cvt.w.s fd, fs, ft 100100 10000
1669  div.s fd, fs, ft 000011 10000
1670  mfc1 ft, fs 000000 00000
1671  mov.s fd, fs 000110 10000
1672  mtc1 ft, fs 000000 00100
1673  mul.s fd, fs, ft 000010 10000
1674  sub.s fd, fs, ft 000001 10000
1675 */
1676 
1677 /* Set the profile register */
1678 static char *mips_get_reg_profile(RzAnalysis *analysis) {
1679  const char *p =
1680 #if 0
1681  "=PC pc\n"
1682  "=SP sp\n"
1683  "=A0 a0\n"
1684  "=A1 a1\n"
1685  "=A2 a2\n"
1686  "=A3 a3\n"
1687  "gpr zero .32 0 0\n"
1688  "gpr at .32 4 0\n"
1689  "gpr v0 .32 8 0\n"
1690  "gpr v1 .32 12 0\n"
1691  "gpr a0 .32 16 0\n"
1692  "gpr a1 .32 20 0\n"
1693  "gpr a2 .32 24 0\n"
1694  "gpr a3 .32 28 0\n"
1695  "gpr t0 .32 32 0\n"
1696  "gpr t1 .32 36 0\n"
1697  "gpr t2 .32 40 0\n"
1698  "gpr t3 .32 44 0\n"
1699  "gpr t4 .32 48 0\n"
1700  "gpr t5 .32 52 0\n"
1701  "gpr t6 .32 56 0\n"
1702  "gpr t7 .32 60 0\n"
1703  "gpr s0 .32 64 0\n"
1704  "gpr s1 .32 68 0\n"
1705  "gpr s2 .32 72 0\n"
1706  "gpr s3 .32 76 0\n"
1707  "gpr s4 .32 80 0\n"
1708  "gpr s5 .32 84 0\n"
1709  "gpr s6 .32 88 0\n"
1710  "gpr s7 .32 92 0\n"
1711  "gpr t8 .32 96 0\n"
1712  "gpr t9 .32 100 0\n"
1713  "gpr k0 .32 104 0\n"
1714  "gpr k1 .32 108 0\n"
1715  "gpr gp .32 112 0\n"
1716  "gpr sp .32 116 0\n"
1717  "gpr fp .32 120 0\n"
1718  "gpr ra .32 124 0\n"
1719  "gpr pc .32 128 0\n";
1720 #else
1721  // take the one from the debugger //
1722  "=PC pc\n"
1723  "=SP sp\n"
1724  "=BP fp\n"
1725  "=A0 a0\n"
1726  "=A1 a1\n"
1727  "=A2 a2\n"
1728  "=A3 a3\n"
1729  "gpr zero .64 0 0\n"
1730  // XXX DUPPED CAUSES FAILURE "gpr at .32 8 0\n"
1731  "gpr at .64 8 0\n"
1732  "gpr v0 .64 16 0\n"
1733  "gpr v1 .64 24 0\n"
1734  /* args */
1735  "gpr a0 .64 32 0\n"
1736  "gpr a1 .64 40 0\n"
1737  "gpr a2 .64 48 0\n"
1738  "gpr a3 .64 56 0\n"
1739  /* tmp */
1740  "gpr t0 .64 64 0\n"
1741  "gpr t1 .64 72 0\n"
1742  "gpr t2 .64 80 0\n"
1743  "gpr t3 .64 88 0\n"
1744  "gpr t4 .64 96 0\n"
1745  "gpr t5 .64 104 0\n"
1746  "gpr t6 .64 112 0\n"
1747  "gpr t7 .64 120 0\n"
1748  /* saved */
1749  "gpr s0 .64 128 0\n"
1750  "gpr s1 .64 136 0\n"
1751  "gpr s2 .64 144 0\n"
1752  "gpr s3 .64 152 0\n"
1753  "gpr s4 .64 160 0\n"
1754  "gpr s5 .64 168 0\n"
1755  "gpr s6 .64 176 0\n"
1756  "gpr s7 .64 184 0\n"
1757  "gpr t8 .64 192 0\n"
1758  "gpr t9 .64 200 0\n"
1759  /* special */
1760  "gpr k0 .64 208 0\n"
1761  "gpr k1 .64 216 0\n"
1762  "gpr gp .64 224 0\n"
1763  "gpr sp .64 232 0\n"
1764  "gpr fp .64 240 0\n"
1765  "gpr ra .64 248 0\n"
1766  /* extra */
1767  "gpr pc .64 272 0\n";
1768 #endif
1769  return strdup(p);
1770 }
1771 
1772 static int archinfo(RzAnalysis *analysis, int q) {
1773  return 4;
1774 }
1775 
1777  .name = "mips.gnu",
1778  .desc = "MIPS code analysis plugin",
1779  .license = "LGPL3",
1780  .arch = "mips",
1781  .bits = 32,
1782  .esil = true,
1783  .archinfo = archinfo,
1784  .op = &mips_op,
1785  .get_reg_profile = mips_get_reg_profile,
1786 };
1787 
1788 #ifndef RZ_PLUGIN_INCORE
1792 };
1793 #endif
size_t len
Definition: 6502dis.c:15
RZ_API RzAnalysisValue * rz_analysis_value_new(void)
Definition: value.c:6
#define rs()
#define rd()
#define mask()
#define imm
#define R_REG(x)
static const char * mips_reg_decode(ut32 reg_num)
static char * mips_get_reg_profile(RzAnalysis *analysis)
static int analop_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, gnu_insn *insn)
#define J_REG(x)
static ut64 t9_pre
mips_insn
@ MIPS_INS_MTP0
@ MIPS_INS_HSUB_S
@ MIPS_INS_PRECR_SRA
@ MIPS_INS_EXTPDPV
@ MIPS_INS_ABSQ_S
@ MIPS_INS_JRADDIUSP
@ MIPS_INS_DDIVU
@ MIPS_INS_EXTPDP
@ MIPS_INS_PRECEU
@ MIPS_INS_SHLL
@ MIPS_INS_MTHLIP
@ MIPS_INS_ADDS_A
@ MIPS_INS_SELEQZ
@ MIPS_INS_DMUH
@ MIPS_INS_ILVL
@ MIPS_INS_BINSR
@ MIPS_INS_DPAQX_S
@ MIPS_INS_TLBP
@ MIPS_INS_FFQR
@ MIPS_INS_AUIPC
@ MIPS_INS_BEQZC
@ MIPS_INS_CMPU
@ MIPS_INS_BGEZL
@ MIPS_INS_XORI
@ MIPS_INS_DPSQX_S
@ MIPS_INS_MSUB
@ MIPS_INS_ADDV
@ MIPS_INS_MIN_U
@ MIPS_INS_AUI
@ MIPS_INS_FLOG2
@ MIPS_INS_TGEIU
@ MIPS_INS_BLTZ
@ MIPS_INS_FMSUB
@ MIPS_INS_DPADD_U
@ MIPS_INS_FFINT_U
@ MIPS_INS_ADDU_S
@ MIPS_INS_LDC1
@ MIPS_INS_DPA
@ MIPS_INS_HADD_S
@ MIPS_INS_FRCP
@ MIPS_INS_SEH
@ MIPS_INS_BNEC
@ MIPS_INS_FSLT
@ MIPS_INS_DMUL
@ MIPS_INS_DSRL32
@ MIPS_INS_LDPC
@ MIPS_INS_SNE
@ MIPS_INS_FSOR
@ MIPS_INS_SHRA
@ MIPS_INS_BGTZ
@ MIPS_INS_INSERT
@ MIPS_INS_BBIT032
@ MIPS_INS_DMULT
@ MIPS_INS_FCULT
@ MIPS_INS_FTRUNC_S
@ MIPS_INS_SYNCI
@ MIPS_INS_DMFC1
@ MIPS_INS_EXTP
@ MIPS_INS_MOV
@ MIPS_INS_TEQ
@ MIPS_INS_DMTC1
@ MIPS_INS_BC3T
@ MIPS_INS_BLTZALC
@ MIPS_INS_SAT_S
@ MIPS_INS_BLTUC
@ MIPS_INS_SUBQH
@ MIPS_INS_LI
@ MIPS_INS_SWP
@ MIPS_INS_ALUIPC
@ MIPS_INS_FCLT
@ MIPS_INS_SELNEZ
@ MIPS_INS_FSEQ
@ MIPS_INS_CEQI
@ MIPS_INS_DROTR
@ MIPS_INS_ST
@ MIPS_INS_WAIT
@ MIPS_INS_FSUN
@ MIPS_INS_CMPGDU
@ MIPS_INS_MSUBU
@ MIPS_INS_BLTZALL
@ MIPS_INS_ADDUH_R
@ MIPS_INS_BC1T
@ MIPS_INS_SWL
@ MIPS_INS_BC1EQZ
@ MIPS_INS_SLT
@ MIPS_INS_PREF
@ MIPS_INS_ILVEV
@ MIPS_INS_DPS
@ MIPS_INS_SWC1
@ MIPS_INS_BMZI
@ MIPS_INS_SUBU16
@ MIPS_INS_NOP
@ MIPS_INS_MOVN
@ MIPS_INS_BNE
@ MIPS_INS_MSUBF
@ MIPS_INS_DPAQ_SA
@ MIPS_INS_SPLAT
@ MIPS_INS_BMNZI
@ MIPS_INS_DSRA
@ MIPS_INS_BGTZC
@ MIPS_INS_MOVF
@ MIPS_INS_DINS
@ MIPS_INS_INS
@ MIPS_INS_FTINT_U
@ MIPS_INS_BREAK
@ MIPS_INS_CLO
@ MIPS_INS_LDC2
@ MIPS_INS_EXTR_S
@ MIPS_INS_VSHF
@ MIPS_INS_FEXUPL
@ MIPS_INS_LWM16
@ MIPS_INS_SDC2
@ MIPS_INS_SHLL_S
@ MIPS_INS_FSLE
@ MIPS_INS_LDL
@ MIPS_INS_DPOP
@ MIPS_INS_SHILOV
@ MIPS_INS_EI
@ MIPS_INS_SYNC
@ MIPS_INS_LWUPC
@ MIPS_INS_ADDVI
@ MIPS_INS_ILVR
@ MIPS_INS_FCUN
@ MIPS_INS_BITREV
@ MIPS_INS_SWC3
@ MIPS_INS_SDXC1
@ MIPS_INS_SW
@ MIPS_INS_BC2F
@ MIPS_INS_DINSM
@ MIPS_INS_BNZ
@ MIPS_INS_C
@ MIPS_INS_JIALC
@ MIPS_INS_DPSQ_S
@ MIPS_INS_BSETI
@ MIPS_INS_NMADD
@ MIPS_INS_EXTPV
@ MIPS_INS_LDC3
@ MIPS_INS_LW16
@ MIPS_INS_NLOC
@ MIPS_INS_LWP
@ MIPS_INS_EXTS32
@ MIPS_INS_SWM16
@ MIPS_INS_CLTI_U
@ MIPS_INS_SRLI
@ MIPS_INS_PCKEV
@ MIPS_INS_FFQL
@ MIPS_INS_DCLZ
@ MIPS_INS_MFHC1
@ MIPS_INS_FCUNE
@ MIPS_INS_ADDUH
@ MIPS_INS_MOVEP
@ MIPS_INS_ORI
@ MIPS_INS_LUI
@ MIPS_INS_BLTZALS
@ MIPS_INS_DIV_S
@ MIPS_INS_BBIT0
@ MIPS_INS_CMPGU
@ MIPS_INS_TGEU
@ MIPS_INS_SH16
@ MIPS_INS_INVALID
@ MIPS_INS_BEQL
@ MIPS_INS_BC0F
@ MIPS_INS_BGEZALC
@ MIPS_INS_REPLV
@ MIPS_INS_BLEZALC
@ MIPS_INS_JALRS
@ MIPS_INS_MAX_A
@ MIPS_INS_SC
@ MIPS_INS_ROTR
@ MIPS_INS_FSAF
@ MIPS_INS_BPOSGE32
@ MIPS_INS_FTRUNC_U
@ MIPS_INS_CLT_S
@ MIPS_INS_DSUBU
@ MIPS_INS_LWL
@ MIPS_INS_FCUEQ
@ MIPS_INS_SWXC1
@ MIPS_INS_FMAX_A
@ MIPS_INS_LI16
@ MIPS_INS_FMUL
@ MIPS_INS_CLASS
@ MIPS_INS_INSVE
@ MIPS_INS_BOVC
@ MIPS_INS_SUBUH
@ MIPS_INS_DPSQ_SA
@ MIPS_INS_ADDS_U
@ MIPS_INS_MUL
@ MIPS_INS_CFCMSA
@ MIPS_INS_BNEG
@ MIPS_INS_DIV_U
@ MIPS_INS_MADD
@ MIPS_INS_PRECR
@ MIPS_INS_SUBQ_S
@ MIPS_INS_MSUBR_Q
@ MIPS_INS_MADDV
@ MIPS_INS_FCAF
@ MIPS_INS_SDL
@ MIPS_INS_MIN_S
@ MIPS_INS_AND16
@ MIPS_INS_FLOOR
@ MIPS_INS_MAXA
@ MIPS_INS_SH
@ MIPS_INS_MTHI
@ MIPS_INS_BNEZALC
@ MIPS_INS_HSUB_U
@ MIPS_INS_BNEGI
@ MIPS_INS_SHRLV
@ MIPS_INS_CVT
@ MIPS_INS_SUXC1
@ MIPS_INS_SQRT
@ MIPS_INS_BEQ
@ MIPS_INS_JAL
@ MIPS_INS_SWR
@ MIPS_INS_RDDSP
@ MIPS_INS_TRUNC
@ MIPS_INS_RINT
@ MIPS_INS_BC2NEZ
@ MIPS_INS_LWR
@ MIPS_INS_LWM32
@ MIPS_INS_JALRS16
@ MIPS_INS_JIC
@ MIPS_INS_COPY_S
@ MIPS_INS_MULQ_RS
@ MIPS_INS_SHRAV_R
@ MIPS_INS_LHX
@ MIPS_INS_BCLR
@ MIPS_INS_JALS
@ MIPS_INS_LUXC1
@ MIPS_INS_MTM2
@ MIPS_INS_LD
@ MIPS_INS_MULSAQ_S
@ MIPS_INS_DPSX
@ MIPS_INS_BEQZ16
@ MIPS_INS_MAXI_S
@ MIPS_INS_LH
@ MIPS_INS_LDXC1
@ MIPS_INS_ADDIUSP
@ MIPS_INS_MULR_Q
@ MIPS_INS_LWXS
@ MIPS_INS_BSEL
@ MIPS_INS_SHRA_R
@ MIPS_INS_SLDI
@ MIPS_INS_LW
@ MIPS_INS_MTP2
@ MIPS_INS_DMFC2
@ MIPS_INS_MAX_U
@ MIPS_INS_LSA
@ MIPS_INS_SRLV
@ MIPS_INS_ABS
@ MIPS_INS_SRL
@ MIPS_INS_ADDS_S
@ MIPS_INS_ADD
@ MIPS_INS_MTC2
@ MIPS_INS_BBIT132
@ MIPS_INS_EXTR
@ MIPS_INS_DEXT
@ MIPS_INS_SUBS_U
@ MIPS_INS_MFLO
@ MIPS_INS_DPAQ_S
@ MIPS_INS_B16
@ MIPS_INS_DPSUB_U
@ MIPS_INS_PCNT
@ MIPS_INS_V3MULU
@ MIPS_INS_NOR
@ MIPS_INS_LWX
@ MIPS_INS_TLT
@ MIPS_INS_MULEU_S
@ MIPS_INS_MINA
@ MIPS_INS_TGE
@ MIPS_INS_BMZ
@ MIPS_INS_MULSA
@ MIPS_INS_DSHD
@ MIPS_INS_SUBSUS_U
@ MIPS_INS_EXTRV
@ MIPS_INS_ADDSC
@ MIPS_INS_JR_HB
@ MIPS_INS_SDR
@ MIPS_INS_SUBU_S
@ MIPS_INS_LDR
@ MIPS_INS_BC2T
@ MIPS_INS_DPSQX_SA
@ MIPS_INS_MTM0
@ MIPS_INS_SRLR
@ MIPS_INS_BGTZL
@ MIPS_INS_EXTR_R
@ MIPS_INS_SUBQH_R
@ MIPS_INS_NOT
@ MIPS_INS_DATI
@ MIPS_INS_MAXI_U
@ MIPS_INS_MUH
@ MIPS_INS_MULU
@ MIPS_INS_BLEZL
@ MIPS_INS_MAQ_SA
@ MIPS_INS_MIN_A
@ MIPS_INS_ADDU
@ MIPS_INS_HADD_U
@ MIPS_INS_SUB
@ MIPS_INS_MAX
@ MIPS_INS_SAT_U
@ MIPS_INS_LHU16
@ MIPS_INS_SEB
@ MIPS_INS_FRINT
@ MIPS_INS_DSRA32
@ MIPS_INS_EXT
@ MIPS_INS_SB16
@ MIPS_INS_BGTZALC
@ MIPS_INS_APPEND
@ MIPS_INS_TLBR
@ MIPS_INS_SLTIU
@ MIPS_INS_DAUI
@ MIPS_INS_SRA
@ MIPS_INS_PRECEQ
@ MIPS_INS_ERET
@ MIPS_INS_BC1TL
@ MIPS_INS_BEQC
@ MIPS_INS_LL
@ MIPS_INS_BLEZC
@ MIPS_INS_JALX
@ MIPS_INS_DSRAV
@ MIPS_INS_DMOD
@ MIPS_INS_SSNOP
@ MIPS_INS_CEQ
@ MIPS_INS_PRECRQ
@ MIPS_INS_SRAR
@ MIPS_INS_DPAQX_SA
@ MIPS_INS_MFHI
@ MIPS_INS_DPAX
@ MIPS_INS_BNEZ
@ MIPS_INS_CACHE
@ MIPS_INS_PREPEND
@ MIPS_INS_EXTRV_RS
@ MIPS_INS_LHU
@ MIPS_INS_BSELI
@ MIPS_INS_BC1FL
@ MIPS_INS_BITSWAP
@ MIPS_INS_DINSU
@ MIPS_INS_NEG
@ MIPS_INS_MADDR_Q
@ MIPS_INS_ADDWC
@ MIPS_INS_CLEI_S
@ MIPS_INS_BGEZ
@ MIPS_INS_BAL
@ MIPS_INS_TLBWR
@ MIPS_INS_DPADD_S
@ MIPS_INS_PRECRQ_RS
@ MIPS_INS_DCLO
@ MIPS_INS_NORI
@ MIPS_INS_BNVC
@ MIPS_INS_DSRLV
@ MIPS_INS_BC0TL
@ MIPS_INS_BINSRI
@ MIPS_INS_ADDI
@ MIPS_INS_EXTRV_R
@ MIPS_INS_FEXP2
@ MIPS_INS_SUBS_S
@ MIPS_INS_FCOR
@ MIPS_INS_DADD
@ MIPS_INS_MADD_Q
@ MIPS_INS_BC1F
@ MIPS_INS_SDC3
@ MIPS_INS_ADDQH_R
@ MIPS_INS_SLTU
@ MIPS_INS_SDC1
@ MIPS_INS_MOVT
@ MIPS_INS_DMULTU
@ MIPS_INS_DSUB
@ MIPS_INS_DSRL
@ MIPS_INS_MOD
@ MIPS_INS_EHB
@ MIPS_INS_BC2FL
@ MIPS_INS_FDIV
@ MIPS_INS_NEGU
@ MIPS_INS_BREAK16
@ MIPS_INS_SNEI
@ MIPS_INS_AND
@ MIPS_INS_JR16
@ MIPS_INS_FMIN_A
@ MIPS_INS_FCEQ
@ MIPS_INS_B
@ MIPS_INS_FSUB
@ MIPS_INS_ADD_A
@ MIPS_INS_DMODU
@ MIPS_INS_FSULT
@ MIPS_INS_SD
@ MIPS_INS_FMIN
@ MIPS_INS_POP
@ MIPS_INS_WSBH
@ MIPS_INS_LWPC
@ MIPS_INS_DALIGN
@ MIPS_INS_AVER_S
@ MIPS_INS_TLBWI
@ MIPS_INS_BBIT1
@ MIPS_INS_SLLI
@ MIPS_INS_DSLLV
@ MIPS_INS_MOD_S
@ MIPS_INS_SHILO
@ MIPS_INS_ALIGN
@ MIPS_INS_SUBSUU_S
@ MIPS_INS_FEXDO
@ MIPS_INS_SHRL
@ MIPS_INS_BLTC
@ MIPS_INS_XOR
@ MIPS_INS_SLD
@ MIPS_INS_BC0T
@ MIPS_INS_SRL16
@ MIPS_INS_MSUB_Q
@ MIPS_INS_BNEZC
@ MIPS_INS_DMTC2
@ MIPS_INS_CINS32
@ MIPS_INS_MUL_Q
@ MIPS_INS_MODSUB
@ MIPS_INS_MTP1
@ MIPS_INS_MOD_U
@ MIPS_INS_DERET
@ MIPS_INS_CTC1
@ MIPS_INS_PACKRL
@ MIPS_INS_BC
@ MIPS_INS_FSULE
@ MIPS_INS_FCULE
@ MIPS_INS_LBU
@ MIPS_INS_SEL
@ MIPS_INS_SUBU
@ MIPS_INS_DIV
@ MIPS_INS_LWC2
@ MIPS_INS_BLEZ
@ MIPS_INS_LDI
@ MIPS_INS_JALRC
@ MIPS_INS_ADDIUR1SP
@ MIPS_INS_FEXUPR
@ MIPS_INS_DEXTU
@ MIPS_INS_ENDING
@ MIPS_INS_BEQZALC
@ MIPS_INS_ASUB_S
@ MIPS_INS_BGEZALS
@ MIPS_INS_SWC2
@ MIPS_INS_DEXTM
@ MIPS_INS_FCNE
@ MIPS_INS_LLD
@ MIPS_INS_MULQ_S
@ MIPS_INS_DMULU
@ MIPS_INS_ROTRV
@ MIPS_INS_RDHWR
@ MIPS_INS_J
@ MIPS_INS_BSET
@ MIPS_INS_LBUX
@ MIPS_INS_CTCMSA
@ MIPS_INS_BGEZALL
@ MIPS_INS_BGEUC
@ MIPS_INS_TEQI
@ MIPS_INS_ADDU16
@ MIPS_INS_SHF
@ MIPS_INS_BC2TL
@ MIPS_INS_CMPI
@ MIPS_INS_MADDU
@ MIPS_INS_SRLRI
@ MIPS_INS_DSLL
@ MIPS_INS_BNEZ16
@ MIPS_INS_BTNEZ
@ MIPS_INS_CFC1
@ MIPS_INS_ADDIU
@ MIPS_INS_SUBUH_R
@ MIPS_INS_FADD
@ MIPS_INS_CLT_U
@ MIPS_INS_NLZC
@ MIPS_INS_MINI_U
@ MIPS_INS_SUBVI
@ MIPS_INS_ILVOD
@ MIPS_INS_NOT16
@ MIPS_INS_BCLRI
@ MIPS_INS_OR16
@ MIPS_INS_BLTZL
@ MIPS_INS_BGEC
@ MIPS_INS_CLEI_U
@ MIPS_INS_FTQ
@ MIPS_INS_MFC0
@ MIPS_INS_DPAU
@ MIPS_INS_BLTZC
@ MIPS_INS_SEQ
@ MIPS_INS_ADDQH
@ MIPS_INS_AVER_U
@ MIPS_INS_FSNE
@ MIPS_INS_LWU
@ MIPS_INS_ADDIUPC
@ MIPS_INS_SRAI
@ MIPS_INS_FTINT_S
@ MIPS_INS_MULEQ_S
@ MIPS_INS_MTC0
@ MIPS_INS_MULV
@ MIPS_INS_DIVU
@ MIPS_INS_MAQ_S
@ MIPS_INS_SYSCALL
@ MIPS_INS_BTEQZ
@ MIPS_INS_SDBBP
@ MIPS_INS_SHLLV
@ MIPS_INS_DPSUB_S
@ MIPS_INS_FILL
@ MIPS_INS_MULTU
@ MIPS_INS_SW16
@ MIPS_INS_DBITSWAP
@ MIPS_INS_OR
@ MIPS_INS_ADDQ
@ MIPS_INS_ADDIUS5
@ MIPS_INS_WRDSP
@ MIPS_INS_LBU16
@ MIPS_INS_TNE
@ MIPS_INS_BC3F
@ MIPS_INS_VMM0
@ MIPS_INS_TLTIU
@ MIPS_INS_MTHC1
@ MIPS_INS_SCD
@ MIPS_INS_JALR
@ MIPS_INS_PRECEQU
@ MIPS_INS_ANDI
@ MIPS_INS_BALC
@ MIPS_INS_DDIV
@ MIPS_INS_SWM32
@ MIPS_INS_COPY_U
@ MIPS_INS_BEQZ
@ MIPS_INS_MODU
@ MIPS_INS_REPL
@ MIPS_INS_SPLATI
@ MIPS_INS_LB
@ MIPS_INS_DI
@ MIPS_INS_DLSA
@ MIPS_INS_MINI_S
@ MIPS_INS_DOTP_S
@ MIPS_INS_DROTRV
@ MIPS_INS_MTLO
@ MIPS_INS_SLL
@ MIPS_INS_MADDF
@ MIPS_INS_SRARI
@ MIPS_INS_TLTU
@ MIPS_INS_PRECRQU_S
@ MIPS_INS_EXTR_RS
@ MIPS_INS_BGEZAL
@ MIPS_INS_PRECR_SRA_R
@ MIPS_INS_CEIL
@ MIPS_INS_MIN
@ MIPS_INS_NMSUB
@ MIPS_INS_BC1NEZ
@ MIPS_INS_SLL16
@ MIPS_INS_CLTI_S
@ MIPS_INS_BINSLI
@ MIPS_INS_MTC1
@ MIPS_INS_DROTR32
@ MIPS_INS_ASUB_U
@ MIPS_INS_PICK
@ MIPS_INS_RADDU
@ MIPS_INS_CMP
@ MIPS_INS_ROUND
@ MIPS_INS_MULT
@ MIPS_INS_MAX_S
@ MIPS_INS_EXTS
@ MIPS_INS_LWC1
@ MIPS_INS_BC0FL
@ MIPS_INS_FSUEQ
@ MIPS_INS_DMFC0
@ MIPS_INS_CLE_U
@ MIPS_INS_MTM1
@ MIPS_INS_BMNZ
@ MIPS_INS_MOVE
@ MIPS_INS_MOVZ
@ MIPS_INS_SRAV
@ MIPS_INS_FRSQRT
@ MIPS_INS_LWXC1
@ MIPS_INS_JRC
@ MIPS_INS_BC2EQZ
@ MIPS_INS_DSBH
@ MIPS_INS_SUBQ
@ MIPS_INS_FSQRT
@ MIPS_INS_FMAX
@ MIPS_INS_DADDIU
@ MIPS_INS_PCKOD
@ MIPS_INS_FFINT_S
@ MIPS_INS_AVE_S
@ MIPS_INS_FMADD
@ MIPS_INS_AVE_U
@ MIPS_INS_BGEZC
@ MIPS_INS_FCLE
@ MIPS_INS_BZ
@ MIPS_INS_SHRAV
@ MIPS_INS_BINSL
@ MIPS_INS_DADDI
@ MIPS_INS_ANDI16
@ MIPS_INS_SDBBP16
@ MIPS_INS_PAUSE
@ MIPS_INS_BALIGN
@ MIPS_INS_VMULU
@ MIPS_INS_BADDU
@ MIPS_INS_EXTRV_S
@ MIPS_INS_INSV
@ MIPS_INS_LWC3
@ MIPS_INS_DPSU
@ MIPS_INS_DOTP_U
@ MIPS_INS_BC3FL
@ MIPS_INS_MSUBV
@ MIPS_INS_SEQI
@ MIPS_INS_SLLV
@ MIPS_INS_TNEI
@ MIPS_INS_CLE_S
@ MIPS_INS_JALR_HB
@ MIPS_INS_TLTI
@ MIPS_INS_SLTI
@ MIPS_INS_CINS
@ MIPS_INS_DAHI
@ MIPS_INS_ADDQ_S
@ MIPS_INS_CLZ
@ MIPS_INS_DMTC0
@ MIPS_INS_FCLASS
@ MIPS_INS_DMUHU
@ MIPS_INS_JR
@ MIPS_INS_ADDIUR2
@ MIPS_INS_SB
@ MIPS_INS_BC3TL
@ MIPS_INS_TGEI
@ MIPS_INS_MFC1
@ MIPS_INS_FSUNE
@ MIPS_INS_DSLL32
@ MIPS_INS_SUBV
@ MIPS_INS_BNEL
@ MIPS_INS_DADDU
@ MIPS_INS_MUHU
@ MIPS_INS_SHLLV_S
@ MIPS_INS_MFC2
@ MIPS_INS_MUL_S
@ MIPS_INS_XOR16
@ MIPS_INS_BLTZAL
#define ES_CALL_DR(ra, addr)
#define ES_ADD_CK32_OVERF(x, y, z)
#define ES_CALL_D(addr)
#define ES_TRAP_DS()
#define ES_ADD_CK64_OVERF(x, y, z)
static void es_sign_n_64(RzAnalysis *a, RzAnalysisOp *op, const char *arg, int bit)
RZ_API RzLibStruct rizin_plugin
#define ES_J(addr)
#define ES_SIGN32_64(arg)
static int mips_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *b, int len, RzAnalysisOpMask mask)
#define ES_IS_NEGATIVE(arg)
static void es_add_ck(RzAnalysisOp *op, const char *a1, const char *a2, const char *re, int bit)
#define REG_BUF_MAX
struct gnu_insn gnu_insn
RzAnalysisPlugin rz_analysis_plugin_mips_gnu
static int archinfo(RzAnalysis *analysis, int q)
#define I_REG(x)
#define ES_W(x)
#define PFMT32x
int jump(int a, int b)
Definition: bcj_test.c:35
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RzCryptoSelector bit
Definition: crypto.c:16
uint32_t ut32
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
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")
ut8 optype
Definition: pic_pic18.c:32
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ RZ_ANALYSIS_OP_MASK_VAL
Definition: rz_analysis.h:442
@ RZ_ANALYSIS_OP_MASK_ESIL
Definition: rz_analysis.h:441
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_UNK
Definition: rz_analysis.h:388
@ RZ_ANALYSIS_OP_TYPE_MUL
Definition: rz_analysis.h:404
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_AND
Definition: rz_analysis.h:411
@ RZ_ANALYSIS_OP_TYPE_NOR
Definition: rz_analysis.h:413
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_SAR
Definition: rz_analysis.h:409
@ RZ_ANALYSIS_OP_TYPE_TRAP
Definition: rz_analysis.h:392
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_ADD
Definition: rz_analysis.h:401
@ RZ_ANALYSIS_OP_TYPE_OR
Definition: rz_analysis.h:410
@ RZ_ANALYSIS_OP_TYPE_STORE
Definition: rz_analysis.h:415
@ RZ_ANALYSIS_OP_TYPE_SHR
Definition: rz_analysis.h:406
@ RZ_ANALYSIS_OP_TYPE_RJMP
Definition: rz_analysis.h:370
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_DIV
Definition: rz_analysis.h:405
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_ANALYSIS_OP_TYPE_SHL
Definition: rz_analysis.h:407
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380
@ RZ_ANALYSIS_OP_TYPE_XOR
Definition: rz_analysis.h:412
static ut32 rz_read_ble32(const void *src, bool big_endian)
Definition: rz_endian.h:497
static ut32 rz_swap_ut32(ut32 val)
Definition: rz_endian.h:580
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
#define PFMT64x
Definition: rz_types.h:393
#define PFMT32d
Definition: rz_types.h:408
#define UT64_MAX
Definition: rz_types_base.h:86
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
struct gnu_jreg j_reg
struct gnu_rreg r_reg
struct gnu_ireg i_reg
const char * rt
const char * rs
ut8 imm[REG_BUF_MAX]
ut8 jump[REG_BUF_MAX]
ut8 jump[REG_BUF_MAX]
const char * rs
ut8 sa[REG_BUF_MAX]
const char * rd
const char * rt
Definition: op.c:222
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
Definition: z80_tab.h:997
static int addr
Definition: z80asm.c:58