Bug 250799 - frexp$fenv_access_off function generates SIGILL
Summary: frexp$fenv_access_off function generates SIGILL
Status: RESOLVED DUPLICATE of bug 142688
Alias: None
Product: valgrind
Classification: Developer tools
Component: vex (other bugs)
Version First Reported In: 3.6 SVN
Platform: Unlisted Binaries macOS
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-09-10 16:45 UTC by Tommy Reilly
Modified: 2010-10-04 12:56 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tommy Reilly 2010-09-10 16:45:02 UTC
Version:           3.6 SVN (using Devel) 
OS:                OS X

Max OS X library function: frexp$fenv_access_off (in /usr/lib/libSystem.B.dylib)

offending instruction:
0x97c42dab <frexp$fenv_access_off+107>:	movsww 0x8(%esp),%ax

context:
(gdb) disass frexp$fenv_access_off
Dump of assembler code for function frexp$fenv_access_off:
0x97c42d40 <frexp$fenv_access_off+0>:	sub    $0x1c,%esp
0x97c42d43 <frexp$fenv_access_off+3>:	mov    0x24(%esp),%eax
0x97c42d47 <frexp$fenv_access_off+7>:	mov    0x28(%esp),%edxx
0x97c42d4b <frexp$fenv_access_off+11>:	mov    %eax,%ecx
0x97c42d4d <frexp$fenv_access_off+13>:	and    $0x7ff00000,%eax
0x97c42d52 <frexp$fenv_access_off+18>:	and    $0x800fffff,%ecx
0x97c42d58 <frexp$fenv_access_off+24>:	add    $0x100000,%eax
0x97c42d5d <frexp$fenv_access_off+29>:	or     $0x3fe00000,%ecx
0x97c42d63 <frexp$fenv_access_off+35>:	cmp    $0x100000,%eax
0x97c42d68 <frexp$fenv_access_off+40>:	jle    0x97c42d8e <frexp$fenv_access_off+78>
0x97c42d6a <frexp$fenv_access_off+42>:	movd   %ecx,%xmm1
0x97c42d6e <frexp$fenv_access_off+46>:	movd   0x20(%esp),%xmm0
0x97c42d74 <frexp$fenv_access_off+52>:	punpckldq %xmm1,%xmm0
0x97c42d78 <frexp$fenv_access_off+56>:	movq   %xmm0,(%esp)
0x97c42d7d <frexp$fenv_access_off+61>:	fldl   (%esp)
0x97c42d80 <frexp$fenv_access_off+64>:	sar    $0x14,%eax
0x97c42d83 <frexp$fenv_access_off+67>:	add    $0xfffffc01,%eax
0x97c42d88 <frexp$fenv_access_off+72>:	mov    %eax,(%edx)
0x97c42d8a <frexp$fenv_access_off+74>:	add    $0x1c,%esp
0x97c42d8d <frexp$fenv_access_off+77>:	ret    
0x97c42d8e <frexp$fenv_access_off+78>:	je     0x97c42d9e <frexp$fenv_access_off+94>
0x97c42d90 <frexp$fenv_access_off+80>:	movl   $0x0,(%edx)
0x97c42d96 <frexp$fenv_access_off+86>:	fldl   0x20(%esp)
0x97c42d9a <frexp$fenv_access_off+90>:	add    $0x1c,%esp
0x97c42d9d <frexp$fenv_access_off+93>:	ret    
0x97c42d9e <frexp$fenv_access_off+94>:	fldl   0x20(%esp)
0x97c42da2 <frexp$fenv_access_off+98>:	fldz   
0x97c42da4 <frexp$fenv_access_off+100>:	fucomip %st(1),%st
0x97c42da6 <frexp$fenv_access_off+102>:	fstpt  (%esp)
0x97c42da9 <frexp$fenv_access_off+105>:	je     0x97c42d90 <frexp$fenv_access_off+80>
0x97c42dab <frexp$fenv_access_off+107>:	movsww 0x8(%esp),%ax
0x97c42db1 <frexp$fenv_access_off+113>:	mov    %eax,%ecx
0x97c42db3 <frexp$fenv_access_off+115>:	and    $0x7fff,%eax
0x97c42db8 <frexp$fenv_access_off+120>:	and    $0x8000,%ecx
0x97c42dbe <frexp$fenv_access_off+126>:	add    $0xffffc002,%eax
0x97c42dc3 <frexp$fenv_access_off+131>:	or     $0x3ffe,%ecx
0x97c42dc9 <frexp$fenv_access_off+137>:	mov    %eax,(%edx)
0x97c42dcb <frexp$fenv_access_off+139>:	mov    %cx,0x8(%esp)
0x97c42dd0 <frexp$fenv_access_off+144>:	fldt   (%esp)
0x97c42dd3 <frexp$fenv_access_off+147>:	add    $0x1c,%esp
0x97c42dd6 <frexp$fenv_access_off+150>:	ret    
0x97c42dd7 <frexp$fenv_access_off+151>:	nopw   0x0(%eax,%eax,1)

Reproducible: Always

Steps to Reproduce:
#include <math.h>
main() 
{
  int i;
  union {
    unsigned long long x;
    double d;
  } u;
  u.x = 0x0000000000000001;
  frexp(u.d, &i); 
}
#include <math.h>
main() 
{
  int i;
  union {
    unsigned long long x;
    double d;
  } u;
  u.x = 0x0000000000000001;
  frexp(u.d, &i); 
}
$ gcc -arch i386 frexp.c
$ valgrind ./a.out



Actual Results:  
Illegal instruction


Expected Results:  
nothing!
Comment 1 Julian Seward 2010-09-10 17:03:50 UTC
Does anyone know anything about movsww?  It's movswl with an 0x66
prefix, but what would be the point?  Is there any difference between
that and movw mem, reg16 ?
Comment 2 Julian Seward 2010-09-10 17:17:56 UTC
Ah, apparently this has been seen before.

*** This bug has been marked as a duplicate of bug 142688 ***
Comment 3 Julian Seward 2010-09-30 15:01:43 UTC
It seems a bit strange that the OSX libm should use an undocumented
instruction.  Anyway.  Tommy, can you try the patch below?

Index: priv/guest_x86_toIR.c
===================================================================
--- priv/guest_x86_toIR.c       (revision 2055)
+++ priv/guest_x86_toIR.c       (working copy)
@@ -2166,9 +2166,16 @@
 {
    UChar rm = getIByte(delta);
    if (epartIsReg(rm)) {
-      putIReg(szd, gregOfRM(rm),
-                   unop(mkWidenOp(szs,szd,sign_extend), 
-                        getIReg(szs,eregOfRM(rm))));
+      if (szd == szs) {
+         // mutant case.  See #250799
+         putIReg(szd, gregOfRM(rm),
+                           getIReg(szs,eregOfRM(rm)));
+      } else {
+         // normal case
+         putIReg(szd, gregOfRM(rm),
+                      unop(mkWidenOp(szs,szd,sign_extend), 
+                           getIReg(szs,eregOfRM(rm))));
+      }
       DIP("mov%c%c%c %s,%s\n", sign_extend ? 's' : 'z',
                                nameISize(szs), nameISize(szd),
                                nameIReg(szs,eregOfRM(rm)),
@@ -2181,10 +2188,16 @@
       Int    len;
       HChar  dis_buf[50];
       IRTemp addr = disAMode ( &len, sorb, delta, dis_buf );
-
-      putIReg(szd, gregOfRM(rm),
-                   unop(mkWidenOp(szs,szd,sign_extend), 
-                        loadLE(szToITy(szs),mkexpr(addr))));
+      if (szd == szs) {
+         // mutant case.  See #250799
+         putIReg(szd, gregOfRM(rm),
+                           loadLE(szToITy(szs),mkexpr(addr)));
+      } else {
+         // normal case
+         putIReg(szd, gregOfRM(rm),
+                      unop(mkWidenOp(szs,szd,sign_extend), 
+                           loadLE(szToITy(szs),mkexpr(addr))));
+      }
       DIP("mov%c%c%c %s,%s\n", sign_extend ? 's' : 'z',
                                nameISize(szs), nameISize(szd),
                                dis_buf, nameIReg(szd,gregOfRM(rm)));
@@ -14608,9 +14621,9 @@
          break;
 
       case 0xBF: /* MOVSXw Ew,Gv */
-         if (sz != 4)
+         if (sz != 4 && /* accept movsww, sigh, see #250799 */sz != 2)
             goto decode_failure;
-         delta = dis_movx_E_G ( sorb, delta, 2, 4, True );
+         delta = dis_movx_E_G ( sorb, delta, 2, sz, True );
          break;
 
 //--       /* =-=-=-=-=-=-=-=-=-=-= MOVNTI -=-=-=-=-=-=-=-=-= */
Comment 4 Julian Seward 2010-10-04 12:56:22 UTC
Fixed, vex r2056.