.globl __sanitizer_sanitize_store1
.type __sanitizer_sanitize_store1, @function
__sanitizer_sanitize_store1:
- subq $128, %rsp
+ leaq -128(%rsp), %rsp
pushq %rax
pushq %rcx
pushfq
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
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
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
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
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
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
.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
.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
.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
.sanitize_load16_done:
popfq
popq %rax
- addq $128, %rsp
+ leaq 128(%rsp), %rsp
ret
#endif // defined(__x86_64__)
/* We do not need executable stack. */
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");
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__)