[compiler-rt] r206387 - [asan] add __asan_load1/__asan_store1/... callbacks to asan-rt; together with -mllvm -asan-instrumentation-with-call-threshold=N this will be a workaround for PR17409

Kostya Serebryany kcc at google.com
Wed Apr 16 06:52:28 PDT 2014


Author: kcc
Date: Wed Apr 16 08:52:28 2014
New Revision: 206387

URL: http://llvm.org/viewvc/llvm-project?rev=206387&view=rev
Log:
[asan] add __asan_load1/__asan_store1/... callbacks to asan-rt; together with -mllvm -asan-instrumentation-with-call-threshold=N this will be a workaround for PR17409

Modified:
    compiler-rt/trunk/lib/asan/asan_interface_internal.h
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc

Modified: compiler-rt/trunk/lib/asan/asan_interface_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interface_internal.h?rev=206387&r1=206386&r2=206387&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interface_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interface_internal.h Wed Apr 16 08:52:28 2014
@@ -121,6 +121,20 @@ extern "C" {
   // Global flag, copy of ASAN_OPTIONS=detect_stack_use_after_return
   SANITIZER_INTERFACE_ATTRIBUTE
   extern int __asan_option_detect_stack_use_after_return;
+
+  SANITIZER_INTERFACE_ATTRIBUTE
+  extern uptr *__asan_test_only_reported_buggy_pointer;
+
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1(uptr p);
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2(uptr p);
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4(uptr p);
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8(uptr p);
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16(uptr p);
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1(uptr p);
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2(uptr p);
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4(uptr p);
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8(uptr p);
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16(uptr p);
 }  // extern "C"
 
 #endif  // ASAN_INTERFACE_INTERNAL_H

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=206387&r1=206386&r2=206387&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed Apr 16 08:52:28 2014
@@ -29,6 +29,7 @@
 #include "lsan/lsan_common.h"
 
 int __asan_option_detect_stack_use_after_return;  // Global interface symbol.
+uptr *__asan_test_only_reported_buggy_pointer;  // Used only for testing asan.
 
 namespace __asan {
 
@@ -374,6 +375,36 @@ void __asan_report_ ## type ## _n(uptr a
 ASAN_REPORT_ERROR_N(load, false)
 ASAN_REPORT_ERROR_N(store, true)
 
+#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size)                      \
+  extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_##type##size(uptr addr); \
+  void __asan_##type##size(uptr addr) {                                        \
+    uptr sp = MEM_TO_SHADOW(addr);                                             \
+    uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp)          \
+                                        : *reinterpret_cast<u16 *>(sp);        \
+    if (s) {                                                                   \
+      if (size >= SHADOW_GRANULARITY ||                                        \
+          (((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >= s) {             \
+        if (__asan_test_only_reported_buggy_pointer) {                         \
+          *__asan_test_only_reported_buggy_pointer = addr;                     \
+        } else {                                                               \
+          GET_CALLER_PC_BP_SP;                                                 \
+          __asan_report_error(pc, bp, sp, addr, is_write, size);               \
+        }                                                                      \
+      }                                                                        \
+    }                                                                          \
+  }
+
+ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
+ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
+ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4)
+ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8)
+ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16)
+ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1)
+ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2)
+ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4)
+ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8)
+ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16)
+
 // Force the linker to keep the symbols for various ASan interface functions.
 // We want to keep those in the executable in order to let the instrumented
 // dynamic libraries access the symbol even if it is not used by the executable

Modified: compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc?rev=206387&r1=206386&r2=206387&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc Wed Apr 16 08:52:28 2014
@@ -217,3 +217,40 @@ TEST(AddressSanitizer, ShadowRegionIsPoi
   ptr = kHighShadowBeg + 200;
   EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));
 }
+
+// Test __asan_load1 & friends.
+TEST(AddressSanitizer, LoadStoreCallbacks) {
+  typedef void (*CB)(uptr p);
+  CB cb[2][5] = {
+      {
+        __asan_load1, __asan_load2, __asan_load4, __asan_load8, __asan_load16,
+      }, {
+        __asan_store1, __asan_store2, __asan_store4, __asan_store8,
+        __asan_store16,
+      }
+  };
+
+  uptr buggy_ptr;
+  __asan_test_only_reported_buggy_pointer = &buggy_ptr;
+  for (uptr len = 16; len <= 32; len++) {
+    char *ptr = new char[len];
+    uptr p = reinterpret_cast<uptr>(ptr);
+    for (uptr is_write = 0; is_write <= 1; is_write++) {
+      for (uptr size_log = 0; size_log <= 4; size_log++) {
+        uptr size = 1 << size_log;
+        CB call = cb[is_write][size_log];
+        // Iterate only size-aligned offsets.
+        for (uptr offset = 0; offset < len; offset += size) {
+          buggy_ptr = 0;
+          call(p + offset);
+          if (offset + size <= len)
+            EXPECT_EQ(buggy_ptr, 0U);
+          else
+            EXPECT_EQ(buggy_ptr, p + offset);
+        }
+      }
+    }
+    delete [] ptr;
+  }
+  __asan_test_only_reported_buggy_pointer = 0;
+}





More information about the llvm-commits mailing list