about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2013-02-14 16:01:29 +0100
committerserpilliere <devnull@localhost>2013-02-14 16:01:29 +0100
commitd71e9f462bd977b581b93839bad49afe4646a797 (patch)
tree56dc3dd4fb90b86001ed4bb98b2185f0a23aa00d
parentbd6a2adb96b1b2caa7964b86e62f84d5af541214 (diff)
downloadmiasm-d71e9f462bd977b581b93839bad49afe4646a797.tar.gz
miasm-d71e9f462bd977b581b93839bad49afe4646a797.zip
fix float issues
Diffstat (limited to '')
-rw-r--r--miasm/arch/ia32_arch.py32
-rw-r--r--miasm/arch/ia32_sem.py80
-rw-r--r--miasm/tools/emul_lib/libcodenat.c75
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;