]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Modify this test so it no longer uses client requests, but instead
authorJulian Seward <jseward@acm.org>
Thu, 7 Jul 2005 11:24:14 +0000 (11:24 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 7 Jul 2005 11:24:14 +0000 (11:24 +0000)
relies on --smc-support=all to work correctly.  Hence it tests the
s-m-c support at least on x86.  Jump through various hoops to defeat
vex's basic-block-chasing optimisation, which has an annoying habit of
making this test work correctly even without --smc-support=all.

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

none/tests/x86/smc1.c
none/tests/x86/smc1.vgtest

index 2b280519343ee1d9b8387de5b80adf5cd2d2ed74..1d6d65450f3fe99c2ae47cf0a2f3029dc59dcabd 100644 (file)
@@ -1,5 +1,5 @@
 
-/* Test Heimdall's ability to spot writes to code which has been
+/* Test Valgrind's ability to spot writes to code which has been
    translated, and discard the out-of-date translations.
 
    CORRECT output is
@@ -30,7 +30,6 @@
 */
 
 #include <stdio.h>
-#include "valgrind.h"
 
 typedef unsigned int Addr;
 typedef unsigned char UChar;
@@ -45,33 +44,52 @@ void p ( int n )
    printf("in p %d\n", n);
 }
 
-UChar code[10];
+static UChar code[10];
 
-/* Make `code' be JMP-32 dest */
+/* Make `code' be PUSHL $dest ; ret */
+// This forces the branch onwards to be indirect, so vex can't chase it
 void set_dest ( Addr dest )
 {
-   unsigned int delta;
-   delta = dest - ((Addr)(&code[0]));
-   delta -= 5;
-   
-   code[0] = 0xE9;   /* JMP d32 */
-   code[1] = (delta & 0xFF);
-   code[2] = ((delta >> 8) & 0xFF);
-   code[3] = ((delta >> 16) & 0xFF);
-   code[4] = ((delta >> 24) & 0xFF);
-
-   /* XXX this should be automatic */
-   VALGRIND_DISCARD_TRANSLATIONS(code, sizeof(code));
+   code[0] = 0x68; /* PUSH imm32 */
+   code[1] = (dest & 0xFF);
+   code[2] = ((dest >> 8) & 0xFF);
+   code[3] = ((dest >> 16) & 0xFF);
+   code[4] = ((dest >> 24) & 0xFF);
+   code[5] = 0xC3;
 }
 
+/* Calling aa gets eventually to the function residing in code[0..].
+   This indirection is necessary to defeat Vex's basic-block chasing
+   optimisation.  That will merge up to three basic blocks into the
+   same IR superblock, which causes the test to succeed when it
+   shouldn't if main calls code[] directly.  */
+
+// force an indirect branch to code[0], so vex can't chase it
+__attribute__((noinline))
+void dd ( int x, void (*f)(int) ) { f(x); }
+
+__attribute__((noinline))
+void cc ( int x ) { dd(x, (void(*)(int)) &code[0]); }
+
+__attribute__((noinline))
+void bb ( int x ) { cc(x); }
+
+__attribute__((noinline))
+void aa ( int x ) { bb(x); }
+
+__attribute__((noinline))
+void diversion ( void ) { }
+
 int main ( void )
 {
    int i;
    for (i = 0; i < 10; i += 2) {
       set_dest ( (Addr)&p );
-      (  (void (*)(int)) (&code[0])  ) (i);
+      //      diversion();
+      aa(i);
       set_dest ( (Addr)&q );
-      (  (void (*)(int)) (&code[0])  ) (i+1);
+      //      diversion();
+      aa(i+1);
    }
    return 0;
 }
index e2ef32cf041049fb5c129ebd6c14f0931bb7b0b2..1e57f2e30c3bb8efc6de819b6caefae98b7bd155 100644 (file)
@@ -1 +1,2 @@
 prog: smc1
+vgopts: --smc-support=all