Index: lib/asan/CMakeLists.txt =================================================================== --- lib/asan/CMakeLists.txt +++ lib/asan/CMakeLists.txt @@ -26,7 +26,8 @@ asan_suppressions.cc asan_thread.cc asan_win.cc - asan_win_coverage_sections.cc) + asan_win_coverage_sections.cc + asan_win_weak_interception.cc) set(ASAN_CXX_SOURCES asan_new_delete.cc) Index: lib/asan/asan_win_weak_interception.cc =================================================================== --- /dev/null +++ lib/asan/asan_win_weak_interception.cc @@ -0,0 +1,92 @@ +//===-- asan_win_weak_interception.cc -------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This module should be statically linked to the Asan dll library in order to +// delegate the calls of weak functions to the implementation in the main +// executable when possible. (Based on: asan_win_dll_thunk.cc) +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_platform.h" +#if SANITIZER_WINDOWS && ASAN_DYNAMIC +#include "asan_interface_internal.h" +#include "interception/interception.h" +#include "sanitizer_common/sanitizer_allocator_interface.h" +#include "sanitizer_common/sanitizer_interface_internal.h" +#include "sanitizer_common/sanitizer_platform_interceptors.h" + +#ifdef _M_IX86 +#define WINAPI __stdcall +#else +#define WINAPI +#endif + +// Interception helper functions and macros. +extern "C" { +void *WINAPI GetModuleHandleA(const char *module_name); +void *WINAPI GetProcAddress(void *module, const char *proc_name); +void abort(); +} + +using __sanitizer::uptr; +using __sanitizer::u32; + +// Try to get a pointer to real_function in the main module and override +// dll_function with that pointer. If the function isn't found, nothing changes. +static void interceptWhenPossible(uptr dll_function, + const char *real_function) { + uptr real = __interception::InternalGetProcAddress( + (void *)GetModuleHandleA(0), real_function); + if (real && !__interception::OverrideFunction((uptr)dll_function, real, 0)) + abort(); +} + +// Override default functions with implementation provided by users. +#define INTERCEPT_WEAK(Name) \ + interceptWhenPossible((uptr) Name, #Name); + +static int asan_weak_init() { + // We need to intercept weak functions and delegate the calls to the + // implementation in the main executable when non-defult implementations are + // provided. + INTERCEPT_WEAK(__sanitizer_malloc_hook) + INTERCEPT_WEAK(__sanitizer_free_hook) + INTERCEPT_WEAK(__sanitizer_print_memory_profile) + INTERCEPT_WEAK(__sanitizer_sandbox_on_notify) + INTERCEPT_WEAK(__sanitizer_report_error_summary) + INTERCEPT_WEAK(__sanitizer_cov_trace_cmp) + INTERCEPT_WEAK(__sanitizer_cov_trace_cmp1) + INTERCEPT_WEAK(__sanitizer_cov_trace_cmp2) + INTERCEPT_WEAK(__sanitizer_cov_trace_cmp4) + INTERCEPT_WEAK(__sanitizer_cov_trace_cmp8) + INTERCEPT_WEAK(__sanitizer_cov_trace_switch) + INTERCEPT_WEAK(__sanitizer_cov_trace_div4) + INTERCEPT_WEAK(__sanitizer_cov_trace_div8) + INTERCEPT_WEAK(__sanitizer_cov_trace_gep) + INTERCEPT_WEAK(__sanitizer_cov_trace_pc_indir) + INTERCEPT_WEAK(__sanitizer_cov_trace_pc_guard) + INTERCEPT_WEAK(__sanitizer_cov_trace_pc_guard_init) + INTERCEPT_WEAK(__asan_default_options) + INTERCEPT_WEAK(__asan_on_error) + // In DLLs, the callbacks are expected to return 0, + // otherwise CRT initialization fails. + return 0; +} + +#pragma section(".CRT$XIB", long, read) // NOLINT +__declspec(allocate(".CRT$XIB")) int (*__asan_weak_preinit)() = asan_weak_init; + +static void WINAPI asan_weak_thread_init(void *mod, unsigned long reason, + void *reserved) { + if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_weak_init(); +} + +#pragma section(".CRT$XLAB", long, read) // NOLINT +__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_weak_tls_init)(void *, + unsigned long, void *) = asan_weak_thread_init; + +#endif // SANITIZER_WINDOWS && ASAN_DYNAMIC