diff options
author | Reid Kleckner <rnk@google.com> | 2019-04-30 20:59:56 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2019-04-30 20:59:56 +0000 |
commit | 56d59bd9cdbd18d00d2b487812e19ff7302201c7 (patch) | |
tree | 0085f5061aec19ff1ad313fccfdc02e55af96aa3 | |
parent | 0128c9bfa882ac8ca16929201352e3d8bea9aff8 (diff) | |
download | compiler-rt-56d59bd9cdbd18d00d2b487812e19ff7302201c7.tar.gz |
Revert r359325 "[NFC][Sanitizer] Change "return type" of INTERCEPT_FUNCTION to void"
Changing INTERCEPT_FUNCTION to return void is not functionally correct.
IMO the best way to communicate failure or success of interception is
with a return value, not some external address comparison.
This change was also creating link errors for _except_handler4_common,
which is exported from ucrtbase.dll in 32-bit Windows.
Also revert dependent changes r359362 and r359466.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@359611 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/asan/asan_interceptors.h | 6 | ||||
-rw-r--r-- | lib/interception/interception_linux.cc | 6 | ||||
-rw-r--r-- | lib/interception/interception_linux.h | 14 | ||||
-rw-r--r-- | lib/interception/tests/interception_linux_test.cc | 11 | ||||
-rw-r--r-- | lib/msan/msan_interceptors.cc | 7 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors.cc | 24 |
6 files changed, 48 insertions, 20 deletions
diff --git a/lib/asan/asan_interceptors.h b/lib/asan/asan_interceptors.h index f0deea391..903ab5991 100644 --- a/lib/asan/asan_interceptors.h +++ b/lib/asan/asan_interceptors.h @@ -122,14 +122,12 @@ DECLARE_REAL(char*, strstr, const char *s1, const char *s2) #if !SANITIZER_MAC #define ASAN_INTERCEPT_FUNC(name) \ do { \ - INTERCEPT_FUNCTION(name); \ - if (&(name) != &WRAP(name) || !REAL(name)) \ + if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \ VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \ } while (0) #define ASAN_INTERCEPT_FUNC_VER(name, ver) \ do { \ - INTERCEPT_FUNCTION_VER(name, ver); \ - if (&(name) != &WRAP(name) || !REAL(name)) \ + if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \ VReport( \ 1, "AddressSanitizer: failed to intercept '" #name "@@" #ver "'\n"); \ } while (0) diff --git a/lib/interception/interception_linux.cc b/lib/interception/interception_linux.cc index 64d04d8df..d019d482d 100644 --- a/lib/interception/interception_linux.cc +++ b/lib/interception/interception_linux.cc @@ -33,6 +33,12 @@ static int StrCmp(const char *s1, const char *s2) { } #endif +bool GetRealFunctionAddress(const char *func_name, uptr *func_addr, + uptr real, uptr wrapper) { + *func_addr = (uptr)GetFuncAddr(func_name); + return real == wrapper; +} + void *GetFuncAddr(const char *name) { #if SANITIZER_NETBSD // FIXME: Find a better way to handle renames diff --git a/lib/interception/interception_linux.h b/lib/interception/interception_linux.h index 0acb4e80b..4c60bd880 100644 --- a/lib/interception/interception_linux.h +++ b/lib/interception/interception_linux.h @@ -22,18 +22,24 @@ #define INTERCEPTION_LINUX_H namespace __interception { +// returns true if a function with the given name was found. +bool GetRealFunctionAddress(const char *func_name, uptr *func_addr, + uptr real, uptr wrapper); void *GetFuncAddr(const char *name); void *GetFuncAddrVer(const char *name, const char *ver); } // namespace __interception #define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ - (REAL(func) = (FUNC_TYPE(func)) ::__interception::GetFuncAddr(#func)) + ::__interception::GetRealFunctionAddress( \ + #func, (::__interception::uptr *)&__interception::PTR_TO_REAL(func), \ + (::__interception::uptr) & (func), \ + (::__interception::uptr) & WRAP(func)) // Android, Solaris and OpenBSD do not have dlvsym #if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD -#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ - (REAL(func) = \ - (FUNC_TYPE(func)) ::__interception::GetFuncAddrVer(#func, symver)) +#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ + (::__interception::real_##func = (func##_type)( \ + unsigned long)::__interception::GetFuncAddrVer(#func, symver)) #else #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) diff --git a/lib/interception/tests/interception_linux_test.cc b/lib/interception/tests/interception_linux_test.cc index 3aade45eb..5a1ca6ecb 100644 --- a/lib/interception/tests/interception_linux_test.cc +++ b/lib/interception/tests/interception_linux_test.cc @@ -33,6 +33,17 @@ INTERCEPTOR(int, isdigit, int d) { namespace __interception { +TEST(Interception, GetRealFunctionAddress) { + uptr malloc_address = 0; + EXPECT_TRUE(GetRealFunctionAddress("malloc", &malloc_address, 0, 0)); + EXPECT_NE(0U, malloc_address); + + uptr dummy_address = 0; + EXPECT_TRUE( + GetRealFunctionAddress("dummy_doesnt_exist__", &dummy_address, 0, 0)); + EXPECT_EQ(0U, dummy_address); +} + TEST(Interception, GetFuncAddr) { EXPECT_NE(GetFuncAddr("malloc"), nullptr); EXPECT_EQ(GetFuncAddr("does_not_exist"), nullptr); diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index 46fbb0f1b..f5120809e 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -1243,16 +1243,13 @@ int OnExit() { #define MSAN_INTERCEPT_FUNC(name) \ do { \ - INTERCEPT_FUNCTION(name); \ - if (&(name) != &WRAP(name) || !REAL(name)) \ + if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \ VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \ } while (0) #define MSAN_INTERCEPT_FUNC_VER(name, ver) \ do { \ - INTERCEPT_FUNCTION_VER(name, ver); \ - name##_type ptr = (::__interception::real_##name); \ - if (&(name) != &WRAP(name) || !REAL(name)) \ + if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \ VReport( \ 1, "MemorySanitizer: failed to intercept '" #name "@@" #ver "'\n"); \ } while (0) diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index b0cc4f57b..28cebb673 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -573,8 +573,12 @@ TSAN_INTERCEPTOR(int, sigsetjmp, void *env); #endif #define TSAN_INTERCEPTOR_SETJMP_(x) __interceptor_ ## x -#define TSAN_INTERCEPTOR_SETJMP TSAN_INTERCEPTOR_SETJMP_(setjmp_symname) -#define TSAN_INTERCEPTOR_SIGSETJMP TSAN_INTERCEPTOR_SETJMP_(sigsetjmp_symname) +#define TSAN_INTERCEPTOR_SETJMP__(x) TSAN_INTERCEPTOR_SETJMP_(x) +#define TSAN_INTERCEPTOR_SETJMP TSAN_INTERCEPTOR_SETJMP__(setjmp_symname) +#define TSAN_INTERCEPTOR_SIGSETJMP TSAN_INTERCEPTOR_SETJMP__(sigsetjmp_symname) + +#define TSAN_STRING_SETJMP SANITIZER_STRINGIFY(setjmp_symname) +#define TSAN_STRING_SIGSETJMP SANITIZER_STRINGIFY(sigsetjmp_symname) // Not called. Merely to satisfy TSAN_INTERCEPT(). extern "C" SANITIZER_INTERFACE_ATTRIBUTE @@ -2639,12 +2643,18 @@ void InitializeInterceptors() { InitializeSignalInterceptors(); InitializeLibdispatchInterceptors(); - TSAN_INTERCEPT(setjmp_symname); - TSAN_INTERCEPT(_setjmp); - TSAN_INTERCEPT(sigsetjmp_symname); - +#if !SANITIZER_MAC + // We can not use TSAN_INTERCEPT to get setjmp addr, + // because it does &setjmp and setjmp is not present in some versions of libc. + using __interception::GetRealFunctionAddress; + GetRealFunctionAddress(TSAN_STRING_SETJMP, + (uptr*)&REAL(setjmp_symname), 0, 0); + GetRealFunctionAddress("_setjmp", (uptr*)&REAL(_setjmp), 0, 0); + GetRealFunctionAddress(TSAN_STRING_SIGSETJMP, + (uptr*)&REAL(sigsetjmp_symname), 0, 0); #if !SANITIZER_NETBSD - TSAN_INTERCEPT(__sigsetjmp); + GetRealFunctionAddress("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0); +#endif #endif TSAN_INTERCEPT(longjmp_symname); |