Commit bef61e29 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Implement _errno().

parent 2ef4cc48
......@@ -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();
......
......@@ -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
......
......@@ -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
......
......@@ -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();
}
......@@ -464,6 +464,15 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
/***********************************************************************
* _errno (NTDLL.@)
*/
int * CDECL _errno(void)
{
return (int *)&NtCurrentTeb()->TlsSlots[NTDLL_TLS_ERRNO];
}
/***********************************************************************
* Fibers
***********************************************************************/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment