📄 tlsdyn.c
字号:
/***
*tlsdyn.c - Thread Local Storage dynamic initialization run-time support module
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* Provide the TLS equivalent of DllMainCRTStartup, to be called by the
* OS when a thread begins or ends. On thread start, walk the list of
* pointers to initialization routines for dynamically-initialized
* __declspec(thread) variables. On thread stop, walk the list of
* destructors for __declspec(thread) variables, as registered at
* initialization time.
*
****/
#ifndef MRTDLL
#ifdef CRTDLL
#undef CRTDLL
#endif /* CRTDLL */
#include <cruntime.h>
#include <internal.h>
#include <sect_attribs.h>
#include <windows.h>
/*
* Start and end sections for array of TLS callBacks to initialize individual
* dynamically initialized __declspec(thread) items. The actual array of
* callbacks is constructed using .CRT$XDA, .CRT$XDC, .CRT$XDL, .CRT$XDU,
* and .CRT$XDZ similar to the way global static initializers are done
* for C++. The C++ compiler will inject function pointers into .CRT$XD[CLU]
* for each dynamically initialized __declspec(thread) variable, as well as
* injecting a /include:__dyn_tls_init directive into the enclosing .obj,
* to force inclusion of this support object.
*/
static _CRTALLOC(".CRT$XDA") _PVFV __xd_a = 0;
static _CRTALLOC(".CRT$XDZ") _PVFV __xd_z = 0;
/*
* __dyn_tls_init - dynamically initialize __declspec(thread) variables
*
* Purpose:
* When any thread starts up, walk the array of function pointers found
* in sections .CRT$XD*, calling each non-NULL entry to dynamically
* initialize that thread's copy of a __declspec(thread) variable.
*
* Entry:
* This is called directly from the Windows loader code, with dwReason
* equal to one of DLL_PROCESS_ATTACH/DETACH or DLL_THREAD_ATTACH_DETACH.
*
* Exit:
* Returns TRUE always, though the loader code ignores the result.
*
* Notes:
* Only calls the initializers on DLL_THREAD_ATTACH and not
* DLL_PROCESS_ATTACH. That's because the DLL_PROCESS_ATTACH call happens
* too early, before the CRT has been initialized in, e.g.,
* DllMainCRTStartup or mainCRTStartup. Instead, the CRT init code will
* call here directly with a DLL_THREAD_ATTACH to initialize any
* __declspec(thread) variables in the primary thread at process startup.
*/
BOOL WINAPI __dyn_tls_init(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
_PVFV *pfunc;
if (dwReason != DLL_THREAD_ATTACH) {
return TRUE;
}
/* prefast assumes we are overflowing __xd_a */
#pragma warning(push)
#pragma warning(disable:26000)
for (pfunc = &__xd_a + 1; pfunc != &__xd_z; ++pfunc) {
if (*pfunc != NULL) {
(*pfunc)();
}
}
#pragma warning(pop)
return TRUE;
}
/*
* Define an initialized callback function pointer, so CRT startup code knows
* we have dynamically initialized __declspec(thread) variables that need to
* be initialized at process startup for the primary thread.
*/
const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback = __dyn_tls_init;
/*
* Enter a callback function pointer into the .CRT$XL* array, which is the
* callback array pointed to by the IMAGE_TLS_DIRECTORY in the PE header, so
* the OS knows we want to be notified on each thread startup/shutdown.
*/
static _CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c = __dyn_tls_init;
#endif /* MRTDLL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -