diff options
Diffstat (limited to 'lib/libtsan/sanitizer_common/sanitizer_win_immortalize.h')
| -rw-r--r-- | lib/libtsan/sanitizer_common/sanitizer_win_immortalize.h | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/libtsan/sanitizer_common/sanitizer_win_immortalize.h b/lib/libtsan/sanitizer_common/sanitizer_win_immortalize.h new file mode 100644 index 0000000000..808cd2f771 --- /dev/null +++ b/lib/libtsan/sanitizer_common/sanitizer_win_immortalize.h @@ -0,0 +1,71 @@ +//===-- sanitizer_win_immortalize.h ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is shared between AddressSanitizer, and interception. +// +// Windows-specific thread-safe and pre-CRT global initialization safe +// infrastructure to create an object whose destructor is never called. +//===----------------------------------------------------------------------===// +#if SANITIZER_WINDOWS +# pragma once +// Requires including sanitizer_placement_new.h (which is not allowed to be +// included in headers). + +# include "sanitizer_win_defs.h" +// These types are required to satisfy XFG which requires that the names of the +// types for indirect calls to be correct as well as the name of the original +// type for any typedefs. + +// TODO: There must be a better way to do this +# ifndef _WINDOWS_ +typedef void* PVOID; +typedef int BOOL; +typedef union _RTL_RUN_ONCE { + PVOID ptr; +} INIT_ONCE, *PINIT_ONCE; + +extern "C" { +__declspec(dllimport) int WINAPI InitOnceExecuteOnce( + PINIT_ONCE, BOOL(WINAPI*)(PINIT_ONCE, PVOID, PVOID*), void*, void*); +} +# endif + +namespace __sanitizer { +template <class Ty> +BOOL WINAPI immortalize_impl(PINIT_ONCE, PVOID storage_ptr, PVOID*) noexcept { + // Ty must provide a placement new operator + new (storage_ptr) Ty(); + return 1; +} + +template <class Ty, typename Arg> +BOOL WINAPI immortalize_impl(PINIT_ONCE, PVOID storage_ptr, + PVOID* param) noexcept { + // Ty must provide a placement new operator + new (storage_ptr) Ty(*((Arg*)param)); + return 1; +} + +template <class Ty> +Ty& immortalize() { // return a reference to an object that will live forever + static INIT_ONCE flag; + alignas(Ty) static unsigned char storage[sizeof(Ty)]; + InitOnceExecuteOnce(&flag, immortalize_impl<Ty>, &storage, nullptr); + return reinterpret_cast<Ty&>(storage); +} + +template <class Ty, typename Arg> +Ty& immortalize( + Arg arg) { // return a reference to an object that will live forever + static INIT_ONCE flag; + alignas(Ty) static unsigned char storage[sizeof(Ty)]; + InitOnceExecuteOnce(&flag, immortalize_impl<Ty, Arg>, &storage, &arg); + return reinterpret_cast<Ty&>(storage); +} +} // namespace __sanitizer +#endif // SANITIZER_WINDOWS |
