forked from OSchip/llvm-project
[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 llvm-svn: 301027
This commit is contained in:
parent
88938d4e67
commit
9703df2b36
|
@ -139,12 +139,9 @@ bool PlatformHasDifferentMemcpyAndMemmove();
|
|||
#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, char *r, const char *s1,
|
|||
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, int c) {
|
|||
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 *s, int c) {
|
|||
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)
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// 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|BUS}} on unknown address
|
||||
assert(r == p);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue