static IRExpr* assignNew_HWord(IRSB* sb_out, IRExpr* expr) { IRTemp tmp = newIRTemp(sb_out->tyenv, Ity_I32); switch (typeOfIRExpr(sb_out->tyenv, expr)) { case Ity_I1: addStmtToIRSB(sb_out, IRStmt_WrTmp(tmp, IRExpr_Unop(Iop_1Uto32, expr))); break; case Ity_I8: addStmtToIRSB(sb_out, IRStmt_WrTmp(tmp, IRExpr_Unop(Iop_8Uto32, expr))); break; case Ity_I16: addStmtToIRSB(sb_out, IRStmt_WrTmp(tmp, IRExpr_Unop(Iop_16Uto32, expr))); break; case Ity_I32: addStmtToIRSB(sb_out, IRStmt_WrTmp(tmp, expr)); break; case Ity_I64: addStmtToIRSB(sb_out, IRStmt_WrTmp(tmp, IRExpr_Unop(Iop_64to32, expr))); break; default: VG_(tool_panic)("assignNew_HWord"); } return IRExpr_RdTmp(tmp); }
/* Converts an IRExpr into 1 or 2 "flat" expressions of type Long */ static void packToI64 ( IRSB* sb, IRExpr* e, IRExpr* res[2], IROp irop) { res[1]=NULL; // won't be used at all IRTemp tmp64; switch (typeOfIRExpr(sb->tyenv,e)) { case Ity_I1: res[0]= IRExpr_Unop(Iop_1Uto64,e); break; case Ity_I8: res[0]= IRExpr_Unop(Iop_8Uto64,e); break; case Ity_I16: res[0]= IRExpr_Unop(Iop_16Uto64,e); break; case Ity_I32: res[0]= IRExpr_Unop(Iop_32Uto64,e); break; case Ity_F32: e = IRExpr_Unop(Iop_ReinterpF32asI32,e); res[0]= IRExpr_Unop(Iop_32Uto64,e); break; case Ity_I64: res[0]= e; return; case Ity_F64: res[0]= IRExpr_Unop(Iop_ReinterpF64asI64,e); break; case Ity_V128: /* 128-bit SIMD */ //tmp64 = newIRTemp(sb->tyenv, Ity_I64); //addStmtToIRSB(sb, IRStmt_WrTmp(tmp64, IRExpr_Unop(Iop_V128to64,e))); //res[0]= IRExpr_Unop(Iop_64to32, IRExpr_RdTmp(tmp64) ); //res[1]= IRExpr_Unop(Iop_64HIto32, IRExpr_RdTmp(tmp64) ); res[0]= IRExpr_Unop(Iop_V128to64, e ); if (dropV128HiPart(irop)) break; res[1]= IRExpr_Unop(Iop_V128HIto64, e ); break; case Ity_I128: /* 128-bit scalar */ case Ity_INVALID: default: VG_(tool_panic)("COJAC cannot packToI64..."); break; } IRTemp myArg = newIRTemp(sb->tyenv, Ity_I64); addStmtToIRSB(sb, IRStmt_WrTmp(myArg, res[0])); res[0]=IRExpr_RdTmp(myArg); // now that's a "flat" expression if (res[1]==NULL) return; // ... else it was 128-bit SIMD IRTemp myArg2 = newIRTemp(sb->tyenv, Ity_I64); addStmtToIRSB(sb, IRStmt_WrTmp(myArg2, res[1])); res[1]=IRExpr_RdTmp(myArg2); // now that's a "flat" expression }
/* Converts an IRExpr into 1 or 2 "flat" expressions of type Int */ static void packToI32 ( IRSB* sb, IRExpr* e, IRExpr* res[2]) { //IRType eType = Ity_I32; IRTemp tmp64; res[1]=NULL; switch (typeOfIRExpr(sb->tyenv,e)) { case Ity_I1: res[0]= IRExpr_Unop(Iop_1Uto32,e); break; case Ity_I8: res[0]= IRExpr_Unop(Iop_8Uto32,e); break; case Ity_I16: res[0]= IRExpr_Unop(Iop_16Uto32,e); break; case Ity_I32: res[0]= e; return; case Ity_F32: res[0]= IRExpr_Unop(Iop_ReinterpF32asI32,e); break; case Ity_I64: res[0]= IRExpr_Unop(Iop_64to32, e); res[1]= IRExpr_Unop(Iop_64HIto32, e); break; case Ity_F64: tmp64 = newIRTemp(sb->tyenv, Ity_I64); addStmtToIRSB(sb, IRStmt_WrTmp(tmp64, IRExpr_Unop(Iop_ReinterpF64asI64,e))); res[0]= IRExpr_Unop(Iop_64to32, IRExpr_RdTmp(tmp64) ); res[1]= IRExpr_Unop(Iop_64HIto32, IRExpr_RdTmp(tmp64) ); break; case Ity_V128: /* 128-bit SIMD */ case Ity_I128: /* 128-bit scalar */ case Ity_INVALID: default: VG_(tool_panic)("COJAC cannot packToI32..."); break; } IRTemp myArg = newIRTemp(sb->tyenv, Ity_I32); addStmtToIRSB(sb, IRStmt_WrTmp(myArg, res[0])); res[0]=IRExpr_RdTmp(myArg); // now that's a "flat" expression if (res[1]==NULL) return; IRTemp myArg2 = newIRTemp(sb->tyenv, Ity_I32); addStmtToIRSB(sb, IRStmt_WrTmp(myArg2, res[1])); res[1]=IRExpr_RdTmp(myArg2); // now that's a "flat" expression }
IRExpr* pyvex_deepCopyIRExpr ( IRExpr* e ) { switch (e->tag) { case Iex_Get: return IRExpr_Get(e->Iex.Get.offset, e->Iex.Get.ty); case Iex_GetI: return IRExpr_GetI(pyvex_deepCopyIRRegArray(e->Iex.GetI.descr), pyvex_deepCopyIRExpr(e->Iex.GetI.ix), e->Iex.GetI.bias); case Iex_RdTmp: return IRExpr_RdTmp(e->Iex.RdTmp.tmp); case Iex_Qop: { IRQop* qop = e->Iex.Qop.details; return IRExpr_Qop(qop->op, pyvex_deepCopyIRExpr(qop->arg1), pyvex_deepCopyIRExpr(qop->arg2), pyvex_deepCopyIRExpr(qop->arg3), pyvex_deepCopyIRExpr(qop->arg4)); } case Iex_Triop: { IRTriop *triop = e->Iex.Triop.details; return IRExpr_Triop(triop->op, pyvex_deepCopyIRExpr(triop->arg1), pyvex_deepCopyIRExpr(triop->arg2), pyvex_deepCopyIRExpr(triop->arg3)); } case Iex_Binop: return IRExpr_Binop(e->Iex.Binop.op, pyvex_deepCopyIRExpr(e->Iex.Binop.arg1), pyvex_deepCopyIRExpr(e->Iex.Binop.arg2)); case Iex_Unop: return IRExpr_Unop(e->Iex.Unop.op, pyvex_deepCopyIRExpr(e->Iex.Unop.arg)); case Iex_Load: return IRExpr_Load(e->Iex.Load.end, e->Iex.Load.ty, pyvex_deepCopyIRExpr(e->Iex.Load.addr)); case Iex_Const: return IRExpr_Const(pyvex_deepCopyIRConst(e->Iex.Const.con)); case Iex_CCall: return IRExpr_CCall(pyvex_deepCopyIRCallee(e->Iex.CCall.cee), e->Iex.CCall.retty, pyvex_deepCopyIRExprVec(e->Iex.CCall.args)); case Iex_ITE: return IRExpr_ITE(pyvex_deepCopyIRExpr(e->Iex.ITE.cond), pyvex_deepCopyIRExpr(e->Iex.ITE.iftrue), pyvex_deepCopyIRExpr(e->Iex.ITE.iffalse)); case Iex_VECRET: return IRExpr_VECRET(); case Iex_BBPTR: return IRExpr_BBPTR(); default: vpanic("pyvex_deepCopyIRExpr"); } }
void instrument_WrTmp_Unop(IRStmt* st, IRSB* sb_out) { IRTemp tmp = st->Ist.WrTmp.tmp; IRExpr* data = st->Ist.WrTmp.data; IROp op = data->Iex.Unop.op; IRExpr* arg = data->Iex.Unop.arg; IRExpr* expr = IRExpr_Unop(op, arg); Int size = sizeofIRType_bits(typeOfIRExpr(sb_out->tyenv, expr)); IRDirty* di; tl_assert(isIRAtom(arg)); tl_assert(typeOfIRTemp(sb_out->tyenv, tmp) == typeOfIRExpr(sb_out->tyenv, expr)); di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_Unop", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_Unop), mkIRExprVec_4(mkIRExpr_HWord(tmp), mkIRExpr_HWord((arg->tag == Iex_RdTmp) ? arg->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord(op), mkIRExpr_HWord(size)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
static IRExpr * log_reads_expr(unsigned tid, IRSB *sb, IRExpr *exp) { if (!exp) return NULL; switch (exp->tag) { case Iex_Get: case Iex_FreeVariable: case Iex_EntryPoint: case Iex_ControlFlow: return exp; case Iex_GetI: { IRExprGetI *e = (IRExprGetI *)exp; return IRExpr_GetI(e->descr, log_reads_expr(tid, sb, e->ix), e->bias, e->tid); } case Iex_Qop: { IRExprQop *e = (IRExprQop *)exp; return IRExpr_Qop(e->op, log_reads_expr(tid, sb, e->arg1), log_reads_expr(tid, sb, e->arg2), log_reads_expr(tid, sb, e->arg3), log_reads_expr(tid, sb, e->arg4)); } case Iex_Triop: { IRExprTriop *e = (IRExprTriop *)exp; return IRExpr_Triop(e->op, log_reads_expr(tid, sb, e->arg1), log_reads_expr(tid, sb, e->arg2), log_reads_expr(tid, sb, e->arg3)); } case Iex_Binop: { IRExprBinop *e = (IRExprBinop *)exp; return IRExpr_Binop(e->op, log_reads_expr(tid, sb, e->arg1), log_reads_expr(tid, sb, e->arg2)); } case Iex_Associative: { IRExprAssociative *e = (IRExprAssociative *)exp; IRExpr **newArgs = alloc_irexpr_array(e->nr_arguments); for (int x = 0; x < e->nr_arguments; x++) newArgs[x] = log_reads_expr(tid, sb, e->contents[x]); return IRExpr_Associative_Claim(e->op, e->nr_arguments, newArgs); } case Iex_Unop: { IRExprUnop *e = (IRExprUnop *)exp; return IRExpr_Unop(e->op, log_reads_expr(tid, sb, e->arg)); } case Iex_Load: { IRExprLoad *e = (IRExprLoad *)exp; IRExpr **args; void *helper; const char *helper_name; IRTemp dest; IRDirty *f; assert(e->addr->type() == Ity_I64); /* Shut compiler up */ helper = (void *)0xf001; helper_name = (const char *)0xdead; #define HLP(x) helper_name = "helper_load_" #x ; helper = (void *)helper_load_ ## x ; switch (e->ty) { case Ity_INVALID: abort(); case Ity_I1: abort(); case Ity_I8: HLP(8); break; case Ity_I16: HLP(16); break; case Ity_I32: HLP(32); break; case Ity_I64: HLP(64); break; case Ity_I128: HLP(128); break; } #undef HLP args = mkIRExprVec_3(log_reads_expr(tid, sb, e->addr), IRExpr_Get(OFFSET_amd64_RSP, Ity_I64, tid, 0), IRExpr_Get(OFFSET_amd64_RIP, Ity_I64, tid, 0)); dest = newIRTemp(sb->tyenv); f = unsafeIRDirty_1_N(threadAndRegister::temp(tid, dest, 0), 0, helper_name, helper, args); addStmtToIRSB(sb, IRStmt_Dirty(f)); return IRExpr_RdTmp(dest, e->ty, tid, 0); } case Iex_Const: return exp; case Iex_CCall: { IRExprCCall *e = (IRExprCCall *)exp; IRExpr **args; int x; int nr_args; for (nr_args = 0; e->args[nr_args]; nr_args++) ; args = alloc_irexpr_array(nr_args + 1); args[nr_args] = NULL; for (x = 0; x < nr_args; x++) args[x] = log_reads_expr(tid, sb, e->args[x]); return IRExpr_CCall(e->cee, e->retty, args); } case Iex_Mux0X: { IRExprMux0X *e = (IRExprMux0X *)exp; return IRExpr_Mux0X(log_reads_expr(tid, sb, e->cond), log_reads_expr(tid, sb, e->expr0), log_reads_expr(tid, sb, e->exprX)); } case Iex_HappensBefore: abort(); } abort(); }