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

📄 ghelpers.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
               Iop_1Uto32,               binop(                  Iop_CmpNE32,                  binop(                     Iop_And32,                     binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_Z)),                     mkU32(1)                  ),                  mkU32(0)               )            );      }      return NULL;   }   /* --------- specialising "x86g_calculate_eflags_c" --------- */   if (vex_streq(function_name, "x86g_calculate_eflags_c")) {      /* specialise calls to above "calculate_eflags_c" function */      IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep;      vassert(arity == 4);      cc_op   = args[0];      cc_dep1 = args[1];      cc_dep2 = args[2];      cc_ndep = args[3];      if (isU32(cc_op, X86G_CC_OP_SUBL)) {         /* C after sub denotes unsigned less than */         return unop(Iop_1Uto32,                     binop(Iop_CmpLT32U, cc_dep1, cc_dep2));      }      if (isU32(cc_op, X86G_CC_OP_SUBB)) {         /* C after sub denotes unsigned less than */         return unop(Iop_1Uto32,                     binop(Iop_CmpLT32U,                            binop(Iop_And32,cc_dep1,mkU32(0xFF)),                           binop(Iop_And32,cc_dep2,mkU32(0xFF))));      }      if (isU32(cc_op, X86G_CC_OP_LOGICL)          || isU32(cc_op, X86G_CC_OP_LOGICW)          || isU32(cc_op, X86G_CC_OP_LOGICB)) {         /* cflag after logic is zero */         return mkU32(0);      }      if (isU32(cc_op, X86G_CC_OP_DECL) || isU32(cc_op, X86G_CC_OP_INCL)) {         /* If the thunk is dec or inc, the cflag is supplied as CC_NDEP. */         return cc_ndep;      }      if (isU32(cc_op, X86G_CC_OP_COPY)) {         /* cflag after COPY is stored in DEP1. */         return            binop(               Iop_And32,               binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)),               mkU32(1)            );      }#     if 0      if (cc_op->tag == Iex_Const) {         vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n");      }#     endif      return NULL;   }   /* --------- specialising "x86g_calculate_eflags_all" --------- */   if (vex_streq(function_name, "x86g_calculate_eflags_all")) {      /* specialise calls to above "calculate_eflags_all" function */      IRExpr *cc_op, *cc_dep1; /*, *cc_dep2, *cc_ndep; */      vassert(arity == 4);      cc_op   = args[0];      cc_dep1 = args[1];      /* cc_dep2 = args[2]; */      /* cc_ndep = args[3]; */      if (isU32(cc_op, X86G_CC_OP_COPY)) {         /* eflags after COPY are stored in DEP1. */         return            binop(               Iop_And32,               cc_dep1,               mkU32(X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z                      | X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P)            );      }      return NULL;   }#  undef unop#  undef binop#  undef mkU32#  undef mkU8   return NULL;}/*---------------------------------------------------------------*//*--- Supporting functions for x87 FPU activities.            ---*//*---------------------------------------------------------------*/static inline Bool host_is_little_endian ( void ){   UInt x = 0x76543210;   UChar* p = (UChar*)(&x);   return toBool(*p == 0x10);}/* 80 and 64-bit floating point formats:   80-bit:    S  0       0-------0      zero    S  0       0X------X      denormals    S  1-7FFE  1X------X      normals (all normals have leading 1)    S  7FFF    10------0      infinity    S  7FFF    10X-----X      snan    S  7FFF    11X-----X      qnan   S is the sign bit.  For runs X----X, at least one of the Xs must be   nonzero.  Exponent is 15 bits, fractional part is 63 bits, and   there is an explicitly represented leading 1, and a sign bit,   giving 80 in total.   64-bit avoids the confusion of an explicitly represented leading 1   and so is simpler:    S  0      0------0   zero    S  0      X------X   denormals    S  1-7FE  any        normals    S  7FF    0------0   infinity    S  7FF    0X-----X   snan    S  7FF    1X-----X   qnan   Exponent is 11 bits, fractional part is 52 bits, and there is a    sign bit, giving 64 in total.*//* Inspect a value and its tag, as per the x87 'FXAM' instruction. *//* CALLED FROM GENERATED CODE: CLEAN HELPER */UInt x86g_calculate_FXAM ( UInt tag, ULong dbl ) {   Bool   mantissaIsZero;   Int    bexp;   UChar  sign;   UChar* f64;   vassert(host_is_little_endian());   /* vex_printf("calculate_FXAM ( %d, %llx ) .. ", tag, dbl ); */   f64  = (UChar*)(&dbl);   sign = toUChar( (f64[7] >> 7) & 1 );   /* First off, if the tag indicates the register was empty,      return 1,0,sign,1 */   if (tag == 0) {      /* vex_printf("Empty\n"); */      return X86G_FC_MASK_C3 | 0 | (sign << X86G_FC_SHIFT_C1)                                  | X86G_FC_MASK_C0;   }   bexp = (f64[7] << 4) | ((f64[6] >> 4) & 0x0F);   bexp &= 0x7FF;   mantissaIsZero      = toBool(           (f64[6] & 0x0F) == 0            && (f64[5] | f64[4] | f64[3] | f64[2] | f64[1] | f64[0]) == 0        );   /* If both exponent and mantissa are zero, the value is zero.      Return 1,0,sign,0. */   if (bexp == 0 && mantissaIsZero) {      /* vex_printf("Zero\n"); */      return X86G_FC_MASK_C3 | 0                              | (sign << X86G_FC_SHIFT_C1) | 0;   }      /* If exponent is zero but mantissa isn't, it's a denormal.      Return 1,1,sign,0. */   if (bexp == 0 && !mantissaIsZero) {      /* vex_printf("Denormal\n"); */      return X86G_FC_MASK_C3 | X86G_FC_MASK_C2                              | (sign << X86G_FC_SHIFT_C1) | 0;   }   /* If the exponent is 7FF and the mantissa is zero, this is an infinity.      Return 0,1,sign,1. */   if (bexp == 0x7FF && mantissaIsZero) {      /* vex_printf("Inf\n"); */      return 0 | X86G_FC_MASK_C2 | (sign << X86G_FC_SHIFT_C1)                                  | X86G_FC_MASK_C0;   }   /* If the exponent is 7FF and the mantissa isn't zero, this is a NaN.      Return 0,0,sign,1. */   if (bexp == 0x7FF && !mantissaIsZero) {      /* vex_printf("NaN\n"); */      return 0 | 0 | (sign << X86G_FC_SHIFT_C1) | X86G_FC_MASK_C0;   }   /* Uh, ok, we give up.  It must be a normal finite number.      Return 0,1,sign,0.   */   /* vex_printf("normal\n"); */   return 0 | X86G_FC_MASK_C2 | (sign << X86G_FC_SHIFT_C1) | 0;}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (reads guest memory) */ULong x86g_dirtyhelper_loadF80le ( UInt addrU ){   ULong f64;   convert_f80le_to_f64le ( (UChar*)ULong_to_Ptr(addrU), (UChar*)&f64 );   return f64;}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (writes guest memory) */void x86g_dirtyhelper_storeF80le ( UInt addrU, ULong f64 ){   convert_f64le_to_f80le( (UChar*)&f64, (UChar*)ULong_to_Ptr(addrU) );}/*----------------------------------------------*//*--- The exported fns ..                    ---*//*----------------------------------------------*//* Layout of the real x87 state. *//* 13 June 05: Fpu_State and auxiliary constants was moved to   g_generic_x87.h *//* CLEAN HELPER *//* fpucw[15:0] contains a x87 native format FPU control word.   Extract from it the required FPROUND value and any resulting   emulation warning, and return (warn << 32) | fpround value. */ULong x86g_check_fldcw ( UInt fpucw ){   /* Decide on a rounding mode.  fpucw[11:10] holds it. */   /* NOTE, encoded exactly as per enum IRRoundingMode. */   UInt rmode = (fpucw >> 10) & 3;   /* Detect any required emulation warnings. */   VexEmWarn ew = EmWarn_NONE;   if ((fpucw & 0x3F) != 0x3F) {      /* unmasked exceptions! */      ew = EmWarn_X86_x87exns;   }   else    if (((fpucw >> 8) & 3) != 3) {      /* unsupported precision */      ew = EmWarn_X86_x87precision;   }   return (((ULong)ew) << 32) | ((ULong)rmode);}/* CLEAN HELPER *//* Given fpround as an IRRoundingMode value, create a suitable x87   native format FPU control word. */UInt x86g_create_fpucw ( UInt fpround ){   fpround &= 3;   return 0x037F | (fpround << 10);}/* CLEAN HELPER *//* mxcsr[15:0] contains a SSE native format MXCSR value.   Extract from it the required SSEROUND value and any resulting   emulation warning, and return (warn << 32) | sseround value.*/ULong x86g_check_ldmxcsr ( UInt mxcsr ){   /* Decide on a rounding mode.  mxcsr[14:13] holds it. */   /* NOTE, encoded exactly as per enum IRRoundingMode. */   UInt rmode = (mxcsr >> 13) & 3;   /* Detect any required emulation warnings. */   VexEmWarn ew = EmWarn_NONE;   if ((mxcsr & 0x1F80) != 0x1F80) {      /* unmasked exceptions! */      ew = EmWarn_X86_sseExns;   }   else    if (mxcsr & (1<<15)) {      /* FZ is set */      ew = EmWarn_X86_fz;   }    else   if (mxcsr & (1<<6)) {      /* DAZ is set */      ew = EmWarn_X86_daz;   }   return (((ULong)ew) << 32) | ((ULong)rmode);}/* CLEAN HELPER *//* Given sseround as an IRRoundingMode value, create a suitable SSE   native format MXCSR value. */UInt x86g_create_mxcsr ( UInt sseround ){   sseround &= 3;   return 0x1F80 | (sseround << 13);}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (writes guest state) *//* Initialise the x87 FPU state as per 'finit'. */void x86g_dirtyhelper_FINIT ( VexGuestX86State* gst ){   Int i;   gst->guest_FTOP = 0;   for (i = 0; i < 8; i++) {      gst->guest_FPTAG[i] = 0; /* empty */      gst->guest_FPREG[i] = 0; /* IEEE754 64-bit zero */   }   gst->guest_FPROUND = (UInt)Irrm_NEAREST;   gst->guest_FC3210  = 0;}/* This is used to implement both 'frstor' and 'fldenv'.  The latter   appears to differ from the former only in that the 8 FP registers   themselves are not transferred into the guest state. */staticVexEmWarn do_put_x87 ( Bool moveRegs,                       /*IN*/UChar* x87_state,                       /*OUT*/VexGuestX86State* vex_state ){   Int        stno, preg;   UInt       tag;   ULong*     vexRegs = (ULong*)(&vex_state->guest_FPREG[0]);   UChar*     vexTags = (UChar*)(&vex_state->guest_FPTAG[0]);   Fpu_State* x87     = (Fpu_State*)x87_state;   UInt       ftop    = (x87->env[FP_ENV_STAT] >> 11) & 7;   UInt       tagw    = x87->env[FP_ENV_TAG];   UInt       fpucw   = x87->env[FP_ENV_CTRL];   UInt       c3210   = x87->env[FP_ENV_STAT] & 0x4700;   VexEmWarn  ew;   UInt       fpround;   ULong      pair;   /* Copy registers and tags */   for (stno = 0; stno < 8; stno++) {      preg = (stno + ftop) & 7;      tag = (tagw >> (2*preg)) & 3;      if (tag == 3) {         /* register is empty */         /* hmm, if it's empty, does it still get written?  Probably            safer to say it does.  If we don't, memcheck could get out            of sync, in that it thinks all FP registers are defined by            this helper, but in reality some have not been updated. */         if (moveRegs)            vexRegs[preg] = 0; /* IEEE754 64-bit zero */         vexTags[preg] = 0;      } else {         /* register is non-empty */         if (moveRegs)            convert_f80le_to_f64le( &x87->reg[10*stno],                                     (UChar*)&vexRegs[preg] );         vexTags[preg] = 1;      }   }   /* stack pointer */   vex_state->guest_FTOP = ftop;

⌨️ 快捷键说明

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