summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Foad <jay.foad@gmail.com>2014-11-21 21:25:09 +0000
committerJay Foad <jay.foad@gmail.com>2014-11-21 21:25:09 +0000
commite47130e407883f17af82bba9889c56453f537856 (patch)
tree5ff40d75fb0b86549cd574d987ae0fa73ac767ea
parente88447d8deb5e58e51db76733a9c92c68e4fe142 (diff)
downloadbcm5719-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.cc4
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common.h14
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_libc.cc12
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.
}
}
OpenPOWER on IntegriCloud