forked from OSchip/llvm-project
[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:
parent
b9aa538db1
commit
687933f55d
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__)
|
||||
|
|
Loading…
Reference in New Issue