brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · 808cd2f Raw
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