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"); } }
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(); }