📄 ghelpers.c
字号:
}/* 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 *//* 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 : 2394.234 cache size : 512 KB*/void x86g_dirtyhelper_CPUID_sse2 ( 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 = 0x00000f27; st->guest_EBX = 0x00010809; st->guest_ECX = 0x00004400; st->guest_EDX = 0xbfebfbff; break; default: st->guest_EAX = 0x665b5101; st->guest_EBX = 0x00000000; st->guest_ECX = 0x00000000; st->guest_EDX = 0x007b7040; break; }}/*---------------------------------------------------------------*//*--- Helpers for MMX/SSE/SSE2. ---*//*---------------------------------------------------------------*/static inline UChar abdU8 ( UChar xx, UChar yy ) { return toUChar(xx>yy ? xx-yy : yy-xx);}static inline ULong mk32x2 ( UInt w1, UInt w0 ) { return (((ULong)w1) << 32) | ((ULong)w0);}static inline UShort sel16x4_3 ( ULong w64 ) { UInt hi32 = toUInt(w64 >> 32); return toUShort(hi32 >> 16);}static inline UShort sel16x4_2 ( ULong w64 ) { UInt hi32 = toUInt(w64 >> 32); return toUShort(hi32);}static inline UShort sel16x4_1 ( ULong w64 ) { UInt lo32 = toUInt(w64); return toUShort(lo32 >> 16);}static inline UShort sel16x4_0 ( ULong w64 ) { UInt lo32 = toUInt(w64); return toUShort(lo32);}static inline UChar sel8x8_7 ( ULong w64 ) { UInt hi32 = toUInt(w64 >> 32); return toUChar(hi32 >> 24);}static inline UChar sel8x8_6 ( ULong w64 ) { UInt hi32 = toUInt(w64 >> 32); return toUChar(hi32 >> 16);}static inline UChar sel8x8_5 ( ULong w64 ) { UInt hi32 = toUInt(w64 >> 32); return toUChar(hi32 >> 8);}static inline UChar sel8x8_4 ( ULong w64 ) { UInt hi32 = toUInt(w64 >> 32); return toUChar(hi32 >> 0);}static inline UChar sel8x8_3 ( ULong w64 ) { UInt lo32 = toUInt(w64); return toUChar(lo32 >> 24);}static inline UChar sel8x8_2 ( ULong w64 ) { UInt lo32 = toUInt(w64); return toUChar(lo32 >> 16);}static inline UChar sel8x8_1 ( ULong w64 ) { UInt lo32 = toUInt(w64); return toUChar(lo32 >> 8);}static inline UChar sel8x8_0 ( ULong w64 ) { UInt lo32 = toUInt(w64); return toUChar(lo32 >> 0);}/* CALLED FROM GENERATED CODE: CLEAN HELPER */ULong x86g_calculate_mmx_pmaddwd ( ULong xx, ULong yy ){ return mk32x2( (((Int)(Short)sel16x4_3(xx)) * ((Int)(Short)sel16x4_3(yy))) + (((Int)(Short)sel16x4_2(xx)) * ((Int)(Short)sel16x4_2(yy))), (((Int)(Short)sel16x4_1(xx)) * ((Int)(Short)sel16x4_1(yy))) + (((Int)(Short)sel16x4_0(xx)) * ((Int)(Short)sel16x4_0(yy))) );}/* CALLED FROM GENERATED CODE: CLEAN HELPER */UInt x86g_calculate_mmx_pmovmskb ( ULong xx ){ UInt r = 0; if (xx & (1ULL << (64-1))) r |= (1<<7); if (xx & (1ULL << (56-1))) r |= (1<<6); if (xx & (1ULL << (48-1))) r |= (1<<5); if (xx & (1ULL << (40-1))) r |= (1<<4); if (xx & (1ULL << (32-1))) r |= (1<<3); if (xx & (1ULL << (24-1))) r |= (1<<2); if (xx & (1ULL << (16-1))) r |= (1<<1); if (xx & (1ULL << ( 8-1))) r |= (1<<0); return r;}/* CALLED FROM GENERATED CODE: CLEAN HELPER */ULong x86g_calculate_mmx_psadbw ( ULong xx, ULong yy ){ UInt t = 0; t += (UInt)abdU8( sel8x8_7(xx), sel8x8_7(yy) ); t += (UInt)abdU8( sel8x8_6(xx), sel8x8_6(yy) ); t += (UInt)abdU8( sel8x8_5(xx), sel8x8_5(yy) ); t += (UInt)abdU8( sel8x8_4(xx), sel8x8_4(yy) ); t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); t &= 0xFFFF; return (ULong)t;}/* CALLED FROM GENERATED CODE: CLEAN HELPER */UInt x86g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo ){ UInt rHi8 = x86g_calculate_mmx_pmovmskb ( w64hi ); UInt rLo8 = x86g_calculate_mmx_pmovmskb ( w64lo ); return ((rHi8 & 0xFF) << 8) | (rLo8 & 0xFF);}/*---------------------------------------------------------------*//*--- Helpers for dealing with segment overrides. ---*//*---------------------------------------------------------------*/static inline UInt get_segdescr_base ( VexGuestX86SegDescr* ent ){ UInt lo = 0xFFFF & (UInt)ent->LdtEnt.Bits.BaseLow; UInt mid = 0xFF & (UInt)ent->LdtEnt.Bits.BaseMid; UInt hi = 0xFF & (UInt)ent->LdtEnt.Bits.BaseHi; return (hi << 24) | (mid << 16) | lo;}static inlineUInt get_segdescr_limit ( VexGuestX86SegDescr* ent ){ UInt lo = 0xFFFF & (UInt)ent->LdtEnt.Bits.LimitLow; UInt hi = 0xF & (UInt)ent->LdtEnt.Bits.LimitHi; UInt limit = (hi << 16) | lo; if (ent->LdtEnt.Bits.Granularity) limit = (limit << 12) | 0xFFF; return limit;}/* CALLED FROM GENERATED CODE: CLEAN HELPER */ULong x86g_use_seg_selector ( HWord ldt, HWord gdt, UInt seg_selector, UInt virtual_addr ){ UInt tiBit, base, limit; VexGuestX86SegDescr* the_descrs; Bool verboze = False; /* If this isn't true, we're in Big Trouble. */ vassert(8 == sizeof(VexGuestX86SegDescr)); if (verboze) vex_printf("x86h_use_seg_selector: " "seg_selector = 0x%x, vaddr = 0x%x\n", seg_selector, virtual_addr); /* Check for wildly invalid selector. */ if (seg_selector & ~0xFFFF) goto bad; seg_selector &= 0x0000FFFF; /* Sanity check the segment selector. Ensure that RPL=11b (least privilege). This forms the bottom 2 bits of the selector. */ if ((seg_selector & 3) != 3) goto bad; /* Extract the TI bit (0 means GDT, 1 means LDT) */ tiBit = (seg_selector >> 2) & 1; /* Convert the segment selector onto a table index */ seg_selector >>= 3; vassert(seg_selector >= 0 && seg_selector < 8192); if (tiBit == 0) { /* GDT access. */ /* Do we actually have a GDT to look at? */ if (gdt == 0) goto bad; /* Check for access to non-existent entry. */ if (seg_selector >= VEX_GUEST_X86_GDT_NENT) goto bad; the_descrs = (VexGuestX86SegDescr*)gdt; base = get_segdescr_base (&the_descrs[seg_selector]); limit = get_segdescr_limit(&the_descrs[seg_selector]); } else { /* All the same stuff, except for the LDT. */ if (ldt == 0) goto bad; if (seg_selector >= VEX_GUEST_X86_LDT_NENT) goto bad; the_descrs = (VexGuestX86SegDescr*)ldt; base = get_segdescr_base (&the_descrs[seg_selector]); limit = get_segdescr_limit(&the_descrs[seg_selector]); } /* Do the limit check. Note, this check is just slightly too slack. Really it should be "if (virtual_addr + size - 1 >= limit)," but we don't have the size info to hand. Getting it could be significantly complex. */ if (virtual_addr >= limit) goto bad; if (verboze) vex_printf("x86h_use_seg_selector: " "base = 0x%x, addr = 0x%x\n", base, base + virtual_addr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -