[compiler-rt] r293952 - [sanitizer] Intercept weak functions in dll_thunks.

Marcos Pividori via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 2 15:01:35 PST 2017


Author: mpividori
Date: Thu Feb  2 17:01:34 2017
New Revision: 293952

URL: http://llvm.org/viewvc/llvm-project?rev=293952&view=rev
Log:
[sanitizer] Intercept weak functions in dll_thunks.

In this diff, I update current implementation of the interception in dll_thunks
to consider the special case of weak functions.
First we check if the client has redefined the function in the main executable
(for example: __sanitizer_cov_trace_pc_guard). It we can't find it, then we look
for the default implementation (__sanitizer_cov_trace_pc_guard__dll). The
default implementation is always available because the static runtime is linked
to the main executable.

Differential Revision: https://reviews.llvm.org/D29155

Modified:
    compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.h
    compiler-rt/trunk/lib/ubsan/ubsan_win_dll_thunk.cc

Modified: compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc?rev=293952&r1=293951&r2=293952&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc Thu Feb  2 17:01:34 2017
@@ -24,7 +24,7 @@
 
 // ASan own interface functions.
 #define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
-#define INTERFACE_WEAK_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
 #include "asan_interface.inc"
 
 // Memory allocation functions.

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc?rev=293952&r1=293951&r2=293952&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc Thu Feb  2 17:01:34 2017
@@ -16,6 +16,6 @@
 #include "sanitizer_win_dll_thunk.h"
 // Sanitizer Coverage interface functions.
 #define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
-#define INTERFACE_WEAK_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
 #include "sanitizer_coverage_interface.inc"
 #endif // SANITIZER_DLL_THUNK

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.cc?rev=293952&r1=293951&r2=293952&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.cc Thu Feb  2 17:01:34 2017
@@ -37,11 +37,22 @@ int dllThunkIntercept(const char* main_f
     abort();
   return 0;
 }
+
+int dllThunkInterceptWhenPossible(const char* main_function,
+    const char* default_function, uptr dll_function) {
+  uptr wrapper = __interception::InternalGetProcAddress(
+    (void *)GetModuleHandleA(0), main_function);
+  if (!wrapper)
+    wrapper = dllThunkGetRealAddrOrDie(default_function);
+  if (!__interception::OverrideFunction(dll_function, wrapper, 0))
+    abort();
+  return 0;
+}
 } // namespace __sanitizer
 
 // Include Sanitizer Common interface.
 #define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
-#define INTERFACE_WEAK_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
 #include "sanitizer_common_interface.inc"
 
 #pragma section(".DLLTH$A", read)  // NOLINT

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.h?rev=293952&r1=293951&r2=293952&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win_dll_thunk.h Thu Feb  2 17:01:34 2017
@@ -19,6 +19,9 @@ namespace __sanitizer {
 uptr dllThunkGetRealAddrOrDie(const char *name);
 
 int dllThunkIntercept(const char* main_function, uptr dll_function);
+
+int dllThunkInterceptWhenPossible(const char* main_function,
+    const char* default_function, uptr dll_function);
 }
 
 extern "C" int __dll_thunk_init();
@@ -34,6 +37,17 @@ extern "C" int __dll_thunk_init();
   __declspec(allocate(".DLLTH$M")) int (*__dll_thunk_##dll_function)() =       \
     intercept_##dll_function;
 
+// Try to override dll_function with main_function from main executable.
+// If main_function is not present, override dll_function with default_function.
+#define INTERCEPT_WHEN_POSSIBLE(main_function, default_function, dll_function) \
+  static int intercept_##dll_function() {                                      \
+    return __sanitizer::dllThunkInterceptWhenPossible(main_function,           \
+        default_function, (__sanitizer::uptr)dll_function);                    \
+  }                                                                            \
+  __pragma(section(".DLLTH$M", long, read))                                    \
+  __declspec(allocate(".DLLTH$M")) int (*__dll_thunk_##dll_function)() =       \
+    intercept_##dll_function;
+
 // -------------------- Function interception macros ------------------------ //
 // Special case of hooks -- ASan own interface functions.  Those are only called
 // after __asan_init, thus an empty implementation is sufficient.
@@ -44,6 +58,17 @@ extern "C" int __dll_thunk_init();
   }                                                                            \
   INTERCEPT_OR_DIE(#name, name)
 
+// Special case of hooks -- Weak functions, could be redefined in the main
+// executable, but that is not necessary, so we shouldn't die if we can not find
+// a reference. Instead, when the function is not present in the main executable
+// we consider the default impl provided by asan library.
+#define INTERCEPT_SANITIZER_WEAK_FUNCTION(name)                                \
+  extern "C" __declspec(noinline) void name() {                                \
+    volatile int prevent_icf = (__LINE__ << 8); (void)prevent_icf;             \
+    __debugbreak();                                                            \
+  }                                                                            \
+  INTERCEPT_WHEN_POSSIBLE(#name, STRINGIFY(WEAK_EXPORT_NAME(name)), name)
+
 // We can't define our own version of strlen etc. because that would lead to
 // link-time or even type mismatch errors.  Instead, we can declare a function
 // just to be able to get its address.  Me may miss the first few calls to the

Modified: compiler-rt/trunk/lib/ubsan/ubsan_win_dll_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_win_dll_thunk.cc?rev=293952&r1=293951&r2=293952&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_win_dll_thunk.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_win_dll_thunk.cc Thu Feb  2 17:01:34 2017
@@ -16,6 +16,6 @@
 #include "sanitizer_common/sanitizer_win_dll_thunk.h"
 // Ubsan interface functions.
 #define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
-#define INTERFACE_WEAK_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
 #include "ubsan_interface.inc"
 #endif // SANITIZER_DLL_THUNK




More information about the llvm-commits mailing list