]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
For FPU/MMX/SSE instructions which don't reference any memory, make memcheck
authorTom Hughes <tom@compton.nu>
Sun, 28 Mar 2004 11:26:29 +0000 (11:26 +0000)
committerTom Hughes <tom@compton.nu>
Sun, 28 Mar 2004 11:26:29 +0000 (11:26 +0000)
look at whether the eflags are read or written and generate UCode to validate
and/or mark as valid the eflags when necessary.

CCMAIL: 78514-done@bugs.kde.org

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2344

memcheck/mc_translate.c
memcheck/tests/.cvsignore
memcheck/tests/Makefile.am
memcheck/tests/fpeflags.c [new file with mode: 0644]
memcheck/tests/fpeflags.stderr.exp [new file with mode: 0644]
memcheck/tests/fpeflags.vgtest [new file with mode: 0644]

index 7a2e05b2a18f2f8e0799272f7b9f1e25ec393e55..301d9da5685afe505e08f5c2268a586dce021dcc 100644 (file)
@@ -1177,12 +1177,26 @@ static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in )
             VG_(copy_UInstr)(cb, u_in);
            break;
          }
-
-         /* For FPU, MMX and SSE insns not referencing memory, just
-            copy thru. */
+         
+         /* For MMX and SSE insns not referencing memory, just
+            make sure the eflags are defined if the instruction
+            read them, and make them defined it it writes them. */
          case SSE5: case SSE4: case SSE3:
          case MMX1: case MMX2: case MMX3:
-         case FPU: 
+         case FPU:
+            if (u_in->flags_r != FlagsEmpty) {
+               qt = create_GETVF(cb, 0);
+               uInstr1(cb, TESTV, 0, TempReg, qt);
+               /* qt should never be referred to again.  Nevertheless
+                  ... */
+               uInstr1(cb, SETV, 0, TempReg, qt);
+            }
+            if (u_in->flags_w != FlagsEmpty) {
+               qd = newTemp(cb);
+               uInstr2(cb, MOV, 4, Literal, 0, TempReg, qd);
+               uLiteral(cb, qd);
+               create_PUTVF(cb, 0, qd);
+            }
             VG_(copy_UInstr)(cb, u_in);
             break;
 
index 42dfbb85269953cd95928e56dd2c2dfc6da38fcb..9fc694b6c3f3adc481fea3e545b2513e57ef6fee 100644 (file)
@@ -16,6 +16,7 @@ execve
 exitprog
 filter_leak_check_size
 filter_stderr
+fpeflags
 fprw
 fwrite
 inits
index 40ba819a4e5f06eb792a3de1087cd7351508bd41..37a3dbae3a52793f4420aed3b18f287011f855a9 100644 (file)
@@ -27,6 +27,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        errs1.stderr.exp errs1.vgtest \
        exitprog.stderr.exp exitprog.vgtest \
        execve.stderr.exp execve.vgtest \
+       fpeflags.stderr.exp fpeflags.vgtest \
        fprw.stderr.exp fprw.vgtest \
        fwrite.stderr.exp fwrite.stdout.exp fwrite.vgtest \
        inits.stderr.exp inits.vgtest \
@@ -75,7 +76,7 @@ check_PROGRAMS = \
        badaddrvalue badfree badjump badloop badrw brk buflen_check \
        clientperm custom_alloc \
        doublefree error_counts errs1 exitprog execve \
-       fprw fwrite inits inline \
+       fpeflags fprw fwrite inits inline \
        malloc1 malloc2 malloc3 manuel1 manuel2 manuel3 \
        memalign_test memcmptest mmaptest nanoleak new_nothrow null_socket \
        overlap pushfpopf \
@@ -102,6 +103,7 @@ error_counts_SOURCES        = error_counts.c
 errs1_SOURCES          = errs1.c
 execve_SOURCES                 = execve.c
 exitprog_SOURCES       = exitprog.c
+fpeflags_SOURCES       = fpeflags.c
 fprw_SOURCES           = fprw.c
 fwrite_SOURCES                 = fwrite.c
 inits_SOURCES          = inits.c
@@ -141,3 +143,5 @@ mismatches_SOURCES  = mismatches.cpp
 new_nothrow_SOURCES    = new_nothrow.cpp
 new_override_SOURCES   = new_override.cpp
 
+# must be built with these flags -- bug only occurred with them
+fpeflags.o: CFLAGS += -march=i686
diff --git a/memcheck/tests/fpeflags.c b/memcheck/tests/fpeflags.c
new file mode 100644 (file)
index 0000000..27cd3e3
--- /dev/null
@@ -0,0 +1,20 @@
+#include <stdlib.h>
+
+struct instance
+{
+    unsigned myVal:1;
+};
+
+static struct instance* myInstance;
+
+int main(int argc, char** argv)
+{
+    float g = 1.0f;
+    
+    myInstance = malloc(sizeof(struct instance));
+
+    myInstance->myVal = 1;
+
+    if (g == 1.0f)
+        return 0;
+}
diff --git a/memcheck/tests/fpeflags.stderr.exp b/memcheck/tests/fpeflags.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/fpeflags.vgtest b/memcheck/tests/fpeflags.vgtest
new file mode 100644 (file)
index 0000000..88ae11d
--- /dev/null
@@ -0,0 +1,2 @@
+vgopts: -q
+prog: fpeflags