mirror of
https://github.com/reactos/reactos.git
synced 2026-06-09 09:23:04 +08:00
[NTDLL] Revert Implict ThreadLocalStorage for now (#8823)
We will continue with this stuff when we can understand the root issues better * Revert "[NTDLL_APITEST] Relicense implicit tls tests as MIT" This reverts commitec6bae2b31. * Revert "[NTDLL:LDR] Add Implicit Thread Local Storage Support (#7594)" This reverts commit23043ce0b8.
This commit is contained in:
@@ -29,18 +29,6 @@ typedef struct _LDRP_TLS_DATA
|
||||
IMAGE_TLS_DIRECTORY TlsDirectory;
|
||||
} LDRP_TLS_DATA, *PLDRP_TLS_DATA;
|
||||
|
||||
typedef struct _LDRP_OLD_TLS_VECTOR_ENTRY
|
||||
{
|
||||
LIST_ENTRY TlsVectorLinks;
|
||||
PVOID* OldTlsVector;
|
||||
} LDRP_OLD_TLS_VECTOR_ENTRY, *PLDRP_OLD_TLS_VECTOR_ENTRY;
|
||||
|
||||
typedef struct _LDRP_TEB_LIST_ENTRY
|
||||
{
|
||||
LIST_ENTRY TebLinks;
|
||||
PTEB Teb;
|
||||
} LDRP_TEB_LIST_ENTRY, *PLDRP_TEB_LIST_ENTRY;
|
||||
|
||||
typedef
|
||||
NTSTATUS
|
||||
(NTAPI* PLDR_APP_COMPAT_DLL_REDIRECTION_CALLBACK_FUNCTION)(
|
||||
@@ -83,7 +71,7 @@ extern PVOID g_pfnSE_ProcessDying;
|
||||
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL);
|
||||
VOID NTAPI LdrpInitializeThread(IN PCONTEXT Context);
|
||||
NTSTATUS NTAPI LdrpInitializeTls(VOID);
|
||||
NTSTATUS NTAPI LdrpAllocateTls(_In_ PTEB Teb);
|
||||
NTSTATUS NTAPI LdrpAllocateTls(VOID);
|
||||
VOID NTAPI LdrpFreeTls(VOID);
|
||||
VOID NTAPI LdrpCallTlsInitializers(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Reason);
|
||||
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context);
|
||||
|
||||
@@ -51,7 +51,6 @@ RTL_BITMAP TlsExpansionBitMap;
|
||||
RTL_BITMAP FlsBitMap;
|
||||
BOOLEAN LdrpImageHasTls;
|
||||
LIST_ENTRY LdrpTlsList;
|
||||
LIST_ENTRY LdrpActiveTebList;
|
||||
ULONG LdrpNumberOfTlsEntries;
|
||||
ULONG LdrpNumberOfProcessors;
|
||||
PVOID NtDllBase;
|
||||
@@ -510,8 +509,6 @@ NTAPI
|
||||
LdrpInitializeThread(IN PCONTEXT Context)
|
||||
{
|
||||
PPEB Peb = NtCurrentPeb();
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
PLDRP_TEB_LIST_ENTRY TebEntry;
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
|
||||
@@ -538,13 +535,7 @@ LdrpInitializeThread(IN PCONTEXT Context)
|
||||
if (LdrpShutdownInProgress) goto Exit;
|
||||
|
||||
/* Allocate TLS */
|
||||
LdrpAllocateTls(Teb);
|
||||
|
||||
/* Add thread to active TEB list */
|
||||
ListHead = &LdrpActiveTebList;
|
||||
TebEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*TebEntry));
|
||||
TebEntry->Teb = NtCurrentTeb();
|
||||
InsertTailList(&LdrpActiveTebList, &TebEntry->TebLinks);
|
||||
LdrpAllocateTls();
|
||||
|
||||
/* Start at the beginning */
|
||||
ListHead = &Peb->Ldr->InMemoryOrderModuleList;
|
||||
@@ -1103,7 +1094,6 @@ LdrShutdownThread(VOID)
|
||||
{
|
||||
PPEB Peb = NtCurrentPeb();
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
PLDRP_TEB_LIST_ENTRY TebEntry;
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
|
||||
@@ -1122,20 +1112,6 @@ LdrShutdownThread(VOID)
|
||||
/* Get the Ldr Lock */
|
||||
RtlEnterCriticalSection(&LdrpLoaderLock);
|
||||
|
||||
/* Remove the thread from the active TEB list */
|
||||
ListHead = &LdrpActiveTebList;
|
||||
for (NextEntry = ListHead->Blink;
|
||||
NextEntry != ListHead;
|
||||
NextEntry = NextEntry->Blink)
|
||||
{
|
||||
TebEntry = CONTAINING_RECORD(NextEntry, LDRP_TEB_LIST_ENTRY, TebLinks);
|
||||
if (TebEntry->Teb == Teb)
|
||||
{
|
||||
RemoveEntryList(NextEntry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start at the end */
|
||||
ListHead = &Peb->Ldr->InInitializationOrderModuleList;
|
||||
NextEntry = ListHead->Blink;
|
||||
@@ -1294,16 +1270,12 @@ LdrpInitializeTls(VOID)
|
||||
{
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
PLDRP_TEB_LIST_ENTRY TebEntry;
|
||||
PIMAGE_TLS_DIRECTORY TlsDirectory;
|
||||
PLDRP_TLS_DATA TlsData;
|
||||
ULONG Size;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN AllocateTls = FALSE;
|
||||
|
||||
/* Initialize the TLS List */
|
||||
if (!LdrpImageHasTls)
|
||||
InitializeListHead(&LdrpTlsList);
|
||||
InitializeListHead(&LdrpTlsList);
|
||||
|
||||
/* Loop all the modules */
|
||||
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
@@ -1323,12 +1295,8 @@ LdrpInitializeTls(VOID)
|
||||
/* Check if we have a directory */
|
||||
if (!TlsDirectory) continue;
|
||||
|
||||
if (LdrEntry->Flags & LDRP_TLS_LOADED)
|
||||
continue;
|
||||
|
||||
/* Check if the image has TLS */
|
||||
if (!LdrpImageHasTls) LdrpImageHasTls = TRUE;
|
||||
AllocateTls = TRUE;
|
||||
|
||||
/* Show debug message */
|
||||
if (ShowSnaps)
|
||||
@@ -1345,7 +1313,6 @@ LdrpInitializeTls(VOID)
|
||||
/* Lock the DLL and mark it for TLS Usage */
|
||||
LdrEntry->LoadCount = -1;
|
||||
LdrEntry->TlsIndex = -1;
|
||||
LdrEntry->Flags |= LDRP_TLS_LOADED;
|
||||
|
||||
/* Save the cached TLS data */
|
||||
TlsData->TlsDirectory = *TlsDirectory;
|
||||
@@ -1357,57 +1324,29 @@ LdrpInitializeTls(VOID)
|
||||
}
|
||||
|
||||
/* Done setting up TLS, allocate entries */
|
||||
if (AllocateTls)
|
||||
{
|
||||
Status = LdrpAllocateTls(NtCurrentTeb());
|
||||
if (Status != STATUS_SUCCESS)
|
||||
return Status;
|
||||
|
||||
ListHead = &LdrpActiveTebList;
|
||||
NextEntry = ListHead->Blink;
|
||||
|
||||
for (NextEntry = ListHead->Blink;
|
||||
NextEntry != ListHead;
|
||||
NextEntry = NextEntry->Blink)
|
||||
{
|
||||
TebEntry = CONTAINING_RECORD(NextEntry, LDRP_TEB_LIST_ENTRY, TebLinks);
|
||||
if (TebEntry->Teb != NtCurrentTeb())
|
||||
{
|
||||
Status = LdrpAllocateTls(TebEntry->Teb);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return LdrpAllocateTls();
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpAllocateTls(_In_ PTEB Teb)
|
||||
LdrpAllocateTls(VOID)
|
||||
{
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
PLDRP_TLS_DATA TlsData;
|
||||
SIZE_T TlsDataSize;
|
||||
PVOID *TlsVector;
|
||||
PVOID *OldTlsVector;
|
||||
PLDRP_OLD_TLS_VECTOR_ENTRY OldTlsVectorEntry;
|
||||
|
||||
/* Check if we have any entries */
|
||||
if (!LdrpNumberOfTlsEntries)
|
||||
return STATUS_SUCCESS;
|
||||
/* Check if there are new entries to add to the vector */
|
||||
if (LdrpNumberOfTlsEntries == Teb->UserReserved.ThreadNumberOfTlsEntries)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
/* Allocate the vector array */
|
||||
TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
LdrpNumberOfTlsEntries * sizeof(PVOID));
|
||||
0,
|
||||
LdrpNumberOfTlsEntries * sizeof(PVOID));
|
||||
if (!TlsVector) return STATUS_NO_MEMORY;
|
||||
/* Grab old TLS vector to retrieve existing values */
|
||||
OldTlsVector = Teb->ThreadLocalStoragePointer;
|
||||
Teb->ThreadLocalStoragePointer = TlsVector;
|
||||
|
||||
/* Loop the TLS Array */
|
||||
ListHead = &LdrpTlsList;
|
||||
@@ -1421,74 +1360,32 @@ LdrpAllocateTls(_In_ PTEB Teb)
|
||||
/* Allocate this vector */
|
||||
TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
|
||||
TlsData->TlsDirectory.StartAddressOfRawData;
|
||||
|
||||
if (!OldTlsVector || ((TlsData->TlsDirectory.Characteristics + 1) > Teb->UserReserved.ThreadNumberOfTlsEntries))
|
||||
TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
TlsDataSize);
|
||||
if (!TlsVector[TlsData->TlsDirectory.Characteristics])
|
||||
{
|
||||
TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
TlsDataSize);
|
||||
if (!TlsVector[TlsData->TlsDirectory.Characteristics])
|
||||
{
|
||||
/* Out of memory */
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Show debug message */
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
|
||||
TlsVector,
|
||||
TlsData->TlsDirectory.Characteristics,
|
||||
&TlsVector[TlsData->TlsDirectory.Characteristics],
|
||||
TlsData->TlsDirectory.StartAddressOfRawData,
|
||||
TlsVector[TlsData->TlsDirectory.Characteristics]);
|
||||
}
|
||||
|
||||
/* Copy the data */
|
||||
RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
|
||||
(PVOID)TlsData->TlsDirectory.StartAddressOfRawData,
|
||||
TlsDataSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reuse the previous thread-local copy of the TLS data in the new vector. */
|
||||
TlsVector[TlsData->TlsDirectory.Characteristics] = OldTlsVector[TlsData->TlsDirectory.Characteristics];
|
||||
/* Show debug message */
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: TlsVector %p Index %lu = %p recycled from %x to %p\n",
|
||||
TlsVector,
|
||||
TlsData->TlsDirectory.Characteristics,
|
||||
&OldTlsVector[TlsData->TlsDirectory.Characteristics],
|
||||
OldTlsVector[TlsData->TlsDirectory.Characteristics],
|
||||
TlsVector[TlsData->TlsDirectory.Characteristics]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OldTlsVector)
|
||||
{
|
||||
OldTlsVectorEntry = RtlAllocateHeap(RtlGetProcessHeap(), 0,
|
||||
sizeof(*OldTlsVectorEntry));
|
||||
if (!OldTlsVectorEntry)
|
||||
{
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, TlsVector);
|
||||
/* Out of memory */
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
OldTlsVectorEntry->OldTlsVector = OldTlsVector;
|
||||
if (Teb->SystemReserved1.OldTlsVectorList)
|
||||
|
||||
/* Show debug message */
|
||||
if (ShowSnaps)
|
||||
{
|
||||
InsertTailList((PLIST_ENTRY)Teb->SystemReserved1.OldTlsVectorList,
|
||||
&OldTlsVectorEntry->TlsVectorLinks);
|
||||
}
|
||||
else
|
||||
{
|
||||
InitializeListHead(&OldTlsVectorEntry->TlsVectorLinks);
|
||||
Teb->SystemReserved1.OldTlsVectorList = OldTlsVectorEntry;
|
||||
DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
|
||||
TlsVector,
|
||||
TlsData->TlsDirectory.Characteristics,
|
||||
&TlsVector[TlsData->TlsDirectory.Characteristics],
|
||||
TlsData->TlsDirectory.StartAddressOfRawData,
|
||||
TlsVector[TlsData->TlsDirectory.Characteristics]);
|
||||
}
|
||||
|
||||
/* Copy the data */
|
||||
RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
|
||||
(PVOID)TlsData->TlsDirectory.StartAddressOfRawData,
|
||||
TlsDataSize);
|
||||
}
|
||||
Teb->ThreadLocalStoragePointer = TlsVector;
|
||||
Teb->UserReserved.ThreadNumberOfTlsEntries = LdrpNumberOfTlsEntries;
|
||||
|
||||
/* Done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1499,7 +1396,6 @@ LdrpFreeTls(VOID)
|
||||
{
|
||||
PLIST_ENTRY ListHead, NextEntry;
|
||||
PLDRP_TLS_DATA TlsData;
|
||||
PLDRP_OLD_TLS_VECTOR_ENTRY OldTlsVectorDataEntry;
|
||||
PVOID *TlsVector;
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
|
||||
@@ -1528,24 +1424,6 @@ LdrpFreeTls(VOID)
|
||||
RtlFreeHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
TlsVector);
|
||||
|
||||
if (Teb->SystemReserved1.OldTlsVectorList)
|
||||
{
|
||||
/* Loop through it */
|
||||
ListHead = (PLIST_ENTRY)Teb->SystemReserved1.OldTlsVectorList;
|
||||
NextEntry = ListHead->Flink;
|
||||
while (NextEntry != ListHead)
|
||||
{
|
||||
OldTlsVectorDataEntry = CONTAINING_RECORD(NextEntry,
|
||||
LDRP_OLD_TLS_VECTOR_ENTRY,
|
||||
TlsVectorLinks);
|
||||
NextEntry = NextEntry->Flink;
|
||||
|
||||
/* Free each old TLS vector and the entry itself */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, OldTlsVectorDataEntry->OldTlsVector);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, OldTlsVectorDataEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
@@ -2558,9 +2436,6 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
RtlpInitializeKeyedEvent();
|
||||
RtlpInitializeThreadPooling();
|
||||
|
||||
/* Initialize Active TEB List */
|
||||
InitializeListHead(&LdrpActiveTebList);
|
||||
|
||||
/* Initialize TLS */
|
||||
Status = LdrpInitializeTls();
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
||||
@@ -2580,18 +2580,6 @@ LdrpLoadDll(IN BOOLEAN Redirected,
|
||||
}
|
||||
|
||||
/* Run the init routine */
|
||||
Status = LdrpInitializeTls();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Failed, unload the DLL */
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DbgPrint("LDR: Unloading %wZ because dynamic TLS allocation failed; status = 0x%08lx\n",
|
||||
DllName,
|
||||
Status);
|
||||
}
|
||||
LdrUnloadDll(LdrEntry->DllBase);
|
||||
}
|
||||
Status = LdrpRunInitializeRoutines(NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
|
||||
add_subdirectory(implicit_tls)
|
||||
add_subdirectory(load_notifications)
|
||||
add_subdirectory(empty_dll)
|
||||
|
||||
include_directories($<TARGET_FILE_DIR:implicit_tls>)
|
||||
include_directories($<TARGET_FILE_DIR:load_notifications>)
|
||||
include_directories($<TARGET_FILE_DIR:empty_dll>)
|
||||
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
||||
@@ -40,7 +38,6 @@ add_dependencies(ntdll_crt_test_lib psdk)
|
||||
|
||||
list(APPEND SOURCE
|
||||
DllLoadNotification.c
|
||||
implicit_tls.c
|
||||
LdrEnumResources.c
|
||||
LdrFindResource_U.c
|
||||
LdrLoadDll.c
|
||||
@@ -164,7 +161,6 @@ endif()
|
||||
list(APPEND PCH_SKIP_SOURCE
|
||||
testlist.c)
|
||||
|
||||
add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/implicit_tls/implicit_tls.dll)
|
||||
add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/load_notifications/load_notifications.dll)
|
||||
add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/empty_dll/empty_dll.dll)
|
||||
|
||||
@@ -184,7 +180,7 @@ target_link_libraries(ntdll_apitest ntdll_crt_test_lib rtl_test_lib wine uuid ${
|
||||
set_module_type(ntdll_apitest win32cui)
|
||||
add_importlibs(ntdll_apitest msvcrt advapi32 kernel32 ntdll)
|
||||
add_pch(ntdll_apitest precomp.h "${PCH_SKIP_SOURCE}")
|
||||
add_dependencies(ntdll_apitest implicit_tls load_notifications empty_dll)
|
||||
add_dependencies(ntdll_apitest load_notifications empty_dll)
|
||||
|
||||
if(NOT MSVC)
|
||||
set_source_files_properties(
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Tests for Implicit Thread Local Storage (TLS) support
|
||||
* COPYRIGHT: Copyright 2025 Shane Fournier <shanefournier@yandex.com>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include <pseh/pseh2.h>
|
||||
|
||||
#define TLS_VECTOR_MAX_SIZE 512
|
||||
|
||||
WCHAR dllpath_implicit_tls[MAX_PATH];
|
||||
|
||||
HANDLE ThreadEvent;
|
||||
|
||||
ULONG ExtantTlsEntryCount = 0;
|
||||
|
||||
DWORD WINAPI
|
||||
AuxThread0Proc(
|
||||
_In_ LPVOID pParameter
|
||||
)
|
||||
{
|
||||
PVOID* TlsVector;
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
int i = 0;
|
||||
WaitForSingleObject(ThreadEvent, INFINITE);
|
||||
TlsVector = Teb->ThreadLocalStoragePointer;
|
||||
while (TlsVector[i] && !((ULONG_PTR)TlsVector[i] % 4))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
WaitForSingleObject(ThreadEvent, INFINITE);
|
||||
ok(i == TLS_VECTOR_MAX_SIZE + ExtantTlsEntryCount, "ThreadLocalStoragePointer length is %d, expected length %lu\n", i, TLS_VECTOR_MAX_SIZE + ExtantTlsEntryCount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI
|
||||
AuxThread1Proc(
|
||||
_In_ LPVOID pParameter
|
||||
)
|
||||
{
|
||||
PVOID* TlsVector;
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
TlsVector = Teb->ThreadLocalStoragePointer;
|
||||
ok(TlsVector[1] != NULL, "ThreadLocalStoragePointer index 1 is NULL; failed to initialize other thread with TLS entries present\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
START_TEST(implicit_tls)
|
||||
{
|
||||
PVOID* TlsVector;
|
||||
WCHAR workdir[MAX_PATH];
|
||||
WCHAR duplicatepath[MAX_PATH];
|
||||
WCHAR basedllname[MAX_PATH];
|
||||
HMODULE DllAddr[TLS_VECTOR_MAX_SIZE];
|
||||
BOOL IsSuccess;
|
||||
DWORD Length;
|
||||
HANDLE AuxThread0, AuxThread1;
|
||||
int i;
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
ULONG TlsIdx0Value;
|
||||
ULONG TlsIdx0ValueAfter;
|
||||
|
||||
IsSuccess = GetTempPathW(_countof(workdir), workdir);
|
||||
ok(IsSuccess, "GetTempPathW error: %lu\n", GetLastError());
|
||||
|
||||
Length = GetTempFileNameW(workdir, L"implicit_tls", 0, dllpath_implicit_tls);
|
||||
ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError());
|
||||
|
||||
IsSuccess = CopyFileW(L"implicit_tls.dll", dllpath_implicit_tls, FALSE);
|
||||
ok(IsSuccess, "CopyFileW failed with %lu\n", GetLastError());
|
||||
|
||||
ThreadEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
ok(ThreadEvent != INVALID_HANDLE_VALUE, "CreateEventA failed with %lu\n", GetLastError());
|
||||
|
||||
AuxThread0 = CreateThread(NULL, 0, AuxThread0Proc, NULL, 0, NULL);
|
||||
ok(AuxThread0 != NULL, "CreateThread failed with %lu\n", GetLastError());
|
||||
|
||||
TlsVector = Teb->ThreadLocalStoragePointer;
|
||||
PULONG_PTR ModuleHandle = TlsVector[0];
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( disable : 4311)
|
||||
#endif
|
||||
*ModuleHandle = (ULONG)GetModuleHandleA(NULL) + 3;
|
||||
|
||||
TlsIdx0Value = *(PULONG)TlsVector[0];
|
||||
while (TlsVector[ExtantTlsEntryCount] && !((ULONG_PTR)TlsVector[ExtantTlsEntryCount] % 4))
|
||||
{
|
||||
++ExtantTlsEntryCount;
|
||||
}
|
||||
for (i = 0; i < TLS_VECTOR_MAX_SIZE; i++)
|
||||
{
|
||||
StringCchPrintfW(basedllname, MAX_PATH, L"basedllname_%d", i);
|
||||
Length = GetTempFileNameW(workdir, basedllname, 0, duplicatepath);
|
||||
ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError());
|
||||
IsSuccess = CopyFileW(dllpath_implicit_tls, duplicatepath, FALSE);
|
||||
ok(IsSuccess, "CopyFileW failed with %lu\n", GetLastError());
|
||||
DllAddr[i] = LoadLibraryW(duplicatepath);
|
||||
ok(DllAddr[i] != NULL, "LoadLibraryW failed with %lu\n", GetLastError());
|
||||
|
||||
if (i == TLS_VECTOR_MAX_SIZE / 2)
|
||||
{
|
||||
AuxThread1 = CreateThread(NULL, 0, AuxThread1Proc, NULL, 0, NULL);
|
||||
ok(AuxThread1 != NULL, "CreateThread failed with %lu\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
TlsVector = Teb->ThreadLocalStoragePointer;
|
||||
ok(TlsVector[1] != NULL, "ThreadLocalStoragePointer index 1 is NULL; Implicit TLS unavailable\n");
|
||||
|
||||
SetEvent(ThreadEvent);
|
||||
|
||||
TlsIdx0ValueAfter = *(PULONG)TlsVector[0];
|
||||
|
||||
ok(TlsIdx0Value == TlsIdx0ValueAfter, "Value in TLS index 0 corrupted by DLL loads; expected %lu and got %lu\n", TlsIdx0Value, TlsIdx0ValueAfter);
|
||||
|
||||
i = 0;
|
||||
while (TlsVector[i] && !((ULONG_PTR)TlsVector[i] % 4))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
ok(i == TLS_VECTOR_MAX_SIZE + ExtantTlsEntryCount, "ThreadLocalStoragePointer length is %d, expected length %lu\n", i, TLS_VECTOR_MAX_SIZE + ExtantTlsEntryCount);
|
||||
|
||||
SetEvent(ThreadEvent);
|
||||
|
||||
for (i = 0; i < TLS_VECTOR_MAX_SIZE; i++)
|
||||
{
|
||||
StringCchPrintfW(basedllname, MAX_PATH, L"basedllname_%d", i);
|
||||
Length = GetTempFileNameW(workdir, basedllname, 0, duplicatepath);
|
||||
ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError());
|
||||
IsSuccess = DeleteFileW(duplicatepath);
|
||||
ok(IsSuccess, "DeleteFileW failed with %lu\n", GetLastError());
|
||||
FreeLibrary(DllAddr[i]);
|
||||
}
|
||||
|
||||
DeleteFileW(dllpath_implicit_tls);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
add_library(implicit_tls MODULE implicit_tls.c)
|
||||
set_module_type(implicit_tls win32dll ENTRYPOINT DllMain 12)
|
||||
add_importlibs(implicit_tls kernel32 ntdll)
|
||||
add_dependencies(implicit_tls psdk)
|
||||
add_rostests_file(TARGET implicit_tls)
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Tests for Implicit Thread Local Storage (TLS) support
|
||||
* COPYRIGHT: Copyright 2025 Shane Fournier <shanefournier@yandex.com>
|
||||
*/
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
|
||||
#include <ndk/ntndk.h>
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define _CRTALLOC(x) __declspec(allocate(x))
|
||||
#elif defined(__GNUC__)
|
||||
#define _CRTALLOC(x) __attribute__ ((section (x) ))
|
||||
#else
|
||||
#error Your compiler is not supported.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Putting this note here as this is more directly related to TLS:
|
||||
* https://web.archive.org/web/20250204223245/http://www.nynaeve.net/?tag=tls
|
||||
*/
|
||||
/* Tls magic stolen from sdk/lib/crt/startup/tlssup.c */
|
||||
/* ROS is built with the flag /Zc:threadSafeInit- which prevents the compilation
|
||||
* of proper TLS code. Instead, hack up a TLS directory to increment the TLS index
|
||||
* and allow the loader to allocate a sufficient buffer in the TLS vector. */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma section(".rdata$T",long,read)
|
||||
#pragma section(".tls",long,read,write)
|
||||
#pragma section(".tls$ZZZ",long,read,write)
|
||||
#endif
|
||||
|
||||
_CRTALLOC(".tls") char _tls_start = 0;
|
||||
_CRTALLOC(".tls$ZZZ") char _tls_end = 0;
|
||||
|
||||
ULONG _tls_index = 0;
|
||||
|
||||
_CRTALLOC(".rdata$T") const IMAGE_TLS_DIRECTORY _tls_used = {
|
||||
(ULONG_PTR) &_tls_start, (ULONG_PTR) &_tls_end + 3,
|
||||
(ULONG_PTR) &_tls_index, (ULONG_PTR) 0,
|
||||
(ULONG) 0, (ULONG) 0
|
||||
};
|
||||
|
||||
BOOL WINAPI
|
||||
DllMain(IN HINSTANCE hDllHandle,
|
||||
IN DWORD dwReason,
|
||||
IN LPVOID lpvReserved)
|
||||
{
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
PVOID* TlsVector = Teb->ThreadLocalStoragePointer;
|
||||
PULONG_PTR ModuleHandle = (PULONG_PTR)TlsVector[_tls_index];
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( disable : 4311)
|
||||
#endif
|
||||
*ModuleHandle = (ULONG_PTR)GetModuleHandleA(NULL) + 1;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -25,7 +25,6 @@ extern void func_wcstoul(void);
|
||||
extern void func_wcstombs(void);
|
||||
|
||||
extern void func_DllLoadNotification(void);
|
||||
extern void func_implicit_tls(void);
|
||||
extern void func_LdrEnumResources(void);
|
||||
extern void func_LdrFindResource_U(void);
|
||||
extern void func_LdrLoadDll(void);
|
||||
@@ -160,7 +159,6 @@ const struct test winetest_testlist[] =
|
||||
{ "wcstombs", func_wcstombs },
|
||||
|
||||
{ "DllLoadNotification", func_DllLoadNotification },
|
||||
{ "implicit_tls", func_implicit_tls },
|
||||
{ "LdrEnumResources", func_LdrEnumResources },
|
||||
{ "LdrFindResource_U", func_LdrFindResource_U },
|
||||
{ "LdrLoadDll", func_LdrLoadDll },
|
||||
|
||||
@@ -43,7 +43,6 @@ Author:
|
||||
#define LDRP_LOAD_NOTIFICATIONS_SENT 0x00000008
|
||||
#endif
|
||||
#define LDRP_IMAGE_INTEGRITY_FORCED 0x00000020
|
||||
#define LDRP_TLS_LOADED 0x00000040
|
||||
#define LDRP_LOAD_IN_PROGRESS 0x00001000
|
||||
#define LDRP_UNLOAD_IN_PROGRESS 0x00002000
|
||||
#define LDRP_ENTRY_PROCESSED 0x00004000
|
||||
|
||||
@@ -240,43 +240,16 @@ typedef struct STRUCT(_TEB)
|
||||
PTR(PVOID) CsrClientThread;
|
||||
PTR(PVOID) Win32ThreadInfo;
|
||||
ULONG User32Reserved[26];
|
||||
union
|
||||
{
|
||||
ULONG UserReserved[5];
|
||||
struct
|
||||
{
|
||||
/* ReactOS specific */
|
||||
ULONG ThreadNumberOfTlsEntries;
|
||||
ULONG Spare[4];
|
||||
};
|
||||
} UserReserved;
|
||||
ULONG UserReserved[5];
|
||||
PTR(PVOID) WOW32Reserved;
|
||||
LCID CurrentLocale;
|
||||
ULONG FpSoftwareStatusRegister;
|
||||
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10) // since 10.0.10240.16384
|
||||
PTR(PVOID) ReservedForDebuggerInstrumentation[16];
|
||||
union
|
||||
{
|
||||
PTR(PVOID) SystemReserved1[38];
|
||||
struct
|
||||
{
|
||||
/* ReactOS specific */
|
||||
PTR(PVOID) OldTlsVectorList;
|
||||
PTR(PVOID) Spare[37];
|
||||
};
|
||||
} SystemReserved1;
|
||||
PTR(PVOID) SystemReserved1[38];
|
||||
#else
|
||||
union
|
||||
{
|
||||
PTR(PVOID) SystemReserved1[54];
|
||||
struct
|
||||
{
|
||||
/* ReactOS specific */
|
||||
PTR(PVOID) OldTlsVectorList;
|
||||
PTR(PVOID) Spare[53];
|
||||
};
|
||||
} SystemReserved1;
|
||||
PTR(PVOID) SystemReserved1[54];
|
||||
#endif
|
||||
LONG ExceptionCode;
|
||||
#ifdef _STRUCT64
|
||||
|
||||
Reference in New Issue
Block a user