[OpenACC] Enable 'attach' clause for combined constructs
[llvm-project.git] / compiler-rt / lib / sanitizer_common / sanitizer_win_interception.cpp
blobc93a411ff2d6ecf3f0e21e67328fcb84500f82c0
1 //===-- sanitizer_win_interception.cpp -------------------- --*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Windows-specific export surface to provide interception for parts of the
10 // runtime that are always statically linked, both for overriding user-defined
11 // functions as well as registering weak functions that the ASAN runtime should
12 // use over defaults.
14 //===----------------------------------------------------------------------===//
16 #include "sanitizer_platform.h"
17 #if SANITIZER_WINDOWS
18 # include <stddef.h>
20 # include "interception/interception.h"
21 # include "sanitizer_addrhashmap.h"
22 # include "sanitizer_common.h"
23 # include "sanitizer_internal_defs.h"
24 # include "sanitizer_placement_new.h"
25 # include "sanitizer_win_immortalize.h"
26 # include "sanitizer_win_interception.h"
28 using namespace __sanitizer;
30 extern "C" void *__ImageBase;
32 namespace __sanitizer {
34 static uptr GetSanitizerDllExport(const char *export_name) {
35 const uptr function_address =
36 __interception::InternalGetProcAddress(&__ImageBase, export_name);
37 if (function_address == 0) {
38 Report("ERROR: Failed to find sanitizer DLL export '%s'\n", export_name);
39 CHECK("Failed to find sanitizer DLL export" && 0);
41 return function_address;
44 struct WeakCallbackList {
45 explicit constexpr WeakCallbackList(RegisterWeakFunctionCallback cb)
46 : callback(cb), next(nullptr) {}
48 static void *operator new(size_t size) { return InternalAlloc(size); }
50 static void operator delete(void *p) { InternalFree(p); }
52 RegisterWeakFunctionCallback callback;
53 WeakCallbackList *next;
55 using WeakCallbackMap = AddrHashMap<WeakCallbackList *, 11>;
57 static WeakCallbackMap *GetWeakCallbackMap() {
58 return &immortalize<WeakCallbackMap>();
61 void AddRegisterWeakFunctionCallback(uptr export_address,
62 RegisterWeakFunctionCallback cb) {
63 WeakCallbackMap::Handle h_find_or_create(GetWeakCallbackMap(), export_address,
64 false, true);
65 CHECK(h_find_or_create.exists());
66 if (h_find_or_create.created()) {
67 *h_find_or_create = new WeakCallbackList(cb);
68 } else {
69 (*h_find_or_create)->next = new WeakCallbackList(cb);
73 static void RunWeakFunctionCallbacks(uptr export_address) {
74 WeakCallbackMap::Handle h_find(GetWeakCallbackMap(), export_address, false,
75 false);
76 if (!h_find.exists()) {
77 return;
80 WeakCallbackList *list = *h_find;
81 do {
82 list->callback();
83 } while ((list = list->next));
86 } // namespace __sanitizer
88 extern "C" __declspec(dllexport) bool __cdecl __sanitizer_override_function(
89 const char *export_name, const uptr user_function,
90 uptr *const old_user_function) {
91 CHECK(export_name);
92 CHECK(user_function);
94 const uptr sanitizer_function = GetSanitizerDllExport(export_name);
96 const bool function_overridden = __interception::OverrideFunction(
97 user_function, sanitizer_function, old_user_function);
98 if (!function_overridden) {
99 Report(
100 "ERROR: Failed to override local function at '%p' with sanitizer "
101 "function '%s'\n",
102 user_function, export_name);
103 CHECK("Failed to replace local function with sanitizer version." && 0);
106 return function_overridden;
109 extern "C"
110 __declspec(dllexport) bool __cdecl __sanitizer_override_function_by_addr(
111 const uptr source_function, const uptr target_function,
112 uptr *const old_target_function) {
113 CHECK(source_function);
114 CHECK(target_function);
116 const bool function_overridden = __interception::OverrideFunction(
117 target_function, source_function, old_target_function);
118 if (!function_overridden) {
119 Report(
120 "ERROR: Failed to override function at '%p' with function at "
121 "'%p'\n",
122 target_function, source_function);
123 CHECK("Failed to apply function override." && 0);
126 return function_overridden;
129 extern "C"
130 __declspec(dllexport) bool __cdecl __sanitizer_register_weak_function(
131 const char *export_name, const uptr user_function,
132 uptr *const old_user_function) {
133 CHECK(export_name);
134 CHECK(user_function);
136 const uptr sanitizer_function = GetSanitizerDllExport(export_name);
138 const bool function_overridden = __interception::OverrideFunction(
139 sanitizer_function, user_function, old_user_function);
140 if (!function_overridden) {
141 Report(
142 "ERROR: Failed to register local function at '%p' to be used in "
143 "place of sanitizer function '%s'\n.",
144 user_function, export_name);
145 CHECK("Failed to register weak function." && 0);
148 // Note that thread-safety of RunWeakFunctionCallbacks in InitializeFlags
149 // depends on __sanitizer_register_weak_functions being called during the
150 // loader lock.
151 RunWeakFunctionCallbacks(sanitizer_function);
153 return function_overridden;
156 #endif // SANITIZER_WINDOWS