[asan] Fix x86 asm instrumentation to preserve flags.

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
This commit is contained in:
Evgeniy Stepanov 2014-05-21 08:21:14 +00:00
parent b9aa538db1
commit 687933f55d
4 changed files with 67 additions and 24 deletions

View 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. */

View File

@ -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

View 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)

View 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__)