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

📄 ghelpers.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
   /* 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;   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    = 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 );}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (reads guest state, writes guest mem) */void x86g_dirtyhelper_FSTENV ( VexGuestX86State* gst, HWord addr ){   /* Somewhat roundabout, but at least it's simple. */   Int       i;   UShort*   addrP = (UShort*)addr;   Fpu_State tmp;   do_get_x87( gst, (UChar*)&tmp );   for (i = 0; i < 14; i++)      addrP[i] = tmp.env[i];}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (writes guest state, reads guest mem) */VexEmWarn x86g_dirtyhelper_FLDENV ( VexGuestX86State* gst, HWord addr ){   return do_put_x87( False/*don't move regs*/, (UChar*)addr, gst);}/*---------------------------------------------------------------*//*--- Misc integer helpers, including rotates and CPUID.      ---*//*---------------------------------------------------------------*//* CALLED FROM GENERATED CODE: CLEAN HELPER *//* Calculate both flags and value result for rotate right   through the carry bit.  Result in low 32 bits,    new flags (OSZACP) in high 32 bits.*/ULong x86g_calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ){   UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf;   switch (sz) {      case 4:         cf        = (eflags_in >> X86G_CC_SHIFT_C) & 1;         of        = ((arg >> 31) ^ cf) & 1;         while (tempCOUNT > 0) {            tempcf = arg & 1;            arg    = (arg >> 1) | (cf << 31);            cf     = tempcf;            tempCOUNT--;         }         break;      case 2:         while (tempCOUNT >= 17) tempCOUNT -= 17;         cf        = (eflags_in >> X86G_CC_SHIFT_C) & 1;         of        = ((arg >> 15) ^ cf) & 1;         while (tempCOUNT > 0) {            tempcf = arg & 1;            arg    = ((arg >> 1) & 0x7FFF) | (cf << 15);            cf     = tempcf;            tempCOUNT--;         }         break;      case 1:         while (tempCOUNT >= 9) tempCOUNT -= 9;         cf        = (eflags_in >> X86G_CC_SHIFT_C) & 1;         of        = ((arg >> 7) ^ cf) & 1;         while (tempCOUNT > 0) {            tempcf = arg & 1;            arg    = ((arg >> 1) & 0x7F) | (cf << 7);            cf     = tempcf;            tempCOUNT--;         }         break;      default:          vpanic("calculate_RCR: invalid size");   }   cf &= 1;   of &= 1;   eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O);   eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O);   return (((ULong)eflags_in) << 32) | ((ULong)arg);}/* CALLED FROM GENERATED CODE: CLEAN HELPER *//* Calculate both flags and value result for rotate left   through the carry bit.  Result in low 32 bits,    new flags (OSZACP) in high 32 bits.*/ULong x86g_calculate_RCL ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ){   UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf;   switch (sz) {      case 4:         cf = (eflags_in >> X86G_CC_SHIFT_C) & 1;         while (tempCOUNT > 0) {            tempcf = (arg >> 31) & 1;            arg    = (arg << 1) | (cf & 1);            cf     = tempcf;            tempCOUNT--;         }         of = ((arg >> 31) ^ cf) & 1;         break;      case 2:         while (tempCOUNT >= 17) tempCOUNT -= 17;         cf = (eflags_in >> X86G_CC_SHIFT_C) & 1;         while (tempCOUNT > 0) {            tempcf = (arg >> 15) & 1;            arg    = 0xFFFF & ((arg << 1) | (cf & 1));            cf     = tempcf;            tempCOUNT--;         }         of = ((arg >> 15) ^ cf) & 1;         break;      case 1:         while (tempCOUNT >= 9) tempCOUNT -= 9;         cf = (eflags_in >> X86G_CC_SHIFT_C) & 1;         while (tempCOUNT > 0) {            tempcf = (arg >> 7) & 1;            arg    = 0xFF & ((arg << 1) | (cf & 1));            cf     = tempcf;            tempCOUNT--;         }         of = ((arg >> 7) ^ cf) & 1;         break;      default:          vpanic("calculate_RCL: invalid size");   }   cf &= 1;   of &= 1;   eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O);   eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O);   return (((ULong)eflags_in) << 32) | ((ULong)arg);}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (non-referentially-transparent) *//* Horrible hack.  On non-x86 platforms, return 1. */ULong x86g_dirtyhelper_RDTSC ( void ){#  if defined(__i386__)   ULong res;   __asm__ __volatile__("rdtsc" : "=A" (res));   return res;#  else   return 1ULL;#  endif}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (modifies guest state) *//* Claim to be a P55C (Intel Pentium/MMX) */void x86g_dirtyhelper_CPUID_sse0 ( VexGuestX86State* st ){   switch (st->guest_EAX) {      case 0:          st->guest_EAX = 0x1;         st->guest_EBX = 0x756e6547;         st->guest_ECX = 0x6c65746e;         st->guest_EDX = 0x49656e69;         break;      default:         st->guest_EAX = 0x543;         st->guest_EBX = 0x0;         st->guest_ECX = 0x0;         st->guest_EDX = 0x8001bf;         break;   }}/* CALLED FROM GENERATED CODE *//* DIRTY HELPER (modifies guest state) *//* Claim to be the following SSE1-capable CPU:   vendor_id       : GenuineIntel   cpu family      : 6   model           : 11   model name      : Intel(R) Pentium(R) III CPU family      1133MHz   stepping        : 1   cpu MHz         : 1131.013   cache size      : 512 KB*/void x86g_dirtyhelper_CPUID_sse1 ( VexGuestX86State* st ){   switch (st->guest_EAX) {      case 0:          st->guest_EAX = 0x00000002;         st->guest_EBX = 0x756e6547;         st->guest_ECX = 0x6c65746e;         st->guest_EDX = 0x49656e69;         break;      case 1:          st->guest_EAX = 0x000006b1;         st->guest_EBX = 0x00000004;         st->guest_ECX = 0x00000000;         st->guest_EDX = 0x0383fbff;         break;      default:         st->guest_EAX = 0x03020101;         st->guest_EBX = 0x00000000;         st->guest_ECX = 0x00000000;         st->guest_EDX = 0x0c040883;         break;   }}/* Claim to be the following SSE2-capable CPU:   vendor_id       : GenuineIntel   cpu family      : 15   model           : 2   model name      : Intel(R) Pentium(R) 4 CPU 2.40GHz   stepping        : 7   cpu MHz  

⌨️ 快捷键说明

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