⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irdefs.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*---------------------------------------------------------------*/void addStmtToIRBB ( IRBB* bb, IRStmt* st ){   Int i;   if (bb->stmts_used == bb->stmts_size) {      IRStmt** stmts2 = LibVEX_Alloc(2 * bb->stmts_size * sizeof(IRStmt*));      for (i = 0; i < bb->stmts_size; i++)         stmts2[i] = bb->stmts[i];      bb->stmts = stmts2;      bb->stmts_size *= 2;   }   vassert(bb->stmts_used < bb->stmts_size);   bb->stmts[bb->stmts_used] = st;   bb->stmts_used++;}/*---------------------------------------------------------------*//*--- Helper functions for the IR -- IR Type Environments     ---*//*---------------------------------------------------------------*//* Allocate a new IRTemp, given its type. */IRTemp newIRTemp ( IRTypeEnv* env, IRType ty ){   vassert(env);   vassert(env->types_used >= 0);   vassert(env->types_size >= 0);   vassert(env->types_used <= env->types_size);   if (env->types_used < env->types_size) {      env->types[env->types_used] = ty;      return env->types_used++;   } else {      Int i;      Int new_size = env->types_size==0 ? 8 : 2*env->types_size;      IRType* new_types          = LibVEX_Alloc(new_size * sizeof(IRType));      for (i = 0; i < env->types_used; i++)         new_types[i] = env->types[i];      env->types      = new_types;      env->types_size = new_size;      return newIRTemp(env, ty);   }}/*---------------------------------------------------------------*//*--- Helper functions for the IR -- finding types of exprs   ---*//*---------------------------------------------------------------*/inline IRType typeOfIRTemp ( IRTypeEnv* env, IRTemp tmp ){   vassert(tmp >= 0);   vassert(tmp < env->types_used);   return env->types[tmp];}IRType typeOfIRConst ( IRConst* con ){   switch (con->tag) {      case Ico_U1:    return Ity_I1;      case Ico_U8:    return Ity_I8;      case Ico_U16:   return Ity_I16;      case Ico_U32:   return Ity_I32;      case Ico_U64:   return Ity_I64;      case Ico_F64:   return Ity_F64;      case Ico_F64i:  return Ity_F64;      case Ico_V128:  return Ity_V128;      default: vpanic("typeOfIRConst");   }}IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e ){   IRType t_dst, t_arg1, t_arg2; start:   switch (e->tag) {      case Iex_Load:         return e->Iex.Load.ty;      case Iex_Get:         return e->Iex.Get.ty;      case Iex_GetI:         return e->Iex.GetI.descr->elemTy;      case Iex_Tmp:         return typeOfIRTemp(tyenv, e->Iex.Tmp.tmp);      case Iex_Const:         return typeOfIRConst(e->Iex.Const.con);      case Iex_Binop:         typeOfPrimop(e->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);         return t_dst;      case Iex_Unop:         typeOfPrimop(e->Iex.Unop.op, &t_dst, &t_arg1, &t_arg2);         return t_dst;      case Iex_CCall:         return e->Iex.CCall.retty;      case Iex_Mux0X:         e = e->Iex.Mux0X.expr0;         goto start;         /* return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0); */      case Iex_Binder:         vpanic("typeOfIRExpr: Binder is not a valid expression");      default:         ppIRExpr(e);         vpanic("typeOfIRExpr");   }}/* Is this any value actually in the enumeration 'IRType' ? */Bool isPlausibleIRType ( IRType ty ){   switch (ty) {      case Ity_INVALID: case Ity_I1:      case Ity_I8: case Ity_I16: case Ity_I32:       case Ity_I64: case Ity_I128:      case Ity_F32: case Ity_F64:      case Ity_V128:         return True;      default:          return False;   }}/*---------------------------------------------------------------*//*--- Sanity checking -- FLATNESS                             ---*//*---------------------------------------------------------------*//* Check that the canonical flatness constraints hold on an   IRStmt. The only place where any expression is allowed to be   non-atomic is the RHS of IRStmt_Tmp. *//* Relies on:   inline static Bool isAtom ( IRExpr* e ) {      return e->tag == Iex_Tmp || e->tag == Iex_Const;   }*/Bool isFlatIRStmt ( IRStmt* st ){   Int      i;   IRExpr*  e;   IRDirty* di;   switch (st->tag) {      case Ist_AbiHint:         return isIRAtom(st->Ist.AbiHint.base);      case Ist_Put:         return isIRAtom(st->Ist.Put.data);      case Ist_PutI:         return toBool( isIRAtom(st->Ist.PutI.ix)                         && isIRAtom(st->Ist.PutI.data) );      case Ist_Tmp:         /* This is the only interesting case.  The RHS can be any            expression, *but* all its subexpressions *must* be            atoms. */         e = st->Ist.Tmp.data;         switch (e->tag) {            case Iex_Binder: return True;            case Iex_Get:    return True;            case Iex_GetI:   return isIRAtom(e->Iex.GetI.ix);            case Iex_Tmp:    return True;            case Iex_Binop:  return toBool(                                    isIRAtom(e->Iex.Binop.arg1)                                     && isIRAtom(e->Iex.Binop.arg2));            case Iex_Unop:   return isIRAtom(e->Iex.Unop.arg);            case Iex_Load:   return isIRAtom(e->Iex.Load.addr);            case Iex_Const:  return True;            case Iex_CCall:  for (i = 0; e->Iex.CCall.args[i]; i++)                                if (!isIRAtom(e->Iex.CCall.args[i]))                                    return False;                             return True;            case Iex_Mux0X:  return toBool (                                    isIRAtom(e->Iex.Mux0X.cond)                                     && isIRAtom(e->Iex.Mux0X.expr0)                                     && isIRAtom(e->Iex.Mux0X.exprX));            default:         vpanic("isFlatIRStmt(e)");         }         /*notreached*/         vassert(0);      case Ist_Store:         return toBool( isIRAtom(st->Ist.Store.addr)                         && isIRAtom(st->Ist.Store.data) );      case Ist_Dirty:         di = st->Ist.Dirty.details;         if (!isIRAtom(di->guard))             return False;         for (i = 0; di->args[i]; i++)            if (!isIRAtom(di->args[i]))                return False;         if (di->mAddr && !isIRAtom(di->mAddr))             return False;         return True;      case Ist_NoOp:      case Ist_IMark:      case Ist_MFence:         return True;      case Ist_Exit:         return isIRAtom(st->Ist.Exit.guard);      default:          vpanic("isFlatIRStmt(st)");   }}/*---------------------------------------------------------------*//*--- Sanity checking                                         ---*//*---------------------------------------------------------------*//* Checks:   Everything is type-consistent.  No ill-typed anything.   The target address at the end of the BB is a 32- or 64-   bit expression, depending on the guest's word size.   Each temp is assigned only once, before its uses.*/static inline Int countArgs ( IRExpr** args ){   Int i;   for (i = 0; args[i]; i++)      ;   return i;}static__attribute((noreturn))void sanityCheckFail ( IRBB* bb, IRStmt* stmt, HChar* what ){   vex_printf("\nIR SANITY CHECK FAILURE\n\n");   ppIRBB(bb);   if (stmt) {      vex_printf("\nIN STATEMENT:\n\n");      ppIRStmt(stmt);   }   vex_printf("\n\nERROR = %s\n\n", what );   vpanic("sanityCheckFail: exiting due to bad IR");}static Bool saneIRArray ( IRArray* arr ){   if (arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */)      return False;   if (arr->elemTy == Ity_I1)      return False;   if (arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */)      return False;   return True;}static Bool saneIRCallee ( IRCallee* cee ){   if (cee->name == NULL)      return False;   if (cee->addr == 0)      return False;   if (cee->regparms < 0 || cee->regparms > 3)      return False;   return True;}static Bool saneIRConst ( IRConst* con ){   switch (con->tag) {      case Ico_U1:          return toBool( con->Ico.U1 == True || con->Ico.U1 == False );      default:          /* Is there anything we can meaningfully check?  I don't            think so. */         return True;   }}/* Traverse a Stmt/Expr, inspecting IRTemp uses.  Report any out of   range ones.  Report any which are read and for which the current   def_count is zero. */staticvoid useBeforeDef_Temp ( IRBB* bb, IRStmt* stmt, IRTemp tmp, Int* def_counts ){   if (tmp < 0 || tmp >= bb->tyenv->types_used)      sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");   if (def_counts[tmp] < 1)      sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr");}staticvoid useBeforeDef_Expr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts ){   Int i;   switch (expr->tag) {      case Iex_Get:          break;      case Iex_GetI:         useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts);         break;      case Iex_Tmp:         useBeforeDef_Temp(bb,stmt,expr->Iex.Tmp.tmp,def_counts);         break;      case Iex_Binop:         useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);         useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);         break;      case Iex_Unop:         useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);         break;      case Iex_Load:         useBeforeDef_Expr(bb,stmt,expr->Iex.Load.addr,def_counts);         break;      case Iex_Const:         break;      case Iex_CCall:         for (i = 0; expr->Iex.CCall.args[i]; i++)            useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts);         break;      case Iex_Mux0X:         useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts);         useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts);         useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts);         break;      default:         vpanic("useBeforeDef_Expr");   }}staticvoid useBeforeDef_Stmt ( IRBB* bb, IRStmt* stmt, Int* def_counts ){   Int      i;   IRDirty* d;   switch (stmt->tag) {      case Ist_IMark:         break;      case Ist_AbiHint:         useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.base,def_counts);         break;      case Ist_Put:         useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);         break;      case Ist_PutI:         useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.ix,def_counts);         useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.data,def_counts);         break;      case Ist_Tmp:         useBeforeDef_Expr(bb,stmt,stmt->Ist.Tmp.data,def_counts);         break;      case Ist_Store:         useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.addr,def_counts);         useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.data,def_counts);         break;      case Ist_Dirty:         d = stmt->Ist.Dirty.details;         for (i = 0; d->args[i] != NULL; i++)            useBeforeDef_Expr(bb,stmt,d->args[i],def_counts);         if (d->mFx != Ifx_None)            useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);         break;      case Ist_NoOp:      case Ist_MFence:         break;      case Ist_Exit:         useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts);         break;      default:          vpanic("useBeforeDef_Stmt");   }}staticvoid tcExpr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy ){   Int        i;   IRType     t_dst, t_arg1, t_arg2;   IRTypeEnv* tyenv = bb->tyenv;   switch (expr->tag) {      case Iex_Get:      case Iex_Tmp:         break;      case Iex_GetI:         tcExpr(bb,stmt, expr->Iex.GetI

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -