summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-04-30 20:59:56 +0000
committerReid Kleckner <rnk@google.com>2019-04-30 20:59:56 +0000
commit56d59bd9cdbd18d00d2b487812e19ff7302201c7 (patch)
tree0085f5061aec19ff1ad313fccfdc02e55af96aa3
parent0128c9bfa882ac8ca16929201352e3d8bea9aff8 (diff)
downloadcompiler-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.h6
-rw-r--r--lib/interception/interception_linux.cc6
-rw-r--r--lib/interception/interception_linux.h14
-rw-r--r--lib/interception/tests/interception_linux_test.cc11
-rw-r--r--lib/msan/msan_interceptors.cc7
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc24
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);