diff options
| author | serpilliere <devnull@localhost> | 2013-02-14 16:01:29 +0100 |
|---|---|---|
| committer | serpilliere <devnull@localhost> | 2013-02-14 16:01:29 +0100 |
| commit | d71e9f462bd977b581b93839bad49afe4646a797 (patch) | |
| tree | 56dc3dd4fb90b86001ed4bb98b2185f0a23aa00d | |
| parent | bd6a2adb96b1b2caa7964b86e62f84d5af541214 (diff) | |
| download | miasm-d71e9f462bd977b581b93839bad49afe4646a797.tar.gz miasm-d71e9f462bd977b581b93839bad49afe4646a797.zip | |
fix float issues
Diffstat (limited to '')
| -rw-r--r-- | miasm/arch/ia32_arch.py | 32 | ||||
| -rw-r--r-- | miasm/arch/ia32_sem.py | 80 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat.c | 75 |
3 files changed, 143 insertions, 44 deletions
diff --git a/miasm/arch/ia32_arch.py b/miasm/arch/ia32_arch.py index a447447d..2493948e 100644 --- a/miasm/arch/ia32_arch.py +++ b/miasm/arch/ia32_arch.py @@ -166,7 +166,8 @@ unsanity_mnemo = ['nop', 'monitor', 'mwait', 'fadd', 'faddp', 'fiadd', 'fcmovb', 'fnstsw', 'fsub', 'fsubr', 'fisubr', 'fsubrp', 'ftst', 'fucom', 'fucompp', 'fxam', 'fxtract', 'fyl2x', 'fyl2xp1', 'fsqrt', 'fsincos', 'fsin', 'fscale', 'fcos', 'fdecstp', 'fnop', 'fpatan', 'fprem', 'fprem1', 'fptan', 'frndint', "shl", 'sal', 'sar', 'fabs', "jmpff", - "fcomi", "fucomi", "fucomip", "fdivp"] + "fcomi", "fucomi", "fucomip", "fdivp", + "fisubr", "fsubp"] mask_drcrsg = {cr:0x100, dr:0x200, sg:0x400} @@ -1096,7 +1097,7 @@ class x86allmncs: addop("fadd", [0xD8], d0, no_rm , {sd:(0,2)} ,{} , {}, ) addop("fadd", [0xD8, 0xC0], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) addop("fiadd", [0xDA], d0, no_rm , {wd:(0,2)} ,{} , {}, ) - addop("faddp", [0xDE, 0xC0], reg, no_rm , {} ,{sd:False} , {}, ) + addop("faddp", [0xDE, 0xC0], reg, [r_eax] , {} ,{sd:False,sw:True}, {}, ) addop("fbld", [0xDF], d4, no_rm , {} ,{} , {}, ) addop("fbstp", [0xDF], d6, no_rm , {} ,{} , {}, ) @@ -1130,7 +1131,7 @@ class x86allmncs: addop("fdiv", [0xDC, 0xF8], reg, [r_eax] , { } ,{sd:True,sw:True }, {}, ) addop("fidiv", [0xDA], d6, no_rm , {wd:(0,2)} ,{} , {}, ) addop("fidivr",[0xDA], d7, no_rm , {wd:(0,2)} ,{} , {}, ) - addop("fdivp", [0xDE, 0xF8], reg, no_rm , {} ,{sd:True} , {}, ) + addop("fdivp", [0xDE, 0xF8], reg, [r_eax] , {} ,{sd:True,sw:True} , {}, ) addop("fdiv", [0xD8, 0xF0], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) addop("fdivr", [0xD8, 0xF8], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) @@ -1161,7 +1162,7 @@ class x86allmncs: addop("fmul", [0xD8], d1, no_rm , {sd:(0,2)} ,{} , {}, ) addop("fmul", [0xD8, 0xC8], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) addop("fimul", [0xDA], d1, no_rm , {wd:(0,2)} ,{} , {}, ) - addop("fmulp", [0xDE, 0xC8], reg, no_rm , {} ,{sd:False} , {}, ) + addop("fmulp", [0xDE, 0xC8], reg, [r_eax] , {} ,{sd:False,sw:True}, {}, ) addop("frstor",[0xDD], d4, no_rm , {} ,{wd:False} , {}, ) #XXX 94/108 @@ -1172,7 +1173,7 @@ class x86allmncs: addop("fst", [0xD9], d2, no_rm , {sd:(0,2)} ,{} , {}, ) addop("fst", [0xDD, 0xD0], reg, no_rm , {} ,{sd:False} , {}, ) - addop("fstp", [0xD9], d3, no_rm , {sd:(0,2)} ,{sd:False} , {}, ) + addop("fstp", [0xD9], d3, no_rm , {sd:(0,2)} ,{sd:True} , {}, ) addop("fstp", [0xDB], d7, no_rm , {} ,{sd:False} , {}, ) #XXX 80 addop("fstp", [0xDD, 0xD8], reg, no_rm , {} ,{sd:True} , {}, ) @@ -1226,14 +1227,25 @@ class x86allmncs: #ddop("fstsw",[0x9B, 0xDF, 0xE0], noafs, no_rm , {} ,{wd:False} , {}, ) #XXX no mnemo addop("fnstsw",[0xDF, 0xE0], noafs, no_rm , {} ,{wd:False} , {}, ) + #addop("fsub", [0xD8], d4, no_rm , {sd:(0,2)} ,{} , {}, ) + #addop("fsubr", [0xD8], d5, no_rm , {sd:(0,2)} ,{} , {}, ) + #addop("fsub", [0xD8, 0xE0], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) + #addop("fisub", [0xDA], d4, no_rm , {wd:(0,2)} ,{} , {}, ) + #addop("fsubp", [0xDE, 0xE8], reg, [r_eax] , {} ,{sd:False,sw:True}, {}, ) + # + #addop("fsubr", [0xD8, 0xE8], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) + #addop("fisubr",[0xDA], d5, no_rm , {wd:(0,2)} ,{} , {}, ) + #addop("fsubrp",[0xDE, 0xE0], reg, no_rm , {} ,{sd:False} , {}, ) addop("fsub", [0xD8], d4, no_rm , {sd:(0,2)} ,{} , {}, ) - addop("fsub", [0xD8, 0xE0], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) - addop("fisub", [0xDA], d4, no_rm , {wd:(0,2)} ,{} , {}, ) - addop("fsubp", [0xDE, 0xE8], reg, no_rm , {} ,{sd:False} , {}, ) - addop("fsubr", [0xD8], d5, no_rm , {sd:(0,2)} ,{} , {}, ) - addop("fsubr", [0xD8, 0xE8], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) + addop("fsub", [0xDC, 0xE8], reg, [r_eax] , { } ,{sd:True,sw:True }, {}, ) + addop("fisub", [0xDA], d4, no_rm , {wd:(0,2)} ,{} , {}, ) addop("fisubr",[0xDA], d5, no_rm , {wd:(0,2)} ,{} , {}, ) + addop("fsubp", [0xDE, 0xE8], reg, [r_eax] , {} ,{sd:True,sw:True} , {}, ) + + addop("fsub", [0xD8, 0xE0], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) + addop("fsubr", [0xD8, 0xE8], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) + addop("fsubr", [0xDC, 0xE0], reg, [r_eax] , { } ,{sd:True,sw:True }, {}, ) addop("fsubrp",[0xDE, 0xE0], reg, no_rm , {} ,{sd:False} , {}, ) addop("ftst", [0xD9, 0xE4], noafs, no_rm , {} ,{sd:False} , {}, ) diff --git a/miasm/arch/ia32_sem.py b/miasm/arch/ia32_sem.py index b66fd8dd..059661e4 100644 --- a/miasm/arch/ia32_sem.py +++ b/miasm/arch/ia32_sem.py @@ -269,6 +269,17 @@ float_st5 = ExprId(reg_float_st5, 64) float_st6 = ExprId(reg_float_st6, 64) float_st7 = ExprId(reg_float_st7, 64) +float_list = [ + float_st0 , + float_st1 , + float_st2 , + float_st3 , + float_st4 , + float_st5 , + float_st6 , + float_st7 , + ] + init_regs = { @@ -1620,8 +1631,17 @@ def movs(info, a, b): return e +def float_prev(flt): + if not flt in float_list: + return None + i = float_list.index(flt) + if i == 0: + fds + flt = float_list[i-1] + return flt def float_pop(avoid_flt = None): + avoid_flt = float_prev(avoid_flt) e= [] if avoid_flt != float_st0: e.append(ExprAff(float_st0, float_st1)) @@ -1778,11 +1798,17 @@ def fadd(info, a, b = None): return e def faddp(info, a, b = None): - e = fadd(info, a, b) if b == None: - e+=float_pop(float_st0) + b = a + a = float_st0 + e = [] + if isinstance(b, ExprMem): + src = ExprOp('mem_%.2d_to_double'%b.get_size(), b) else: - e+=float_pop(a) + src = b + e.append(ExprAff(float_prev(a), ExprOp('fadd', a, src))) + e += set_float_cs_eip(info) + e += float_pop(a) return e def fninit(info): @@ -1856,16 +1882,47 @@ def fdiv(info, a, b = None): e += set_float_cs_eip(info) return e +def fdivr(info, a, b = None): + if b == None: + b = a + a = float_st0 + e = [] + if isinstance(b, ExprMem): + src = ExprOp('mem_%.2d_to_double'%b.get_size(), b) + else: + src = b + e.append(ExprAff(a, ExprOp('fdiv', src, a))) + e += set_float_cs_eip(info) + return e + def fdivp(info, a): # Invalid emulation - e = fdiv(info, a) - e+=float_pop(a) + if b == None: + b = a + a = float_st0 + e = [] + if isinstance(b, ExprMem): + src = ExprOp('mem_%.2d_to_double'%b.get_size(), b) + else: + src = b + e.append(ExprAff(float_prev(a), ExprOp('fdiv', a, src))) + e += set_float_cs_eip(info) + e += float_pop(a) return e -def fmulp(info, a): +def fmulp(info, a, b): # Invalid emulation - e = fmul(info, a) - e+=float_pop(a) + if b == None: + b = a + a = float_st0 + e = [] + if isinstance(b, ExprMem): + src = ExprOp('mem_%.2d_to_double'%b.get_size(), b) + else: + src = b + e.append(ExprAff(float_prev(a), ExprOp('fmul', a, src))) + e += set_float_cs_eip(info) + e += float_pop(a) return e def ftan(info, a): @@ -1902,12 +1959,6 @@ def fptan(info): e.append(ExprAff(float_stack_ptr, ExprOp('+', float_stack_ptr, ExprInt32(1)))) return e - e.append(ExprAff(float_st0, ExprOp('ftan', src))) - - e = ftan(a) - e+=float_pop(a) - return e - def frndint(info): e = [] @@ -2403,6 +2454,7 @@ mnemo_func = {'mov': mov, 'fmul':fmul, 'fmulp':fmulp, 'fdiv':fdiv, + 'fdivr':fdivr, 'fdivp':fdivp, 'fxch':fxch, 'fptan':fptan, diff --git a/miasm/tools/emul_lib/libcodenat.c b/miasm/tools/emul_lib/libcodenat.c index 4a558b4b..ba491e16 100644 --- a/miasm/tools/emul_lib/libcodenat.c +++ b/miasm/tools/emul_lib/libcodenat.c @@ -683,8 +683,9 @@ int imul_hi_op_16(short a, short b) int imul_hi_op_32(int a, int b) { int64_t res = 0; - res = a*b; - return res>>32; + res = (int64_t)a*(int64_t)b; + //printf("%x %x dd %"PRIx64"\n", a, b, res); + return res>>32ULL; } unsigned int umul16_lo(unsigned short a, unsigned short b) @@ -918,6 +919,20 @@ unsigned int cpuid(unsigned int a, unsigned int reg_num) #define DEBUG_MIASM_DOUBLE + +void dump_float(void) +{ + printf("%e\n", vmcpu.float_st0); + printf("%e\n", vmcpu.float_st1); + printf("%e\n", vmcpu.float_st2); + printf("%e\n", vmcpu.float_st3); + printf("%e\n", vmcpu.float_st4); + printf("%e\n", vmcpu.float_st5); + printf("%e\n", vmcpu.float_st6); + printf("%e\n", vmcpu.float_st7); + +} + double mem_32_to_double(unsigned int m) { float f; @@ -926,7 +941,8 @@ double mem_32_to_double(unsigned int m) f = *((float*)&m); d = f; #ifdef DEBUG_MIASM_DOUBLE - printf("%d %e\n", m, d); + dump_float(); + printf("%d float %e\n", m, d); #endif return d; } @@ -937,7 +953,8 @@ double mem_64_to_double(uint64_t m) double d; d = *((double*)&m); #ifdef DEBUG_MIASM_DOUBLE - printf("%"PRId64" %e\n", m, d); + dump_float(); + printf("%"PRId64" double %e\n", m, d); #endif return d; } @@ -948,7 +965,8 @@ double int_16_to_double(unsigned int m) d = (double)(m&0xffff); #ifdef DEBUG_MIASM_DOUBLE - printf("%d %e\n", m, d); + dump_float(); + printf("%d double %e\n", m, d); #endif return d; } @@ -959,7 +977,8 @@ double int_32_to_double(unsigned int m) d = (double)m; #ifdef DEBUG_MIASM_DOUBLE - printf("%d %e\n", m, d); + dump_float(); + printf("%d double %e\n", m, d); #endif return d; } @@ -970,7 +989,8 @@ double int_64_to_double(uint64_t m) d = (double)m; #ifdef DEBUG_MIASM_DOUBLE - printf("%"PRId64" %e\n", m, d); + dump_float(); + printf("%"PRId64" double %e\n", m, d); #endif return d; } @@ -981,7 +1001,8 @@ int double_to_int_32(double d) i = (int)d; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %d\n", d, i); + dump_float(); + printf("%e int %d\n", d, i); #endif return i; } @@ -991,7 +1012,8 @@ double fadd(double a, double b) double c; c = a + b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e + %e -> %e\n", a, b, c); #endif return c; } @@ -1001,7 +1023,8 @@ double fsub(double a, double b) double c; c = a - b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e - %e -> %e\n", a, b, c); #endif return c; } @@ -1011,7 +1034,8 @@ double fmul(double a, double b) double c; c = a * b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e * %e -> %e\n", a, b, c); #endif return c; } @@ -1021,7 +1045,8 @@ double fdiv(double a, double b) double c; c = a / b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e / %e -> %e\n", a, b, c); #endif return c; } @@ -1031,7 +1056,8 @@ double ftan(double a) double b; b = tan(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e tan %e\n", a, b); #endif return b; } @@ -1043,7 +1069,8 @@ double frndint(double a) b = (int64_t)a; c = (double)b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, c); + dump_float(); + printf("%e double %e\n", a, c); #endif return c; } @@ -1053,7 +1080,8 @@ double fsin(double a) double b; b = sin(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e sin %e\n", a, b); #endif return b; } @@ -1063,7 +1091,8 @@ double fcos(double a) double b; b = cos(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e cos %e\n", a, b); #endif return b; } @@ -1074,7 +1103,8 @@ double fscale(double a, double b) double c; c = a * exp2(trunc(b)); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e *exp2 %e -> %e\n", a, b, c); #endif return c; } @@ -1084,7 +1114,8 @@ double f2xm1(double a) double b; b = exp2(a)-1; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e exp2 -1 %e\n", a, b); #endif return b; } @@ -1094,7 +1125,8 @@ double fsqrt(double a) double b; b = sqrt(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e sqrt %e\n", a, b); #endif return b; } @@ -1104,7 +1136,8 @@ double fabs(double a) double b; b = abs(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e abs %e\n", a, b); #endif return b; } @@ -1141,6 +1174,7 @@ unsigned int double_to_mem_32(double d) f = d; m = *((unsigned int*)&f); #ifdef DEBUG_MIASM_DOUBLE + dump_float(); printf("%d %e\n", m, d); #endif return m; @@ -1151,6 +1185,7 @@ uint64_t double_to_mem_64(double d) uint64_t m; m = *((uint64_t*)&d); #ifdef DEBUG_MIASM_DOUBLE + dump_float(); printf("%"PRId64" %e\n", m, d); #endif return m; |