asan_interceptors.h revision b3010e75d1c88b6f2084c80530e06ffe8d6f19a2
1//===-- asan_interceptors.h -------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of AddressSanitizer, an address sanity checker. 11// 12// ASan-private header for asan_interceptors.cc 13//===----------------------------------------------------------------------===// 14#ifndef ASAN_INTERCEPTORS_H 15#define ASAN_INTERCEPTORS_H 16 17#include "asan_internal.h" 18 19// To replace weak system functions on Linux we just need to declare functions 20// with same names in our library and then obtain the real function pointers 21// using dlsym(). This is not so on Mac OS, where the two-level namespace makes 22// our replacement functions invisible to other libraries. This may be overcomed 23// using the DYLD_FORCE_FLAT_NAMESPACE, but some errors loading the shared 24// libraries in Chromium were noticed when doing so. 25// Instead we use mach_override, a handy framework for patching functions at 26// runtime. To avoid possible name clashes, our replacement functions have 27// the "wrap_" prefix on Mac. 28// 29// After interception, the calls to system functions will be substituted by 30// calls to our interceptors. We store pointers to system function f() 31// in __asan::real_f(). 32// 33// TODO(glider): mach_override_ptr() tends to spend too much time 34// in allocateBranchIsland(). This should be ok for real-word 35// application, but slows down our tests which fork too many children. 36#ifdef __APPLE__ 37#include "mach_override/mach_override.h" 38#define WRAP(x) wrap_##x 39#define WRAPPER_NAME(x) "wrap_"#x 40 41#define OVERRIDE_FUNCTION(oldfunc, newfunc) \ 42 CHECK(0 == mach_override_ptr((void*)(oldfunc), \ 43 (void*)(newfunc), \ 44 (void**)&real_##oldfunc)); \ 45 CHECK(real_##oldfunc != NULL); 46 47#define OVERRIDE_FUNCTION_IF_EXISTS(oldfunc, newfunc) \ 48 do { mach_override_ptr((void*)(oldfunc), \ 49 (void*)(newfunc), \ 50 (void**)&real_##oldfunc); } while (0) 51 52#define INTERCEPT_FUNCTION(func) \ 53 OVERRIDE_FUNCTION(func, WRAP(func)) 54 55#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ 56 OVERRIDE_FUNCTION_IF_EXISTS(func, WRAP(func)) 57 58#else // __linux__ 59#define WRAP(x) x 60#define WRAPPER_NAME(x) #x 61 62#define INTERCEPT_FUNCTION(func) \ 63 CHECK((real_##func = (func##_f)dlsym(RTLD_NEXT, #func))); 64 65#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ 66 do { real_##func = (func##_f)dlsym(RTLD_NEXT, #func); } while (0) 67#endif 68 69#ifdef __APPLE__ 70void *WRAP(memcpy)(void *to, const void *from, size_t size); 71void *WRAP(memmove)(void *to, const void *from, size_t size); 72void *WRAP(memset)(void *block, int c, size_t size); 73char *WRAP(strchr)(const char *string, int c); 74int WRAP(strcmp)(const char *s1, const char *s2); 75char *WRAP(strcpy)(char *to, const char *from); // NOLINT 76char *WRAP(strdup)(const char *s); 77size_t WRAP(strlen)(const char *s); 78int WRAP(strncmp)(const char *s1, const char *s2, size_t size); 79char *WRAP(strncpy)(char *to, const char *from, size_t size); 80#endif 81 82namespace __asan { 83 84typedef void* (*index_f)(const char *string, int c); 85typedef void* (*memcpy_f)(void *to, const void *from, size_t size); 86typedef void* (*memmove_f)(void *to, const void *from, size_t size); 87typedef void* (*memset_f)(void *block, int c, size_t size); 88typedef char* (*strchr_f)(const char *str, int c); 89typedef int (*strcmp_f)(const char *s1, const char *s2); 90typedef char* (*strcpy_f)(char *to, const char *from); 91typedef char* (*strdup_f)(const char *s); 92typedef size_t (*strlen_f)(const char *s); 93typedef int (*strncmp_f)(const char *s1, const char *s2, size_t size); 94typedef char* (*strncpy_f)(char *to, const char *from, size_t size); 95typedef size_t (*strnlen_f)(const char *s, size_t maxlen); 96 97// __asan::real_X() holds pointer to library implementation of X(). 98extern index_f real_index; 99extern memcpy_f real_memcpy; 100extern memmove_f real_memmove; 101extern memset_f real_memset; 102extern strchr_f real_strchr; 103extern strcmp_f real_strcmp; 104extern strcpy_f real_strcpy; 105extern strdup_f real_strdup; 106extern strlen_f real_strlen; 107extern strncmp_f real_strncmp; 108extern strncpy_f real_strncpy; 109extern strnlen_f real_strnlen; 110 111// __asan::internal_X() is the implementation of X() for use in RTL. 112size_t internal_strlen(const char *s); 113size_t internal_strnlen(const char *s, size_t maxlen); 114 115// Initializes pointers to str*/mem* functions. 116void InitializeAsanInterceptors(); 117 118} // namespace __asan 119 120#endif // ASAN_INTERCEPTORS_H 121