int main() { START_MACHINE; JUMP(CONTINUE); #include "char.lib" #include "io.lib" #include "math.lib" #include "string.lib" #include "system.lib" #include "scheme.lib" CONTINUE: PUSH(IMM(64)); CALL(MALLOC); SHOW("MALLOC RETURNED ", R0); DROP(1); PUSH(R0); OUT(IMM(2), IMM('?')); OUT(IMM(2), IMM(' ')); CALL(READLINE); SHOW("READ IN STRING AT ADDRESS ", R0); PUSH(R0); CALL(STRING_TO_NUMBER); DROP(1); SHOW("READ IN ", R0); MUL(R0, R0); SHOW("SQUARE IS ", R0); PUSH(R0); CALL(NUMBER_TO_STRING); DROP(1); PUSH(R0); SHOW("STR[0] = ", INDD(R0, 0)); SHOW("STR[1] = ", INDD(R1, 0)); SHOW("STR[2] = ", INDD(R2, 0)); SHOW("STR[3] = ", INDD(R3, 0)); CALL(WRITELN); DROP(1); STOP_MACHINE; return 0; }
static int dis_tcc(uint32_t *pc, uint32_t inst) { char *tcc[0x10] = { "tn", "te", "tle", "tl", "tleu", "tcs", "tneg", "tvs", "ta", "tne", "tg", "tge", "tgu", "tcc", "tpos", "tvc" }; (void)printf("%p:\t%s%s\t%s, ", (void *)pc, HT(inst) ? "h" : "", tcc[COND(inst)], TCC(inst) ? "%xcc" : "%icc"); if (IMM(inst)) (void)printf("0x%x\n", SWTRAP(inst)); else (void)printf("%s\n", sregs[RS2(inst)]); return OK; }
int main() { START_MACHINE; JUMP(CONTINUE); #include "char.lib" #include "io.lib" #include "math.lib" #include "string.lib" #include "system.lib" #include "scheme.lib" CONTINUE: /* initialize the 4 singletons */ PUSH(IMM(1)); CALL(MAKE_SOB_BOOL); /* define SOB_BOOL_TRUE in mem[1]*/ DROP(1); PUSH(IMM(0)); CALL(MAKE_SOB_BOOL); /* define SOB_BOOL_FALSE in mem[3]*/ DROP(1); CALL(MAKE_SOB_NIL); /* define nil in mem[5] */ CALL(MAKE_SOB_VOID); /* define #Void in mem[6] */ /* start of code */ /* CALL(MAKE_SOB_NIL); */ /* MOV(R0, IND(IMM(4))); */ MOV(R0, IMM(5)); PUSH(R0); CALL(IS_SOB_TRUE); CMP(R0, IMM(1)); /* 1 means R0 was true, 0 means it was #f */ JUMP_EQ(Lelse1); PUSH(IMM(1)); CALL(MAKE_SOB_BOOL); JUMP(Lexit1); Lelse1: PUSH(IMM(0)); CALL(MAKE_SOB_BOOL); Lexit1: PUSH(R0); CALL(WRITE_SOB); /* newline and stop machine */ PUSH(IMM('\n')); CALL(PUTCHAR); STOP_MACHINE; return 0; }
void v_link(void) { extern v_label_type v_epilogue_l; v_code *last_ip = v_ip-1; linkdbg(("last ip is %p\n",last_ip)); for(ltp--; ltp >= &link_table[0]; ltp--) { switch(ltp->type) { case V_JUMP: { v_code *dst = labels[ltp->label].addr, *src = ltp->addr; int disp; /* relative offset of label and delay slot */ demand(dst != FLAG, not linked); linkdbg(("jump: dst=%p src=%p\n", dst, src)); if(ltp->label == _vlr(v_epilogue_l)) { linkdbg(("jump to epilogue: dst=%p src=%p last=%p\n",\ dst, src, last_ip)); /* if this is the last jump, delete it. */ if(ltp->addr == last_ip) { v_ip--; v_nop(); /* Can't change position of epilogue */ break; } } disp = (((int)dst - (int)src) - 8) / 4; (*ltp->addr).h |= IMM((unsigned short)disp); break; } case V_DATA: linkdbg(("v_data: dst=%p src=%p\n", labels[ltp->label].addr,\ ltp->addr)); *(unsigned *)ltp->addr = (unsigned)labels[ltp->label].addr; break; default: demand(0, bogus type); } } v_link_reset(); }
static int dis_wrpr(uint32_t *pc, uint32_t inst) { char *prs[] = { "%tpc", "%tnpc", "%tstate", "%tt", "%tick", "%tba", "%pstate", "%tl", "%pil", "%cwp", "%cansave", "%canrestore", "%cleanwin", "%otherwin", "%wstate", "%fq", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-" }; if (RD(inst) >= 15) { ILLEGAL; } (void)printf("%p:\twrpr\t%s,%s, ", (void *)pc, prs[RD(inst)], sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld, ", SIMM13(inst)); else (void)printf("%s, ", sregs[RS2(inst)]); (void)printf("%s\n", sregs[RD(inst)]); return OK; }
MOV(R15, VAR(p)) MOV(RDI, VAR(ldp)) LEA(RBX, MEM(,RBX,8)) //inca in bytes LEA(RCX, MEM(,RCX,8)) //lda in bytes LEA(RDI, MEM(,RDI,8)) //ldp in bytes LEA(R11, MEM(RDI,RDI,2)) //ldp*3 LEA(R12, MEM(RDI,RDI,4)) //ldp*5 LEA(R13, MEM(R11,RDI,4)) //ldp*7 VBROADCASTSD(ZMM(31), VAR(kappa)) TEST(RSI, RSI) JZ(PACK30_DONE) CMP(RBX, IMM(8)) JNE(PACK30_T) LABEL(PACK30_N) MOV(RDX, RSI) AND(RDX, IMM(7)) SAR(RSI, IMM(3)) JZ(PACK30_N_TAIL) LEA(R8, MEM(RCX,RCX,2)) //lda*3 LEA(R9, MEM(RCX,RCX,4)) //lda*5 LEA(R10, MEM(R8 ,RCX,4)) //lda*7 LABEL(PACK30_N_LOOP)
void targetCallBack(const laser_package::state::ConstPtr& msg) { rho = msg->Measured_Rho; theta = msg->Measured_Theta; real_state(XI_INDEX) = msg->Real_X; real_state(XI_DOT_INDEX) = msg->Real_X_Speed; real_state(ETA_INDEX) = msg->Real_Y; real_state(ETA_DOT_INDEX) = msg->Real_Y_Speed; real_state(OMEGA_INDEX) = msg->Real_Omega; z(RHO_INDEX) = rho; z(THETA_INDEX) = theta; if(msg_count>1) { update_time = msg->Time_Of_Measurement; //extended kalman filter ExtendedKF.updateFilter(z, update_time,real_state); ExtendedKF.updateCovariance(); updateStateMessage(&ExtendedKF,msg); extended_kalman_pub.publish(state_msg); //regular kalman filter KF.updateFilter(z, update_time, real_state); KF.updateCovariance(); updateStateMessage(&KF,msg); kalman_pub.publish(state_msg); //imm imm.update(); updateStateMessage(&imm,msg); imm_pub.publish(state_msg); } else if(msg_count == 0) { first_xi = rho*cos(theta)+SENSOR_XI; first_eta = rho*sin(theta)+SENSOR_ETA; first_time = msg->Time_Of_Measurement; msg_count++; } else if(msg_count==1) { second_time = msg->Time_Of_Measurement; T = SAMPLING_INTERVAL; initial_state(XI_INDEX) = rho*cos(theta)+SENSOR_XI; initial_state(ETA_INDEX) = rho*sin(theta)+SENSOR_ETA; initial_state(XI_DOT_INDEX) = (initial_state(XI_INDEX)-first_xi)/(T); initial_state(ETA_DOT_INDEX) = (initial_state(ETA_INDEX)-first_eta)/(T); initial_state(OMEGA_INDEX) = 0.0001; //extended kalman filter ExtendedKF = ExtendedKalmanFilter(initial_state,T , extended_kalman_noise_data,0.5,z);//instantiate Extended kalman filter updateStateMessage(&ExtendedKF,msg); extended_kalman_pub.publish(state_msg); //regular kalman filter KF = KalmanFilter(initial_state,T , kalman_noise_data, 0.5,z);//instantiate kalman filter updateStateMessage(&KF,msg); kalman_pub.publish(state_msg); //imm filters.push_back(&KF); filters.push_back(&ExtendedKF); imm = IMM(filters);//instantiate IMM with vector of filters imm.update(); msg_count++; } //These are for when we want to publish to Rviz target_point_msg.x = msg->Real_X; target_point_msg.y = msg->Real_Y; target_point_stamped_msg.point = target_point_msg; target_point_stamped_msg.header.frame_id = "/my_frame"; //The below allows us to publish values so that Rviz can plot. You decide which points to plot from the target class. target_real_pub.publish(target_point_stamped_msg); }
VMOVAPS(ZMM(10), ZMM(2)) MOV(RSI, VAR(k)) //loop index VMOVAPS(ZMM(11), ZMM(2)) MOV(RAX, VAR(a)) //load address of a VMOVAPS(ZMM(12), ZMM(2)) MOV(RBX, VAR(b)) //load address of b VMOVAPS(ZMM(13), ZMM(2)) MOV(RCX, VAR(c)) //load address of c VMOVAPS(ZMM(14), ZMM(2)) VMOVAPD(ZMM(0), MEM(RBX)) //pre-load b VMOVAPS(ZMM(15), ZMM(2)) MOV(RDI, VAR(offsetPtr)) VMOVAPS(ZMM(16), ZMM(2)) VMOVAPS(ZMM(17), ZMM(2)) VMOVAPS(ZMM(18), ZMM(2)) VMOVAPS(ZMM(19), ZMM(2)) LEA(R13, MEM(R12,R12,2)) VMOVAPS(ZMM(20), ZMM(2)) LEA(R14, MEM(R12,R12,4)) VMOVAPS(ZMM(21), ZMM(2)) LEA(R15, MEM(R13,R12,4)) VMOVAPS(ZMM(22), ZMM(2)) VMOVAPS(ZMM(23), ZMM(2)) VMOVAPS(ZMM(24), ZMM(2)) VMOVAPS(ZMM(25), ZMM(2)) MOV(R8, IMM(4*32*8)) //offset for 4 iterations VMOVAPS(ZMM(26), ZMM(2)) LEA(R9, MEM(R8,R8,2)) //*3 VMOVAPS(ZMM(27), ZMM(2)) LEA(R10, MEM(R8,R8,4)) //*5 VMOVAPS(ZMM(28), ZMM(2)) LEA(R11, MEM(R9,R8,4)) //*7 VMOVAPS(ZMM(29), ZMM(2)) VMOVAPS(ZMM(30), ZMM(2)) VMOVAPS(ZMM(31), ZMM(2)) SUB(RSI, IMM(38)) JLE(TAIL) //prefetch C into L2 #if SCATTER_PREFETCH_C VPBROADCASTD(ZMM(0), R12D) VPBROADCASTD(ZMM(1), R12D) VPMULLD(ZMM(0), ZMM(0), MEM(RDI))
static int analop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { int n, ret, opsize = -1; static csh hndl = 0; static csh *handle = &hndl; static int omode = -1; static int obits = 32; cs_insn* insn; int mode = anal->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN; mode |= (anal->bits==64)? CS_MODE_64: CS_MODE_32; if (mode != omode || anal->bits != obits) { cs_close (&hndl); hndl = 0; omode = mode; obits = anal->bits; } // XXX no arch->cpu ?!?! CS_MODE_MICRO, N64 op->delay = 0; op->type = R_ANAL_OP_TYPE_ILL; if (len<4) return -1; op->size = 4; if (hndl == 0) { ret = cs_open (CS_ARCH_MIPS, mode, &hndl); if (ret != CS_ERR_OK) goto fin; cs_option (hndl, CS_OPT_DETAIL, CS_OPT_ON); } n = cs_disasm (hndl, (ut8*)buf, len, addr, 1, &insn); if (n<1 || insn->size<1) goto beach; op->type = R_ANAL_OP_TYPE_NULL; op->delay = 0; op->jump = UT64_MAX; op->fail = UT64_MAX; opsize = op->size = insn->size; switch (insn->id) { case MIPS_INS_INVALID: op->type = R_ANAL_OP_TYPE_ILL; break; case MIPS_INS_LB: case MIPS_INS_LBU: case MIPS_INS_LBUX: case MIPS_INS_LW: case MIPS_INS_LWC1: case MIPS_INS_LWC2: case MIPS_INS_LWL: case MIPS_INS_LWR: case MIPS_INS_LWXC1: case MIPS_INS_LD: case MIPS_INS_LDC1: case MIPS_INS_LDC2: case MIPS_INS_LDL: case MIPS_INS_LDR: case MIPS_INS_LDXC1: op->type = R_ANAL_OP_TYPE_LOAD; op->refptr = 4; switch (OPERAND(1).type) { case MIPS_OP_MEM: if (OPERAND(1).mem.base == MIPS_REG_GP) { op->ptr = anal->gp + OPERAND(1).mem.disp; op->refptr = 4; } break; case MIPS_OP_IMM: op->ptr = OPERAND(1).imm; break; case MIPS_OP_REG: // wtf? break; default: break; } // TODO: fill break; case MIPS_INS_SW: case MIPS_INS_SWC1: case MIPS_INS_SWC2: case MIPS_INS_SWL: case MIPS_INS_SWR: case MIPS_INS_SWXC1: op->type = R_ANAL_OP_TYPE_STORE; break; case MIPS_INS_NOP: op->type = R_ANAL_OP_TYPE_NOP; break; case MIPS_INS_SYSCALL: case MIPS_INS_BREAK: op->type = R_ANAL_OP_TYPE_TRAP; break; case MIPS_INS_JALR: op->type = R_ANAL_OP_TYPE_UCALL; op->delay = 1; break; case MIPS_INS_JAL: case MIPS_INS_JALS: case MIPS_INS_JALX: case MIPS_INS_JRADDIUSP: case MIPS_INS_BAL: // (no blezal/bgtzal or blezall/bgtzall, only blezalc/bgtzalc) case MIPS_INS_BLTZAL: // Branch on <0 and link case MIPS_INS_BGEZAL: // Branch on >=0 and link case MIPS_INS_BLTZALL: // "likely" versions case MIPS_INS_BGEZALL: case MIPS_INS_BLTZALC: // compact versions case MIPS_INS_BLEZALC: case MIPS_INS_BGEZALC: case MIPS_INS_BGTZALC: case MIPS_INS_JIALC: case MIPS_INS_JIC: op->type = R_ANAL_OP_TYPE_CALL; op->jump = IMM(0); switch (insn->id) { case MIPS_INS_JIALC: case MIPS_INS_JIC: case MIPS_INS_BLTZALC: case MIPS_INS_BLEZALC: case MIPS_INS_BGEZALC: case MIPS_INS_BGTZALC: // compact vesions (no delay) op->delay = 0; op->fail = addr+4; break; default: op->delay = 1; op->fail = addr+8; break; } break; case MIPS_INS_LUI: case MIPS_INS_MOVE: op->type = R_ANAL_OP_TYPE_MOV; SET_SRC_DST_2_REGS (op); break; case MIPS_INS_ADD: case MIPS_INS_ADDI: case MIPS_INS_ADDU: case MIPS_INS_ADDIU: case MIPS_INS_DADD: case MIPS_INS_DADDI: case MIPS_INS_DADDIU: SET_VAL (op, 2); SET_SRC_DST_3_REG_OR_IMM (op); op->type = R_ANAL_OP_TYPE_ADD; break; case MIPS_INS_SUB: case MIPS_INS_SUBV: case MIPS_INS_SUBVI: case MIPS_INS_DSUBU: case MIPS_INS_FSUB: case MIPS_INS_FMSUB: case MIPS_INS_SUBU: case MIPS_INS_DSUB: case MIPS_INS_SUBS_S: case MIPS_INS_SUBS_U: case MIPS_INS_SUBUH: case MIPS_INS_SUBUH_R: SET_VAL (op,2); SET_SRC_DST_3_REG_OR_IMM (op); op->type = R_ANAL_OP_TYPE_SUB; break; case MIPS_INS_MULV: case MIPS_INS_MULT: case MIPS_INS_MULSA: case MIPS_INS_FMUL: case MIPS_INS_MUL: case MIPS_INS_DMULT: case MIPS_INS_DMULTU: op->type = R_ANAL_OP_TYPE_MUL; break; case MIPS_INS_XOR: case MIPS_INS_XORI: SET_VAL (op,2); SET_SRC_DST_3_REG_OR_IMM (op); op->type = R_ANAL_OP_TYPE_XOR; break; case MIPS_INS_AND: case MIPS_INS_ANDI: SET_VAL (op,2); SET_SRC_DST_3_REG_OR_IMM (op); op->type = R_ANAL_OP_TYPE_AND; break; case MIPS_INS_NOT: op->type = R_ANAL_OP_TYPE_NOT; break; case MIPS_INS_OR: case MIPS_INS_ORI: SET_VAL (op,2); SET_SRC_DST_3_REG_OR_IMM (op); op->type = R_ANAL_OP_TYPE_OR; break; case MIPS_INS_DIV: case MIPS_INS_DIVU: case MIPS_INS_DDIV: case MIPS_INS_DDIVU: case MIPS_INS_FDIV: case MIPS_INS_DIV_S: case MIPS_INS_DIV_U: SET_SRC_DST_3_REGS (op); op->type = R_ANAL_OP_TYPE_DIV; break; case MIPS_INS_CMPGDU: case MIPS_INS_CMPGU: case MIPS_INS_CMPU: case MIPS_INS_CMPI: op->type = R_ANAL_OP_TYPE_CMP; break; case MIPS_INS_J: case MIPS_INS_B: case MIPS_INS_BZ: case MIPS_INS_BEQ: case MIPS_INS_BNZ: case MIPS_INS_BNE: case MIPS_INS_BEQZ: case MIPS_INS_BNEG: case MIPS_INS_BNEGI: case MIPS_INS_BNEZ: case MIPS_INS_BTEQZ: case MIPS_INS_BTNEZ: case MIPS_INS_BLTZ: case MIPS_INS_BLTZL: case MIPS_INS_BLEZ: case MIPS_INS_BLEZL: case MIPS_INS_BGEZ: case MIPS_INS_BGEZL: case MIPS_INS_BGTZ: case MIPS_INS_BGTZL: case MIPS_INS_BLEZC: case MIPS_INS_BGEZC: case MIPS_INS_BLTZC: case MIPS_INS_BGTZC: if (insn->id == MIPS_INS_J || insn->id == MIPS_INS_B ) { op->type = R_ANAL_OP_TYPE_JMP; } else { op->type = R_ANAL_OP_TYPE_CJMP; } if (OPERAND(0).type == MIPS_OP_IMM) { op->jump = IMM(0); } else if (OPERAND(1).type == MIPS_OP_IMM) { op->jump = IMM(1); } else if (OPERAND(2).type == MIPS_OP_IMM) { op->jump = IMM(2); } switch (insn->id) { case MIPS_INS_BLEZC: case MIPS_INS_BGEZC: case MIPS_INS_BLTZC: case MIPS_INS_BGTZC: // compact vesions (no delay) op->delay = 0; op->fail = addr+4; break; default: op->delay = 1; op->fail = addr+8; break; } break; case MIPS_INS_JR: case MIPS_INS_JRC: op->type = R_ANAL_OP_TYPE_JMP; op->delay = 1; // register is $ra, so jmp is a return if (insn->detail->mips.operands[0].reg == MIPS_REG_RA) { op->type = R_ANAL_OP_TYPE_RET; } break; case MIPS_INS_SLTI: case MIPS_INS_SLTIU: SET_SRC_DST_3_IMM (op); SET_VAL (op,2); break; case MIPS_INS_SHRAV: case MIPS_INS_SHRAV_R: case MIPS_INS_SHRA: case MIPS_INS_SHRA_R: case MIPS_INS_SRA: op->type = R_ANAL_OP_TYPE_SAR; SET_SRC_DST_3_REG_OR_IMM (op); SET_VAL (op,2); break; case MIPS_INS_SHRL: case MIPS_INS_SRLV: case MIPS_INS_SRL: op->type = R_ANAL_OP_TYPE_SHR; SET_SRC_DST_3_REG_OR_IMM (op); SET_VAL (op,2); break; case MIPS_INS_SLLV: case MIPS_INS_SLL: op->type = R_ANAL_OP_TYPE_SHL; SET_SRC_DST_3_REG_OR_IMM (op); SET_VAL (op,2); break; } beach: if (anal->decode) { if (analop_esil (anal, op, addr, buf, len, &hndl, insn) != 0) r_strbuf_fini (&op->esil); } cs_free (insn, n); //cs_close (&handle); fin: return opsize; }
static int dis_rdasr(uint32_t *pc, uint32_t inst) { char *asrs[32] = { "rdy", "-", "rdccr", "rdasi", "rdtick", "rdpc", "rdfprs", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", }; switch(RS1(inst)) { case 0x01: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: ILLEGAL; case 0x0: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: (void)printf("%p:\t%s\t%s\n", (void *)pc, asrs[RS1(inst)], sregs[RD(inst)]); return OK; case 0xf: /* MEMBAR / STBAR */ if (RD(inst) == 0) { if (IMM(inst)) { (void)printf("%p\tmembar\t", (void *)pc); if ((CMASK(inst) & 1)) (void)printf("#Lookaside "); if ((CMASK(inst) & 2)) (void)printf("#MemIssue "); if ((CMASK(inst) & 4)) (void)printf("#Sync "); if ((MMASK(inst) & 1)) (void)printf("#LoadLoad "); if ((MMASK(inst) & 2)) (void)printf("#StoreLoad "); if ((MMASK(inst) & 4)) (void)printf("#LoadStore "); if ((MMASK(inst) & 8)) (void)printf("#StoreStore"); (void)printf("\n"); } else { (void)printf("%p:\tstbar\n", (void *)pc); } return OK; } else { ILLEGAL; } case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: default: (void)printf("%p:\trd\t%%asr%d, %s\n", (void *)pc, RS1(inst), sregs[RD(inst)]); return OK; } }
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) { int n, ret, opsize = -1; static csh handle = 0; static int omode = -1; static int obits = 32; cs_insn* insn; cs_m68k *m68k; cs_detail *detail; int mode = a->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN; //mode |= (a->bits==64)? CS_MODE_64: CS_MODE_32; if (mode != omode || a->bits != obits) { cs_close (&handle); handle = 0; omode = mode; obits = a->bits; } // XXX no arch->cpu ?!?! CS_MODE_MICRO, N64 op->delay = 0; // replace this with the asm.features? if (a->cpu && strstr (a->cpu, "68000")) { mode |= CS_MODE_M68K_000; } if (a->cpu && strstr (a->cpu, "68010")) { mode |= CS_MODE_M68K_010; } if (a->cpu && strstr (a->cpu, "68020")) { mode |= CS_MODE_M68K_020; } if (a->cpu && strstr (a->cpu, "68030")) { mode |= CS_MODE_M68K_030; } if (a->cpu && strstr (a->cpu, "68040")) { mode |= CS_MODE_M68K_040; } if (a->cpu && strstr (a->cpu, "68060")) { mode |= CS_MODE_M68K_060; } op->size = 4; if (handle == 0) { ret = cs_open (CS_ARCH_M68K, mode, &handle); if (ret != CS_ERR_OK) { goto fin; } cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON); } n = cs_disasm (handle, (ut8*)buf, len, addr, 1, &insn); if (n < 1 || insn->size < 1) { op->type = R_ANAL_OP_TYPE_ILL; op->size = 2; opsize = -1; goto beach; } if (!memcmp (buf, "\xff\xff", R_MIN (len, 2))) { op->type = R_ANAL_OP_TYPE_ILL; op->size = 2; opsize = -1; goto beach; } detail = insn->detail; m68k = &detail->m68k; op->type = R_ANAL_OP_TYPE_NULL; op->delay = 0; op->id = insn->id; opsize = op->size = insn->size; if (mask & R_ANAL_OP_MASK_OPEX) { opex (&op->opex, handle, insn); } switch (insn->id) { case M68K_INS_INVALID: op->type = R_ANAL_OP_TYPE_ILL; break; case M68K_INS_ADD: case M68K_INS_ADDA: case M68K_INS_ADDI: case M68K_INS_ADDQ: case M68K_INS_ADDX: op->type = R_ANAL_OP_TYPE_ADD; break; case M68K_INS_AND: case M68K_INS_ANDI: op->type = R_ANAL_OP_TYPE_AND; break; case M68K_INS_ASL: op->type = R_ANAL_OP_TYPE_SHL; break; case M68K_INS_ASR: op->type = R_ANAL_OP_TYPE_SHR; break; case M68K_INS_ABCD: break; case M68K_INS_BHS: case M68K_INS_BLO: case M68K_INS_BHI: case M68K_INS_BLS: case M68K_INS_BCC: case M68K_INS_BCS: case M68K_INS_BNE: case M68K_INS_BEQ: case M68K_INS_BVC: case M68K_INS_BVS: case M68K_INS_BPL: case M68K_INS_BMI: case M68K_INS_BGE: case M68K_INS_BLT: case M68K_INS_BGT: case M68K_INS_BLE: handle_branch_instruction (op, addr, m68k, R_ANAL_OP_TYPE_CJMP, 0); break; case M68K_INS_BRA: handle_branch_instruction (op, addr, m68k, R_ANAL_OP_TYPE_JMP, 0); break; case M68K_INS_BSR: handle_branch_instruction (op, addr, m68k, R_ANAL_OP_TYPE_CALL, 0); break; case M68K_INS_BCHG: case M68K_INS_BCLR: case M68K_INS_BSET: case M68K_INS_BTST: case M68K_INS_BFCHG: case M68K_INS_BFCLR: case M68K_INS_BFEXTS: case M68K_INS_BFEXTU: case M68K_INS_BFFFO: case M68K_INS_BFINS: case M68K_INS_BFSET: case M68K_INS_BFTST: case M68K_INS_BKPT: case M68K_INS_CALLM: case M68K_INS_CAS: case M68K_INS_CAS2: case M68K_INS_CHK: case M68K_INS_CHK2: case M68K_INS_CLR: // TODO: break; case M68K_INS_CMP: case M68K_INS_CMPA: case M68K_INS_CMPI: case M68K_INS_CMPM: case M68K_INS_CMP2: op->type = R_ANAL_OP_TYPE_CMP; break; case M68K_INS_CINVL: case M68K_INS_CINVP: case M68K_INS_CINVA: op->type = R_ANAL_OP_TYPE_ILL; break; case M68K_INS_CPUSHL: case M68K_INS_CPUSHP: case M68K_INS_CPUSHA: break; case M68K_INS_DBT: case M68K_INS_DBF: case M68K_INS_DBHI: case M68K_INS_DBLS: case M68K_INS_DBCC: case M68K_INS_DBCS: case M68K_INS_DBNE: case M68K_INS_DBEQ: case M68K_INS_DBVC: case M68K_INS_DBVS: case M68K_INS_DBPL: case M68K_INS_DBMI: case M68K_INS_DBGE: case M68K_INS_DBLT: case M68K_INS_DBGT: case M68K_INS_DBLE: case M68K_INS_DBRA: handle_branch_instruction (op, addr, m68k, R_ANAL_OP_TYPE_CJMP, 1); break; case M68K_INS_DIVS: case M68K_INS_DIVSL: case M68K_INS_DIVU: case M68K_INS_DIVUL: op->type = R_ANAL_OP_TYPE_DIV; break; case M68K_INS_EOR: case M68K_INS_EORI: op->type = R_ANAL_OP_TYPE_XOR; break; case M68K_INS_EXG: op->type = R_ANAL_OP_TYPE_MOV; break; case M68K_INS_EXT: case M68K_INS_EXTB: break; case M68K_INS_FABS: case M68K_INS_FSABS: case M68K_INS_FDABS: case M68K_INS_FACOS: case M68K_INS_FADD: case M68K_INS_FSADD: case M68K_INS_FDADD: case M68K_INS_FASIN: case M68K_INS_FATAN: case M68K_INS_FATANH: case M68K_INS_FBF: case M68K_INS_FBEQ: case M68K_INS_FBOGT: case M68K_INS_FBOGE: case M68K_INS_FBOLT: case M68K_INS_FBOLE: case M68K_INS_FBOGL: case M68K_INS_FBOR: case M68K_INS_FBUN: case M68K_INS_FBUEQ: case M68K_INS_FBUGT: case M68K_INS_FBUGE: case M68K_INS_FBULT: case M68K_INS_FBULE: case M68K_INS_FBNE: case M68K_INS_FBT: case M68K_INS_FBSF: case M68K_INS_FBSEQ: case M68K_INS_FBGT: case M68K_INS_FBGE: case M68K_INS_FBLT: case M68K_INS_FBLE: case M68K_INS_FBGL: case M68K_INS_FBGLE: case M68K_INS_FBNGLE: case M68K_INS_FBNGL: case M68K_INS_FBNLE: case M68K_INS_FBNLT: case M68K_INS_FBNGE: case M68K_INS_FBNGT: case M68K_INS_FBSNE: case M68K_INS_FBST: case M68K_INS_FCMP: case M68K_INS_FCOS: case M68K_INS_FCOSH: case M68K_INS_FDBF: case M68K_INS_FDBEQ: case M68K_INS_FDBOGT: case M68K_INS_FDBOGE: case M68K_INS_FDBOLT: case M68K_INS_FDBOLE: case M68K_INS_FDBOGL: case M68K_INS_FDBOR: case M68K_INS_FDBUN: case M68K_INS_FDBUEQ: case M68K_INS_FDBUGT: case M68K_INS_FDBUGE: case M68K_INS_FDBULT: case M68K_INS_FDBULE: case M68K_INS_FDBNE: case M68K_INS_FDBT: case M68K_INS_FDBSF: case M68K_INS_FDBSEQ: case M68K_INS_FDBGT: case M68K_INS_FDBGE: case M68K_INS_FDBLT: case M68K_INS_FDBLE: case M68K_INS_FDBGL: case M68K_INS_FDBGLE: case M68K_INS_FDBNGLE: case M68K_INS_FDBNGL: case M68K_INS_FDBNLE: case M68K_INS_FDBNLT: case M68K_INS_FDBNGE: case M68K_INS_FDBNGT: case M68K_INS_FDBSNE: case M68K_INS_FDBST: case M68K_INS_FDIV: case M68K_INS_FSDIV: case M68K_INS_FDDIV: case M68K_INS_FETOX: case M68K_INS_FETOXM1: case M68K_INS_FGETEXP: case M68K_INS_FGETMAN: case M68K_INS_FINT: case M68K_INS_FINTRZ: case M68K_INS_FLOG10: case M68K_INS_FLOG2: case M68K_INS_FLOGN: case M68K_INS_FLOGNP1: case M68K_INS_FMOD: case M68K_INS_FMOVE: case M68K_INS_FSMOVE: case M68K_INS_FDMOVE: case M68K_INS_FMOVECR: case M68K_INS_FMOVEM: case M68K_INS_FMUL: case M68K_INS_FSMUL: case M68K_INS_FDMUL: case M68K_INS_FNEG: case M68K_INS_FSNEG: case M68K_INS_FDNEG: case M68K_INS_FNOP: case M68K_INS_FREM: case M68K_INS_FRESTORE: case M68K_INS_FSAVE: case M68K_INS_FSCALE: case M68K_INS_FSGLDIV: case M68K_INS_FSGLMUL: case M68K_INS_FSIN: case M68K_INS_FSINCOS: case M68K_INS_FSINH: case M68K_INS_FSQRT: case M68K_INS_FSSQRT: case M68K_INS_FDSQRT: case M68K_INS_FSF: case M68K_INS_FSBEQ: case M68K_INS_FSOGT: case M68K_INS_FSOGE: case M68K_INS_FSOLT: case M68K_INS_FSOLE: case M68K_INS_FSOGL: case M68K_INS_FSOR: case M68K_INS_FSUN: case M68K_INS_FSUEQ: case M68K_INS_FSUGT: case M68K_INS_FSUGE: case M68K_INS_FSULT: case M68K_INS_FSULE: case M68K_INS_FSNE: case M68K_INS_FST: case M68K_INS_FSSF: case M68K_INS_FSSEQ: case M68K_INS_FSGT: case M68K_INS_FSGE: case M68K_INS_FSLT: case M68K_INS_FSLE: case M68K_INS_FSGL: case M68K_INS_FSGLE: case M68K_INS_FSNGLE: case M68K_INS_FSNGL: case M68K_INS_FSNLE: case M68K_INS_FSNLT: case M68K_INS_FSNGE: case M68K_INS_FSNGT: case M68K_INS_FSSNE: case M68K_INS_FSST: case M68K_INS_FSUB: case M68K_INS_FSSUB: case M68K_INS_FDSUB: case M68K_INS_FTAN: case M68K_INS_FTANH: case M68K_INS_FTENTOX: case M68K_INS_FTRAPF: case M68K_INS_FTRAPEQ: case M68K_INS_FTRAPOGT: case M68K_INS_FTRAPOGE: case M68K_INS_FTRAPOLT: case M68K_INS_FTRAPOLE: case M68K_INS_FTRAPOGL: case M68K_INS_FTRAPOR: case M68K_INS_FTRAPUN: case M68K_INS_FTRAPUEQ: case M68K_INS_FTRAPUGT: case M68K_INS_FTRAPUGE: case M68K_INS_FTRAPULT: case M68K_INS_FTRAPULE: case M68K_INS_FTRAPNE: case M68K_INS_FTRAPT: case M68K_INS_FTRAPSF: case M68K_INS_FTRAPSEQ: case M68K_INS_FTRAPGT: case M68K_INS_FTRAPGE: case M68K_INS_FTRAPLT: case M68K_INS_FTRAPLE: case M68K_INS_FTRAPGL: case M68K_INS_FTRAPGLE: case M68K_INS_FTRAPNGLE: case M68K_INS_FTRAPNGL: case M68K_INS_FTRAPNLE: case M68K_INS_FTRAPNLT: case M68K_INS_FTRAPNGE: case M68K_INS_FTRAPNGT: case M68K_INS_FTRAPSNE: case M68K_INS_FTRAPST: case M68K_INS_FTST: case M68K_INS_FTWOTOX: op->type = R_ANAL_OP_TYPE_UNK; op->family = R_ANAL_OP_FAMILY_FPU; break; case M68K_INS_HALT: op->type = R_ANAL_OP_TYPE_NOP; break; case M68K_INS_ILLEGAL: op->type = R_ANAL_OP_TYPE_ILL; break; case M68K_INS_JMP: handle_jump_instruction (op, addr, m68k, R_ANAL_OP_TYPE_JMP); break; case M68K_INS_JSR: handle_jump_instruction (op, addr, m68k, R_ANAL_OP_TYPE_CALL); break; case M68K_INS_LPSTOP: op->type = R_ANAL_OP_TYPE_NOP; break; case M68K_INS_LSL: op->type = R_ANAL_OP_TYPE_SHL; break; case M68K_INS_LINK: op->type = R_ANAL_OP_TYPE_PUSH; op->stackop = R_ANAL_STACK_INC; op->stackptr = -(st16)IMM(1); break; case M68K_INS_LSR: op->type = R_ANAL_OP_TYPE_SHR; break; case M68K_INS_PEA: case M68K_INS_LEA: op->type = R_ANAL_OP_TYPE_LEA; break; case M68K_INS_MOVE: case M68K_INS_MOVEA: case M68K_INS_MOVEC: case M68K_INS_MOVEM: case M68K_INS_MOVEP: case M68K_INS_MOVEQ: case M68K_INS_MOVES: case M68K_INS_MOVE16: op->type = R_ANAL_OP_TYPE_MOV; break; case M68K_INS_MULS: case M68K_INS_MULU: op->type = R_ANAL_OP_TYPE_MUL; break; case M68K_INS_NBCD: case M68K_INS_NEG: case M68K_INS_NEGX: break; case M68K_INS_NOP: op->type = R_ANAL_OP_TYPE_NOP; break; case M68K_INS_NOT: op->type = R_ANAL_OP_TYPE_NOT; break; case M68K_INS_OR: case M68K_INS_ORI: op->type = R_ANAL_OP_TYPE_OR; break; case M68K_INS_PACK: case M68K_INS_PFLUSH: case M68K_INS_PFLUSHA: case M68K_INS_PFLUSHAN: case M68K_INS_PFLUSHN: case M68K_INS_PLOADR: case M68K_INS_PLOADW: case M68K_INS_PLPAR: case M68K_INS_PLPAW: case M68K_INS_PMOVE: case M68K_INS_PMOVEFD: case M68K_INS_PTESTR: case M68K_INS_PTESTW: case M68K_INS_PULSE: case M68K_INS_REMS: case M68K_INS_REMU: case M68K_INS_RESET: break; case M68K_INS_ROL: op->type = R_ANAL_OP_TYPE_ROL; break; case M68K_INS_ROR: op->type = R_ANAL_OP_TYPE_ROR; break; case M68K_INS_ROXL: case M68K_INS_ROXR: break; case M68K_INS_RTD: case M68K_INS_RTE: case M68K_INS_RTM: case M68K_INS_RTR: case M68K_INS_RTS: op->type = R_ANAL_OP_TYPE_RET; break; case M68K_INS_SBCD: case M68K_INS_ST: case M68K_INS_SF: case M68K_INS_SHI: case M68K_INS_SLS: case M68K_INS_SCC: case M68K_INS_SHS: case M68K_INS_SCS: case M68K_INS_SLO: case M68K_INS_SNE: case M68K_INS_SEQ: case M68K_INS_SVC: case M68K_INS_SVS: case M68K_INS_SPL: case M68K_INS_SMI: case M68K_INS_SGE: case M68K_INS_SLT: case M68K_INS_SGT: case M68K_INS_SLE: case M68K_INS_STOP: break; case M68K_INS_SUB: case M68K_INS_SUBA: case M68K_INS_SUBI: case M68K_INS_SUBQ: case M68K_INS_SUBX: op->type = R_ANAL_OP_TYPE_SUB; break; case M68K_INS_SWAP: op->type = R_ANAL_OP_TYPE_MOV; break; case M68K_INS_TAS: break; case M68K_INS_TRAP: case M68K_INS_TRAPV: case M68K_INS_TRAPT: case M68K_INS_TRAPF: case M68K_INS_TRAPHI: case M68K_INS_TRAPLS: case M68K_INS_TRAPCC: case M68K_INS_TRAPHS: case M68K_INS_TRAPCS: case M68K_INS_TRAPLO: case M68K_INS_TRAPNE: case M68K_INS_TRAPEQ: case M68K_INS_TRAPVC: case M68K_INS_TRAPVS: case M68K_INS_TRAPPL: case M68K_INS_TRAPMI: case M68K_INS_TRAPGE: case M68K_INS_TRAPLT: case M68K_INS_TRAPGT: case M68K_INS_TRAPLE: op->type = R_ANAL_OP_TYPE_TRAP; break; case M68K_INS_TST: op->type = R_ANAL_OP_TYPE_CMP; break; case M68K_INS_UNPK: // unpack BCD op->type = R_ANAL_OP_TYPE_MOV; break; case M68K_INS_UNLK: op->type = R_ANAL_OP_TYPE_POP; // reset stackframe op->stackop = R_ANAL_STACK_SET; op->stackptr = 0; break; } if (mask & R_ANAL_OP_MASK_VAL) { op_fillval (op, handle, insn); } beach: cs_free (insn, n); //cs_close (&handle); fin: return opsize; }
__asm__ volatile ( VPXORD(ZMM(8), ZMM(8), ZMM(8)) MOV(RAX, VAR(a)) VMOVAPD(ZMM( 9), ZMM(8)) MOV(RBX, VAR(b)) VMOVAPD(ZMM(10), ZMM(8)) //no ADD(RBX, IMM(4*64)) VMOVAPD(ZMM(11), ZMM(8)) //maybe? PREFETCH(0, MEM(RAX, 0)) VMOVAPD(ZMM(12), ZMM(8)) //maybe? PREFETCH(0, MEM(RAX,64)) VMOVAPD(ZMM(13), ZMM(8)) VMOVAPD(ZMM(0), MEM(RBX,0*64)) VMOVAPD(ZMM(14), ZMM(8)) VMOVAPD(ZMM(1), MEM(RBX,1*64)) VMOVAPD(ZMM(15), ZMM(8)) MOV(RCX, VAR(c)) VMOVAPD(ZMM(16), ZMM(8)) MOV(RDI, RCX) VMOVAPD(ZMM(17), ZMM(8)) VBROADCASTSS(ZMM(4), VAR(cs_c)) VMOVAPD(ZMM(18), ZMM(8)) VMOVAPS(ZMM(5), VAR(offsetPtr)) VMOVAPD(ZMM(19), ZMM(8)) VPMULLD(ZMM(4), ZMM(5), ZMM(4)) VMOVAPD(ZMM(20), ZMM(8)) MOV(RDX, IMM(0xFFF)) VMOVAPD(ZMM(21), ZMM(8)) KMOV(K(1), EDX) VMOVAPD(ZMM(22), ZMM(8)) KMOV(K(2), EDX) VMOVAPD(ZMM(23), ZMM(8)) KMOV(K(3), EDX) VMOVAPD(ZMM(24), ZMM(8)) VSCATTERPFDPS(0, MEM(RCX,ZMM(4),8, 0) MASK_K(1)) VMOVAPD(ZMM(25), ZMM(8)) VSCATTERPFDPS(0, MEM(RCX,ZMM(4),8, 8*8) MASK_K(2)) VMOVAPD(ZMM(26), ZMM(8)) VSCATTERPFDPS(0, MEM(RCX,ZMM(4),8,15*8) MASK_K(3)) VMOVAPD(ZMM(27), ZMM(8)) MOV(RSI, VAR(k)) VMOVAPD(ZMM(28), ZMM(8)) SAR(RSI, IMM(2)) // rsi = k/4 VMOVAPD(ZMM(29), ZMM(8)) VMOVAPD(ZMM(30), ZMM(8)) VMOVAPD(ZMM(31), ZMM(8)) JZ(.DCONSIDKLEFT) ALIGN16
VMOVAPS(ZMM(18), ZMM(8)) VMOVAPS(ZMM(19), ZMM(8)) VBROADCASTSS(ZMM(5), VAR(rs_c)) VMOVAPS(ZMM(20), ZMM(8)) VMOVAPS(ZMM(21), ZMM(8)) VPMULLD(ZMM(2), ZMM(4), ZMM(5)) VMOVAPS(ZMM(22), ZMM(8)) VMOVAPS(YMM(3), MEM(RDI,64)) VMOVAPS(ZMM(23), ZMM(8)) VPMULLD(YMM(3), YMM(3), YMM(5)) #else VMOVAPS(ZMM(17), ZMM(8)) VMOVAPS(ZMM(18), ZMM(8)) LEA(R13, MEM(R12,R12,2)) VMOVAPS(ZMM(19), ZMM(8)) LEA(R14, MEM(R12,R12,4)) VMOVAPS(ZMM(20), ZMM(8)) LEA(R15, MEM(R13,R12,4)) VMOVAPS(ZMM(21), ZMM(8)) VMOVAPS(ZMM(22), ZMM(8)) VMOVAPS(ZMM(23), ZMM(8)) #endif VMOVAPS(ZMM(24), ZMM(8)) VPSLLD(ZMM(4), ZMM(4), IMM(2)) VMOVAPS(ZMM(25), ZMM(8)) MOV(R8, IMM(4*24*4)) //offset for 4 iterations VMOVAPS(ZMM(26), ZMM(8)) LEA(R9, MEM(R8,R8,2)) //*3 VMOVAPS(ZMM(27), ZMM(8)) LEA(R10, MEM(R8,R8,4)) //*5 VMOVAPS(ZMM(28), ZMM(8)) LEA(R11, MEM(R9,R8,4)) //*7 VMOVAPS(ZMM(29), ZMM(8)) VMOVAPS(ZMM(30), ZMM(8)) VMOVAPS(ZMM(31), ZMM(8)) #ifdef MONITORS RDTSC MOV(VAR(midl), EAX) MOV(VAR(midh), EDX) #endif SUB(RSI, IMM(32))
static void anop32 (RAnalOp *op, cs_insn *insn) { ut64 addr = op->addr; int i; switch (insn->id) { case ARM_INS_NOP: op->type = R_ANAL_OP_TYPE_NOP; break; case ARM_INS_POP: case ARM_INS_LDM: op->type = R_ANAL_OP_TYPE_POP; for (i = 0; i < insn->detail->arm.op_count; i++) { if (insn->detail->arm.operands[i].type == ARM_OP_REG && insn->detail->arm.operands[i].reg == ARM_REG_PC) { if (insn->detail->arm.cc == ARM_CC_AL) op->type = R_ANAL_OP_TYPE_RET; else op->type = R_ANAL_OP_TYPE_CRET; break; } } break; case ARM_INS_SUB: op->type = R_ANAL_OP_TYPE_SUB; if (ISREG(0)) { if (REGID(0) == ARM_REG_SP) { // 0x00008254 10d04de2 sub sp, sp, 0x10 op->stackop = R_ANAL_STACK_INC; op->stackptr = IMM (2); } } break; case ARM_INS_ADD: op->type = R_ANAL_OP_TYPE_ADD; if (REGID(1)==ARM_REG_PC) { op->ptr = addr + 8 + IMM(2); op->refptr = 0; } break; case ARM_INS_MOV: case ARM_INS_MOVS: case ARM_INS_MOVT: case ARM_INS_MOVW: case ARM_INS_VMOVL: case ARM_INS_VMOVN: case ARM_INS_VQMOVUN: case ARM_INS_VQMOVN: op->type = R_ANAL_OP_TYPE_MOV; break; case ARM_INS_AND: op->type = R_ANAL_OP_TYPE_AND; break; case ARM_INS_CMP: case ARM_INS_TST: op->type = R_ANAL_OP_TYPE_CMP; break; case ARM_INS_ROR: case ARM_INS_ORN: case ARM_INS_LSL: case ARM_INS_LSR: break; //case ARM_INS_POP: case ARM_INS_PUSH: case ARM64_INS_STRB: case ARM_INS_STR: op->type = R_ANAL_OP_TYPE_STORE; // 0x00008160 04202de5 str r2, [sp, -4]! // 0x000082a0 28000be5 str r0, [fp, -0x28] if (REGBASE(1) == ARM_REG_FP) { op->stackop = R_ANAL_STACK_SET; op->stackptr = 0; op->ptr = MEMDISP(1); } break; case ARM_INS_LDR: case ARM_INS_LDRD: case ARM_INS_LDRB: // 0x000082a8 28301be5 ldr r3, [fp, -0x28] if (insn->detail->arm.operands[0].reg == ARM_REG_PC) { op->type = R_ANAL_OP_TYPE_UJMP; } else { op->type = R_ANAL_OP_TYPE_LOAD; } if (REGBASE(1) == ARM_REG_FP) { op->stackop = R_ANAL_STACK_GET; op->stackptr = 0; op->ptr = MEMDISP(1); } break; case ARM_INS_BL: case ARM_INS_BLX: op->type = R_ANAL_OP_TYPE_CALL; op->jump = IMM(0); break; case ARM_INS_B: case ARM_INS_BX: case ARM_INS_BXJ: // BX LR == RET if (insn->detail->arm.operands[0].reg == ARM_REG_LR) { op->type = R_ANAL_OP_TYPE_RET; } else if (insn->detail->arm.cc) { op->type = R_ANAL_OP_TYPE_CJMP; op->jump = (ut64) (ut32)IMM(0); op->fail = addr+op->size; } else { op->type = R_ANAL_OP_TYPE_JMP; op->jump = IMM(0); } break; default: break; } }
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { static csh handle = 0; static int omode = -1, obits = -1; int n, ret; cs_insn *insn; int mode = (a->bits == 64) ? CS_MODE_64 : (a->bits == 32) ? CS_MODE_32 : 0; mode |= a->big_endian ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN; op->delay = 0; op->type = R_ANAL_OP_TYPE_NULL; op->jump = UT64_MAX; op->fail = UT64_MAX; op->ptr = op->val = UT64_MAX; if (a->cpu && strncmp (a->cpu, "vle", 3) == 0) { // vle is big-endian only if (!a->big_endian) { return -1; } ret = analop_vle (a, op, addr, buf, len); if (ret >= 0) { return op->size; } } if (mode != omode || a->bits != obits) { cs_close (&handle); handle = 0; omode = mode; obits = a->bits; } if (handle == 0) { ret = cs_open (CS_ARCH_PPC, mode, &handle); if (ret != CS_ERR_OK) { return -1; } cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON); } op->size = 4; r_strbuf_init (&op->esil); r_strbuf_set (&op->esil, ""); // capstone-next n = cs_disasm (handle, (const ut8*)buf, len, addr, 1, &insn); if (n < 1) { op->type = R_ANAL_OP_TYPE_ILL; } else { opex (&op->opex, handle, insn); struct Getarg gop = { .handle = handle, .insn = insn, .bits = a->bits }; op->size = insn->size; op->id = insn->id; switch (insn->id) { #if CS_API_MAJOR >= 4 case PPC_INS_CMPB: #endif case PPC_INS_CMPD: case PPC_INS_CMPDI: case PPC_INS_CMPLD: case PPC_INS_CMPLDI: case PPC_INS_CMPLW: case PPC_INS_CMPLWI: case PPC_INS_CMPW: case PPC_INS_CMPWI: op->type = R_ANAL_OP_TYPE_CMP; op->sign = true; if (ARG (2)[0] == '\0') esilprintf (op, "%s,%s,-,0xff,&,cr0,=", ARG (1), ARG (0)); else esilprintf (op, "%s,%s,-,0xff,&,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_MFLR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "lr,%s,=", ARG (0)); break; case PPC_INS_MTLR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s,lr,=", ARG (0)); break; case PPC_INS_MR: case PPC_INS_LI: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s,%s,=", ARG (1), ARG (0)); break; case PPC_INS_LIS: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s0000,%s,=", ARG (1), ARG (0)); break; case PPC_INS_CLRLWI: op->type = R_ANAL_OP_TYPE_AND; esilprintf (op, "%s,%s,&,%s,=", ARG (1), cmask32 (ARG (2), "0x1F"), ARG (0)); break; case PPC_INS_RLWINM: op->type = R_ANAL_OP_TYPE_ROL; esilprintf (op, "%s,%s,<<<,%s,&,%s,=", ARG (2), ARG (1), cmask32 (ARG (3), ARG (4)), ARG (0)); break; case PPC_INS_SC: op->type = R_ANAL_OP_TYPE_SWI; esilprintf (op, "0,$"); break; case PPC_INS_EXTSB: op->sign = true; op->type = R_ANAL_OP_TYPE_MOV; if (a->bits == 64) esilprintf (op, "%s,0x80,&,?{,0xFFFFFFFFFFFFFF00,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0)); else esilprintf (op, "%s,0x80,&,?{,0xFFFFFF00,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0)); break; case PPC_INS_EXTSH: op->sign = true; if (a->bits == 64) esilprintf (op, "%s,0x8000,&,?{,0xFFFFFFFFFFFF0000,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0)); else esilprintf (op, "%s,0x8000,&,?{,0xFFFF0000,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0)); break; case PPC_INS_EXTSW: op->sign = true; esilprintf (op, "%s,0x80000000,&,?{,0xFFFFFFFF00000000,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0)); break; case PPC_INS_SYNC: case PPC_INS_ISYNC: case PPC_INS_LWSYNC: case PPC_INS_MSYNC: case PPC_INS_PTESYNC: case PPC_INS_TLBSYNC: case PPC_INS_SLBIA: case PPC_INS_SLBIE: case PPC_INS_SLBMFEE: case PPC_INS_SLBMTE: case PPC_INS_EIEIO: case PPC_INS_NOP: op->type = R_ANAL_OP_TYPE_NOP; esilprintf (op, ","); break; case PPC_INS_STW: case PPC_INS_STWU: case PPC_INS_STWUX: case PPC_INS_STWX: case PPC_INS_STWCX: op->type = R_ANAL_OP_TYPE_STORE; esilprintf (op, "%s,%s", ARG (0), ARG2 (1, "=[4]")); break; case PPC_INS_STWBRX: op->type = R_ANAL_OP_TYPE_STORE; break; case PPC_INS_STB: case PPC_INS_STBU: op->type = R_ANAL_OP_TYPE_STORE; esilprintf (op, "%s,%s", ARG (0), ARG2 (1, "=[1]")); break; case PPC_INS_STH: case PPC_INS_STHU: op->type = R_ANAL_OP_TYPE_STORE; esilprintf (op, "%s,%s", ARG (0), ARG2 (1, "=[2]")); break; case PPC_INS_STD: case PPC_INS_STDU: op->type = R_ANAL_OP_TYPE_STORE; esilprintf (op, "%s,%s", ARG (0), ARG2 (1, "=[8]")); break; case PPC_INS_LBZ: #if CS_API_MAJOR >= 4 case PPC_INS_LBZCIX: #endif case PPC_INS_LBZU: case PPC_INS_LBZUX: case PPC_INS_LBZX: op->type = R_ANAL_OP_TYPE_LOAD; esilprintf (op, "%s,%s,=", ARG2 (1, "[1]"), ARG (0)); break; case PPC_INS_LD: case PPC_INS_LDARX: #if CS_API_MAJOR >= 4 case PPC_INS_LDCIX: #endif case PPC_INS_LDU: case PPC_INS_LDUX: case PPC_INS_LDX: op->type = R_ANAL_OP_TYPE_LOAD; esilprintf (op, "%s,%s,=", ARG2 (1, "[8]"), ARG (0)); break; case PPC_INS_LDBRX: op->type = R_ANAL_OP_TYPE_LOAD; break; case PPC_INS_LFD: case PPC_INS_LFDU: case PPC_INS_LFDUX: case PPC_INS_LFDX: case PPC_INS_LFIWAX: case PPC_INS_LFIWZX: case PPC_INS_LFS: case PPC_INS_LFSU: case PPC_INS_LFSUX: case PPC_INS_LFSX: op->type = R_ANAL_OP_TYPE_LOAD; esilprintf (op, "%s,%s,=", ARG2 (1, "[4]"), ARG (0)); break; case PPC_INS_LHA: case PPC_INS_LHAU: case PPC_INS_LHAUX: case PPC_INS_LHAX: case PPC_INS_LHZ: case PPC_INS_LHZU: op->type = R_ANAL_OP_TYPE_LOAD; esilprintf (op, "%s,%s,=", ARG2 (1, "[2]"), ARG (0)); break; case PPC_INS_LHBRX: op->type = R_ANAL_OP_TYPE_LOAD; break; case PPC_INS_LWA: case PPC_INS_LWARX: case PPC_INS_LWAUX: case PPC_INS_LWAX: case PPC_INS_LWZ: #if CS_API_MAJOR >= 4 case PPC_INS_LWZCIX: #endif case PPC_INS_LWZU: case PPC_INS_LWZUX: case PPC_INS_LWZX: op->type = R_ANAL_OP_TYPE_LOAD; esilprintf (op, "%s,%s,=", ARG2 (1, "[4]"), ARG (0)); break; case PPC_INS_LWBRX: op->type = R_ANAL_OP_TYPE_LOAD; break; case PPC_INS_SLW: case PPC_INS_SLWI: op->type = R_ANAL_OP_TYPE_SHL; esilprintf (op, "%s,%s,<<,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_SRW: case PPC_INS_SRWI: op->type = R_ANAL_OP_TYPE_SHR; esilprintf (op, "%s,%s,>>,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_MULLI: op->sign = true; case PPC_INS_MULLW: case PPC_INS_MULLD: op->type = R_ANAL_OP_TYPE_MUL; esilprintf (op, "%s,%s,*,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_SUB: case PPC_INS_SUBC: case PPC_INS_SUBF: case PPC_INS_SUBFIC: case PPC_INS_SUBFZE: op->type = R_ANAL_OP_TYPE_SUB; esilprintf (op, "%s,%s,-,%s,=", ARG (1), ARG (2), ARG (0)); break; case PPC_INS_ADD: case PPC_INS_ADDI: op->sign = true; op->type = R_ANAL_OP_TYPE_ADD; esilprintf (op, "%s,%s,+,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_ADDC: case PPC_INS_ADDIC: op->type = R_ANAL_OP_TYPE_ADD; esilprintf (op, "%s,%s,+,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_ADDE: case PPC_INS_ADDIS: case PPC_INS_ADDME: case PPC_INS_ADDZE: op->type = R_ANAL_OP_TYPE_ADD; esilprintf (op, "%s,%s,+,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_MTSPR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s,%s,=", ARG (1), PPCSPR (0)); break; case PPC_INS_BCTR: // switch table here op->type = R_ANAL_OP_TYPE_UJMP; esilprintf (op, "ctr,pc,="); break; case PPC_INS_BCTRL: // switch table here op->type = R_ANAL_OP_TYPE_CALL; esilprintf (op, "pc,lr,=,ctr,pc,="); break; case PPC_INS_B: case PPC_INS_BC: op->jump = ARG (1)[0] == '\0' ? IMM (0) : IMM (1); op->type = R_ANAL_OP_TYPE_CJMP; op->fail = addr + op->size; switch (insn->detail->ppc.bc) { case PPC_BC_LT: if (ARG (1)[0] == '\0') { esilprintf (op, "0,cr0,<,?{,%s,pc,=,},", ARG (0)); } else { esilprintf (op, "0,%s,<,?{,%s,pc,=,},", ARG (0), ARG (1)); } break; case PPC_BC_LE: if (ARG (1)[0] == '\0') { esilprintf (op, "0,cr0,<=,?{,%s,pc,=,},", ARG (0)); } else { esilprintf (op, "0,%s,<=,?{,%s,pc,=,},", ARG (0), ARG (1)); } break; case PPC_BC_EQ: if (ARG (1)[0] == '\0') { esilprintf (op, "0,cr0,==,?{,%s,pc,=,},", ARG (0)); } else { esilprintf (op, "0,%s,==,?{,%s,pc,=,},", ARG (0), ARG (1)); } break; case PPC_BC_GE: if (ARG (1)[0] == '\0') { esilprintf (op, "0,cr0,>=,?{,%s,pc,=,},", ARG (0)); } else { esilprintf (op, "0,%s,>=,?{,%s,pc,=,},", ARG (0), ARG (1)); } break; case PPC_BC_GT: if (ARG (1)[0] == '\0') { esilprintf (op, "0,cr0,>,?{,%s,pc,=,},", ARG (0)); } else { esilprintf (op, "0,%s,>,?{,%s,pc,=,},", ARG (0), ARG (1)); } break; case PPC_BC_NE: if (ARG (1)[0] == '\0') { esilprintf (op, "cr0,?{,%s,pc,=,},", ARG (0)); } else { esilprintf (op, "%s,?{,%s,pc,=,},", ARG (0), ARG (1)); } break; case PPC_BC_INVALID: op->type = R_ANAL_OP_TYPE_JMP; esilprintf (op, "%s,pc,=", ARG (0)); case PPC_BC_UN: // unordered case PPC_BC_NU: // not unordered case PPC_BC_SO: // summary overflow case PPC_BC_NS: // not summary overflow default: break; } break; case PPC_INS_BA: switch (insn->detail->ppc.operands[0].type) { case PPC_OP_CRX: op->type = R_ANAL_OP_TYPE_CJMP; op->fail = addr + op->size; break; case PPC_OP_REG: if (op->type == R_ANAL_OP_TYPE_CJMP) { op->type = R_ANAL_OP_TYPE_UCJMP; } else { op->type = R_ANAL_OP_TYPE_CJMP; } op->jump = IMM (1); op->fail = addr + op->size; //op->type = R_ANAL_OP_TYPE_UJMP; default: break; } break; case PPC_INS_BDNZ: op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM (0); op->fail = addr + op->size; esilprintf (op, "1,ctr,-=,ctr,?{,%s,pc,=,}", ARG (0)); break; case PPC_INS_BDNZA: op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM (0); op->fail = addr + op->size; break; case PPC_INS_BDNZL: op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM (0); op->fail = addr + op->size; break; case PPC_INS_BDNZLA: op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM (0); op->fail = addr + op->size; break; case PPC_INS_BDNZLR: op->type = R_ANAL_OP_TYPE_CJMP; op->fail = addr + op->size; esilprintf (op, "1,ctr,-=,ctr,?{,lr,pc,=,},"); break; case PPC_INS_BDNZLRL: op->fail = addr + op->size; op->type = R_ANAL_OP_TYPE_CJMP; break; case PPC_INS_BDZ: op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM (0); op->fail = addr + op->size; esilprintf (op, "1,ctr,-=,ctr,0,==,?{,%s,pc,=,}", ARG (0)); break; case PPC_INS_BDZA: op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM (0); op->fail = addr + op->size; break; case PPC_INS_BDZL: op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM (0); op->fail = addr + op->size; break; case PPC_INS_BDZLA: op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM (0); op->fail = addr + op->size; break; case PPC_INS_BDZLR: op->type = R_ANAL_OP_TYPE_CJMP; op->fail = addr + op->size; esilprintf (op, "1,ctr,-=,ctr,0,==,?{,lr,pc,=,}"); break; case PPC_INS_BDZLRL: op->type = R_ANAL_OP_TYPE_CJMP; op->fail = addr + op->size; break; case PPC_INS_BLR: case PPC_INS_BLRL: case PPC_INS_BCLR: case PPC_INS_BCLRL: op->type = R_ANAL_OP_TYPE_CRET; op->fail = addr + op->size; switch (insn->detail->ppc.bc) { case PPC_BC_INVALID: op->type = R_ANAL_OP_TYPE_RET; esilprintf (op, "lr,pc,="); break; case PPC_BC_LT: if (ARG (0)[0] == '\0') { esilprintf (op, "0,cr0,<,?{,lr,pc,=,},"); } else { esilprintf (op, "0,%s,<,?{,lr,pc,=,},", ARG (0)); } break; case PPC_BC_LE: if (ARG (0)[0] == '\0') { esilprintf (op, "0,cr0,<=,?{,lr,pc,=,},"); } else { esilprintf (op, "0,%s,<=,?{,lr,pc,=,},", ARG (0)); } break; case PPC_BC_EQ: if (ARG (0)[0] == '\0') { esilprintf (op, "0,cr0,==,?{,lr,pc,=,},"); } else { esilprintf (op, "0,%s,==,?{,lr,pc,=,},", ARG (0)); } break; case PPC_BC_GE: if (ARG (0)[0] == '\0') { esilprintf (op, "0,cr0,>=,?{,lr,pc,=,},"); } else { esilprintf (op, "0,%s,>=,?{,lr,pc,=,},", ARG (0)); } break; case PPC_BC_GT: if (ARG (0)[0] == '\0') { esilprintf (op, "0,cr0,>,?{,lr,pc,=,},"); } else { esilprintf (op, "0,%s,>,?{,lr,pc,=,},", ARG (0)); } break; case PPC_BC_NE: if (ARG (0)[0] == '\0') { esilprintf (op, "cr0,?{,lr,pc,=,},"); } else { esilprintf (op, "%s,?{,lr,pc,=,},", ARG (0)); } break; case PPC_BC_UN: // unordered case PPC_BC_NU: // not unordered case PPC_BC_SO: // summary overflow case PPC_BC_NS: // not summary overflow default: break; } break; case PPC_INS_NOR: op->type = R_ANAL_OP_TYPE_NOR; esilprintf (op, "%s,%s,|,!,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_XOR: case PPC_INS_XORI: op->type = R_ANAL_OP_TYPE_XOR; esilprintf (op, "%s,%s,^,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_XORIS: op->type = R_ANAL_OP_TYPE_XOR; esilprintf (op, "16,%s,<<,%s,^,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_DIVD: case PPC_INS_DIVW: op->sign = true; op->type = R_ANAL_OP_TYPE_DIV; esilprintf (op, "%s,%s,/,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_DIVDU: case PPC_INS_DIVWU: op->type = R_ANAL_OP_TYPE_DIV; esilprintf (op, "%s,%s,/,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_BL: case PPC_INS_BLA: op->type = R_ANAL_OP_TYPE_CALL; op->jump = IMM (0); op->fail = addr + op->size; esilprintf (op, "pc,lr,=,%s,pc,=", ARG (0)); break; case PPC_INS_TRAP: op->sign = true; op->type = R_ANAL_OP_TYPE_TRAP; break; case PPC_INS_AND: case PPC_INS_NAND: case PPC_INS_ANDI: op->type = R_ANAL_OP_TYPE_AND; esilprintf (op, "%s,%s,&,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_ANDIS: op->type = R_ANAL_OP_TYPE_AND; esilprintf (op, "16,%s,<<,%s,&,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_OR: case PPC_INS_ORI: op->type = R_ANAL_OP_TYPE_OR; esilprintf (op, "%s,%s,|,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_ORIS: op->type = R_ANAL_OP_TYPE_OR; esilprintf (op, "16,%s,<<,%s,|,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_MFPVR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "pvr,%s,=", ARG (0)); break; case PPC_INS_MFSPR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s,%s,=", PPCSPR (1), ARG (0)); break; case PPC_INS_MFCTR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "ctr,%s,=", ARG (0)); break; case PPC_INS_MFDCCR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "dccr,%s,=", ARG (0)); break; case PPC_INS_MFICCR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "iccr,%s,=", ARG (0)); break; case PPC_INS_MFDEAR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "dear,%s,=", ARG (0)); break; case PPC_INS_MFMSR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "msr,%s,=", ARG (0)); break; case PPC_INS_MTCTR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s,ctr,=", ARG (0)); break; case PPC_INS_MTDCCR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s,dccr,=", ARG (0)); break; case PPC_INS_MTICCR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s,iccr,=", ARG (0)); break; case PPC_INS_MTDEAR: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s,dear,=", ARG (0)); break; case PPC_INS_MTMSR: case PPC_INS_MTMSRD: op->type = R_ANAL_OP_TYPE_MOV; esilprintf (op, "%s,msr,=", ARG (0)); break; // Data Cache Block Zero case PPC_INS_DCBZ: op->type = R_ANAL_OP_TYPE_STORE; esilprintf (op, "%s,%s", ARG (0), ARG2 (1, ",=[128]")); break; case PPC_INS_CLRLDI: op->type = R_ANAL_OP_TYPE_AND; esilprintf (op, "%s,%s,&,%s,=", ARG (1), cmask64 (ARG (2), "0x3F"), ARG (0)); break; case PPC_INS_ROTLDI: op->type = R_ANAL_OP_TYPE_ROL; esilprintf (op, "%s,%s,<<<,%s,=", ARG (2), ARG (1), ARG (0)); break; case PPC_INS_RLDCL: case PPC_INS_RLDICL: op->type = R_ANAL_OP_TYPE_ROL; esilprintf (op, "%s,%s,<<<,%s,&,%s,=", ARG (2), ARG (1), cmask64 (ARG (3), "0x3F"), ARG (0)); break; case PPC_INS_RLDCR: case PPC_INS_RLDICR: op->type = R_ANAL_OP_TYPE_ROL; esilprintf (op, "%s,%s,<<<,%s,&,%s,=", ARG (2), ARG (1), cmask64 (0, ARG (3)), ARG (0)); break; } if (a->fillval) { op_fillval (op, handle, insn); } r_strbuf_fini (&op->esil); cs_free (insn, n); //cs_close (&handle); } return op->size; } static int archinfo(RAnal *a, int q) { if (a->cpu && !strncmp (a->cpu, "vle", 3)) { return 2; } return 4; } RAnalPlugin r_anal_plugin_ppc_cs = { .name = "ppc", .desc = "Capstone PowerPC analysis", .license = "BSD", .esil = true, .arch = "ppc", .bits = 32 | 64, .archinfo = archinfo, .op = &analop, .set_reg_profile = &set_reg_profile, }; #ifndef CORELIB RLibStruct radare_plugin = { .type = R_LIB_TYPE_ANAL, .data = &r_anal_plugin_ppc_cs, .version = R2_VERSION };
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { int n, ret, opsize = -1; static csh handle = 0; static int omode = -1; static int obits = 32; cs_insn* insn; int mode = a->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN; mode |= (a->bits==64)? CS_MODE_64: CS_MODE_32; if (mode != omode || a->bits != obits) { cs_close (&handle); handle = 0; omode = mode; obits = a->bits; } // XXX no arch->cpu ?!?! CS_MODE_MICRO, N64 op->delay = 0; op->size = 4; if (handle == 0) { ret = cs_open (CS_ARCH_M68K, mode, &handle); if (ret != CS_ERR_OK) goto fin; cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON); } n = cs_disasm (handle, (ut8*)buf, len, addr, 1, &insn); if (n<1 || insn->size<1) { op->type = R_ANAL_OP_TYPE_ILL; op->size = 2; opsize = -1; goto beach; } if (!memcmp (buf, "\xff\xff", 2)) { op->type = R_ANAL_OP_TYPE_ILL; op->size = 2; opsize = -1; goto beach; } op->type = R_ANAL_OP_TYPE_NULL; op->delay = 0; opsize = op->size = insn->size; switch (insn->id) { case M68K_INS_INVALID: op->type = R_ANAL_OP_TYPE_ILL; break; case M68K_INS_ADD: case M68K_INS_ADDA: case M68K_INS_ADDI: case M68K_INS_ADDQ: case M68K_INS_ADDX: op->type = R_ANAL_OP_TYPE_ADD; break; case M68K_INS_AND: case M68K_INS_ANDI: op->type = R_ANAL_OP_TYPE_AND; break; case M68K_INS_ASL: op->type = R_ANAL_OP_TYPE_SHL; break; case M68K_INS_ASR: op->type = R_ANAL_OP_TYPE_SHR; break; case M68K_INS_ABCD: break; case M68K_INS_BHS: case M68K_INS_BLO: case M68K_INS_BHI: case M68K_INS_BLS: case M68K_INS_BCC: case M68K_INS_BCS: case M68K_INS_BNE: case M68K_INS_BEQ: case M68K_INS_BVC: case M68K_INS_BVS: case M68K_INS_BPL: case M68K_INS_BMI: case M68K_INS_BGE: case M68K_INS_BLT: case M68K_INS_BGT: case M68K_INS_BLE: op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM(0) - 0x100; // XXX wtf capstone bug op->fail = addr + 2; break; case M68K_INS_BRA: op->type = R_ANAL_OP_TYPE_JMP; break; case M68K_INS_BSR: op->type = R_ANAL_OP_TYPE_CALL; op->jump = IMM(0) - 0x100; // XXX wtf capstone bug op->fail = addr + 2; break; case M68K_INS_BCHG: case M68K_INS_BCLR: case M68K_INS_BSET: case M68K_INS_BTST: case M68K_INS_BFCHG: case M68K_INS_BFCLR: case M68K_INS_BFEXTS: case M68K_INS_BFEXTU: case M68K_INS_BFFFO: case M68K_INS_BFINS: case M68K_INS_BFSET: case M68K_INS_BFTST: case M68K_INS_BKPT: case M68K_INS_CALLM: case M68K_INS_CAS: case M68K_INS_CAS2: case M68K_INS_CHK: case M68K_INS_CHK2: case M68K_INS_CLR: // TODO: break; case M68K_INS_CMP: case M68K_INS_CMPA: case M68K_INS_CMPI: case M68K_INS_CMPM: case M68K_INS_CMP2: op->type = R_ANAL_OP_TYPE_CMP; break; case M68K_INS_CINVL: case M68K_INS_CINVP: case M68K_INS_CINVA: op->type = R_ANAL_OP_TYPE_ILL; break; case M68K_INS_CPUSHL: case M68K_INS_CPUSHP: case M68K_INS_CPUSHA: case M68K_INS_DBT: case M68K_INS_DBF: case M68K_INS_DBHI: case M68K_INS_DBLS: case M68K_INS_DBCC: case M68K_INS_DBCS: case M68K_INS_DBNE: case M68K_INS_DBEQ: case M68K_INS_DBVC: case M68K_INS_DBVS: case M68K_INS_DBPL: case M68K_INS_DBMI: case M68K_INS_DBGE: case M68K_INS_DBLT: case M68K_INS_DBGT: case M68K_INS_DBLE: case M68K_INS_DBRA: break; case M68K_INS_DIVS: case M68K_INS_DIVSL: case M68K_INS_DIVU: case M68K_INS_DIVUL: op->type = R_ANAL_OP_TYPE_DIV; break; case M68K_INS_EOR: case M68K_INS_EORI: op->type = R_ANAL_OP_TYPE_XOR; break; case M68K_INS_EXG: case M68K_INS_EXT: case M68K_INS_EXTB: break; case M68K_INS_FABS: case M68K_INS_FSABS: case M68K_INS_FDABS: case M68K_INS_FACOS: case M68K_INS_FADD: case M68K_INS_FSADD: case M68K_INS_FDADD: case M68K_INS_FASIN: case M68K_INS_FATAN: case M68K_INS_FATANH: case M68K_INS_FBF: case M68K_INS_FBEQ: case M68K_INS_FBOGT: case M68K_INS_FBOGE: case M68K_INS_FBOLT: case M68K_INS_FBOLE: case M68K_INS_FBOGL: case M68K_INS_FBOR: case M68K_INS_FBUN: case M68K_INS_FBUEQ: case M68K_INS_FBUGT: case M68K_INS_FBUGE: case M68K_INS_FBULT: case M68K_INS_FBULE: case M68K_INS_FBNE: case M68K_INS_FBT: case M68K_INS_FBSF: case M68K_INS_FBSEQ: case M68K_INS_FBGT: case M68K_INS_FBGE: case M68K_INS_FBLT: case M68K_INS_FBLE: case M68K_INS_FBGL: case M68K_INS_FBGLE: case M68K_INS_FBNGLE: case M68K_INS_FBNGL: case M68K_INS_FBNLE: case M68K_INS_FBNLT: case M68K_INS_FBNGE: case M68K_INS_FBNGT: case M68K_INS_FBSNE: case M68K_INS_FBST: case M68K_INS_FCMP: case M68K_INS_FCOS: case M68K_INS_FCOSH: case M68K_INS_FDBF: case M68K_INS_FDBEQ: case M68K_INS_FDBOGT: case M68K_INS_FDBOGE: case M68K_INS_FDBOLT: case M68K_INS_FDBOLE: case M68K_INS_FDBOGL: case M68K_INS_FDBOR: case M68K_INS_FDBUN: case M68K_INS_FDBUEQ: case M68K_INS_FDBUGT: case M68K_INS_FDBUGE: case M68K_INS_FDBULT: case M68K_INS_FDBULE: case M68K_INS_FDBNE: case M68K_INS_FDBT: case M68K_INS_FDBSF: case M68K_INS_FDBSEQ: case M68K_INS_FDBGT: case M68K_INS_FDBGE: case M68K_INS_FDBLT: case M68K_INS_FDBLE: case M68K_INS_FDBGL: case M68K_INS_FDBGLE: case M68K_INS_FDBNGLE: case M68K_INS_FDBNGL: case M68K_INS_FDBNLE: case M68K_INS_FDBNLT: case M68K_INS_FDBNGE: case M68K_INS_FDBNGT: case M68K_INS_FDBSNE: case M68K_INS_FDBST: case M68K_INS_FDIV: case M68K_INS_FSDIV: case M68K_INS_FDDIV: case M68K_INS_FETOX: case M68K_INS_FETOXM1: case M68K_INS_FGETEXP: case M68K_INS_FGETMAN: case M68K_INS_FINT: case M68K_INS_FINTRZ: case M68K_INS_FLOG10: case M68K_INS_FLOG2: case M68K_INS_FLOGN: case M68K_INS_FLOGNP1: case M68K_INS_FMOD: case M68K_INS_FMOVE: case M68K_INS_FSMOVE: case M68K_INS_FDMOVE: case M68K_INS_FMOVECR: case M68K_INS_FMOVEM: case M68K_INS_FMUL: case M68K_INS_FSMUL: case M68K_INS_FDMUL: case M68K_INS_FNEG: case M68K_INS_FSNEG: case M68K_INS_FDNEG: case M68K_INS_FNOP: case M68K_INS_FREM: case M68K_INS_FRESTORE: case M68K_INS_FSAVE: case M68K_INS_FSCALE: case M68K_INS_FSGLDIV: case M68K_INS_FSGLMUL: case M68K_INS_FSIN: case M68K_INS_FSINCOS: case M68K_INS_FSINH: case M68K_INS_FSQRT: case M68K_INS_FSSQRT: case M68K_INS_FDSQRT: case M68K_INS_FSF: case M68K_INS_FSBEQ: case M68K_INS_FSOGT: case M68K_INS_FSOGE: case M68K_INS_FSOLT: case M68K_INS_FSOLE: case M68K_INS_FSOGL: case M68K_INS_FSOR: case M68K_INS_FSUN: case M68K_INS_FSUEQ: case M68K_INS_FSUGT: case M68K_INS_FSUGE: case M68K_INS_FSULT: case M68K_INS_FSULE: case M68K_INS_FSNE: case M68K_INS_FST: case M68K_INS_FSSF: case M68K_INS_FSSEQ: case M68K_INS_FSGT: case M68K_INS_FSGE: case M68K_INS_FSLT: case M68K_INS_FSLE: case M68K_INS_FSGL: case M68K_INS_FSGLE: case M68K_INS_FSNGLE: case M68K_INS_FSNGL: case M68K_INS_FSNLE: case M68K_INS_FSNLT: case M68K_INS_FSNGE: case M68K_INS_FSNGT: case M68K_INS_FSSNE: case M68K_INS_FSST: case M68K_INS_FSUB: case M68K_INS_FSSUB: case M68K_INS_FDSUB: case M68K_INS_FTAN: case M68K_INS_FTANH: case M68K_INS_FTENTOX: case M68K_INS_FTRAPF: case M68K_INS_FTRAPEQ: case M68K_INS_FTRAPOGT: case M68K_INS_FTRAPOGE: case M68K_INS_FTRAPOLT: case M68K_INS_FTRAPOLE: case M68K_INS_FTRAPOGL: case M68K_INS_FTRAPOR: case M68K_INS_FTRAPUN: case M68K_INS_FTRAPUEQ: case M68K_INS_FTRAPUGT: case M68K_INS_FTRAPUGE: case M68K_INS_FTRAPULT: case M68K_INS_FTRAPULE: case M68K_INS_FTRAPNE: case M68K_INS_FTRAPT: case M68K_INS_FTRAPSF: case M68K_INS_FTRAPSEQ: case M68K_INS_FTRAPGT: case M68K_INS_FTRAPGE: case M68K_INS_FTRAPLT: case M68K_INS_FTRAPLE: case M68K_INS_FTRAPGL: case M68K_INS_FTRAPGLE: case M68K_INS_FTRAPNGLE: case M68K_INS_FTRAPNGL: case M68K_INS_FTRAPNLE: case M68K_INS_FTRAPNLT: case M68K_INS_FTRAPNGE: case M68K_INS_FTRAPNGT: case M68K_INS_FTRAPSNE: case M68K_INS_FTRAPST: case M68K_INS_FTST: case M68K_INS_FTWOTOX: op->type = R_ANAL_OP_TYPE_UNK; op->family = R_ANAL_OP_FAMILY_FPU; break; case M68K_INS_HALT: op->type = R_ANAL_OP_TYPE_NOP; break; case M68K_INS_ILLEGAL: op->type = R_ANAL_OP_TYPE_ILL; break; case M68K_INS_JMP: op->type = R_ANAL_OP_TYPE_JMP; break; case M68K_INS_JSR: op->type = R_ANAL_OP_TYPE_CALL; break; case M68K_INS_LINK: case M68K_INS_LPSTOP: case M68K_INS_LSL: op->type = R_ANAL_OP_TYPE_SHL; break; case M68K_INS_LSR: op->type = R_ANAL_OP_TYPE_SHR; break; case M68K_INS_LEA: case M68K_INS_MOVE: case M68K_INS_MOVEA: case M68K_INS_MOVEC: case M68K_INS_MOVEM: case M68K_INS_MOVEP: case M68K_INS_MOVEQ: case M68K_INS_MOVES: case M68K_INS_MOVE16: op->type = R_ANAL_OP_TYPE_MOV; break; case M68K_INS_MULS: case M68K_INS_MULU: op->type = R_ANAL_OP_TYPE_MUL; break; case M68K_INS_NBCD: case M68K_INS_NEG: case M68K_INS_NEGX: break; case M68K_INS_NOP: op->type = R_ANAL_OP_TYPE_NOP; break; case M68K_INS_NOT: case M68K_INS_OR: case M68K_INS_ORI: op->type = R_ANAL_OP_TYPE_OR; break; case M68K_INS_PACK: case M68K_INS_PEA: case M68K_INS_PFLUSH: case M68K_INS_PFLUSHA: case M68K_INS_PFLUSHAN: case M68K_INS_PFLUSHN: case M68K_INS_PLOADR: case M68K_INS_PLOADW: case M68K_INS_PLPAR: case M68K_INS_PLPAW: case M68K_INS_PMOVE: case M68K_INS_PMOVEFD: case M68K_INS_PTESTR: case M68K_INS_PTESTW: case M68K_INS_PULSE: case M68K_INS_REMS: case M68K_INS_REMU: case M68K_INS_RESET: case M68K_INS_ROL: case M68K_INS_ROR: case M68K_INS_ROXL: case M68K_INS_ROXR: case M68K_INS_RTD: case M68K_INS_RTE: case M68K_INS_RTM: case M68K_INS_RTR: case M68K_INS_RTS: case M68K_INS_SBCD: case M68K_INS_ST: case M68K_INS_SF: case M68K_INS_SHI: case M68K_INS_SLS: case M68K_INS_SCC: case M68K_INS_SHS: case M68K_INS_SCS: case M68K_INS_SLO: case M68K_INS_SNE: case M68K_INS_SEQ: case M68K_INS_SVC: case M68K_INS_SVS: case M68K_INS_SPL: case M68K_INS_SMI: case M68K_INS_SGE: case M68K_INS_SLT: case M68K_INS_SGT: case M68K_INS_SLE: case M68K_INS_STOP: break; case M68K_INS_SUB: case M68K_INS_SUBA: case M68K_INS_SUBI: case M68K_INS_SUBQ: case M68K_INS_SUBX: op->type = R_ANAL_OP_TYPE_SUB; break; case M68K_INS_SWAP: op->type = R_ANAL_OP_TYPE_MOV; break; case M68K_INS_TAS: break; case M68K_INS_TRAP: case M68K_INS_TRAPV: case M68K_INS_TRAPT: case M68K_INS_TRAPF: case M68K_INS_TRAPHI: case M68K_INS_TRAPLS: case M68K_INS_TRAPCC: case M68K_INS_TRAPHS: case M68K_INS_TRAPCS: case M68K_INS_TRAPLO: case M68K_INS_TRAPNE: case M68K_INS_TRAPEQ: case M68K_INS_TRAPVC: case M68K_INS_TRAPVS: case M68K_INS_TRAPPL: case M68K_INS_TRAPMI: case M68K_INS_TRAPGE: case M68K_INS_TRAPLT: case M68K_INS_TRAPGT: case M68K_INS_TRAPLE: op->type = R_ANAL_OP_TYPE_TRAP; break; case M68K_INS_TST: op->type = R_ANAL_OP_TYPE_CMP; break; case M68K_INS_UNLK: case M68K_INS_UNPK: break; } beach: cs_free (insn, n); //cs_close (&handle); fin: return opsize; }
static int dis_class2(uint32_t *pc, uint32_t inst) { int op3 = OP3(inst); char *opc[] = { "add", "and", "or", "xor", "sub", "andn", "orn", "xnor", "addc", "mulx", "umul", "smul", "subc", "udivx", "udiv", "sdiv", "addcc", "andcc", "orcc", "xorcc", "subcc", "andncc", "orncc", "xnorcc", "addccc", "-", "umulcc", "smulcc", "subccc", "-", "udivcc", "sdivcc", "taddcc", "tsubcc", "taddcctv", "tsubcctv", "mulscc", "sll", "srl", "sra", "rdy", "-", "rdpr", "flushw", "movcc", "sdivx", "popc", "movr", "wry", "saved", "wrpr", "-", "fpop1", "fpop2", "impldep1", "impldep2", "jmpl", "return", "tcc", "flush", "save", "restore", "done", "-" }; switch(op3) { case 0x00: /* ADD */ case 0x01: /* AND */ case 0x02: /* OR */ case 0x03: /* XOR */ case 0x04: /* SUB */ case 0x05: /* ANDN */ case 0x06: /* ORN */ case 0x07: /* XNOR */ case 0x08: /* ADDC */ case 0x09: /* MULX */ case 0x0a: /* UMUL */ case 0x0b: /* SMUL */ case 0x0c: /* SUBC */ case 0x0d: /* UDIVX */ case 0x0e: /* UDIV */ case 0x0f: /* SDIV */ case 0x10: /* ADDcc */ case 0x11: /* ANDcc */ case 0x12: /* ORcc */ case 0x13: /* XORcc */ case 0x14: /* SUBcc */ case 0x15: /* ANDNcc */ case 0x16: /* ORNcc */ case 0x17: /* XNORcc */ case 0x18: /* ANDCcc */ case 0x1a: /* UMULcc */ case 0x1b: /* SMULcc */ case 0x1c: /* SUBCcc */ case 0x1e: /* UDIVcc */ case 0x1f: /* SDIVcc */ case 0x20: /* TADDcc */ case 0x21: /* TSUBcc */ case 0x22: /* TADDccTV */ case 0x23: /* TSUBccTV */ case 0x24: /* MULScc */ case 0x2c: /* MOVcc */ case 0x2d: /* SDIVX */ case 0x2f: /* MOVr */ case 0x38: /* JMPL */ case 0x3c: /* SAVE */ case 0x3d: /* RESTORE */ (void)printf("%p:\t%s\t%s, ", (void *)pc, opc[op3], sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld, ", SIMM13(inst)); else (void)printf("%s, ", sregs[RS2(inst)]); (void)printf("%s\n", sregs[RD(inst)]); return (op3 == 0x38) ? DELAY : OK; case 0x2b: /* FLUSHW */ if ((RD(inst) == 0) && (RS1(inst) == 0) && (IMM(inst) == 0) && (SIMM13(inst) == 0)) { (void)printf("%p:\t%s\n", (void *)pc, opc[op3]); return OK; } ILLEGAL; case 0x39: /* RETURN */ case 0x3b: /* FLUSH */ if (RD(inst)) { ILLEGAL; } (void)printf("%p:\t%s\t%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld\n", SIMM13(inst)); else (void)printf("%s\n", sregs[RS2(inst)]); return OK; case 0x19: case 0x1d: case 0x29: case 0x33: case 0x3f: ILLEGAL; case 0x25: /* SLL/SLLX */ case 0x26: /* SRL/SRLX */ case 0x27: /* SRA/SRAX */ (void)printf("%p:\t%s%s\t%s, ", (void *)pc, opc[op3], X(inst) ? "x" : "", sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%d, ", X(inst) ? SHIFT64(inst) : SHIFT32(inst)); else (void)printf("%s, ", sregs[RS2(inst)]); (void)printf("%s\n", sregs[RD(inst)]); return OK; case 0x28: /* RDASR */ return dis_rdasr(pc, inst); case 0x2a: /* RDPR */ return dis_rdpr(pc, inst); case 0x30: /* WRASR */ return dis_wrasr(pc, inst); case 0x31: /* SAVED/RESTORED */ if(FCN(inst) == 0) { (void)printf("%p:\tsaved\n", (void *)pc); return OK; } if(FCN(inst) == 1) { (void)printf("%p:\trestored\n", (void *)pc); return OK; } ILLEGAL; case 0x32: /* WRPR */ return dis_wrpr(pc, inst); case 0x3a: /* Tcc */ return dis_tcc(pc, inst); case 0x3e: /* DONE/RETRY */ if(FCN(inst) == 0) { (void)printf("%p:\tdone\n", (void *)pc); return OK; } if(FCN(inst) == 1) { (void)printf("%p:\tretry\n", (void *)pc); return OK; } ILLEGAL; case 0x36: /* IMPDEP1 */ (void)printf("XXXX %p:\timpldep1\n", (void *)pc ); return ERR; case 0x37: /* IMPLDEP2 */ (void)printf("XXXX %p:\timpldep2\n", (void *)pc); return ERR; default: (void)printf("XXXX dis_class2 op3=%x\n", op3); return ERR; } }
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { int n, ret, opsize = -1; csh handle; cs_insn* insn; int mode = a->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN; mode |= (a->bits==64)? CS_MODE_64: CS_MODE_32; // XXX no arch->cpu ?!?! CS_MODE_MICRO, N64 ret = cs_open (CS_ARCH_MIPS, mode, &handle); op->delay = 0; op->type = R_ANAL_OP_TYPE_ILL; op->size = 4; if (ret != CS_ERR_OK) goto fin; cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON); n = cs_disasm (handle, (ut8*)buf, len, addr, 1, &insn); if (n<1 || insn->size<1) goto beach; op->type = R_ANAL_OP_TYPE_NULL; op->delay = 0; opsize = op->size = insn->size; switch (insn->id) { case MIPS_INS_INVALID: op->type = R_ANAL_OP_TYPE_ILL; break; case MIPS_INS_LB: case MIPS_INS_LBU: case MIPS_INS_LBUX: case MIPS_INS_LW: case MIPS_INS_LWC1: case MIPS_INS_LWC2: case MIPS_INS_LWL: case MIPS_INS_LWR: case MIPS_INS_LWXC1: case MIPS_INS_LD: case MIPS_INS_LDC1: case MIPS_INS_LDC2: case MIPS_INS_LDL: case MIPS_INS_LDR: case MIPS_INS_LDXC1: op->type = R_ANAL_OP_TYPE_LOAD; op->refptr = 4; switch (OPERAND(1).type) { case MIPS_OP_MEM: if (OPERAND(1).mem.base == MIPS_REG_GP) { op->ptr = a->gp + OPERAND(1).mem.disp; op->refptr = 4; } break; case MIPS_OP_IMM: op->ptr = OPERAND(1).imm; break; case MIPS_OP_REG: // wtf? break; default: break; } // TODO: fill break; case MIPS_INS_SW: case MIPS_INS_SWC1: case MIPS_INS_SWC2: case MIPS_INS_SWL: case MIPS_INS_SWR: case MIPS_INS_SWXC1: op->type = R_ANAL_OP_TYPE_STORE; break; case MIPS_INS_NOP: op->type = R_ANAL_OP_TYPE_NOP; break; case MIPS_INS_SYSCALL: case MIPS_INS_BREAK: op->type = R_ANAL_OP_TYPE_TRAP; break; case MIPS_INS_JALR: op->type = R_ANAL_OP_TYPE_UCALL; op->delay = 1; break; case MIPS_INS_JAL: case MIPS_INS_JALS: case MIPS_INS_JALX: case MIPS_INS_JIALC: case MIPS_INS_JIC: case MIPS_INS_JRADDIUSP: case MIPS_INS_BAL: case MIPS_INS_BGEZAL: // Branch on less than zero and link op->type = R_ANAL_OP_TYPE_CALL; op->delay = 1; op->jump = IMM(0); op->fail = addr+4; break; case MIPS_INS_MOVE: op->type = R_ANAL_OP_TYPE_MOV; break; case MIPS_INS_ADD: case MIPS_INS_ADDI: case MIPS_INS_ADDIU: case MIPS_INS_DADD: case MIPS_INS_DADDI: case MIPS_INS_DADDIU: op->type = R_ANAL_OP_TYPE_ADD; break; case MIPS_INS_SUB: case MIPS_INS_SUBV: case MIPS_INS_SUBVI: case MIPS_INS_DSUBU: case MIPS_INS_FSUB: case MIPS_INS_FMSUB: case MIPS_INS_SUBU: case MIPS_INS_DSUB: case MIPS_INS_SUBS_S: case MIPS_INS_SUBS_U: case MIPS_INS_SUBUH: case MIPS_INS_SUBUH_R: op->type = R_ANAL_OP_TYPE_SUB; break; case MIPS_INS_MULV: case MIPS_INS_MULT: case MIPS_INS_MULSA: case MIPS_INS_FMUL: case MIPS_INS_MUL: case MIPS_INS_DMULT: case MIPS_INS_DMULTU: op->type = R_ANAL_OP_TYPE_MUL; break; case MIPS_INS_XOR: case MIPS_INS_XORI: op->type = R_ANAL_OP_TYPE_XOR; break; case MIPS_INS_AND: case MIPS_INS_ANDI: op->type = R_ANAL_OP_TYPE_AND; break; case MIPS_INS_NOT: op->type = R_ANAL_OP_TYPE_NOT; break; case MIPS_INS_OR: case MIPS_INS_ORI: op->type = R_ANAL_OP_TYPE_OR; break; case MIPS_INS_DIV: case MIPS_INS_DIVU: case MIPS_INS_DDIV: case MIPS_INS_DDIVU: case MIPS_INS_FDIV: case MIPS_INS_DIV_S: case MIPS_INS_DIV_U: op->type = R_ANAL_OP_TYPE_DIV; break; case MIPS_INS_CMPGDU: case MIPS_INS_CMPGU: case MIPS_INS_CMPU: case MIPS_INS_CMPI: op->type = R_ANAL_OP_TYPE_CMP; break; case MIPS_INS_J: case MIPS_INS_B: case MIPS_INS_BZ: case MIPS_INS_BEQ: case MIPS_INS_BNZ: case MIPS_INS_BNE: case MIPS_INS_BEQZ: case MIPS_INS_BNEG: case MIPS_INS_BNEGI: case MIPS_INS_BNEZ: case MIPS_INS_BTEQZ: case MIPS_INS_BTNEZ: case MIPS_INS_BLTZ: case MIPS_INS_BGEZ: case MIPS_INS_BGEZC: case MIPS_INS_BGEZALC: op->type = R_ANAL_OP_TYPE_JMP; op->delay = 1; if (OPERAND(0).type == MIPS_OP_IMM) { op->jump = IMM(0); } else if (OPERAND(1).type == MIPS_OP_IMM) { op->jump = IMM(1); } else if (OPERAND(2).type == MIPS_OP_IMM) { op->jump = IMM(2); } break; case MIPS_INS_JR: case MIPS_INS_JRC: op->type = R_ANAL_OP_TYPE_JMP; op->delay = 1; // register 32 is $ra, so jmp is a return if (insn->detail->mips.operands[0].reg == 32) { op->type = R_ANAL_OP_TYPE_RET; } break; } beach: if (a->decode) { if (!analop_esil (a, op, addr, buf, len, &handle, insn)) r_strbuf_fini (&op->esil); } cs_free (insn, n); cs_close (&handle); fin: return opsize; }
static int dis_wrasr(uint32_t *pc, uint32_t inst) { char *asrs[] = { "wry", "-", "wrccr", "wrasi", "wrtick", "-", "wrfprs", "-", "-", "-", "-", "-", "-", "-", "-", "sir", }; if ((RD(inst) == 0xf) && (RS1(inst) != 0) && (IMM(inst) == 0)) { ILLEGAL; } switch(RD(inst)) { case 0x01: ILLEGAL; case 0x0f: /* SIR */ case 0x00: /* WRY */ case 0x02: /* WRCCR */ case 0x03: /* WRASI */ case 0x06: /* WRFPRS */ (void)printf("%p:\t%s\t%s,", (void *)pc, asrs[RD(inst)], sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld, ", SIMM13(inst)); else (void)printf("%s, ", sregs[RS2(inst)]); (void)printf("\n"); return OK; case 0x04: case 0x05: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: ILLEGAL; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: (void)printf("%p:\twr\t%s, ", (void *)pc, sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld, ", SIMM13(inst)); else (void)printf("%s, ", sregs[RS2(inst)]); (void)printf("%%asr%d\n", RD(inst)); return ERR; default: (void)printf("XXXX wrasr %d\n", RD(inst)); return ERR; } }
static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) { char str[32][32]; r_strbuf_init (&op->esil); r_strbuf_set (&op->esil, ""); if (insn) switch (insn->id) { case MIPS_INS_NOP: r_strbuf_setf (&op->esil, ","); break; case MIPS_INS_SW: r_strbuf_appendf (&op->esil, "%s,%s,=[4]", ARG(0), ARG(1)); break; case MIPS_INS_SWC1: case MIPS_INS_SWC2: r_strbuf_setf (&op->esil, "%s,$", ARG(1)); break; case MIPS_INS_SB: r_strbuf_appendf (&op->esil, "%s,%s,=[1]", ARG(0), ARG(1)); break; case MIPS_INS_CMP: case MIPS_INS_CMPU: case MIPS_INS_CMPGU: case MIPS_INS_CMPGDU: case MIPS_INS_CMPI: r_strbuf_appendf (&op->esil, "%s,%s,==", ARG(1), ARG(0)); break; case MIPS_INS_SHRAV: case MIPS_INS_SHRAV_R: case MIPS_INS_SHRA: case MIPS_INS_SHRA_R: case MIPS_INS_SRA: r_strbuf_appendf (&op->esil, "%s,%s,>>,31,%s,>>,?{,32,%s,-,%s,1,<<,1,-,<<,}{,0,},|,%s,=,", ARG(2), ARG(1), ARG(1), ARG(2), ARG(2), ARG(0)); break; case MIPS_INS_SHRL: // suffix 'S' forces conditional flag to be updated case MIPS_INS_SRLV: case MIPS_INS_SRL: r_strbuf_appendf (&op->esil, "%s,%s,>>,%s,=", ARG(2), ARG(1), ARG(0)); break; case MIPS_INS_SLLV: case MIPS_INS_SLL: r_strbuf_appendf (&op->esil, "%s,%s,<<,%s,=", ARG(2), ARG(1), ARG(0)); break; case MIPS_INS_BAL: case MIPS_INS_JAL: case MIPS_INS_JALR: case MIPS_INS_JALRS: case MIPS_INS_JALRC: case MIPS_INS_BLTZAL: // Branch on less than zero and link r_strbuf_appendf (&op->esil, "pc,8,+,ra,=,%s,pc,=", ARG(0)); break; case MIPS_INS_JR: case MIPS_INS_JRC: case MIPS_INS_J: // jump to address with conditional r_strbuf_appendf (&op->esil, "%s,pc,=", ARG(0)); break; case MIPS_INS_B: // ??? case MIPS_INS_BZ: case MIPS_INS_BGTZ: case MIPS_INS_BGTZC: case MIPS_INS_BGTZALC: case MIPS_INS_BGEZ: case MIPS_INS_BGEZC: case MIPS_INS_BGEZAL: // Branch on less than zero and link case MIPS_INS_BGEZALC: r_strbuf_appendf (&op->esil, "%s,pc,=", ARG(0)); break; case MIPS_INS_BNE: // bne $s, $t, offset case MIPS_INS_BNEZ: r_strbuf_appendf (&op->esil, "%s,%s,==,!,?{,%s,pc,=,}", ARG(0), ARG(1), ARG(2)); break; case MIPS_INS_BEQ: case MIPS_INS_BEQZ: case MIPS_INS_BEQZC: case MIPS_INS_BEQZALC: r_strbuf_appendf (&op->esil, "%s,%s,==,?{,%s,pc,=,}", ARG(0), ARG(1), ARG(2)); break; case MIPS_INS_BTEQZ: case MIPS_INS_BTNEZ: r_strbuf_appendf (&op->esil, "%s,pc,=", ARG(0)); break; case MIPS_INS_MOV: case MIPS_INS_MOVE: case MIPS_INS_MOVF: case MIPS_INS_MOVT: case MIPS_INS_MOVZ: if (REG(0)[0]!='z'){ r_strbuf_appendf (&op->esil, "%s,%s,=", ARG(1), REG(0)); } else { r_strbuf_appendf (&op->esil, ","); } break; case MIPS_INS_FSUB: case MIPS_INS_SUB: if (REG(0)[0]!='z'){ r_strbuf_appendf(&op->esil, "%s,%s,>,?{,$$,}{,%s,%s,-,%s,=",ARG(2), ARG(1), ARG(1), ARG(2), ARG(0)); } else { r_strbuf_appendf (&op->esil, ","); } break; case MIPS_INS_SUBU: case MIPS_INS_NEGU: case MIPS_INS_DSUB: case MIPS_INS_DSUBU: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); r_strbuf_appendf (&op->esil, "%s,%s,-,%s,=", arg1, arg2, arg0); } break; /** signed -- sets overflow flag */ case MIPS_INS_ADD: { if (REG(0)[0]!='z'){ r_strbuf_appendf (&op->esil, "32,%s,%s,+,>>,0,>,?{,$$,}{,%s,%s,+,%s,=,}", ARG(2), ARG(1), ARG(2), ARG(1), ARG(0)); } else { r_strbuf_appendf (&op->esil, ","); } } break; case MIPS_INS_ADDI: if (REG(0)[0]!='z'){ r_strbuf_appendf (&op->esil, "32,%s,0xffffffff,&,%s,+,>>,0,>,?{,$$,}{,%s,%s,+,%s,=,}", ARG(2), ARG(1), ARG(2), ARG(1), ARG(0)); } else { r_strbuf_appendf (&op->esil, ","); } break; case MIPS_INS_DADD: case MIPS_INS_DADDI: /** unsigned */ case MIPS_INS_ADDU: case MIPS_INS_ADDIU: case MIPS_INS_DADDIU: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); if (REG(0)[0]!='z'){ r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=", arg2, arg1, arg0); } else { r_strbuf_appendf (&op->esil, ","); } } break; case MIPS_INS_LI: r_strbuf_appendf (&op->esil, "0x%"PFMT64x",%s,=", IMM(1), ARG(0)); break; case MIPS_INS_LUI: r_strbuf_appendf (&op->esil, "0x%"PFMT64x"0000,%s,=", IMM(1), ARG(0)); break; case MIPS_INS_LB: case MIPS_INS_LBU: //one of these is wrong r_strbuf_appendf (&op->esil, "%s,[1],%s,=", ARG(1), REG(0)); break; case MIPS_INS_LW: case MIPS_INS_LWC1: case MIPS_INS_LWC2: case MIPS_INS_LWL: case MIPS_INS_LWR: case MIPS_INS_LWU: case MIPS_INS_LWX: case MIPS_INS_LH: case MIPS_INS_LHX: case MIPS_INS_LL: case MIPS_INS_LLD: case MIPS_INS_LD: case MIPS_INS_LDI: case MIPS_INS_LDL: case MIPS_INS_LDC1: case MIPS_INS_LDC2: r_strbuf_appendf (&op->esil, "%s,[4],%s,=", ARG(1), REG(0)); break; case MIPS_INS_AND: case MIPS_INS_ANDI: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); r_strbuf_appendf (&op->esil, "%s,%s,&,%s,=", arg2, arg1, arg0); } break; case MIPS_INS_OR: case MIPS_INS_ORI: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); if (REG(0)[0]!='z'){ r_strbuf_appendf (&op->esil, "%s,%s,|,%s,=", arg2, arg1, arg0); } else { r_strbuf_appendf (&op->esil, ","); } } break; case MIPS_INS_XOR: case MIPS_INS_XORI: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); if (REG(0)[0]!='z'){ r_strbuf_appendf (&op->esil, "%s,%s,^,%s,=", arg2, arg1, arg0); } else { r_strbuf_appendf (&op->esil, ","); } } break; case MIPS_INS_NOR: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); if (REG(0)[0]!='z'){ r_strbuf_appendf (&op->esil, "%s,%s,|,0xffffffff,^,%s,=", arg2, arg1, arg0); } else { r_strbuf_appendf (&op->esil, ","); } } break; case MIPS_INS_SLTU: r_strbuf_appendf (&op->esil, "%s,%s,<,%s,=", ARG(1), ARG(2), ARG(0)); break; case MIPS_INS_SLTIU: { r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,<,?{%s,1,=,}{,%s,0,=,}", ARG(1), ARG(2), ARG(0), ARG(0)); } break; } return 0; }
static int dis_class3(uint32_t *pc, uint32_t inst) { int op3 = OP3(inst); char *opc[0x40] = { "lduw", "ldub", "lduh", "ldd", "stw", "stb", "sth", "std", "ldsw", "ldsb", "ldsh", "ldx", "-", "ldstub", "stx", "swap", "lduwa", "lduba", "lduha", "ldda", "stwa", "stba", "stha", "stda", "ldswa", "ldsba", "ldsha", "ldxa", "-", "ldstuba", "stxa", "swapa", "ldf", "ldfsr", "ldqf", "lddf" "stf", "stfsr", "stqf", "stdf", "-", "-", "-", "-", "-", "prefetch", "-", "-", "ldfa", "-", "ldqfa", "lddfa", "stfa", "-", "stqfa", "stdfa", "-", "-", "-", "-", "casa", "prefetcha", "casxa", "-" }; switch(op3) { case 0x0c: case 0x1c: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2e: case 0x31: case 0x35: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3f: ILLEGAL; case 0x00: /* LDUW */ case 0x01: /* LDUB */ case 0x02: /* LDUH */ case 0x03: /* LDD */ case 0x08: /* LDSW */ case 0x09: /* LDSB */ case 0x0a: /* LDSH */ case 0x0b: /* LDX */ case 0x0d: /* LDSTUB */ case 0x1f: /* SWAP */ (void)printf("%p:\t%s\t[%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld], ", SIMM13(inst)); else (void)printf("%s], ", sregs[RS2(inst)]); (void)printf("%s\n", sregs[RD(inst)]); return OK; case 0x04: /* STW */ case 0x05: /* STB */ case 0x06: /* STH */ case 0x07: /* STD */ case 0x0e: /* STX */ (void)printf("%p:\t%s\t%s, ", (void *)pc, opc[op3], sregs[RD(inst)]); (void)printf("[%s + ", sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld]\n", SIMM13(inst)); else (void)printf("%s]\n", sregs[RS2(inst)]); return OK; case 0x10: /* LDUWA */ case 0x11: /* LDUBA */ case 0x12: /* LDUHA */ case 0x13: /* LDDA */ case 0x18: /* LDSWA */ case 0x19: /* LDSBA */ case 0x1a: /* LDSHA */ case 0x1b: /* LDXA */ case 0x1d: /* LDSTUBA */ case 0x2f: /* SWAPA */ case 0x3c: /* CASA */ case 0x3e: /* CASXA */ (void)printf("%p:\t%s\t[%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld] %%asi, ", SIMM13(inst)); else (void)printf("%s] 0x%x, ", sregs[RS2(inst)], IMMASI(inst)); (void)printf("%s\n", sregs[RD(inst)]); return OK; case 0x14: /* STWA */ case 0x15: /* STBA */ case 0x16: /* STHA */ case 0x17: /* STDA */ case 0x1e: /* STXA */ (void)printf("%p:\t%s\t%s, ", (void *)pc, opc[op3], sregs[RD(inst)]); (void)printf("[%s + ", sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld] %%asi\n", SIMM13(inst)); else (void)printf("%s] 0x%x\n", sregs[RS2(inst)], IMMASI(inst)); return OK; case 0x2d: /* PREFETCH */ if ((RD(inst) >=5) && (RD(inst) <= 15)) { ILLEGAL; } (void)printf("%p:\t%s\t[%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld], ", SIMM13(inst)); else (void)printf("%s], ", sregs[RS2(inst)]); (void)printf("%d\n", RD(inst)); return OK; case 0x3d: /* PREFETCHA */ if ((RD(inst) >=5) && (RD(inst) <= 15)) { ILLEGAL; } (void)printf("%p:\t%s\t[%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); if (IMM(inst)) (void)printf("%ld] %%asi, ", SIMM13(inst)); else (void)printf("%s] 0x%x, ", sregs[RS2(inst)], IMMASI(inst)); (void)printf("%d\n", RD(inst)); return OK; case 0x20: case 0x21: case 0x22: case 0x23: case 0x30: case 0x32: case 0x33: (void)printf("XXXX %p:\tLDF XXX op3=%x\n", (void *)pc, OP3(inst)); return ERR; case 0x24: case 0x25: case 0x26: case 0x27: case 0x34: case 0x36: case 0x37: (void)printf("XXXX %p:\tSTF XXX op3=%x\n", (void *)pc, OP3(inst)); return ERR; default: (void)printf("XXXX dis_class3 op3=%x\n", OP3(inst)); return ERR; } }
V4FMADDPS(ZMM(19), ZMM(0), MEM(RBX, (11)*16)) V4FMADDPS(ZMM(20), ZMM(0), MEM(RBX, (12)*16)) V4FMADDPS(ZMM(21), ZMM(0), MEM(RBX, (13)*16)) V4FMADDPS(ZMM(22), ZMM(0), MEM(RBX, (14)*16)) V4FMADDPS(ZMM(23), ZMM(0), MEM(RBX, (15)*16)) V4FMADDPS(ZMM(24), ZMM(0), MEM(RBX, (16)*16)) V4FMADDPS(ZMM(25), ZMM(0), MEM(RBX, (17)*16)) V4FMADDPS(ZMM(26), ZMM(0), MEM(RBX, (18)*16)) V4FMADDPS(ZMM(27), ZMM(0), MEM(RBX, (19)*16)) V4FMADDPS(ZMM(28), ZMM(0), MEM(RBX, (20)*16)) V4FMADDPS(ZMM(29), ZMM(0), MEM(RBX, (21)*16)) V4FMADDPS(ZMM(30), ZMM(0), MEM(RBX, (22)*16)) V4FMADDPS(ZMM(31), ZMM(0), MEM(RBX, (23)*16)) // Update pointers to a and b ADD(RAX, IMM(256)) // RAX += 16*4*sizeof(float) ADD(RBX, IMM(384)) // RAX += 24*4*sizeof(float) // Update loop counter and compare SUB(RSI, IMM(1)) JNZ(MAIN_LOOP) // Load alpha and beta MOV(RAX, VAR(alpha)) MOV(RBX, VAR(beta)) VBROADCASTSS(ZMM(0), MEM(RAX)) VBROADCASTSS(ZMM(1), MEM(RBX)) // Update C UPDATE_C_FOUR_COLS(8, 9, 10, 11)
static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) { char str[8][32]; int i; r_strbuf_init (&op->esil); r_strbuf_set (&op->esil, ""); if (insn) { // caching operands for (i=0; i<insn->detail->mips.op_count && i<8; i++) { *str[i]=0; ARG (i); } } if (insn) switch (insn->id) { case MIPS_INS_NOP: r_strbuf_setf (&op->esil, ","); break; case MIPS_INS_BREAK: r_strbuf_setf (&op->esil, "%s,%s,TRAP", ARG (0), ARG (0)); break; case MIPS_INS_SW: case MIPS_INS_SWL: case MIPS_INS_SWR: r_strbuf_appendf (&op->esil, "%s,%s,=[4]", ARG (0), ARG (1)); break; case MIPS_INS_SH: r_strbuf_appendf (&op->esil, "%s,%s,=[2]", ARG (0), ARG (1)); break; case MIPS_INS_SWC1: case MIPS_INS_SWC2: r_strbuf_setf (&op->esil, "%s,$", ARG (1)); break; case MIPS_INS_SB: r_strbuf_appendf (&op->esil, "%s,%s,=[1]", ARG (0), ARG (1)); break; case MIPS_INS_CMP: case MIPS_INS_CMPU: case MIPS_INS_CMPGU: case MIPS_INS_CMPGDU: case MIPS_INS_CMPI: r_strbuf_appendf (&op->esil, "%s,%s,==", ARG (1), ARG (0)); break; case MIPS_INS_SHRAV: case MIPS_INS_SHRAV_R: case MIPS_INS_SHRA: case MIPS_INS_SHRA_R: case MIPS_INS_SRA: r_strbuf_appendf (&op->esil, "%s,%s,>>,31,%s,>>,?{,32,%s,-,%s,1,<<,1,-,<<,}{,0,},|,%s,=,", ARG (2), ARG (1), ARG (1), ARG (2), ARG (2), ARG (0)); break; case MIPS_INS_SHRL: // suffix 'S' forces conditional flag to be updated case MIPS_INS_SRLV: case MIPS_INS_SRL: r_strbuf_appendf (&op->esil, "%s,%s,>>,%s,=", ARG (2), ARG (1), ARG (0)); break; case MIPS_INS_SLLV: case MIPS_INS_SLL: r_strbuf_appendf (&op->esil, "%s,%s,<<,%s,=", ARG (2), ARG (1), ARG (0)); break; case MIPS_INS_BAL: case MIPS_INS_JAL: r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_D ("%s"), ARG (0)); break; case MIPS_INS_JALR: case MIPS_INS_JALRS: if (OPCOUNT () < 2) { r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_D ("%s"), ARG (0)); } else { PROTECT_ZERO () { r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_DR ("%s","%s"), ARG (0), ARG (1)); } } break; case MIPS_INS_JALRC: // no delay if (OPCOUNT () < 2) { r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_ND ("%s"), ARG (0)); } else { PROTECT_ZERO () { r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_NDR ("%s","%s"), ARG (0), ARG (1)); } } break; case MIPS_INS_JRADDIUSP: // increment stackpointer in X and jump to %ra r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%d,sp,+=,"ES_J ("ra"), ARG (0)); break; case MIPS_INS_JR: case MIPS_INS_JRC: case MIPS_INS_J: case MIPS_INS_B: // ??? // jump to address with conditional r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_J ("%s"), ARG (0)); break; case MIPS_INS_BNE: // bne $s, $t, offset r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,%s,==,$z,!,?{,"ES_J ("%s")",}", ARG (0), ARG (1), ARG (2)); break; case MIPS_INS_BEQ: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,%s,==,$z,?{,"ES_J ("%s")",}", ARG (0), ARG (1), ARG (2)); break; case MIPS_INS_BZ: case MIPS_INS_BEQZ: case MIPS_INS_BEQZC: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,0,==,$z,?{,"ES_J ("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BNEZ: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,0,==,$z,!,?{,"ES_J ("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BEQZALC: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,0,==,$z,?{,"ES_CALL_ND ("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BLEZ: case MIPS_INS_BLEZC: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,%s,==,$z,?{,"ES_J ("%s")",BREAK,},", ARG (0), ARG (1)); r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",1,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_J ("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BGEZ: case MIPS_INS_BGEZC: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_J ("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BGEZAL: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_CALL_D ("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BGEZALC: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_CALL_ND ("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BGTZALC: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,%s,==,$z,?{,BREAK,},", ARG(0)); r_strbuf_appendf (&op->esil, "0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_CALL_ND ("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BLTZAL: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",1,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_CALL_D ("%s")",}", ARG(0), ARG(1)); break; case MIPS_INS_BLTZ: case MIPS_INS_BLTZC: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",1,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_J ("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BGTZ: case MIPS_INS_BGTZC: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,%s,==,$z,?{,BREAK,},", ARG (0)); r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_J("%s")",}", ARG (0), ARG (1)); break; case MIPS_INS_BTEQZ: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,t,==,$z,?{,"ES_J ("%s")",}", ARG (0)); break; case MIPS_INS_BTNEZ: r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,t,==,$z,!,?{,"ES_J ("%s")",}", ARG (0)); break; case MIPS_INS_MOV: case MIPS_INS_MOVE: PROTECT_ZERO () { r_strbuf_appendf (&op->esil, "%s,%s,=", ARG (1), REG (0)); } break; case MIPS_INS_MOVZ: case MIPS_INS_MOVF: PROTECT_ZERO () { r_strbuf_appendf (&op->esil, "0,%s,==,$z,?{,%s,%s,=,}", ARG (2), ARG (1), REG (0)); } break; case MIPS_INS_MOVT: PROTECT_ZERO () { r_strbuf_appendf (&op->esil, "1,%s,==,$z,?{,%s,%s,=,}", ARG (2), ARG (1), REG (0)); } break; case MIPS_INS_FSUB: case MIPS_INS_SUB: PROTECT_ZERO () { r_strbuf_appendf(&op->esil, "%s,%s,-,%s,=", ARG (1), ARG (2), ARG (0)); //r_strbuf_appendf(&op->esil, "%s,%s,>,?{,1,TRAP,}{,%s,%s,-,%s,=", // ARG (1), ARG (2), ARG (1), ARG (2), ARG (0)); } break; case MIPS_INS_SUBU: case MIPS_INS_DSUB: case MIPS_INS_DSUBU: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); r_strbuf_appendf (&op->esil, "%s,%s,-,%s,=", arg2, arg1, arg0); } break; case MIPS_INS_NEG: case MIPS_INS_NEGU: r_strbuf_appendf (&op->esil, "%s,0,-,%s,=,", ARG (1), ARG (0)); break; /** signed -- sets overflow flag */ case MIPS_INS_ADD: { PROTECT_ZERO () { r_strbuf_appendf(&op->esil, "%s,%s,-,%s,=", ARG (1), ARG (2), ARG (0)); #if 0 r_strbuf_appendf (&op->esil, "0,32,%s,%s,+,>>,>,?{,1,TRAP,}{,%s,%s,+,%s,=,}", ARG(2), ARG(1), ARG(2), ARG(1), ARG(0)); #endif } } break; case MIPS_INS_ADDI: PROTECT_ZERO () { r_strbuf_appendf (&op->esil, "0,32,%s,0xffffffff,&,%s,+,>>,>,?{,1,TRAP,}{,%s,%s,+,%s,=,}", ARG(2), ARG(1), ARG(2), ARG(1), ARG(0)); } break; case MIPS_INS_DADD: case MIPS_INS_DADDI: /** unsigned */ case MIPS_INS_ADDU: case MIPS_INS_ADDIU: case MIPS_INS_DADDIU: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); PROTECT_ZERO () { if (*arg2 == '-') { r_strbuf_appendf (&op->esil, "%s,%s,-,%s,=", arg2+1, arg1, arg0); } else { r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=", arg2, arg1, arg0); } } } break; case MIPS_INS_LI: r_strbuf_appendf (&op->esil, "0x%"PFMT64x",%s,=", IMM(1), ARG(0)); break; case MIPS_INS_LUI: r_strbuf_appendf (&op->esil, "0x%"PFMT64x"0000,%s,=", IMM(1), ARG(0)); break; case MIPS_INS_LB: case MIPS_INS_LBU: //one of these is wrong ESIL_LOAD ("1"); break; case MIPS_INS_LW: case MIPS_INS_LWC1: case MIPS_INS_LWC2: case MIPS_INS_LWL: case MIPS_INS_LWR: case MIPS_INS_LWU: case MIPS_INS_LL: case MIPS_INS_LLD: case MIPS_INS_LD: case MIPS_INS_LDI: case MIPS_INS_LDL: case MIPS_INS_LDC1: case MIPS_INS_LDC2: ESIL_LOAD ("4"); break; case MIPS_INS_LWX: case MIPS_INS_LH: case MIPS_INS_LHU: case MIPS_INS_LHX: ESIL_LOAD ("2"); break; case MIPS_INS_AND: case MIPS_INS_ANDI: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); r_strbuf_appendf (&op->esil, "%s,%s,&,%s,=", arg2, arg1, arg0); } break; case MIPS_INS_OR: case MIPS_INS_ORI: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); PROTECT_ZERO () { r_strbuf_appendf (&op->esil, "%s,%s,|,%s,=", arg2, arg1, arg0); } } break; case MIPS_INS_XOR: case MIPS_INS_XORI: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); PROTECT_ZERO () { r_strbuf_appendf (&op->esil, "%s,%s,^,%s,=", arg2, arg1, arg0); } } break; case MIPS_INS_NOR: { const char *arg0 = ARG(0); const char *arg1 = ARG(1); const char *arg2 = ARG(2); PROTECT_ZERO () { r_strbuf_appendf (&op->esil, "%s,%s,|,0xffffffff,^,%s,=", arg2, arg1, arg0); } } break; case MIPS_INS_SLT: case MIPS_INS_SLTI: if (OPCOUNT () < 3) { r_strbuf_appendf (&op->esil, ES_IS_NEGATIVE ("%s")"," ES_IS_NEGATIVE ("%s")"," "==,$z,?{," "%s,%s,<,t,=," "}{," "%s,%s,>=,t,=," "}", ARG (1), ARG (0), ARG (1), ARG (0), ARG (1), ARG (0)); } else { r_strbuf_appendf (&op->esil, ES_IS_NEGATIVE ("%s")"," ES_IS_NEGATIVE ("%s")"," "==,$z,?{," "%s,%s,<,%s,=," "}{," "%s,%s,>=,%s,=," "}", ARG (2), ARG (1), ARG (2), ARG (1), ARG (0), ARG (2), ARG (1), ARG (0)); } break; case MIPS_INS_SLTU: case MIPS_INS_SLTIU: if (OPCOUNT () < 3) { r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,t,=", ARG (1), ARG (0)); } else { r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,%s,=", ARG (2), ARG (1), ARG (0)); } break; case MIPS_INS_MULT: case MIPS_INS_MULTU: r_strbuf_appendf (&op->esil, "%s,%s,*,0xffffffff,&,lo,=," ES_SIGN_EXT64 ("lo") ",32,%s,%s,*,>>,0xffffffff,&,hi,=," ES_SIGN_EXT64 ("hi"), ARG (0), ARG (1), ARG (0), ARG (1)); break; case MIPS_INS_MFLO: PROTECT_ZERO () { r_strbuf_appendf (&op->esil, "lo,%s,=", REG (0)); } break; case MIPS_INS_MFHI: PROTECT_ZERO () { r_strbuf_appendf (&op->esil, "hi,%s,=", REG (0)); } break; case MIPS_INS_MTLO: r_strbuf_appendf (&op->esil, "%s,lo,=,"ES_SIGN_EXT64 ("lo"), REG (0)); break; case MIPS_INS_MTHI: r_strbuf_appendf (&op->esil, "%s,hi,=,"ES_SIGN_EXT64 ("hi"), REG (0)); break; #if 0 // could not test div case MIPS_INS_DIV: case MIPS_INS_DIVU: case MIPS_INS_DDIV: case MIPS_INS_DDIVU: PROTECT_ZERO () { // 32 bit needs sign extend r_strbuf_appendf (&op->esil, "%s,%s,/,lo,=,%s,%s,%%,hi,=", REG(1), REG(0), REG(1), REG(0)); } break; #endif default: return -1; } return 0; }
int main() { START_MACHINE; JUMP(CONTINUE); #include "char.lib" #include "io.lib" #include "math.lib" #include "string.lib" #include "system.lib" #include "scheme.lib" #define SOB_BOOL_TRUE (ADDR(1)); #define SOB_BOOL_FALSE (ADDR(3)); #define SOB_NIL (M(mem)[5]); #define SOB_VOID (ADDR(6)); #define IS_TRUE(reg) CONTINUE: /* initialize the 4 singletons */ PUSH(IMM(1)); CALL(MAKE_SOB_BOOL); /* define SOB_BOOL_TRUE */ DROP(1); PUSH(IMM(0)); CALL(MAKE_SOB_BOOL); /* define SOB_BOOL_FALSE */ DROP(1); CALL(MAKE_SOB_NIL); /* define nil */ CALL(MAKE_SOB_VOID); /* start of code */ /* code for the expression: (begin #t #t #f () #t) */ /* code for the expression: #t */ MOV(R0, IMM(1)); /* assigning true to R0 */ /* code for the expression: #t */ MOV(R0, IMM(1)); /* assigning true to R0 */ /* code for the expression: #f */ MOV(R0, IMM(3)); /* assigning false to R0 */ /* code for the expression: () */ MOV(R0, IMM(5)); /* assign nil to R0 */ /* code for the expression: #t */ MOV(R0, IMM(1)); /* assigning true to R0 */ /* end of generated code. CONCLUSION: */ MOV(R1, R0); /* save the result in R1 */ PUSH(R1); /* pushing R1 for void-check */ CALL(IS_SOB_VOID); /* if R0 is #Void, don't print */ DROP(1); CMP(R0, IMM(1)); /* 1 means R0 was void, 0 means it wasn't */ JUMP_EQ(END_OF_THE_WORLD); /* do not print */ PUSH(R1); /* push R1 for print */ CALL(WRITE_SOB); /* print the result before quitting */ DROP(1); /* that was useless.. */ END_OF_THE_WORLD: /* (only as we know it.) */ /* newline and stop machine */ PUSH(IMM('\n')); CALL(PUTCHAR); STOP_MACHINE; return 0; }
int main() { START_MACHINE; JUMP(CONTINUE); #include "scheme.lib" #include "char.lib" #include "io.lib" #include "math.lib" #include "string.lib" #include "system.lib" CONTINUE: /* Initialize stack with default values */ /* Void */ CALL(MAKE_SOB_VOID); MOV(ADDR(10), IND(R0)); /* Nil (Empty List) */ CALL(MAKE_SOB_NIL); MOV(ADDR(11), IND(R0)); /* False (Boolean) */ PUSH(IMM(0)); CALL(MAKE_SOB_BOOL); MOV(ADDR(12), IND(R0)); MOV(ADDR(13), INDD(R0,1)); DROP(IMM(1)); /* True (Boolean) */ PUSH(IMM(1)); CALL(MAKE_SOB_BOOL); MOV(ADDR(14), IND(R0)); MOV(ADDR(15), INDD(R0,1)); DROP(IMM(1)); /* END of initialization */ /* Internal function to check if a type is a SOB */ IS_SOB_TYPE: MOV(R0, STARG(0)); MOV(R0, IND(R0)); CMP(R0, IMM(T_VOID)); JUMP_EQ(TRUE_SOB_TYPE); CMP(R0, IMM(T_NIL)); JUMP_EQ(TRUE_SOB_TYPE); CMP(R0, IMM(T_BOOL)); JUMP_EQ(TRUE_SOB_TYPE); CMP(R0, IMM(T_CHAR)); JUMP_EQ(TRUE_SOB_TYPE); CMP(R0, IMM(T_INTEGER)); JUMP_EQ(TRUE_SOB_TYPE); CMP(R0, IMM(T_STRING)); JUMP_EQ(TRUE_SOB_TYPE); CMP(R0, IMM(T_SYMBOL)); JUMP_EQ(TRUE_SOB_TYPE); CMP(R0, IMM(T_PAIR)); JUMP_EQ(TRUE_SOB_TYPE); CMP(R0, IMM(T_VECTOR)); JUMP_EQ(TRUE_SOB_TYPE); CMP(R0, IMM(T_CLOSURE)); JUMP_EQ(TRUE_SOB_TYPE); MOV(R0, IMM(0)); JUMP(EXIT_IS_SOB_TYPE); TRUE_SOB_TYPE: MOV(R0, IMM(1)); EXIT_IS_SOB_TYPE: POP(FP); RETURN; /* End of IS_SOB_TYPE */ /* applic_3342061*/ /* applic_3342061 - B4 */ MOV(R0, IMM(12)); PUSH(R0); /* applic_3342061 - B3 */ MOV(R0, IMM(14)); PUSH(R0); /* applic_3342061 - B2 */ MOV(R0, IMM(12)); PUSH(R0); /* applic_3342061 - B1 */ MOV(R0, IMM(14)); PUSH(R0); PUSH(4); PUSH(INDD(R0,1)) CALL(INDD(R0,2)) MOV(IND(R1),IMM(2)); ADD(IND(R1),IMM(4)); MOV(SP,IND(R1)); PUSH(R0); CALL(WRITE_SOB); STOP_MACHINE; return 0; }
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { csh handle; cs_insn *insn; int mode = (a->bits==16)? CS_MODE_THUMB: CS_MODE_ARM; int i, n, ret = (a->bits==64)? cs_open (CS_ARCH_ARM64, mode, &handle): cs_open (CS_ARCH_ARM, mode, &handle); cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON); op->type = R_ANAL_OP_TYPE_NULL; op->size = (a->bits==16)? 2: 4; op->delay = 0; r_strbuf_init (&op->esil); if (ret == CS_ERR_OK) { n = cs_disasm_ex (handle, (ut8*)buf, len, addr, 1, &insn); if (n<1) { op->type = R_ANAL_OP_TYPE_ILL; } else { op->size = insn->size; switch (insn->id) { case ARM_INS_POP: case ARM_INS_LDM: op->type = R_ANAL_OP_TYPE_POP; for (i = 0; i < insn->detail->arm.op_count; i++) { if (insn->detail->arm.operands[i].type == ARM_OP_REG && insn->detail->arm.operands[i].reg == ARM_REG_PC) { if (insn->detail->arm.cc == ARM_CC_AL) op->type = R_ANAL_OP_TYPE_RET; else op->type = R_ANAL_OP_TYPE_CRET; break; } } break; case ARM_INS_SUB: op->type = R_ANAL_OP_TYPE_SUB; break; case ARM_INS_ADD: op->type = R_ANAL_OP_TYPE_ADD; break; case ARM_INS_MOV: case ARM_INS_MOVS: case ARM_INS_MOVT: case ARM_INS_MOVW: case ARM_INS_VMOVL: case ARM_INS_VMOVN: case ARM_INS_VQMOVUN: case ARM_INS_VQMOVN: op->type = R_ANAL_OP_TYPE_MOV; break; case ARM_INS_CMP: case ARM_INS_TST: op->type = R_ANAL_OP_TYPE_CMP; break; case ARM_INS_ROR: case ARM_INS_ORN: case ARM_INS_LSL: case ARM_INS_LSR: break; case ARM_INS_PUSH: case ARM_INS_STR: //case ARM_INS_POP: case ARM_INS_LDR: op->type = R_ANAL_OP_TYPE_LOAD; break; case ARM_INS_BL: case ARM_INS_BLX: op->type = R_ANAL_OP_TYPE_CALL; op->jump = IMM(0); break; case ARM_INS_B: case ARM_INS_BX: case ARM_INS_BXJ: if (insn->detail->arm.cc) { op->type = R_ANAL_OP_TYPE_CJMP; op->jump = IMM(0); op->fail = addr+op->size; } else { op->type = R_ANAL_OP_TYPE_JMP; op->jump = IMM(0); } break; } if (a->decode) { if (!analop_esil (a, op, addr, buf, len, &handle, insn)) r_strbuf_fini (&op->esil); } cs_free (insn, n); } } cs_close (&handle); return op->size; }
static inline int do_32(unsigned long inst, struct pt_regs *regs) { int imm, regular, load, len, sign_ext; unsigned long unaligned_addr, target_val, shift; unaligned_addr = *idx_to_addr(regs, RA(inst)); switch ((inst >> 25) << 1) { case 0x02: /* LHI */ imm = 1; regular = 1; load = 1; len = 2; sign_ext = 0; break; case 0x0A: /* LHI.bi */ imm = 1; regular = 0; load = 1; len = 2; sign_ext = 0; break; case 0x22: /* LHSI */ imm = 1; regular = 1; load = 1; len = 2; sign_ext = 1; break; case 0x2A: /* LHSI.bi */ imm = 1; regular = 0; load = 1; len = 2; sign_ext = 1; break; case 0x04: /* LWI */ imm = 1; regular = 1; load = 1; len = 4; sign_ext = 0; break; case 0x0C: /* LWI.bi */ imm = 1; regular = 0; load = 1; len = 4; sign_ext = 0; break; case 0x12: /* SHI */ imm = 1; regular = 1; load = 0; len = 2; sign_ext = 0; break; case 0x1A: /* SHI.bi */ imm = 1; regular = 0; load = 0; len = 2; sign_ext = 0; break; case 0x14: /* SWI */ imm = 1; regular = 1; load = 0; len = 4; sign_ext = 0; break; case 0x1C: /* SWI.bi */ imm = 1; regular = 0; load = 0; len = 4; sign_ext = 0; break; default: switch (inst & 0xff) { case 0x01: /* LH */ imm = 0; regular = 1; load = 1; len = 2; sign_ext = 0; break; case 0x05: /* LH.bi */ imm = 0; regular = 0; load = 1; len = 2; sign_ext = 0; break; case 0x11: /* LHS */ imm = 0; regular = 1; load = 1; len = 2; sign_ext = 1; break; case 0x15: /* LHS.bi */ imm = 0; regular = 0; load = 1; len = 2; sign_ext = 1; break; case 0x02: /* LW */ imm = 0; regular = 1; load = 1; len = 4; sign_ext = 0; break; case 0x06: /* LW.bi */ imm = 0; regular = 0; load = 1; len = 4; sign_ext = 0; break; case 0x09: /* SH */ imm = 0; regular = 1; load = 0; len = 2; sign_ext = 0; break; case 0x0D: /* SH.bi */ imm = 0; regular = 0; load = 0; len = 2; sign_ext = 0; break; case 0x0A: /* SW */ imm = 0; regular = 1; load = 0; len = 4; sign_ext = 0; break; case 0x0E: /* SW.bi */ imm = 0; regular = 0; load = 0; len = 4; sign_ext = 0; break; default: return -EFAULT; } } if (imm) shift = GET_IMMSVAL(IMM(inst)) * len; else shift = *idx_to_addr(regs, RB(inst)) << SV(inst); if (regular) unaligned_addr += shift; if (load) { if (!access_ok(VERIFY_READ, (void *)unaligned_addr, len)) return -EACCES; get_data(unaligned_addr, &target_val, len); if (sign_ext) *idx_to_addr(regs, RT(inst)) = sign_extend(target_val, len); else *idx_to_addr(regs, RT(inst)) = target_val; } else { if (!access_ok(VERIFY_WRITE, (void *)unaligned_addr, len)) return -EACCES; target_val = *idx_to_addr(regs, RT(inst)); set_data((void *)unaligned_addr, target_val, len); } if (!regular) *idx_to_addr(regs, RA(inst)) = unaligned_addr + shift; regs->ipc += 4; return 0; fault: return -EACCES; }
_common_check_code(json_value.isObject(), value_name, "is absent or not an object"); return json_value.toObject(); } QJsonObject expect_json_object(IMM(QJsonDocument) json_doc, IMM(QString) value_name) { _common_check_code(json_doc.isObject(), value_name, "is absent or not an object"); return json_doc.object(); } QJsonArray expect_json_array(IMM(QJsonValue) json_value, IMM(QString) value_name) { _common_check_code(json_value.isArray(), value_name, "is absent or not an array"); return json_value.toArray(); } QJsonArray expect_json_array(IMM(QJsonDocument) json_doc, IMM(QString) value_name) { _common_check_code(json_doc.isArray(), value_name, "is absent or not an array"); return json_doc.array(); } QString expect_json_string(IMM(QJsonValue) json_value, IMM(QString) value_name) { _common_check_code(json_value.isString(), value_name, "is absent or not a string"); return json_value.toString(); } }}}