[asan] Fix x86 asm instrumentation to preserve flags.
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Wed, 21 May 2014 08:21:14 +0000 (08:21 +0000)
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Wed, 21 May 2014 08:21:14 +0000 (08:21 +0000)
This change also enables asm instrumentation in asan tests that was
accidentally disabled yearlier, and adds a sanity test for that.

Patch by Yuri Gorshenin.

llvm-svn: 209282

compiler-rt/lib/asan/asan_asm_instrumentation.S
compiler-rt/lib/asan/scripts/gen_asm_instrumentation.sh
compiler-rt/lib/asan/tests/CMakeLists.txt
compiler-rt/lib/asan/tests/asan_asm_test.cc

index f67326d..2f812e7 100644 (file)
@@ -324,7 +324,7 @@ __sanitizer_sanitize_load16:
 .globl __sanitizer_sanitize_store1
 .type __sanitizer_sanitize_store1, @function
 __sanitizer_sanitize_store1:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushq %rcx
   pushfq
@@ -347,14 +347,14 @@ __sanitizer_sanitize_store1:
   popfq
   popq %rcx
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 // Sanitize 1-byte load. Takes one 8-byte address as an argument in %rdi,
 // nothing is returned.
 .globl __sanitizer_sanitize_load1
 .type __sanitizer_sanitize_load1, @function
 __sanitizer_sanitize_load1:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushq %rcx
   pushfq
@@ -377,14 +377,14 @@ __sanitizer_sanitize_load1:
   popfq
   popq %rcx
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 // Sanitize 2-byte store. Takes one 8-byte address as an argument in %rdi,
 // nothing is returned.
 .globl __sanitizer_sanitize_store2
 .type __sanitizer_sanitize_store2, @function
 __sanitizer_sanitize_store2:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushq %rcx
   pushfq
@@ -408,14 +408,14 @@ __sanitizer_sanitize_store2:
   popfq
   popq %rcx
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 // Sanitize 2-byte load. Takes one 8-byte address as an argument in %rdi,
 // nothing is returned.
 .globl __sanitizer_sanitize_load2
 .type __sanitizer_sanitize_load2, @function
 __sanitizer_sanitize_load2:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushq %rcx
   pushfq
@@ -439,14 +439,14 @@ __sanitizer_sanitize_load2:
   popfq
   popq %rcx
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 // Sanitize 4-byte store. Takes one 8-byte address as an argument in %rdi,
 // nothing is returned.
 .globl __sanitizer_sanitize_store4
 .type __sanitizer_sanitize_store4, @function
 __sanitizer_sanitize_store4:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushq %rcx
   pushfq
@@ -470,14 +470,14 @@ __sanitizer_sanitize_store4:
   popfq
   popq %rcx
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 // Sanitize 4-byte load. Takes one 8-byte address as an argument in %rdi,
 // nothing is returned.
 .globl __sanitizer_sanitize_load4
 .type __sanitizer_sanitize_load4, @function
 __sanitizer_sanitize_load4:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushq %rcx
   pushfq
@@ -501,14 +501,14 @@ __sanitizer_sanitize_load4:
   popfq
   popq %rcx
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 // Sanitize 8-byte store. Takes one 8-byte address as an argument in %rdi,
 // nothing is returned.
 .globl __sanitizer_sanitize_store8
 .type __sanitizer_sanitize_store8, @function
 __sanitizer_sanitize_store8:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushfq
   movq %rdi, %rax
@@ -523,14 +523,14 @@ __sanitizer_sanitize_store8:
 .sanitize_store8_done:
   popfq
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 // Sanitize 8-byte load. Takes one 8-byte address as an argument in %rdi,
 // nothing is returned.
 .globl __sanitizer_sanitize_load8
 .type __sanitizer_sanitize_load8, @function
 __sanitizer_sanitize_load8:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushfq
   movq %rdi, %rax
@@ -545,14 +545,14 @@ __sanitizer_sanitize_load8:
 .sanitize_load8_done:
   popfq
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 // Sanitize 16-byte store. Takes one 8-byte address as an argument in %rdi,
 // nothing is returned.
 .globl __sanitizer_sanitize_store16
 .type __sanitizer_sanitize_store16, @function
 __sanitizer_sanitize_store16:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushfq
   movq %rdi, %rax
@@ -567,14 +567,14 @@ __sanitizer_sanitize_store16:
 .sanitize_store16_done:
   popfq
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 // Sanitize 16-byte load. Takes one 8-byte address as an argument in %rdi,
 // nothing is returned.
 .globl __sanitizer_sanitize_load16
 .type __sanitizer_sanitize_load16, @function
 __sanitizer_sanitize_load16:
-  subq $128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushfq
   movq %rdi, %rax
@@ -589,7 +589,7 @@ __sanitizer_sanitize_load16:
 .sanitize_load16_done:
   popfq
   popq %rax
-  addq $128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 #endif // defined(__x86_64__)
 /* We do not need executable stack. */
index 6ca6769..e8bee80 100755 (executable)
@@ -181,7 +181,7 @@ cat <<EOF
 .globl $(func_name $at $as)
 .type $(func_name $at $as), @function
 $(func_name $at $as):
-  subq \$128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushq %rcx
   pushfq
@@ -211,7 +211,7 @@ $(func_label $at $as):
   popfq
   popq %rcx
   popq %rax
-  addq \$128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 EOF
   done
@@ -228,7 +228,7 @@ cat <<EOF
 .globl $(func_name $at $as)
 .type $(func_name $at $as), @function
 $(func_name $at $as):
-  subq \$128, %rsp
+  leaq -128(%rsp), %rsp
   pushq %rax
   pushfq
   movq %rdi, %rax
@@ -248,7 +248,7 @@ $(emit_call_report $at $as)
 $(func_label $at $as):
   popfq
   popq %rax
-  addq \$128, %rsp
+  leaq 128(%rsp), %rsp
   ret
 EOF
   done
index 331f38f..470543f 100644 (file)
@@ -60,6 +60,7 @@ set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
   ${ASAN_UNITTEST_COMMON_CFLAGS}
   -fsanitize=address
   "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
+  -mllvm -asan-instrument-assembly
 )
 
 if(NOT MSVC)
index adb98de..709ff5d 100644 (file)
@@ -197,8 +197,25 @@ template<> void TestAsmRead<__m128i>(const char *DeathPattern) {
   delete [] buf;
 }
 
+U4 AsmLoad(U4 *a) {
+  U4 r;
+  __asm__("movl (%[a]), %[r]  \n\t" : [r] "=r" (r) : [a] "r" (a) : "memory");
+  return r;
+}
+
+void AsmStore(U4 r, U4 *a) {
+  __asm__("movl %[r], (%[a])  \n\t" : : [a] "r" (a), [r] "r" (r) : "memory");
+}
+
 } // End of anonymous namespace
 
+TEST(AddressSanitizer, asm_load_store) {
+  U4* buf = new U4[2];
+  EXPECT_DEATH(AsmLoad(&buf[3]), "READ of size 4");
+  EXPECT_DEATH(AsmStore(0x1234, &buf[3]), "WRITE of size 4");
+  delete [] buf;
+}
+
 TEST(AddressSanitizer, asm_rw) {
   TestAsmWrite<U1>("WRITE of size 1");
   TestAsmWrite<U2>("WRITE of size 2");
@@ -213,6 +230,31 @@ TEST(AddressSanitizer, asm_rw) {
   TestAsmRead<__m128i>("READ of size 16");
 }
 
+TEST(AddressSanitizer, asm_flags) {
+  long magic = 0x1234;
+  long r = 0x0;
+
+#if defined(__x86_64__)
+  __asm__("xorq %%rax, %%rax  \n\t"
+          "movq (%[p]), %%rax \n\t"
+          "sete %%al          \n\t"
+          "movzbq %%al, %[r]  \n\t"
+          : [r] "=r"(r)
+          : [p] "r"(&magic)
+          : "rax", "memory");
+#else
+  __asm__("xorl %%eax, %%eax  \n\t"
+          "movl (%[p]), %%eax \n\t"
+          "sete %%al          \n\t"
+          "movzbl %%al, %[r]  \n\t"
+          : [r] "=r"(r)
+          : [p] "r"(&magic)
+          : "eax", "memory");
+#endif // defined(__x86_64__)
+
+  ASSERT_EQ(0x1, r);
+}
+
 #endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
 
 #endif // defined(__linux__)