diff options
author | Julian Lettner <jlettner@apple.com> | 2019-05-01 20:57:59 +0000 |
---|---|---|
committer | Julian Lettner <jlettner@apple.com> | 2019-05-01 20:57:59 +0000 |
commit | 91448959dae346b8ccb85693f3f94f79f9e0b33d (patch) | |
tree | ef53c52d0e072bdf4d85d23119f11d9a9f381c12 | |
parent | 99cd89c106a10f18ccbaeda9a920d28ae3e943cf (diff) | |
download | compiler-rt-91448959dae346b8ccb85693f3f94f79f9e0b33d.tar.gz |
[Sanitizer] Reland "Cleanup INTERCEPT_FUNCTION macro"
On Linux both version of the INTERCEPT_FUNCTION macro now return true
when interception was successful. Adapt and cleanup some usages.
Also note that `&(func) == &WRAP(func)` is a link-time property, but we
do a runtime check.
Tested on Linux and macOS.
Previous attempt reverted by: 5642c3feb03d020dc06a62e3dc54f3206a97a391
This attempt to bring order to the interceptor macro goes the other
direction and aligns the Linux implementation with the way things are
done on Windows.
Reviewed By: vitalybuka, rnk
Differential Revision: https://reviews.llvm.org/D61358
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@359725 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/asan/asan_interceptors.h | 4 | ||||
-rw-r--r-- | lib/interception/interception_linux.cc | 24 | ||||
-rw-r--r-- | lib/interception/interception_linux.h | 25 | ||||
-rw-r--r-- | lib/interception/tests/interception_linux_test.cc | 15 | ||||
-rw-r--r-- | lib/msan/msan_interceptors.cc | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors.cc | 13 |
6 files changed, 45 insertions, 40 deletions
diff --git a/lib/asan/asan_interceptors.h b/lib/asan/asan_interceptors.h index 903ab5991..2792e2f14 100644 --- a/lib/asan/asan_interceptors.h +++ b/lib/asan/asan_interceptors.h @@ -122,12 +122,12 @@ DECLARE_REAL(char*, strstr, const char *s1, const char *s2) #if !SANITIZER_MAC #define ASAN_INTERCEPT_FUNC(name) \ do { \ - if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \ + if (!INTERCEPT_FUNCTION(name)) \ VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \ } while (0) #define ASAN_INTERCEPT_FUNC_VER(name, ver) \ do { \ - if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \ + if (!INTERCEPT_FUNCTION_VER(name, ver)) \ 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 d019d482d..d07f060b5 100644 --- a/lib/interception/interception_linux.cc +++ b/lib/interception/interception_linux.cc @@ -33,13 +33,7 @@ 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) { +static void *GetFuncAddr(const char *name) { #if SANITIZER_NETBSD // FIXME: Find a better way to handle renames if (StrCmp(name, "sigaction")) @@ -57,11 +51,25 @@ void *GetFuncAddr(const char *name) { return addr; } +bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, + uptr wrapper) { + void *addr = GetFuncAddr(name); + *ptr_to_real = (uptr)addr; + return addr && (func == wrapper); +} + // Android and Solaris do not have dlvsym #if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD -void *GetFuncAddrVer(const char *name, const char *ver) { +static void *GetFuncAddr(const char *name, const char *ver) { return dlvsym(RTLD_NEXT, name, ver); } + +bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, + uptr func, uptr wrapper) { + void *addr = GetFuncAddr(name, ver); + *ptr_to_real = (uptr)addr; + return addr && (func == wrapper); +} #endif // !SANITIZER_ANDROID } // namespace __interception diff --git a/lib/interception/interception_linux.h b/lib/interception/interception_linux.h index 4c60bd880..e578da0cf 100644 --- a/lib/interception/interception_linux.h +++ b/lib/interception/interception_linux.h @@ -22,24 +22,27 @@ #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); +bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, + uptr wrapper); +bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, + uptr func, uptr wrapper); } // namespace __interception -#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ - ::__interception::GetRealFunctionAddress( \ - #func, (::__interception::uptr *)&__interception::PTR_TO_REAL(func), \ - (::__interception::uptr) & (func), \ +#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ + ::__interception::InterceptFunction( \ + #func, \ + (::__interception::uptr *) & 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) \ - (::__interception::real_##func = (func##_type)( \ - unsigned long)::__interception::GetFuncAddrVer(#func, symver)) + ::__interception::InterceptFunction( \ + #func, symver, \ + (::__interception::uptr *) & REAL(func), \ + (::__interception::uptr) & (func), \ + (::__interception::uptr) & WRAP(func)) #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 5a1ca6ecb..3e859cb1a 100644 --- a/lib/interception/tests/interception_linux_test.cc +++ b/lib/interception/tests/interception_linux_test.cc @@ -33,24 +33,19 @@ INTERCEPTOR(int, isdigit, int d) { namespace __interception { -TEST(Interception, GetRealFunctionAddress) { +TEST(Interception, InterceptFunction) { uptr malloc_address = 0; - EXPECT_TRUE(GetRealFunctionAddress("malloc", &malloc_address, 0, 0)); + EXPECT_TRUE(InterceptFunction("malloc", &malloc_address, 0, 0)); EXPECT_NE(0U, malloc_address); + EXPECT_FALSE(InterceptFunction("malloc", &malloc_address, 0, 1)); uptr dummy_address = 0; - EXPECT_TRUE( - GetRealFunctionAddress("dummy_doesnt_exist__", &dummy_address, 0, 0)); + EXPECT_FALSE(InterceptFunction("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); -} - TEST(Interception, Basic) { - INTERCEPT_FUNCTION(isdigit); + EXPECT_TRUE(INTERCEPT_FUNCTION(isdigit)); // After interception, the counter should be incremented. InterceptorFunctionCalled = 0; diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index f67cfe489..af9d14029 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -1248,13 +1248,13 @@ int OnExit() { #define MSAN_INTERCEPT_FUNC(name) \ do { \ - if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \ + if (!INTERCEPT_FUNCTION(name)) \ VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \ } while (0) #define MSAN_INTERCEPT_FUNC_VER(name, ver) \ do { \ - if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \ + if (!INTERCEPT_FUNCTION_VER(name, ver)) \ 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 062a3622b..e8908ac98 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -2659,14 +2659,13 @@ void InitializeInterceptors() { #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); + using __interception::InterceptFunction; + InterceptFunction(TSAN_STRING_SETJMP, (uptr*)&REAL(setjmp_symname), 0, 0); + InterceptFunction("_setjmp", (uptr*)&REAL(_setjmp), 0, 0); + InterceptFunction(TSAN_STRING_SIGSETJMP, (uptr*)&REAL(sigsetjmp_symname), 0, + 0); #if !SANITIZER_NETBSD - GetRealFunctionAddress("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0); + InterceptFunction("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0); #endif #endif |