示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
文件: anal_sh.c 项目: kuduka/radare2
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;
}
示例#4
0
/* 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 {