diff options
author | Jay Foad <jay.foad@gmail.com> | 2014-11-21 21:25:09 +0000 |
---|---|---|
committer | Jay Foad <jay.foad@gmail.com> | 2014-11-21 21:25:09 +0000 |
commit | e47130e407883f17af82bba9889c56453f537856 (patch) | |
tree | 5ff40d75fb0b86549cd574d987ae0fa73ac767ea | |
parent | e88447d8deb5e58e51db76733a9c92c68e4fe142 (diff) | |
download | bcm5719-llvm-e47130e407883f17af82bba9889c56453f537856.tar.gz bcm5719-llvm-e47130e407883f17af82bba9889c56453f537856.zip |
[ASan] Get fake stack code working with GCC 4.8.2.
Summary:
TestCases/Linux/heavy_uar_test.cc was failing on my
PowerPC64 box with GCC 4.8.2, because the compiler recognised
a memset-like loop and turned it into a call to memset, which
got intercepted by __asan_memset, which got upset because it was
being called on an address in high shadow memory.
Use break_optimization to stop the compiler from doing this.
Reviewers: kcc, samsonov
Reviewed By: kcc
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D6266
llvm-svn: 222572
-rw-r--r-- | compiler-rt/lib/asan/asan_fake_stack.cc | 4 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common.h | 14 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_libc.cc | 12 |
3 files changed, 18 insertions, 12 deletions
diff --git a/compiler-rt/lib/asan/asan_fake_stack.cc b/compiler-rt/lib/asan/asan_fake_stack.cc index c7f13c7317b..c95bc11f6cd 100644 --- a/compiler-rt/lib/asan/asan_fake_stack.cc +++ b/compiler-rt/lib/asan/asan_fake_stack.cc @@ -27,8 +27,10 @@ ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) { CHECK_EQ(SHADOW_SCALE, 3); // This code expects SHADOW_SCALE=3. u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr)); if (class_id <= 6) { - for (uptr i = 0; i < (1U << class_id); i++) + for (uptr i = 0; i < (1U << class_id); i++) { shadow[i] = magic; + SanitizerBreakOptimization(0); // Make sure this does not become memset. + } } else { // The size class is too big, it's cheaper to poison only size bytes. PoisonShadow(ptr, size, static_cast<u8>(magic)); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index c1e2101ea83..25dcc52c830 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -535,6 +535,20 @@ INLINE void AndroidLogWrite(const char *buffer_unused) {} INLINE void GetExtraActivationFlags(char *buf, uptr size) { *buf = '\0'; } INLINE void SanitizerInitializeUnwinder() {} #endif + +// Make the compiler think that something is going on there. +// Use this inside a loop that looks like memset/memcpy/etc to prevent the +// compiler from recognising it and turning it into an actual call to +// memset/memcpy/etc. +static inline void SanitizerBreakOptimization(void *arg) { +#if _MSC_VER + // FIXME: make sure this is actually enough. + __asm; +#else + __asm__ __volatile__("" : : "r" (arg) : "memory"); +#endif +} + } // namespace __sanitizer inline void *operator new(__sanitizer::operator_new_size_type size, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc b/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc index 8d8ad59f0e0..d8bd1cf7a7e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc @@ -16,16 +16,6 @@ namespace __sanitizer { -// Make the compiler think that something is going on there. -static inline void break_optimization(void *arg) { -#if _MSC_VER - // FIXME: make sure this is actually enough. - __asm; -#else - __asm__ __volatile__("" : : "r" (arg) : "memory"); -#endif -} - s64 internal_atoll(const char *nptr) { return internal_simple_strtoll(nptr, (char**)0, 10); } @@ -78,7 +68,7 @@ void internal_bzero_aligned16(void *s, uptr n) { CHECK_EQ((reinterpret_cast<uptr>(s) | n) & 15, 0); for (S16 *p = reinterpret_cast<S16*>(s), *end = p + n / 16; p < end; p++) { p->a = p->b = 0; - break_optimization(0); // Make sure this does not become memset. + SanitizerBreakOptimization(0); // Make sure this does not become memset. } } |