summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Lettner <jlettner@apple.com>2019-05-01 20:57:59 +0000
committerJulian Lettner <jlettner@apple.com>2019-05-01 20:57:59 +0000
commit91448959dae346b8ccb85693f3f94f79f9e0b33d (patch)
treeef53c52d0e072bdf4d85d23119f11d9a9f381c12
parent99cd89c106a10f18ccbaeda9a920d28ae3e943cf (diff)
downloadcompiler-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.h4
-rw-r--r--lib/interception/interception_linux.cc24
-rw-r--r--lib/interception/interception_linux.h25
-rw-r--r--lib/interception/tests/interception_linux_test.cc15
-rw-r--r--lib/msan/msan_interceptors.cc4
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc13
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