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 "asan_globals_win.h"
|
||||
#include "asan_interceptors.h"
|
||||
#include "asan_internal.h"
|
||||
#include "asan_report.h"
|
||||
|
@ -28,6 +27,7 @@
|
|||
#include "asan_mapping.h"
|
||||
#include "sanitizer_common/sanitizer_libc.h"
|
||||
#include "sanitizer_common/sanitizer_mutex.h"
|
||||
#include "sanitizer_common/sanitizer_win_defs.h"
|
||||
|
||||
using namespace __asan; // NOLINT
|
||||
|
||||
|
@ -44,31 +44,17 @@ uptr __asan_get_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_free_hook(void *ptr) { }
|
||||
const char* __asan_default_default_options() { return ""; }
|
||||
const char* __asan_default_default_suppressions() { return ""; }
|
||||
void __asan_default_on_error() {}
|
||||
// 64-bit msvc will not prepend an underscore for symbols.
|
||||
#ifdef _WIN64
|
||||
#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
|
||||
#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
|
||||
// }}}
|
||||
|
||||
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 ---------------- {{{
|
||||
|
@ -368,7 +354,7 @@ __declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(void *,
|
|||
unsigned long, void *) = asan_thread_init;
|
||||
#endif
|
||||
|
||||
ASAN_LINK_GLOBALS_WIN()
|
||||
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
||||
|
||||
// }}}
|
||||
} // namespace __asan
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
// simplifies the build procedure.
|
||||
#ifdef ASAN_DLL_THUNK
|
||||
#include "asan_init_version.h"
|
||||
#include "asan_globals_win.h"
|
||||
#include "interception/interception.h"
|
||||
#include "sanitizer_common/sanitizer_platform_interceptors.h"
|
||||
#include "sanitizer_common/sanitizer_win_defs.h"
|
||||
|
||||
#ifdef _M_IX86
|
||||
#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 *,
|
||||
unsigned long, void *) = asan_thread_init;
|
||||
|
||||
ASAN_LINK_GLOBALS_WIN()
|
||||
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
||||
|
||||
#endif // ASAN_DLL_THUNK
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
// Using #ifdef rather than relying on Makefiles etc.
|
||||
// simplifies the build procedure.
|
||||
#ifdef ASAN_DYNAMIC_RUNTIME_THUNK
|
||||
#include "asan_globals_win.h"
|
||||
#include "sanitizer_common/sanitizer_win_defs.h"
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
@ -122,6 +122,6 @@ __declspec(allocate(".CRT$XCAB")) int (*__asan_seh_interceptor)() =
|
|||
SetSEHFilter;
|
||||
}
|
||||
|
||||
ASAN_LINK_GLOBALS_WIN()
|
||||
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
||||
|
||||
#endif // ASAN_DYNAMIC_RUNTIME_THUNK
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "sanitizer_procmaps.h"
|
||||
#include "sanitizer_stacktrace.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,
|
||||
// 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.
|
||||
extern "C" void __sanitizer_print_memory_profile(int top_percent) {}
|
||||
|
||||
#ifdef _WIN64
|
||||
#pragma comment(linker, "/alternatename:__sanitizer_print_memory_profile=__sanitizer_default_print_memory_profile") // NOLINT
|
||||
#else
|
||||
#pragma comment(linker, "/alternatename:___sanitizer_print_memory_profile=___sanitizer_default_print_memory_profile") // NOLINT
|
||||
#endif
|
||||
WIN_WEAK_ALIAS(__sanitizer_print_memory_profile,
|
||||
__sanitizer_default_print_memory_profile)
|
||||
#endif
|
||||
|
||||
#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_flags.h"
|
||||
#include "sanitizer_common/sanitizer_flag_parser.h"
|
||||
#include "sanitizer_common/sanitizer_win_defs.h"
|
||||
|
||||
namespace __ubsan {
|
||||
|
||||
|
@ -76,11 +77,8 @@ const char *__ubsan_default_options() { return ""; }
|
|||
|
||||
#if SANITIZER_WINDOWS
|
||||
const char *__ubsan_default_default_options() { return ""; }
|
||||
# ifdef _WIN64
|
||||
# pragma comment(linker, "/alternatename:__ubsan_default_options=__ubsan_default_default_options")
|
||||
# else
|
||||
# pragma comment(linker, "/alternatename:___ubsan_default_options=___ubsan_default_default_options")
|
||||
# endif
|
||||
|
||||
WIN_WEAK_ALIAS(__ubsan_default_options, __ubsan_default_default_options)
|
||||
#endif
|
||||
|
||||
} // extern "C"
|
||||
|
|
Loading…
Reference in New Issue