ReactOS 0.4.15-dev-7677-g8209aa5
tlssup.c
Go to the documentation of this file.
1
9#ifdef CRTDLL
10#undef CRTDLL
11#endif
12
13#include <sect_attribs.h>
14
15#ifndef WIN32_LEAN_AND_MEAN
16#define WIN32_LEAN_AND_MEAN
17#endif
18#include <windows.h>
19
20#include <stdio.h>
21#include <memory.h>
22#include <malloc.h>
23#ifndef __REACTOS__
24#include <corecrt_startup.h>
25#else
26#include <internal.h>
27#endif
28
30
31#define FUNCS_PER_NODE 30
32
33typedef struct TlsDtorNode {
34 int count;
38
40
41/* TLS raw template data start and end.
42 We use here pointer-types for start/end so that tls-data remains
43 aligned on pointer-size-width. This seems to be required for
44 pe-loader. */
45_CRTALLOC(".tls") char *_tls_start = NULL;
46_CRTALLOC(".tls$ZZZ") char *_tls_end = NULL;
47
48_CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0;
49_CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0;
50
51const IMAGE_TLS_DIRECTORY _tls_used = {
52 (ULONG_PTR) &_tls_start, (ULONG_PTR) &_tls_end,
53 (ULONG_PTR) &_tls_index, (ULONG_PTR) (&__xl_a+1),
54 (ULONG) 0, (ULONG) 0
55};
56
57#ifndef __CRT_THREAD
58#ifdef HAVE_ATTRIBUTE_THREAD
59#define __CRT_THREAD __declspec(thread)
60#else
61#define __CRT_THREAD __thread
62#endif
63#endif
64
65#define DISABLE_MS_TLS 1
66
67static _CRTALLOC(".CRT$XDA") _PVFV __xd_a = 0;
68static _CRTALLOC(".CRT$XDZ") _PVFV __xd_z = 0;
69
70#if !defined (DISABLE_MS_TLS)
71static __CRT_THREAD TlsDtorNode *dtor_list;
72static __CRT_THREAD TlsDtorNode dtor_list_head;
73#endif
74
75extern int _CRT_MT;
76
77BOOL WINAPI __dyn_tls_init (HANDLE, DWORD, LPVOID);
78
80__dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
81{
82 _PVFV *pfunc;
83 uintptr_t ps;
84
85 /* We don't let us trick here. */
86 if (_CRT_MT != 2)
87 _CRT_MT = 2;
88
90 {
92 __mingw_TLScallback (hDllHandle, dwReason, lpreserved);
93 return TRUE;
94 }
95
96 ps = (uintptr_t) &__xd_a;
97 ps += sizeof (uintptr_t);
98 for ( ; ps != (uintptr_t) &__xd_z; ps += sizeof (uintptr_t))
99 {
100 pfunc = (_PVFV *) ps;
101 if (*pfunc != NULL)
102 (*pfunc)();
103 }
104 return TRUE;
105}
106
108_CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c = (PIMAGE_TLS_CALLBACK) __dyn_tls_init;
109
110int __cdecl __tlregdtor (_PVFV);
111
112int __cdecl
113__tlregdtor (_PVFV func)
114{
115 if (!func)
116 return 0;
117#if !defined (DISABLE_MS_TLS)
118 if (dtor_list == NULL)
119 {
120 dtor_list = &dtor_list_head;
121 dtor_list_head.count = 0;
122 }
123 else if (dtor_list->count == FUNCS_PER_NODE)
124 {
125 TlsDtorNode *pnode = (TlsDtorNode *) malloc (sizeof (TlsDtorNode));
126 if (pnode == NULL)
127 return -1;
128 pnode->count = 0;
129 pnode->next = dtor_list;
130 dtor_list = pnode;
131
132 dtor_list->count = 0;
133 }
134 dtor_list->funcs[dtor_list->count++] = func;
135#endif
136 return 0;
137}
138
139static BOOL WINAPI
140__dyn_tls_dtor (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
141{
142#if !defined (DISABLE_MS_TLS)
143 TlsDtorNode *pnode, *pnext;
144 int i;
145#endif
146
148 return TRUE;
149 /* As TLS variables are detroyed already by DLL_THREAD_DETACH
150 call, we have to avoid access on the possible DLL_PROCESS_DETACH
151 call the already destroyed TLS vars.
152 TODO: The used local thread based variables have to be handled
153 manually, so that we can control their lifetime here. */
154#if !defined (DISABLE_MS_TLS)
156 {
157 for (pnode = dtor_list; pnode != NULL; pnode = pnext)
158 {
159 for (i = pnode->count - 1; i >= 0; --i)
160 {
161 if (pnode->funcs[i] != NULL)
162 (*pnode->funcs[i])();
163 }
164 pnext = pnode->next;
165 if (pnext != NULL)
166 free ((void *) pnode);
167 }
168 }
169#endif
170 __mingw_TLScallback (hDllHandle, dwReason, lpreserved);
171 return TRUE;
172}
173
175
176
#define __cdecl
Definition: accygwin.h:79
DWORD dwReason
Definition: misc.cpp:154
unsigned int uintptr_t
Definition: crtdefs.h:321
int mingw_initltsdrot_force
int mingw_initltsdyn_force
int mingw_initltssuo_force
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
#define DLL_THREAD_DETACH
Definition: compat.h:133
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define DLL_THREAD_ATTACH
Definition: compat.h:132
unsigned char
Definition: typeof.h:29
r reserved
Definition: btrfs.c:3006
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define _CRTALLOC(x)
GLenum func
Definition: glext.h:6028
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID(NTAPI * PIMAGE_TLS_CALLBACK)(PVOID DllHandle, ULONG Reason, PVOID Reserved)
Definition: ntimage.h:531
void(__cdecl * _PVFV)(void)
Definition: internal.h:33
int count
Definition: tlssup.c:34
struct TlsDtorNode * next
Definition: tlssup.c:35
_PVFV funcs[FUNCS_PER_NODE]
Definition: tlssup.c:36
int _CRT_MT
Definition: tlsmcrt.c:12
#define __CRT_THREAD
Definition: tlssup.c:61
const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback
Definition: tlssup.c:107
static BOOL WINAPI __dyn_tls_dtor(HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
Definition: tlssup.c:140
WINBOOL __mingw_TLScallback(HANDLE hDllHandle, DWORD reason, LPVOID reserved)
#define FUNCS_PER_NODE
Definition: tlssup.c:31
ULONG _tls_index
Definition: tlssup.c:39
int32_t WINBOOL
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define WINAPI
Definition: msvc.h:6
#define const
Definition: zconf.h:233