Module: wine Branch: master Commit: bef61e293cc5c809be93c40760f2be97f7a70c8f URL: https://gitlab.winehq.org/wine/wine/-/commit/bef61e293cc5c809be93c40760f2be9...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Jun 21 12:09:25 2023 +0200
ntdll: Implement _errno().
---
dlls/ntdll/loader.c | 1 + dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/ntdll_misc.h | 2 ++ dlls/ntdll/tests/thread.c | 21 +++++++++++++++++++++ dlls/ntdll/thread.c | 9 +++++++++ 5 files changed, 34 insertions(+)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index c8e85970604..fc2d2ff7a12 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -4216,6 +4216,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR sizeof(peb->TlsExpansionBitmapBits) * 8 ); /* TLS index 0 is always reserved, and wow64 reserves extra TLS entries */ RtlSetBits( peb->TlsBitmap, 0, NtCurrentTeb()->WowTebOffset ? WOW64_TLS_MAX_NUMBER : 1 ); + RtlSetBits( peb->TlsBitmap, NTDLL_TLS_ERRNO, 1 );
init_user_process_params(); load_global_options(); diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 80277005672..4471a5e59d4 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -1514,6 +1514,7 @@ @ cdecl -norelay -arch=i386 -ret64 _aullrem(int64 int64) @ cdecl -norelay -arch=i386 -ret64 _aullshr(int64 long) @ cdecl -arch=i386 -norelay _chkstk() +@ cdecl _errno() @ stub _fltused @ cdecl -arch=i386 -ret64 _ftol() @ cdecl -arch=i386 -ret64 _ftol2() _ftol diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index f6b77b79cde..ad8e2691224 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -39,6 +39,8 @@
#define MAX_NT_PATH_LENGTH 277
+#define NTDLL_TLS_ERRNO 16 /* TLS slot for _errno() */ + #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) static const UINT_PTR page_size = 0x1000; #else diff --git a/dlls/ntdll/tests/thread.c b/dlls/ntdll/tests/thread.c index 3086247d5f4..56fb078babc 100644 --- a/dlls/ntdll/tests/thread.c +++ b/dlls/ntdll/tests/thread.c @@ -24,12 +24,14 @@ static NTSTATUS (WINAPI *pNtCreateThreadEx)( HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *, HANDLE, PRTL_THREAD_START_ROUTINE, void *, ULONG, ULONG_PTR, SIZE_T, SIZE_T, PS_ATTRIBUTE_LIST * ); +static int * (CDECL *p_errno)(void);
static void init_function_pointers(void) { HMODULE hntdll = GetModuleHandleA( "ntdll.dll" ); #define GET_FUNC(name) p##name = (void *)GetProcAddress( hntdll, #name ); GET_FUNC( NtCreateThreadEx ); + GET_FUNC( _errno ); #undef GET_FUNC }
@@ -177,10 +179,29 @@ static void test_unique_teb(void) ok( args1.teb != args2.teb, "Multiple threads have TEB %p.\n", args1.teb ); }
+static void test_errno(void) +{ + int val; + + if (!p_errno) + { + win_skip( "_errno not available\n" ); + return; + } + ok( NtCurrentTeb()->Peb->TlsBitmap->Buffer[0] & (1 << 16), "TLS entry 16 not allocated\n" ); + *p_errno() = 0xdead; + val = PtrToLong( TlsGetValue( 16 )); + ok( val == 0xdead, "wrong value %x\n", val ); + *p_errno() = 0xbeef; + val = PtrToLong( TlsGetValue( 16 )); + ok( val == 0xbeef, "wrong value %x\n", val ); +} + START_TEST(thread) { init_function_pointers();
test_dbg_hidden_thread_creation(); test_unique_teb(); + test_errno(); } diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 8e5c6ef47dc..15a686738ff 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -463,6 +463,15 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void) }
+/*********************************************************************** + * _errno (NTDLL.@) + */ +int * CDECL _errno(void) +{ + return (int *)&NtCurrentTeb()->TlsSlots[NTDLL_TLS_ERRNO]; +} + + /*********************************************************************** * Fibers ***********************************************************************/