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

📄 ghelpers.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
   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_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_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;   Double*    vexRegs = (Double*)(&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.0;         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;   /* status word */   vex_state->guest_FC3210 = c3210;   /* handle the control word, setting FPROUND and detecting any      emulation warnings. */   pair    = x86g_check_fldcw ( (UInt)fpucw );   fpround = (UInt)pair;   ew      = (VexEmWarn)(pair >> 32);      vex_state->guest_FPROUND = fpround & 3;   /* emulation warnings --> caller */   return ew;}/* Create an x87 FPU state from the guest state, as close as   we can approximate it. */staticvoid do_get_x87 ( /*IN*/VexGuestX86State* vex_state,                  /*OUT*/UChar* x87_state ){   Int        i, stno, preg;   UInt       tagw;   Double*    vexRegs = (Double*)(&vex_state->guest_FPREG[0]);   UChar*     vexTags = (UChar*)(&vex_state->guest_FPTAG[0]);   Fpu_State* x87     = (Fpu_State*)x87_state;   UInt       ftop    = vex_state->guest_FTOP;   UInt       c3210   = vex_state->guest_FC3210;   for (i = 0; i < 14; i++)      x87->env[i] = 0;   x87->env[1] = x87->env[3] = x87->env[5] = x87->env[13] = 0xFFFF;   x87->env[FP_ENV_STAT]       = toUShort(((ftop & 7) << 11) | (c3210 & 0x4700));   x87->env[FP_ENV_CTRL]       = toUShort(x86g_create_fpucw( vex_state->guest_FPROUND ));   /* Dump the register stack in ST order. */   tagw = 0;   for (stno = 0; stno < 8; stno++) {      preg = (stno + ftop) & 7;      if (vexTags[preg] == 0) {         /* register is empty */         tagw |= (3 << (2*preg));         convert_f64le_to_f80le( (UChar*)&vexRegs[preg],                                  &x87->reg[10*stno] );      } else {         /* register is full. */         tagw |= (0 << (2*preg));         convert_f64le_to_f80le( (UChar*)&vexRegs[preg],                                  &x87->reg[10*stno] );      }   }   x87->env[FP_ENV_TAG] = toUShort(tagw);}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (reads guest state, writes guest mem) */void x86g_dirtyhelper_FXSAVE ( VexGuestX86State* gst, HWord addr ){   /* Somewhat roundabout, but at least it's simple. */   Fpu_State tmp;   UShort*   addrS = (UShort*)addr;   UChar*    addrC = (UChar*)addr;   U128*     xmm   = (U128*)(addr + 160);   UInt      mxcsr;   UShort    fp_tags;   UInt      summary_tags;   Int       r, stno;   UShort    *srcS, *dstS;   do_get_x87( gst, (UChar*)&tmp );   mxcsr = x86g_create_mxcsr( gst->guest_SSEROUND );   /* Now build the proper fxsave image from the x87 image we just      made. */   addrS[0]  = tmp.env[FP_ENV_CTRL]; /* FCW: fpu control word */   addrS[1]  = tmp.env[FP_ENV_STAT]; /* FCW: fpu status word */   /* set addrS[2] in an endian-independent way */   summary_tags = 0;   fp_tags = tmp.env[FP_ENV_TAG];   for (r = 0; r < 8; r++) {      if ( ((fp_tags >> (2*r)) & 3) != 3 )         summary_tags |= (1 << r);   }   addrC[4]  = toUChar(summary_tags); /* FTW: tag summary byte */   addrC[5]  = 0; /* pad */   addrS[3]  = 0; /* FOP: fpu opcode (bogus) */   addrS[4]  = 0;   addrS[5]  = 0; /* FPU IP (bogus) */   addrS[6]  = 0; /* FPU IP's segment selector (bogus) (although we                     could conceivably dump %CS here) */   addrS[7]  = 0; /* Intel reserved */   addrS[8]  = 0; /* FPU DP (operand pointer) (bogus) */   addrS[9]  = 0; /* FPU DP (operand pointer) (bogus) */   addrS[10] = 0; /* segment selector for above operand pointer; %DS                     perhaps? */   addrS[11] = 0; /* Intel reserved */   addrS[12] = toUShort(mxcsr);  /* MXCSR */   addrS[13] = toUShort(mxcsr >> 16);   addrS[14] = 0xFFFF; /* MXCSR mask (lo16); who knows what for */   addrS[15] = 0xFFFF; /* MXCSR mask (hi16); who knows what for */   /* Copy in the FP registers, in ST order. */   for (stno = 0; stno < 8; stno++) {      srcS = (UShort*)(&tmp.reg[10*stno]);      dstS = (UShort*)(&addrS[16 + 8*stno]);      dstS[0] = srcS[0];      dstS[1] = srcS[1];      dstS[2] = srcS[2];      dstS[3] = srcS[3];      dstS[4] = srcS[4];      dstS[5] = 0;      dstS[6] = 0;      dstS[7] = 0;   }   /* That's the first 160 bytes of the image done.  Now only %xmm0      .. %xmm7 remain to be copied.  If the host is big-endian, these      need to be byte-swapped. */   vassert(host_is_little_endian());#  define COPY_U128(_dst,_src)                       \      do { _dst[0] = _src[0]; _dst[1] = _src[1];     \           _dst[2] = _src[2]; _dst[3] = _src[3]; }   \      while (0)   COPY_U128( xmm[0], gst->guest_XMM0 );   COPY_U128( xmm[1], gst->guest_XMM1 );   COPY_U128( xmm[2], gst->guest_XMM2 );   COPY_U128( xmm[3], gst->guest_XMM3 );   COPY_U128( xmm[4], gst->guest_XMM4 );   COPY_U128( xmm[5], gst->guest_XMM5 );   COPY_U128( xmm[6], gst->guest_XMM6 );   COPY_U128( xmm[7], gst->guest_XMM7 );#  undef COPY_U128}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (reads guest state, writes guest mem) */void x86g_dirtyhelper_FSAVE ( VexGuestX86State* gst, HWord addr ){   do_get_x87( gst, (UChar*)addr );}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (writes guest state, reads guest mem) */VexEmWarn x86g_dirtyhelper_FRSTOR ( VexGuestX86State* gst, HWord addr ){   return do_put_x87( True/*regs too*/, (UChar*)addr, gst );

⌨️ 快捷键说明

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