Index: lib/asan/asan_allocator.cc =================================================================== --- lib/asan/asan_allocator.cc +++ lib/asan/asan_allocator.cc @@ -956,17 +956,13 @@ return allocated_size; } -#if !SANITIZER_SUPPORTS_WEAK_HOOKS // Provide default (no-op) implementation of malloc hooks. extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_malloc_hook(void *ptr, uptr size) { +WEAK_DEF(void, __sanitizer_malloc_hook, (void *ptr, uptr size)) { (void)ptr; (void)size; } -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_free_hook(void *ptr) { +WEAK_DEF(void, __sanitizer_free_hook, (void *ptr)) { (void)ptr; } } // extern "C" -#endif Index: lib/asan/asan_flags.cc =================================================================== --- lib/asan/asan_flags.cc +++ lib/asan/asan_flags.cc @@ -181,9 +181,6 @@ } // namespace __asan -#if !SANITIZER_SUPPORTS_WEAK_HOOKS extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -const char* __asan_default_options() { return ""; } +WEAK_DEF(const char*, __asan_default_options, ()) { return ""; } } // extern "C" -#endif Index: lib/asan/asan_interface_internal.h =================================================================== --- lib/asan/asan_interface_internal.h +++ lib/asan/asan_interface_internal.h @@ -164,13 +164,11 @@ SANITIZER_INTERFACE_ATTRIBUTE void __asan_set_error_report_callback(void (*callback)(const char*)); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - /* OPTIONAL */ void __asan_on_error(); + WEAK_INTERFACE_DECL(void, __asan_on_error, ()); SANITIZER_INTERFACE_ATTRIBUTE void __asan_print_accumulated_stats(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - /* OPTIONAL */ const char* __asan_default_options(); + WEAK_INTERFACE_DECL(const char*, __asan_default_options, ()); SANITIZER_INTERFACE_ATTRIBUTE extern uptr __asan_shadow_memory_dynamic_address; Index: lib/asan/asan_report.cc =================================================================== --- lib/asan/asan_report.cc +++ lib/asan/asan_report.cc @@ -488,9 +488,6 @@ } } // extern "C" -#if !SANITIZER_SUPPORTS_WEAK_HOOKS // Provide default implementation of __asan_on_error that does nothing // and may be overriden by user. -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE -void __asan_on_error() {} -#endif +WEAK_DEF(void, __asan_on_error, ()) {} Index: lib/asan/asan_suppressions.cc =================================================================== --- lib/asan/asan_suppressions.cc +++ lib/asan/asan_suppressions.cc @@ -32,13 +32,7 @@ kODRViolation}; extern "C" { -#if SANITIZER_SUPPORTS_WEAK_HOOKS -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -const char *__asan_default_suppressions(); -#else -// No week hooks, provide empty implementation. -const char *__asan_default_suppressions() { return ""; } -#endif // SANITIZER_SUPPORTS_WEAK_HOOKS +WEAK_DEF(const char *, __asan_default_suppressions, ()) { return ""; } } // extern "C" void InitializeSuppressions() { Index: lib/asan/asan_win.cc =================================================================== --- lib/asan/asan_win.cc +++ lib/asan/asan_win.cc @@ -43,18 +43,6 @@ __asan_init(); return __asan_shadow_memory_dynamic_address; } - -void __sanitizer_default_malloc_hook(void *ptr, uptr size) { } -void __sanitizer_default_free_hook(void *ptr) { } -const char* __asan_default_default_options() { return ""; } -const char* __asan_default_default_suppressions() { return ""; } -void __asan_default_on_error() {} - -WIN_WEAK_ALIAS(__sanitizer_malloc_hook, __sanitizer_default_malloc_hook) -WIN_WEAK_ALIAS(__sanitizer_free_hook, __sanitizer_default_free_hook) -WIN_WEAK_ALIAS(__asan_default_options, __asan_default_default_options) -WIN_WEAK_ALIAS(__asan_default_suppressions, __asan_default_default_suppressions) -WIN_WEAK_ALIAS(__asan_on_error, __asan_default_on_error) } // extern "C" // ---------------------- Windows-specific interceptors ---------------- {{{ Index: lib/sanitizer_common/sancov_flags.h =================================================================== --- lib/sanitizer_common/sancov_flags.h +++ lib/sanitizer_common/sancov_flags.h @@ -32,9 +32,9 @@ void InitializeSancovFlags(); -extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE const char* -__sancov_default_options(); - +extern "C" { +WEAK_INTERFACE_DECL(const char*, __sancov_default_options, ()); +} } // namespace __sancov #endif Index: lib/sanitizer_common/sanitizer_allocator_interface.h =================================================================== --- lib/sanitizer_common/sanitizer_allocator_interface.h +++ lib/sanitizer_common/sanitizer_allocator_interface.h @@ -33,14 +33,9 @@ void (*malloc_hook)(const void *, uptr), void (*free_hook)(const void *)); -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - /* OPTIONAL */ void __sanitizer_malloc_hook(void *ptr, uptr size); -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - /* OPTIONAL */ void __sanitizer_free_hook(void *ptr); - - -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_print_memory_profile(int top_percent); +WEAK_INTERFACE_DECL(void, __sanitizer_malloc_hook, (void *ptr, uptr size)); +WEAK_INTERFACE_DECL(void, __sanitizer_free_hook, (void *ptr)); +WEAK_INTERFACE_DECL(void, __sanitizer_print_memory_profile, (int top_percent)); } // extern "C" #endif // SANITIZER_ALLOCATOR_INTERFACE_H Index: lib/sanitizer_common/sanitizer_common.cc =================================================================== --- lib/sanitizer_common/sanitizer_common.cc +++ lib/sanitizer_common/sanitizer_common.cc @@ -505,9 +505,8 @@ return InstallMallocFreeHooks(malloc_hook, free_hook); } -#if !SANITIZER_GO && !SANITIZER_SUPPORTS_WEAK_HOOKS -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_print_memory_profile(int top_percent) { +#if !SANITIZER_GO +WEAK_DEF(void, __sanitizer_print_memory_profile, (int top_percent)) { (void)top_percent; } #endif Index: lib/sanitizer_common/sanitizer_coverage_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_coverage_libcdep.cc +++ lib/sanitizer_common/sanitizer_coverage_libcdep.cc @@ -1016,27 +1016,16 @@ uptr __sanitizer_update_counter_bitset_and_clear_counters(u8 *bitset) { return coverage_data.Update8bitCounterBitsetAndClearCounters(bitset); } + // Default empty implementations (weak). Users should redefine them. -#if !SANITIZER_WINDOWS // weak does not work on Windows. -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_cmp() {} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_cmp1() {} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_cmp2() {} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_cmp4() {} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_cmp8() {} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_switch() {} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_div4() {} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_div8() {} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_gep() {} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_cov_trace_pc_indir() {} -#endif // !SANITIZER_WINDOWS +WEAK_DEF(void, __sanitizer_cov_trace_cmp, ()) {} +WEAK_DEF(void, __sanitizer_cov_trace_cmp1, ()) {} +WEAK_DEF(void, __sanitizer_cov_trace_cmp2, ()) {} +WEAK_DEF(void, __sanitizer_cov_trace_cmp4, ()) {} +WEAK_DEF(void, __sanitizer_cov_trace_cmp8, ()) {} +WEAK_DEF(void, __sanitizer_cov_trace_switch, ()) {} +WEAK_DEF(void, __sanitizer_cov_trace_div4, ()) {} +WEAK_DEF(void, __sanitizer_cov_trace_div8, ()) {} +WEAK_DEF(void, __sanitizer_cov_trace_gep, ()) {} +WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, ()) {} } // extern "C" Index: lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc =================================================================== --- lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc +++ lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc @@ -161,14 +161,12 @@ return __sancov::SanitizerDumpCoverage(pcs, len); } -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void -__sanitizer_cov_trace_pc_guard(u32* guard) { +WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, (u32* guard)) { if (!*guard) return; __sancov::pc_guard_controller.TracePcGuard(guard, GET_CALLER_PC() - 1); } -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void -__sanitizer_cov_trace_pc_guard_init(u32* start, u32* end) { +WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, (u32* start, u32* end)) { if (start == end) return; __sancov::pc_guard_controller.InitTracePcGuard(start, end); } Index: lib/sanitizer_common/sanitizer_interface_internal.h =================================================================== --- lib/sanitizer_common/sanitizer_interface_internal.h +++ lib/sanitizer_common/sanitizer_interface_internal.h @@ -37,14 +37,14 @@ } __sanitizer_sandbox_arguments; // Notify the tools that the sandbox is going to be turned on. - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void - __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args); + WEAK_INTERFACE_DECL(void, __sanitizer_sandbox_on_notify, + (__sanitizer_sandbox_arguments *args)); // This function is called by the tool when it has just finished reporting // an error. 'error_summary' is a one-line string that summarizes // the error message. This function can be overridden by the client. - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_report_error_summary(const char *error_summary); + WEAK_INTERFACE_DECL(void, __sanitizer_report_error_summary, + (const char *error_summary)); SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init(); SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump(); Index: lib/sanitizer_common/sanitizer_internal_defs.h =================================================================== --- lib/sanitizer_common/sanitizer_internal_defs.h +++ lib/sanitizer_common/sanitizer_internal_defs.h @@ -14,6 +14,7 @@ #define SANITIZER_DEFS_H #include "sanitizer_platform.h" +#include "sanitizer_win_defs.h" #ifndef SANITIZER_DEBUG # define SANITIZER_DEBUG 0 @@ -24,12 +25,50 @@ # define SANITIZER_INTERFACE_ATTRIBUTE __declspec(dllexport) // FIXME find out what we need on Windows, if anything. # define SANITIZER_WEAK_ATTRIBUTE +// In Windows, we don't have a direct equivalent of weak symbols, but we can +// use WIN_WEAK_ALIAS() which defines an alias to a default implementation, and +// only works when linking statically. +// So, to define a weak function "fun", we define a default implementation with +// a different name "fun__def" and we create a "weak alias" fun = fun__def. +// Then, users can override it just defining "fun". +// We impose "extern "C"" because otherwise WIN_WEAK_ALIAS() will fail because +// of name mangling. +// Name for default implementation of weak function. +# define WEAK_DEF_NAME(Name) Name##__def +// Use this macro when you need to define a weak function. For example: +// WEAK_DEF(bool, compare, (int a, int b)) { return a > b; } +# define WEAK_DEF(ReturnType, Name, Params) \ + WIN_WEAK_ALIAS(Name, WEAK_DEF_NAME(Name)) \ + extern "C" ReturnType Name Params; \ + extern "C" ReturnType WEAK_DEF_NAME(Name) Params +// Use this macro when you need to declare and export a weak function. +// For example: WEAK_INTERFACE_DECL(bool, compare, (int a, int b)); +# define WEAK_INTERFACE_DECL(ReturnType, Name, Params) \ + extern "C" ReturnType Name Params; \ + extern "C" SANITIZER_INTERFACE_ATTRIBUTE ReturnType WEAK_DEF_NAME(Name) Params +// So, for Windows we provide something similar to weak symbols in Linux, with +// some differences: +// + Always a default implementation must me provided. +// + When linking dynamically with a library (dll), only the default +// implementation is provided (fun__def()). If some unit overrides the function +// (redefining fun()), the rest of the units (other dlls, or main executable) +// doesn't have access to it (which is different in linux). When access to the +// implementation in a different unit is required, interception can be used. #elif SANITIZER_GO # define SANITIZER_INTERFACE_ATTRIBUTE # define SANITIZER_WEAK_ATTRIBUTE +# define WEAK_DEF(ReturnType, Name, Params) \ + extern "C" ReturnType Name Params +# define WEAK_INTERFACE_DECL(ReturnType, Name, Params) \ + extern "C" SANITIZER_INTERFACE_ATTRIBUTE ReturnType Name Params #else # define SANITIZER_INTERFACE_ATTRIBUTE __attribute__((visibility("default"))) # define SANITIZER_WEAK_ATTRIBUTE __attribute__((weak)) +# define WEAK_DEF(ReturnType, Name, Params) \ + extern "C" SANITIZER_WEAK_ATTRIBUTE ReturnType Name Params +# define WEAK_INTERFACE_DECL(ReturnType, Name, Params) \ + extern "C" SANITIZER_INTERFACE_ATTRIBUTE \ + SANITIZER_WEAK_ATTRIBUTE ReturnType Name Params #endif #if (SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_WINDOWS) && !SANITIZER_GO Index: lib/sanitizer_common/sanitizer_printf.cc =================================================================== --- lib/sanitizer_common/sanitizer_printf.cc +++ lib/sanitizer_common/sanitizer_printf.cc @@ -213,10 +213,10 @@ PrintfAndReportCallback = callback; } +extern "C" { // Can be overriden in frontend. #if SANITIZER_SUPPORTS_WEAK_HOOKS -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void OnPrint(const char *str) { +WEAK_DEF(void, OnPrint, (const char *str)) { (void)str; } #elif SANITIZER_GO && defined(TSAN_EXTERNAL_HOOKS) @@ -226,6 +226,7 @@ (void)str; } #endif +} // extern "C" static void CallPrintfAndReportCallback(const char *str) { OnPrint(str); Index: lib/sanitizer_common/sanitizer_win.cc =================================================================== --- lib/sanitizer_common/sanitizer_win.cc +++ lib/sanitizer_common/sanitizer_win.cc @@ -940,15 +940,4 @@ } // namespace __sanitizer -#if !SANITIZER_GO -// Workaround to implement weak hooks on Windows. COFF doesn't directly support -// weak symbols, but it does support /alternatename, which is similar. If the -// user does not override the hook, we will use this default definition instead -// of null. -extern "C" void __sanitizer_print_memory_profile(int top_percent) {} - -WIN_WEAK_ALIAS(__sanitizer_print_memory_profile, - __sanitizer_default_print_memory_profile) -#endif - #endif // _WIN32 Index: lib/ubsan/ubsan_flags.h =================================================================== --- lib/ubsan/ubsan_flags.h +++ lib/ubsan/ubsan_flags.h @@ -42,8 +42,7 @@ extern "C" { // Users may provide their own implementation of __ubsan_default_options to // override the default flag values. -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -const char *__ubsan_default_options(); +WEAK_INTERFACE_DECL(const char *, __ubsan_default_options, ()); } // extern "C" #endif // UBSAN_FLAGS_H Index: lib/ubsan/ubsan_flags.cc =================================================================== --- lib/ubsan/ubsan_flags.cc +++ lib/ubsan/ubsan_flags.cc @@ -70,16 +70,7 @@ extern "C" { -#if !SANITIZER_SUPPORTS_WEAK_HOOKS -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -const char *__ubsan_default_options() { return ""; } -#endif - -#if SANITIZER_WINDOWS -const char *__ubsan_default_default_options() { return ""; } - -WIN_WEAK_ALIAS(__ubsan_default_options, __ubsan_default_default_options) -#endif +WEAK_DEF(const char *, __ubsan_default_options, ()) { return ""; } } // extern "C"