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

📄 toir.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
      case Ity_I8:  return unop(Iop_8Uto32,e);      default: vpanic("widenUto32");   }}/* S-widen 8/16/32 bit int expr to 32. */static IRExpr* widenSto32 ( IRExpr* e ){   switch (typeOfIRExpr(irbb->tyenv,e)) {      case Ity_I32: return e;      case Ity_I16: return unop(Iop_16Sto32,e);      case Ity_I8:  return unop(Iop_8Sto32,e);      default: vpanic("widenSto32");   }}/* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some   of these combinations make sense. */static IRExpr* narrowTo ( IRType dst_ty, IRExpr* e ){   IRType src_ty = typeOfIRExpr(irbb->tyenv,e);   if (src_ty == dst_ty)      return e;   if (src_ty == Ity_I32 && dst_ty == Ity_I16)      return unop(Iop_32to16, e);   if (src_ty == Ity_I32 && dst_ty == Ity_I8)      return unop(Iop_32to8, e);   vex_printf("\nsrc, dst tys are: ");   ppIRType(src_ty);   vex_printf(", ");   ppIRType(dst_ty);   vex_printf("\n");   vpanic("narrowTo(x86)");}/* Set the flags thunk OP, DEP1 and DEP2 fields.  The supplied op is   auto-sized up to the real op. */static void setFlags_DEP1_DEP2 ( IROp op8, IRTemp dep1, IRTemp dep2, IRType ty ){   Int ccOp = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);   vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);   switch (op8) {      case Iop_Add8: ccOp += X86G_CC_OP_ADDB;   break;      case Iop_Sub8: ccOp += X86G_CC_OP_SUBB;   break;      default:       ppIROp(op8);                     vpanic("setFlags_DEP1_DEP2(x86)");   }   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(ccOp)) );   stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(dep1))) );   stmt( IRStmt_Put( OFFB_CC_DEP2, widenUto32(mkexpr(dep2))) );   /* Set NDEP even though it isn't used.  This makes redundant-PUT      elimination of previous stores to this field work better. */   stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));}/* Set the OP and DEP1 fields only, and write zero to DEP2. */static void setFlags_DEP1 ( IROp op8, IRTemp dep1, IRType ty ){   Int ccOp = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);   vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);   switch (op8) {      case Iop_Or8:      case Iop_And8:      case Iop_Xor8: ccOp += X86G_CC_OP_LOGICB; break;      default:       ppIROp(op8);                     vpanic("setFlags_DEP1(x86)");   }   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(ccOp)) );   stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(dep1))) );   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0)) );   /* Set NDEP even though it isn't used.  This makes redundant-PUT      elimination of previous stores to this field work better. */   stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));}/* For shift operations, we put in the result and the undershifted   result.  Except if the shift amount is zero, the thunk is left   unchanged. */static void setFlags_DEP1_DEP2_shift ( IROp    op32,                                       IRTemp  res,                                       IRTemp  resUS,                                       IRType  ty,                                       IRTemp  guard ){   Int ccOp = ty==Ity_I8 ? 2 : (ty==Ity_I16 ? 1 : 0);   vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);   vassert(guard);   /* Both kinds of right shifts are handled by the same thunk      operation. */   switch (op32) {      case Iop_Shr32:      case Iop_Sar32: ccOp = X86G_CC_OP_SHRL - ccOp; break;      case Iop_Shl32: ccOp = X86G_CC_OP_SHLL - ccOp; break;      default:        ppIROp(op32);                      vpanic("setFlags_DEP1_DEP2_shift(x86)");   }   /* DEP1 contains the result, DEP2 contains the undershifted value. */   stmt( IRStmt_Put( OFFB_CC_OP,                     IRExpr_Mux0X( mkexpr(guard),                                   IRExpr_Get(OFFB_CC_OP,Ity_I32),                                   mkU32(ccOp))) );   stmt( IRStmt_Put( OFFB_CC_DEP1,                     IRExpr_Mux0X( mkexpr(guard),                                   IRExpr_Get(OFFB_CC_DEP1,Ity_I32),                                   widenUto32(mkexpr(res)))) );   stmt( IRStmt_Put( OFFB_CC_DEP2,                      IRExpr_Mux0X( mkexpr(guard),                                   IRExpr_Get(OFFB_CC_DEP2,Ity_I32),                                   widenUto32(mkexpr(resUS)))) );   /* Set NDEP even though it isn't used.  This makes redundant-PUT      elimination of previous stores to this field work better. */   stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));}/* For the inc/dec case, we store in DEP1 the result value and in NDEP   the former value of the carry flag, which unfortunately we have to   compute. */static void setFlags_INC_DEC ( Bool inc, IRTemp res, IRType ty ){   Int ccOp = inc ? X86G_CC_OP_INCB : X86G_CC_OP_DECB;      ccOp += ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);   vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);   /* This has to come first, because calculating the C flag       may require reading all four thunk fields. */   stmt( IRStmt_Put( OFFB_CC_NDEP, mk_x86g_calculate_eflags_c()) );   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(ccOp)) );   stmt( IRStmt_Put( OFFB_CC_DEP1, mkexpr(res)) );   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0)) );}/* Multiplies are pretty much like add and sub: DEP1 and DEP2 hold the   two arguments. */staticvoid setFlags_MUL ( IRType ty, IRTemp arg1, IRTemp arg2, UInt base_op ){   switch (ty) {      case Ity_I8:         stmt( IRStmt_Put( OFFB_CC_OP, mkU32(base_op+0) ) );         break;      case Ity_I16:         stmt( IRStmt_Put( OFFB_CC_OP, mkU32(base_op+1) ) );         break;      case Ity_I32:         stmt( IRStmt_Put( OFFB_CC_OP, mkU32(base_op+2) ) );         break;      default:         vpanic("setFlags_MUL(x86)");   }   stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(arg1)) ));   stmt( IRStmt_Put( OFFB_CC_DEP2, widenUto32(mkexpr(arg2)) ));   /* Set NDEP even though it isn't used.  This makes redundant-PUT      elimination of previous stores to this field work better. */   stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));}/* -------------- Condition codes. -------------- *//* Condition codes, using the Intel encoding.  */static HChar* name_X86Condcode ( X86Condcode cond ){   switch (cond) {      case X86CondO:      return "o";      case X86CondNO:     return "no";      case X86CondB:      return "b";      case X86CondNB:     return "nb";      case X86CondZ:      return "z";      case X86CondNZ:     return "nz";      case X86CondBE:     return "be";      case X86CondNBE:    return "nbe";      case X86CondS:      return "s";      case X86CondNS:     return "ns";      case X86CondP:      return "p";      case X86CondNP:     return "np";      case X86CondL:      return "l";      case X86CondNL:     return "nl";      case X86CondLE:     return "le";      case X86CondNLE:    return "nle";      case X86CondAlways: return "ALWAYS";      default: vpanic("name_X86Condcode");   }}static X86Condcode positiveIse_X86Condcode ( X86Condcode  cond,                                      Bool*        needInvert ){   vassert(cond >= X86CondO && cond <= X86CondNLE);   if (cond & 1) {      *needInvert = True;      return cond-1;   } else {      *needInvert = False;      return cond;   }}/* -------------- Helpers for ADD/SUB with carry. -------------- *//* Given ta1, ta2 and tres, compute tres = ADC(ta1,ta2) and set flags   appropriately.*/static void helper_ADC ( Int sz,                         IRTemp tres, IRTemp ta1, IRTemp ta2 ){   UInt    thunkOp;   IRType  ty    = szToITy(sz);   IRTemp  oldc  = newTemp(Ity_I32);   IRTemp  oldcn = newTemp(ty);   IROp    plus  = mkSizedOp(ty, Iop_Add8);   IROp    xor   = mkSizedOp(ty, Iop_Xor8);   vassert(sz == 1 || sz == 2 || sz == 4);   thunkOp = sz==4 ? X86G_CC_OP_ADCL                    : (sz==2 ? X86G_CC_OP_ADCW : X86G_CC_OP_ADCB);   /* oldc = old carry flag, 0 or 1 */   assign( oldc,  binop(Iop_And32,                        mk_x86g_calculate_eflags_c(),                        mkU32(1)) );   assign( oldcn, narrowTo(ty, mkexpr(oldc)) );   assign( tres, binop(plus,                       binop(plus,mkexpr(ta1),mkexpr(ta2)),                       mkexpr(oldcn)) );   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(thunkOp) ) );   stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(ta1)) ));   stmt( IRStmt_Put( OFFB_CC_DEP2, widenUto32(binop(xor, mkexpr(ta2),                                                          mkexpr(oldcn)) )) );   stmt( IRStmt_Put( OFFB_CC_NDEP, mkexpr(oldc) ) );}/* Given ta1, ta2 and tres, compute tres = SBB(ta1,ta2) and set flags   appropriately.*/static void helper_SBB ( Int sz,                         IRTemp tres, IRTemp ta1, IRTemp ta2 ){   UInt    thunkOp;   IRType  ty    = szToITy(sz);   IRTemp  oldc  = newTemp(Ity_I32);   IRTemp  oldcn = newTemp(ty);   IROp    minus = mkSizedOp(ty, Iop_Sub8);   IROp    xor   = mkSizedOp(ty, Iop_Xor8);   vassert(sz == 1 || sz == 2 || sz == 4);   thunkOp = sz==4 ? X86G_CC_OP_SBBL                    : (sz==2 ? X86G_CC_OP_SBBW : X86G_CC_OP_SBBB);   /* oldc = old carry flag, 0 or 1 */   assign( oldc, binop(Iop_And32,                       mk_x86g_calculate_eflags_c(),                       mkU32(1)) );   assign( oldcn, narrowTo(ty, mkexpr(oldc)) );   assign( tres, binop(minus,                       binop(minus,mkexpr(ta1),mkexpr(ta2)),                       mkexpr(oldcn)) );   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(thunkOp) ) );   stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(ta1) )) );   stmt( IRStmt_Put( OFFB_CC_DEP2, widenUto32(binop(xor, mkexpr(ta2),                                                          mkexpr(oldcn)) )) );   stmt( IRStmt_Put( OFFB_CC_NDEP, mkexpr(oldc) ) );}/* -------------- Helpers for disassembly printing. -------------- */static HChar* nameGrp1 ( Int opc_aux ){   static HChar* grp1_names[8]      = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" };   if (opc_aux < 0 || opc_aux > 7) vpanic("nameGrp1(x86)");   return grp1_names[opc_aux];}static HChar* nameGrp2 ( Int opc_aux ){   static HChar* grp2_names[8]      = { "rol", "ror", "rcl", "rcr", "shl", "shr", "shl", "sar" };   if (opc_aux < 0 || opc_aux > 7) vpanic("nameGrp2(x86)");   return grp2_names[opc_aux];}static HChar* nameGrp4 ( Int opc_aux ){   static HChar* grp4_names[8]      = { "inc", "dec", "???", "???", "???", "???", "???", "???" };   if (opc_aux < 0 || opc_aux > 1) vpanic("nameGrp4(x86)");   return grp4_names[opc_aux];}static HChar* nameGrp5 ( Int opc_aux ){   static HChar* grp5_names[8]      = { "inc", "dec", "call*", "call*", "jmp*", "jmp*", "push", "???" };   if (opc_aux < 0 || opc_aux > 6) vpanic("nameGrp5(x86)");   return grp5_names[opc_aux];}static HChar* nameGrp8 ( Int opc_aux ){   static HChar* grp8_names[8]      = { "???", "???", "???", "???", "bt", "bts", "btr", "btc" };   if (opc_aux < 4 || opc_aux > 7) vpanic("nameGrp8(x86)");   return grp8_names[opc_aux];}static HChar* nameIReg ( Int size, Int reg ){   static HChar* ireg32_names[8]      = { "%eax", "%ecx", "%edx", "%ebx",          "%esp", "%ebp", "%esi", "%edi" };   static HChar* ireg16_names[8]      = { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di" };   static HChar* ireg8_names[8]      = { "%al", "%cl", "%dl", "%bl",          "%ah{sp}", "%ch{bp}", "%dh{si}", "%bh{di}" };   if (reg < 0 || reg > 7) goto bad;   switch (size) {      case 4: return ireg32_names[reg];      case 2: return ireg16_names[reg];      case 1: return ireg8_names[reg];   }  bad:   vpanic("nameIReg(X86)");   return NULL; /*notreached*/}static HChar* nameSReg ( UInt sreg ){   switch (sreg) {      case R_ES: return "%es";      case R_CS: return "%cs";      case R_SS: return "%ss";      case R_DS: return "%ds";      case R_FS: return "%fs";      case R_GS: return "%gs";      default: vpanic("nameSReg(x86)");   }}static HChar* nameMMXReg ( Int mmxreg ){   static HChar* mmx_names[8]      = { "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" };   if (mmxreg < 0 || mmxreg > 7) vpanic("nameMMXReg(x86,guest)");   return mmx_names[mmxreg];}static HChar* nameXMMReg ( Int xmmreg ){   static HChar* xmm_names[8]      = { "%xmm0", "%xmm1", "%xmm2", "%xmm3",          "%xmm4", "%xmm5", "%xmm6", "%xmm7" };   if (xmmreg < 0 || xmmreg > 7) vpanic("name_of_xmm_reg");   return xmm_names[xmmreg];} static HChar* nameMMXGran ( Int gran ){   switch (gran) {      case 0: return "b";      case 1: return "w";      case 2: return "d";      case 3: return "q";      default: vpanic("nameMMXGran(x86,guest)");   }}static HChar nameISize ( Int size ){   switch (size) {      case 4: return 'l';      case 2: return 'w';      case 1: return 'b';      default: vpanic("nameISize(x86)");   }}/*------------------------------------------------------------*/

⌨️ 快捷键说明

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