diff options
Diffstat (limited to 'compiler-rt/lib/interception')
-rw-r--r-- | compiler-rt/lib/interception/interception_linux.cc | 6 | ||||
-rw-r--r-- | compiler-rt/lib/interception/interception_linux.h | 14 | ||||
-rw-r--r-- | compiler-rt/lib/interception/tests/interception_linux_test.cc | 11 |
3 files changed, 27 insertions, 4 deletions
diff --git a/compiler-rt/lib/interception/interception_linux.cc b/compiler-rt/lib/interception/interception_linux.cc index 64d04d8df51..d019d482d6d 100644 --- a/compiler-rt/lib/interception/interception_linux.cc +++ b/compiler-rt/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/compiler-rt/lib/interception/interception_linux.h b/compiler-rt/lib/interception/interception_linux.h index 0acb4e80b8c..4c60bd88090 100644 --- a/compiler-rt/lib/interception/interception_linux.h +++ b/compiler-rt/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/compiler-rt/lib/interception/tests/interception_linux_test.cc b/compiler-rt/lib/interception/tests/interception_linux_test.cc index 3aade45ebcd..5a1ca6ecbf5 100644 --- a/compiler-rt/lib/interception/tests/interception_linux_test.cc +++ b/compiler-rt/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); |