168d75effSDimitry Andric //===-- asan_globals_win.cpp ----------------------------------------------===//
268d75effSDimitry Andric //
368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668d75effSDimitry Andric //
768d75effSDimitry Andric //===----------------------------------------------------------------------===//
868d75effSDimitry Andric //
968d75effSDimitry Andric // Global registration code that is linked into every Windows DLL and EXE.
1068d75effSDimitry Andric //
1168d75effSDimitry Andric //===----------------------------------------------------------------------===//
1268d75effSDimitry Andric
1368d75effSDimitry Andric #include "asan_interface_internal.h"
1468d75effSDimitry Andric #if SANITIZER_WINDOWS
1568d75effSDimitry Andric
1668d75effSDimitry Andric namespace __asan {
1768d75effSDimitry Andric
1868d75effSDimitry Andric #pragma section(".ASAN$GA", read, write)
1968d75effSDimitry Andric #pragma section(".ASAN$GZ", read, write)
20*0fca6ea1SDimitry Andric extern "C" alignas(sizeof(__asan_global))
21*0fca6ea1SDimitry Andric __declspec(allocate(".ASAN$GA")) __asan_global __asan_globals_start = {};
22*0fca6ea1SDimitry Andric extern "C" alignas(sizeof(__asan_global))
23*0fca6ea1SDimitry Andric __declspec(allocate(".ASAN$GZ")) __asan_global __asan_globals_end = {};
2468d75effSDimitry Andric #pragma comment(linker, "/merge:.ASAN=.data")
2568d75effSDimitry Andric
call_on_globals(void (* hook)(__asan_global *,uptr))2668d75effSDimitry Andric static void call_on_globals(void (*hook)(__asan_global *, uptr)) {
2768d75effSDimitry Andric __asan_global *start = &__asan_globals_start + 1;
2868d75effSDimitry Andric __asan_global *end = &__asan_globals_end;
2968d75effSDimitry Andric uptr bytediff = (uptr)end - (uptr)start;
3068d75effSDimitry Andric if (bytediff % sizeof(__asan_global) != 0) {
3168d75effSDimitry Andric #if defined(SANITIZER_DLL_THUNK) || defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
3268d75effSDimitry Andric __debugbreak();
3368d75effSDimitry Andric #else
3468d75effSDimitry Andric CHECK("corrupt asan global array");
3568d75effSDimitry Andric #endif
3668d75effSDimitry Andric }
3768d75effSDimitry Andric // We know end >= start because the linker sorts the portion after the dollar
3868d75effSDimitry Andric // sign alphabetically.
3968d75effSDimitry Andric uptr n = end - start;
4068d75effSDimitry Andric hook(start, n);
4168d75effSDimitry Andric }
4268d75effSDimitry Andric
register_dso_globals()4368d75effSDimitry Andric static void register_dso_globals() {
4468d75effSDimitry Andric call_on_globals(&__asan_register_globals);
4568d75effSDimitry Andric }
4668d75effSDimitry Andric
unregister_dso_globals()4768d75effSDimitry Andric static void unregister_dso_globals() {
4868d75effSDimitry Andric call_on_globals(&__asan_unregister_globals);
4968d75effSDimitry Andric }
5068d75effSDimitry Andric
5168d75effSDimitry Andric // Register globals
5268d75effSDimitry Andric #pragma section(".CRT$XCU", long, read)
5368d75effSDimitry Andric #pragma section(".CRT$XTX", long, read)
5468d75effSDimitry Andric extern "C" __declspec(allocate(".CRT$XCU"))
5568d75effSDimitry Andric void (*const __asan_dso_reg_hook)() = ®ister_dso_globals;
5668d75effSDimitry Andric extern "C" __declspec(allocate(".CRT$XTX"))
5768d75effSDimitry Andric void (*const __asan_dso_unreg_hook)() = &unregister_dso_globals;
5868d75effSDimitry Andric
5968d75effSDimitry Andric } // namespace __asan
6068d75effSDimitry Andric
6168d75effSDimitry Andric #endif // SANITIZER_WINDOWS
62