72 lines · c
1//===-- sanitizer_win_immortalize.h ---------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is shared between AddressSanitizer, and interception.10//11// Windows-specific thread-safe and pre-CRT global initialization safe12// infrastructure to create an object whose destructor is never called.13//===----------------------------------------------------------------------===//14#if SANITIZER_WINDOWS15# pragma once16// Requires including sanitizer_placement_new.h (which is not allowed to be17// included in headers).18 19# include "sanitizer_win_defs.h"20// These types are required to satisfy XFG which requires that the names of the21// types for indirect calls to be correct as well as the name of the original22// type for any typedefs.23 24// TODO: There must be a better way to do this25# ifndef _WINDOWS_26typedef void* PVOID;27typedef int BOOL;28typedef union _RTL_RUN_ONCE {29 PVOID ptr;30} INIT_ONCE, *PINIT_ONCE;31 32extern "C" {33__declspec(dllimport) int WINAPI InitOnceExecuteOnce(34 PINIT_ONCE, BOOL(WINAPI*)(PINIT_ONCE, PVOID, PVOID*), void*, void*);35}36# endif37 38namespace __sanitizer {39template <class Ty>40BOOL WINAPI immortalize_impl(PINIT_ONCE, PVOID storage_ptr, PVOID*) noexcept {41 // Ty must provide a placement new operator42 new (storage_ptr) Ty();43 return 1;44}45 46template <class Ty, typename Arg>47BOOL WINAPI immortalize_impl(PINIT_ONCE, PVOID storage_ptr,48 PVOID* param) noexcept {49 // Ty must provide a placement new operator50 new (storage_ptr) Ty(*((Arg*)param));51 return 1;52}53 54template <class Ty>55Ty& immortalize() { // return a reference to an object that will live forever56 static INIT_ONCE flag;57 alignas(Ty) static unsigned char storage[sizeof(Ty)];58 InitOnceExecuteOnce(&flag, immortalize_impl<Ty>, &storage, nullptr);59 return reinterpret_cast<Ty&>(storage);60}61 62template <class Ty, typename Arg>63Ty& immortalize(64 Arg arg) { // return a reference to an object that will live forever65 static INIT_ONCE flag;66 alignas(Ty) static unsigned char storage[sizeof(Ty)];67 InitOnceExecuteOnce(&flag, immortalize_impl<Ty, Arg>, &storage, &arg);68 return reinterpret_cast<Ty&>(storage);69}70} // namespace __sanitizer71#endif // SANITIZER_WINDOWS72