static int first_nibble_is_3(RAnal* anal, RAnalOp* op, ut16 code){ //TODO Handle carry/overflow , CMP/xx? if( IS_ADD(code) || IS_ADDC(code) || IS_ADDV(code) ) { op->type = R_ANAL_OP_TYPE_ADD; op->src[0] = anal_fill_ai_rg (anal, GET_SOURCE_REG(code)); op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); } else if ( IS_SUB(code) || IS_SUBC(code) || IS_SUBV(code)) { op->type = R_ANAL_OP_TYPE_SUB; op->src[0] = anal_fill_ai_rg (anal, GET_SOURCE_REG(code)); op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); } else if (IS_CMPEQ(code) || IS_CMPGE(code) || IS_CMPGT(code) || IS_CMPHI(code) || IS_CMPHS(code)) { //TODO : finish implementing op->type = R_ANAL_OP_TYPE_CMP; op->src[0] = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); op->src[1] = anal_fill_ai_rg (anal, GET_SOURCE_REG(code)); } else if (IS_DIV1(code)) { op->type = R_ANAL_OP_TYPE_DIV; op->src[0] = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); op->src[1] = anal_fill_ai_rg (anal, GET_SOURCE_REG(code)); //todo: dest ? } else if (IS_DMULU(code) || IS_DMULS(code)) { op->type = R_ANAL_OP_TYPE_MUL; op->src[0] = anal_fill_ai_rg (anal, GET_SOURCE_REG(code)); op->src[1] = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); //todo: dest=MACL,MACH } return op->size; }
static int op_val(char *c, t_bistro *bistro) { if (c == NULL) return 0; if (IS_MUL(*c, bistro) || IS_DIV(*c, bistro) || IS_DIVENT(*c, bistro)) return 1; if (IS_ADD(*c, bistro) || IS_SUB(*c, bistro)) return 3; return -1; }
static int first_nibble_is_3(RAnal* anal, RAnalOp* op, ut16 code){ //TODO Handle carry/overflow , CMP/xx? if( IS_ADD(code) || IS_ADDC(code) || IS_ADDV(code) ){ op->type = R_ANAL_OP_TYPE_ADD; op->src[0] = anal_fill_ai_rg(anal,GET_SOURCE_REG(code)); op->dst = anal_fill_ai_rg(anal,GET_TARGET_REG(code)); } else if ( IS_SUB(code) || IS_SUBC(code) || IS_SUBV(code)){ op->type = R_ANAL_OP_TYPE_SUB; op->src[0] = anal_fill_ai_rg(anal,GET_SOURCE_REG(code)); op->dst = anal_fill_ai_rg(anal,GET_TARGET_REG(code)); } return op->size; }
/* For tools that want to know about SP changes, this pass adds in the appropriate hooks. We have to do it after the tool's instrumentation, so the tool doesn't have to worry about the C calls it adds in, and we must do it before register allocation because spilled temps make it much harder to work out the SP deltas. This it is done with Vex's "second instrumentation" pass. Basically, we look for GET(SP)/PUT(SP) pairs and track constant increments/decrements of SP between them. (This requires tracking one or more "aliases", which are not exact aliases but instead are tempregs whose value is equal to the SP's plus or minus a known constant.) If all the changes to SP leading up to a PUT(SP) are by known, small constants, we can do a specific call to eg. new_mem_stack_4, otherwise we fall back to the case that handles an unknown SP change. */ static IRSB* vg_SP_update_pass ( void* closureV, IRSB* sb_in, VexGuestLayout* layout, VexGuestExtents* vge, IRType gWordTy, IRType hWordTy ) { Int i, j, minoff_ST, maxoff_ST, sizeof_SP, offset_SP; IRDirty *dcall, *d; IRStmt* st; IRExpr* e; IRRegArray* descr; IRType typeof_SP; Long delta, con; /* Set up BB */ IRSB* bb = emptyIRSB(); bb->tyenv = deepCopyIRTypeEnv(sb_in->tyenv); bb->next = deepCopyIRExpr(sb_in->next); bb->jumpkind = sb_in->jumpkind; delta = 0; sizeof_SP = layout->sizeof_SP; offset_SP = layout->offset_SP; typeof_SP = sizeof_SP==4 ? Ity_I32 : Ity_I64; vg_assert(sizeof_SP == 4 || sizeof_SP == 8); # define IS_ADD(op) (sizeof_SP==4 ? ((op)==Iop_Add32) : ((op)==Iop_Add64)) # define IS_SUB(op) (sizeof_SP==4 ? ((op)==Iop_Sub32) : ((op)==Iop_Sub64)) # define IS_ADD_OR_SUB(op) (IS_ADD(op) || IS_SUB(op)) # define GET_CONST(con) \ (sizeof_SP==4 ? (Long)(Int)(con->Ico.U32) \ : (Long)(con->Ico.U64)) // XXX: convert this to a function # define DO(kind, syze, tmpp) \ do { \ if (!VG_(tdict).track_##kind##_mem_stack_##syze) \ goto generic; \ \ /* I don't know if it's really necessary to say that the */ \ /* call reads the stack pointer. But anyway, we do. */ \ dcall = unsafeIRDirty_0_N( \ 1/*regparms*/, \ "track_" #kind "_mem_stack_" #syze, \ VG_(fnptr_to_fnentry)( \ VG_(tdict).track_##kind##_mem_stack_##syze ), \ mkIRExprVec_1(IRExpr_RdTmp(tmpp)) \ ); \ dcall->nFxState = 1; \ dcall->fxState[0].fx = Ifx_Read; \ dcall->fxState[0].offset = layout->offset_SP; \ dcall->fxState[0].size = layout->sizeof_SP; \ \ addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \ \ update_SP_aliases(-delta); \ \ n_SP_updates_fast++; \ \ } while (0) clear_SP_aliases(); for (i = 0; i < sb_in->stmts_used; i++) { st = sb_in->stmts[i]; /* t = Get(sp): curr = t, delta = 0 */ if (st->tag != Ist_WrTmp) goto case2; e = st->Ist.WrTmp.data; if (e->tag != Iex_Get) goto case2; if (e->Iex.Get.offset != offset_SP) goto case2; if (e->Iex.Get.ty != typeof_SP) goto case2; add_SP_alias(st->Ist.WrTmp.tmp, 0); addStmtToIRSB( bb, st ); continue; case2: /* t' = curr +/- const: curr = t', delta +=/-= const */ if (st->tag != Ist_WrTmp) goto case3; e = st->Ist.WrTmp.data; if (e->tag != Iex_Binop) goto case3; if (e->Iex.Binop.arg1->tag != Iex_RdTmp) goto case3; if (!get_SP_delta(e->Iex.Binop.arg1->Iex.RdTmp.tmp, &delta)) goto case3; if (e->Iex.Binop.arg2->tag != Iex_Const) goto case3; if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3; con = GET_CONST(e->Iex.Binop.arg2->Iex.Const.con); if (IS_ADD(e->Iex.Binop.op)) { add_SP_alias(st->Ist.WrTmp.tmp, delta + con); } else { add_SP_alias(st->Ist.WrTmp.tmp, delta - con); } addStmtToIRSB( bb, st ); continue; case3: /* t' = curr: curr = t' */ if (st->tag != Ist_WrTmp) goto case4; e = st->Ist.WrTmp.data; if (e->tag != Iex_RdTmp) goto case4; if (!get_SP_delta(e->Iex.RdTmp.tmp, &delta)) goto case4; add_SP_alias(st->Ist.WrTmp.tmp, delta); addStmtToIRSB( bb, st ); continue; case4: /* Put(sp) = curr */ if (st->tag != Ist_Put) goto case5; if (st->Ist.Put.offset != offset_SP) goto case5; if (st->Ist.Put.data->tag != Iex_RdTmp) goto case5; if (get_SP_delta(st->Ist.Put.data->Iex.RdTmp.tmp, &delta)) { IRTemp tttmp = st->Ist.Put.data->Iex.RdTmp.tmp; switch (delta) { case 0: addStmtToIRSB(bb,st); continue; case 4: DO(die, 4, tttmp); addStmtToIRSB(bb,st); continue; case -4: DO(new, 4, tttmp); addStmtToIRSB(bb,st); continue; case 8: DO(die, 8, tttmp); addStmtToIRSB(bb,st); continue; case -8: DO(new, 8, tttmp); addStmtToIRSB(bb,st); continue; case 12: DO(die, 12, tttmp); addStmtToIRSB(bb,st); continue; case -12: DO(new, 12, tttmp); addStmtToIRSB(bb,st); continue; case 16: DO(die, 16, tttmp); addStmtToIRSB(bb,st); continue; case -16: DO(new, 16, tttmp); addStmtToIRSB(bb,st); continue; case 32: DO(die, 32, tttmp); addStmtToIRSB(bb,st); continue; case -32: DO(new, 32, tttmp); addStmtToIRSB(bb,st); continue; case 112: DO(die, 112, tttmp); addStmtToIRSB(bb,st); continue; case -112: DO(new, 112, tttmp); addStmtToIRSB(bb,st); continue; case 128: DO(die, 128, tttmp); addStmtToIRSB(bb,st); continue; case -128: DO(new, 128, tttmp); addStmtToIRSB(bb,st); continue; case 144: DO(die, 144, tttmp); addStmtToIRSB(bb,st); continue; case -144: DO(new, 144, tttmp); addStmtToIRSB(bb,st); continue; case 160: DO(die, 160, tttmp); addStmtToIRSB(bb,st); continue; case -160: DO(new, 160, tttmp); addStmtToIRSB(bb,st); continue; default: /* common values for ppc64: 144 128 160 112 176 */ n_SP_updates_generic_known++; goto generic; } } else {