forked from OSchip/llvm-project
[sanitizer] [asan] Use macros to simplify weak aliases on Windows.
This patch adds some useful macros for dealing with pragma directives on Windows. Also, I add appropriate documentation for future users. Differential Revision: https://reviews.llvm.org/D28525 llvm-svn: 292650
This commit is contained in:
parent
68af279533
commit
74694b19e0
|
@ -1,34 +0,0 @@
|
||||||
//===-- asan_globals_win.h --------------------------------------*- C++ -*-===//
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file is distributed under the University of Illinois Open Source
|
|
||||||
// License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// Interface to the Windows-specific global management code. Separated into a
|
|
||||||
// standalone header to allow inclusion from asan_win_dynamic_runtime_thunk,
|
|
||||||
// which defines symbols that clash with other sanitizer headers.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#ifndef ASAN_GLOBALS_WIN_H
|
|
||||||
#define ASAN_GLOBALS_WIN_H
|
|
||||||
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
#error "this file is Windows-only, and uses MSVC pragmas"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN64)
|
|
||||||
#define SANITIZER_SYM_PREFIX
|
|
||||||
#else
|
|
||||||
#define SANITIZER_SYM_PREFIX "_"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Use this macro to force linking asan_globals_win.cc into the DSO.
|
|
||||||
#define ASAN_LINK_GLOBALS_WIN() \
|
|
||||||
__pragma( \
|
|
||||||
comment(linker, "/include:" SANITIZER_SYM_PREFIX "__asan_dso_reg_hook"))
|
|
||||||
|
|
||||||
#endif // ASAN_GLOBALS_WIN_H
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "asan_globals_win.h"
|
|
||||||
#include "asan_interceptors.h"
|
#include "asan_interceptors.h"
|
||||||
#include "asan_internal.h"
|
#include "asan_internal.h"
|
||||||
#include "asan_report.h"
|
#include "asan_report.h"
|
||||||
|
@ -28,6 +27,7 @@
|
||||||
#include "asan_mapping.h"
|
#include "asan_mapping.h"
|
||||||
#include "sanitizer_common/sanitizer_libc.h"
|
#include "sanitizer_common/sanitizer_libc.h"
|
||||||
#include "sanitizer_common/sanitizer_mutex.h"
|
#include "sanitizer_common/sanitizer_mutex.h"
|
||||||
|
#include "sanitizer_common/sanitizer_win_defs.h"
|
||||||
|
|
||||||
using namespace __asan; // NOLINT
|
using namespace __asan; // NOLINT
|
||||||
|
|
||||||
|
@ -44,31 +44,17 @@ uptr __asan_get_shadow_memory_dynamic_address() {
|
||||||
return __asan_shadow_memory_dynamic_address;
|
return __asan_shadow_memory_dynamic_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------- A workaround for the absence of weak symbols ----- {{{
|
|
||||||
// We don't have a direct equivalent of weak symbols when using MSVC, but we can
|
|
||||||
// use the /alternatename directive to tell the linker to default a specific
|
|
||||||
// symbol to a specific value, which works nicely for allocator hooks and
|
|
||||||
// __asan_default_options().
|
|
||||||
void __sanitizer_default_malloc_hook(void *ptr, uptr size) { }
|
void __sanitizer_default_malloc_hook(void *ptr, uptr size) { }
|
||||||
void __sanitizer_default_free_hook(void *ptr) { }
|
void __sanitizer_default_free_hook(void *ptr) { }
|
||||||
const char* __asan_default_default_options() { return ""; }
|
const char* __asan_default_default_options() { return ""; }
|
||||||
const char* __asan_default_default_suppressions() { return ""; }
|
const char* __asan_default_default_suppressions() { return ""; }
|
||||||
void __asan_default_on_error() {}
|
void __asan_default_on_error() {}
|
||||||
// 64-bit msvc will not prepend an underscore for symbols.
|
|
||||||
#ifdef _WIN64
|
WIN_WEAK_ALIAS(__sanitizer_malloc_hook, __sanitizer_default_malloc_hook)
|
||||||
#pragma comment(linker, "/alternatename:__sanitizer_malloc_hook=__sanitizer_default_malloc_hook") // NOLINT
|
WIN_WEAK_ALIAS(__sanitizer_free_hook, __sanitizer_default_free_hook)
|
||||||
#pragma comment(linker, "/alternatename:__sanitizer_free_hook=__sanitizer_default_free_hook") // NOLINT
|
WIN_WEAK_ALIAS(__asan_default_options, __asan_default_default_options)
|
||||||
#pragma comment(linker, "/alternatename:__asan_default_options=__asan_default_default_options") // NOLINT
|
WIN_WEAK_ALIAS(__asan_default_suppressions, __asan_default_default_suppressions)
|
||||||
#pragma comment(linker, "/alternatename:__asan_default_suppressions=__asan_default_default_suppressions") // NOLINT
|
WIN_WEAK_ALIAS(__asan_on_error, __asan_default_on_error)
|
||||||
#pragma comment(linker, "/alternatename:__asan_on_error=__asan_default_on_error") // NOLINT
|
|
||||||
#else
|
|
||||||
#pragma comment(linker, "/alternatename:___sanitizer_malloc_hook=___sanitizer_default_malloc_hook") // NOLINT
|
|
||||||
#pragma comment(linker, "/alternatename:___sanitizer_free_hook=___sanitizer_default_free_hook") // NOLINT
|
|
||||||
#pragma comment(linker, "/alternatename:___asan_default_options=___asan_default_default_options") // NOLINT
|
|
||||||
#pragma comment(linker, "/alternatename:___asan_default_suppressions=___asan_default_default_suppressions") // NOLINT
|
|
||||||
#pragma comment(linker, "/alternatename:___asan_on_error=___asan_default_on_error") // NOLINT
|
|
||||||
#endif
|
|
||||||
// }}}
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
// ---------------------- Windows-specific interceptors ---------------- {{{
|
// ---------------------- Windows-specific interceptors ---------------- {{{
|
||||||
|
@ -368,7 +354,7 @@ __declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(void *,
|
||||||
unsigned long, void *) = asan_thread_init;
|
unsigned long, void *) = asan_thread_init;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ASAN_LINK_GLOBALS_WIN()
|
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
} // namespace __asan
|
} // namespace __asan
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
// simplifies the build procedure.
|
// simplifies the build procedure.
|
||||||
#ifdef ASAN_DLL_THUNK
|
#ifdef ASAN_DLL_THUNK
|
||||||
#include "asan_init_version.h"
|
#include "asan_init_version.h"
|
||||||
#include "asan_globals_win.h"
|
|
||||||
#include "interception/interception.h"
|
#include "interception/interception.h"
|
||||||
#include "sanitizer_common/sanitizer_platform_interceptors.h"
|
#include "sanitizer_common/sanitizer_platform_interceptors.h"
|
||||||
|
#include "sanitizer_common/sanitizer_win_defs.h"
|
||||||
|
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
#define WINAPI __stdcall
|
#define WINAPI __stdcall
|
||||||
|
@ -478,6 +478,6 @@ static void WINAPI asan_thread_init(void *mod, unsigned long reason,
|
||||||
__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,
|
__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,
|
||||||
unsigned long, void *) = asan_thread_init;
|
unsigned long, void *) = asan_thread_init;
|
||||||
|
|
||||||
ASAN_LINK_GLOBALS_WIN()
|
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
||||||
|
|
||||||
#endif // ASAN_DLL_THUNK
|
#endif // ASAN_DLL_THUNK
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
// Using #ifdef rather than relying on Makefiles etc.
|
// Using #ifdef rather than relying on Makefiles etc.
|
||||||
// simplifies the build procedure.
|
// simplifies the build procedure.
|
||||||
#ifdef ASAN_DYNAMIC_RUNTIME_THUNK
|
#ifdef ASAN_DYNAMIC_RUNTIME_THUNK
|
||||||
#include "asan_globals_win.h"
|
#include "sanitizer_common/sanitizer_win_defs.h"
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
@ -122,6 +122,6 @@ __declspec(allocate(".CRT$XCAB")) int (*__asan_seh_interceptor)() =
|
||||||
SetSEHFilter;
|
SetSEHFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASAN_LINK_GLOBALS_WIN()
|
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
||||||
|
|
||||||
#endif // ASAN_DYNAMIC_RUNTIME_THUNK
|
#endif // ASAN_DYNAMIC_RUNTIME_THUNK
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "sanitizer_procmaps.h"
|
#include "sanitizer_procmaps.h"
|
||||||
#include "sanitizer_stacktrace.h"
|
#include "sanitizer_stacktrace.h"
|
||||||
#include "sanitizer_symbolizer.h"
|
#include "sanitizer_symbolizer.h"
|
||||||
|
#include "sanitizer_win_defs.h"
|
||||||
|
|
||||||
// A macro to tell the compiler that this part of the code cannot be reached,
|
// A macro to tell the compiler that this part of the code cannot be reached,
|
||||||
// if the compiler supports this feature. Since we're using this in
|
// if the compiler supports this feature. Since we're using this in
|
||||||
|
@ -946,11 +947,8 @@ void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) { }
|
||||||
// of null.
|
// of null.
|
||||||
extern "C" void __sanitizer_print_memory_profile(int top_percent) {}
|
extern "C" void __sanitizer_print_memory_profile(int top_percent) {}
|
||||||
|
|
||||||
#ifdef _WIN64
|
WIN_WEAK_ALIAS(__sanitizer_print_memory_profile,
|
||||||
#pragma comment(linker, "/alternatename:__sanitizer_print_memory_profile=__sanitizer_default_print_memory_profile") // NOLINT
|
__sanitizer_default_print_memory_profile)
|
||||||
#else
|
|
||||||
#pragma comment(linker, "/alternatename:___sanitizer_print_memory_profile=___sanitizer_default_print_memory_profile") // NOLINT
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
//===-- sanitizer_win_defs.h ------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Common definitions for Windows-specific code.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
#ifndef SANITIZER_WIN_DEFS_H
|
||||||
|
#define SANITIZER_WIN_DEFS_H
|
||||||
|
|
||||||
|
#include "sanitizer_platform.h"
|
||||||
|
#if SANITIZER_WINDOWS
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
#define WIN_SYM_PREFIX
|
||||||
|
#else
|
||||||
|
#define WIN_SYM_PREFIX "_"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Intermediate macro to ensure the parameter is expanded before stringified.
|
||||||
|
#define STRINGIFY(A) #A
|
||||||
|
|
||||||
|
// ----------------- A workaround for the absence of weak symbols --------------
|
||||||
|
// We don't have a direct equivalent of weak symbols when using MSVC, but we can
|
||||||
|
// use the /alternatename directive to tell the linker to default a specific
|
||||||
|
// symbol to a specific value.
|
||||||
|
// Take into account that the function will be marked as UNDEF in the symbol
|
||||||
|
// table of the resulting object file, even if we provided a default value, and
|
||||||
|
// the linker won't find the default implementation until it links with that
|
||||||
|
// object file.
|
||||||
|
// So, suppose we provide a default implementation "fundef" for "fun", and this
|
||||||
|
// is compiled into the object file "test.obj".
|
||||||
|
// If we have some code with references to "fun" and we link that code with
|
||||||
|
// "test.obj", it will work because the linker always link object files.
|
||||||
|
// But, if "test.obj" is included in a static library, like "test.lib", then the
|
||||||
|
// liker will only link to "test.obj" if necessary. If we only included the
|
||||||
|
// definition of "fun", it won't link to "test.obj" (from test.lib) because
|
||||||
|
// "fun" appears as UNDEF, so it doesn't resolve the symbol "fun", and this will
|
||||||
|
// result in a link error.
|
||||||
|
// So, a workaround is to force linkage with the modules that include weak
|
||||||
|
// definitions, with the following macro: WIN_FORCE_LINK()
|
||||||
|
|
||||||
|
#define WIN_WEAK_ALIAS_(Name, Default) \
|
||||||
|
__pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY(Name) "="\
|
||||||
|
WIN_SYM_PREFIX STRINGIFY(Default)))
|
||||||
|
|
||||||
|
#define WIN_WEAK_ALIAS(Name, Default) \
|
||||||
|
WIN_WEAK_ALIAS_(Name, Default)
|
||||||
|
|
||||||
|
#define WIN_FORCE_LINK(Name) \
|
||||||
|
__pragma(comment(linker, "/include:" WIN_SYM_PREFIX STRINGIFY(Name)))
|
||||||
|
|
||||||
|
#endif // SANITIZER_WINDOWS
|
||||||
|
#endif // SANITIZER_WIN_DEFS_H
|
|
@ -17,6 +17,7 @@
|
||||||
#include "sanitizer_common/sanitizer_common.h"
|
#include "sanitizer_common/sanitizer_common.h"
|
||||||
#include "sanitizer_common/sanitizer_flags.h"
|
#include "sanitizer_common/sanitizer_flags.h"
|
||||||
#include "sanitizer_common/sanitizer_flag_parser.h"
|
#include "sanitizer_common/sanitizer_flag_parser.h"
|
||||||
|
#include "sanitizer_common/sanitizer_win_defs.h"
|
||||||
|
|
||||||
namespace __ubsan {
|
namespace __ubsan {
|
||||||
|
|
||||||
|
@ -76,11 +77,8 @@ const char *__ubsan_default_options() { return ""; }
|
||||||
|
|
||||||
#if SANITIZER_WINDOWS
|
#if SANITIZER_WINDOWS
|
||||||
const char *__ubsan_default_default_options() { return ""; }
|
const char *__ubsan_default_default_options() { return ""; }
|
||||||
# ifdef _WIN64
|
|
||||||
# pragma comment(linker, "/alternatename:__ubsan_default_options=__ubsan_default_default_options")
|
WIN_WEAK_ALIAS(__ubsan_default_options, __ubsan_default_default_options)
|
||||||
# else
|
|
||||||
# pragma comment(linker, "/alternatename:___ubsan_default_options=___ubsan_default_default_options")
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
Loading…
Reference in New Issue