[compiler-rt] r300889 - [asan] Optimize strchr for strict_string_checks=false

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 20 13:59:38 PDT 2017


Author: vitalybuka
Date: Thu Apr 20 15:59:37 2017
New Revision: 300889

URL: http://llvm.org/viewvc/llvm-project?rev=300889&view=rev
Log:
[asan] Optimize strchr for strict_string_checks=false

Summary:
strchr interceptor does not need to call strlen if strict_string_checks is not
enabled. Unnecessary strlen calls affect python parser performance.

Reviewers: eugenis, kcc

Subscribers: llvm-commits, kubamracek

Differential Revision: https://reviews.llvm.org/D32264

Added:
    compiler-rt/trunk/test/asan/TestCases/Posix/strchr.c
Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=300889&r1=300888&r2=300889&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Apr 20 15:59:37 2017
@@ -139,12 +139,9 @@ bool PlatformHasDifferentMemcpyAndMemmov
 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
 #endif
 
-#define COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n)       \
-    COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
-      common_flags()->strict_string_checks ? (len) + 1 : (n) )
-
 #define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \
-    COMMON_INTERCEPTOR_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
+    COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
+      common_flags()->strict_string_checks ? (REAL(strlen)(s)) + 1 : (n) )
 
 #ifndef COMMON_INTERCEPTOR_ON_DLOPEN
 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
@@ -450,8 +447,7 @@ static inline void StrstrCheck(void *ctx
                                const char *s2) {
     uptr len1 = REAL(strlen)(s1);
     uptr len2 = REAL(strlen)(s2);
-    COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s1, len1,
-                                          r ? r - s1 + len2 : len1 + 1);
+    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1);
     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
 }
 #endif
@@ -577,10 +573,11 @@ INTERCEPTOR(char*, strchr, const char *s
     return internal_strchr(s, c);
   COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);
   char *result = REAL(strchr)(s, c);
-  uptr len = internal_strlen(s);
-  uptr n = result ? result - s + 1 : len + 1;
-  if (common_flags()->intercept_strchr)
-    COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n);
+  if (common_flags()->intercept_strchr) {
+    // Keep strlen as macro argument, as macro may ignore it.
+    COMMON_INTERCEPTOR_READ_STRING(ctx, s,
+      (result ? result - s : REAL(strlen)(s)) + 1);
+  }
   return result;
 }
 #define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)
@@ -609,9 +606,8 @@ INTERCEPTOR(char*, strrchr, const char *
   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
     return internal_strrchr(s, c);
   COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);
-  uptr len = internal_strlen(s);
   if (common_flags()->intercept_strchr)
-    COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, len + 1);
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
   return REAL(strrchr)(s, c);
 }
 #define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)

Added: compiler-rt/trunk/test/asan/TestCases/Posix/strchr.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Posix/strchr.c?rev=300889&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Posix/strchr.c (added)
+++ compiler-rt/trunk/test/asan/TestCases/Posix/strchr.c Thu Apr 20 15:59:37 2017
@@ -0,0 +1,36 @@
+// Test strchr for strict_string_checks=false does not look beyond necessary
+// char.
+// RUN: %clang_asan %s -o %t
+// RUN: %env_asan_opts=strict_string_checks=false %run %t 2>&1
+// RUN: %env_asan_opts=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+  size_t page_size = sysconf(_SC_PAGE_SIZE);
+  size_t size = 2 * page_size;
+  char *s = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
+                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  assert(s);
+  assert(((uintptr_t)s & (page_size - 1)) == 0);
+  memset(s, 'o', size);
+  s[size - 1] = 0;
+
+  char *p = s + page_size - 1;
+  *p = 'x';
+
+  if (mprotect(p + 1, 1, PROT_NONE))
+    return 1;
+  char *r = strchr(s, 'x');
+  // CHECK: AddressSanitizer: SEGV on unknown address
+  // CHECK: The signal is caused by a READ memory access
+  // CHECK: strchr.c:[[@LINE-3]]
+  assert(r == p);
+
+  return 0;
+}




More information about the llvm-commits mailing list