ntdll: Always allocate space for both 32- and 64-bit TEB.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
cda02cdddb
commit
6a9e19344d
|
@ -3096,6 +3096,10 @@ static void test_wow64(void)
|
||||||
"wrong WowTebOffset %x (%p/%p)\n", NtCurrentTeb()->WowTebOffset, teb64, NtCurrentTeb() );
|
"wrong WowTebOffset %x (%p/%p)\n", NtCurrentTeb()->WowTebOffset, teb64, NtCurrentTeb() );
|
||||||
ok( (char *)teb64 + 0x2000 == (char *)NtCurrentTeb(), "unexpected diff %p / %p\n",
|
ok( (char *)teb64 + 0x2000 == (char *)NtCurrentTeb(), "unexpected diff %p / %p\n",
|
||||||
teb64, NtCurrentTeb() );
|
teb64, NtCurrentTeb() );
|
||||||
|
ok( (char *)teb64 + teb64->WowTebOffset == (char *)NtCurrentTeb() ||
|
||||||
|
broken( NtCurrentTeb()->WowTebOffset == 1 ), /* vista */
|
||||||
|
"wrong WowTebOffset %x (%p/%p)\n", teb64->WowTebOffset, teb64, NtCurrentTeb() );
|
||||||
|
ok( !teb64->GdiBatchCount, "GdiBatchCount set %x\n", teb64->GdiBatchCount );
|
||||||
ok( teb64->Tib.ExceptionList == PtrToUlong( NtCurrentTeb() ), "wrong Tib.ExceptionList %s / %p\n",
|
ok( teb64->Tib.ExceptionList == PtrToUlong( NtCurrentTeb() ), "wrong Tib.ExceptionList %s / %p\n",
|
||||||
wine_dbgstr_longlong(teb64->Tib.ExceptionList), NtCurrentTeb() );
|
wine_dbgstr_longlong(teb64->Tib.ExceptionList), NtCurrentTeb() );
|
||||||
ok( teb64->Tib.Self == PtrToUlong( teb64 ), "wrong Tib.Self %s / %p\n",
|
ok( teb64->Tib.Self == PtrToUlong( teb64 ), "wrong Tib.Self %s / %p\n",
|
||||||
|
|
|
@ -1459,6 +1459,7 @@ static void init_teb64( TEB *teb )
|
||||||
teb->WowTebOffset = -teb_offset;
|
teb->WowTebOffset = -teb_offset;
|
||||||
teb64->ClientId.UniqueProcess = PtrToUlong( teb->ClientId.UniqueProcess );
|
teb64->ClientId.UniqueProcess = PtrToUlong( teb->ClientId.UniqueProcess );
|
||||||
teb64->ClientId.UniqueThread = PtrToUlong( teb->ClientId.UniqueThread );
|
teb64->ClientId.UniqueThread = PtrToUlong( teb->ClientId.UniqueThread );
|
||||||
|
teb64->WowTebOffset = teb_offset;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,16 +70,10 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const SIZE_T page_size = 0x1000;
|
static const SIZE_T page_size = 0x1000;
|
||||||
|
static const SIZE_T teb_size = 0x3000; /* TEB64 + TEB32 */
|
||||||
static const SIZE_T signal_stack_mask = 0xffff;
|
static const SIZE_T signal_stack_mask = 0xffff;
|
||||||
#ifdef _WIN64
|
|
||||||
static const SIZE_T teb_size = 0x2000;
|
|
||||||
static const SIZE_T teb_offset = 0;
|
|
||||||
static const SIZE_T signal_stack_size = 0x10000 - 0x2000;
|
|
||||||
#else
|
|
||||||
static const SIZE_T teb_size = 0x3000; /* TEB64 + TEB */
|
|
||||||
static const SIZE_T teb_offset = 0x2000;
|
|
||||||
static const SIZE_T signal_stack_size = 0x10000 - 0x3000;
|
static const SIZE_T signal_stack_size = 0x10000 - 0x3000;
|
||||||
#endif
|
static const LONG teb_offset = 0x2000;
|
||||||
|
|
||||||
/* callbacks to PE ntdll from the Unix side */
|
/* callbacks to PE ntdll from the Unix side */
|
||||||
extern void (WINAPI *pDbgUiRemoteBreakin)( void *arg ) DECLSPEC_HIDDEN;
|
extern void (WINAPI *pDbgUiRemoteBreakin)( void *arg ) DECLSPEC_HIDDEN;
|
||||||
|
@ -298,7 +292,7 @@ static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len )
|
||||||
|
|
||||||
static inline void *get_signal_stack(void)
|
static inline void *get_signal_stack(void)
|
||||||
{
|
{
|
||||||
return (char *)NtCurrentTeb() + teb_size - teb_offset;
|
return (void *)(((ULONG_PTR)NtCurrentTeb() & ~signal_stack_mask) + teb_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mutex_lock( pthread_mutex_t *mutex )
|
static inline void mutex_lock( pthread_mutex_t *mutex )
|
||||||
|
|
|
@ -2837,16 +2837,29 @@ static PEB *init_peb( void *ptr )
|
||||||
|
|
||||||
|
|
||||||
/* set some initial values in a new TEB */
|
/* set some initial values in a new TEB */
|
||||||
static void init_teb( TEB *teb, PEB *peb )
|
static TEB *init_teb( void *ptr, PEB *peb )
|
||||||
{
|
{
|
||||||
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
struct ntdll_thread_data *thread_data;
|
||||||
|
TEB *teb;
|
||||||
#ifndef _WIN64
|
TEB64 *teb64 = ptr;
|
||||||
TEB64 *teb64 = (TEB64 *)((char *)teb - teb_offset);
|
TEB32 *teb32 = (TEB32 *)((char *)ptr + teb_offset);
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
teb = (TEB *)teb64;
|
||||||
|
teb32->Peb = PtrToUlong( (char *)peb - page_size );
|
||||||
|
teb32->Tib.Self = PtrToUlong( teb32 );
|
||||||
|
teb32->Tib.ExceptionList = ~0u;
|
||||||
|
teb32->ActivationContextStackPointer = PtrToUlong( &teb32->ActivationContextStack );
|
||||||
|
teb32->ActivationContextStack.FrameListCache.Flink =
|
||||||
|
teb32->ActivationContextStack.FrameListCache.Blink =
|
||||||
|
PtrToUlong( &teb32->ActivationContextStack.FrameListCache );
|
||||||
|
teb32->StaticUnicodeString.Buffer = PtrToUlong( teb32->StaticUnicodeBuffer );
|
||||||
|
teb32->StaticUnicodeString.MaximumLength = sizeof( teb32->StaticUnicodeBuffer );
|
||||||
|
#else
|
||||||
|
teb = (TEB *)teb32;
|
||||||
teb64->Peb = PtrToUlong( (char *)peb + page_size );
|
teb64->Peb = PtrToUlong( (char *)peb + page_size );
|
||||||
teb64->Tib.Self = PtrToUlong( teb64 );
|
teb64->Tib.Self = PtrToUlong( teb64 );
|
||||||
teb64->Tib.ExceptionList = PtrToUlong( teb );
|
teb64->Tib.ExceptionList = PtrToUlong( teb32 );
|
||||||
teb64->ActivationContextStackPointer = PtrToUlong( &teb64->ActivationContextStack );
|
teb64->ActivationContextStackPointer = PtrToUlong( &teb64->ActivationContextStack );
|
||||||
teb64->ActivationContextStack.FrameListCache.Flink =
|
teb64->ActivationContextStack.FrameListCache.Flink =
|
||||||
teb64->ActivationContextStack.FrameListCache.Blink =
|
teb64->ActivationContextStack.FrameListCache.Blink =
|
||||||
|
@ -2862,11 +2875,13 @@ static void init_teb( TEB *teb, PEB *peb )
|
||||||
InitializeListHead( &teb->ActivationContextStack.FrameListCache );
|
InitializeListHead( &teb->ActivationContextStack.FrameListCache );
|
||||||
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
||||||
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
||||||
|
thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
||||||
thread_data->request_fd = -1;
|
thread_data->request_fd = -1;
|
||||||
thread_data->reply_fd = -1;
|
thread_data->reply_fd = -1;
|
||||||
thread_data->wait_fd[0] = -1;
|
thread_data->wait_fd[0] = -1;
|
||||||
thread_data->wait_fd[1] = -1;
|
thread_data->wait_fd[1] = -1;
|
||||||
list_add_head( &teb_list, &thread_data->entry );
|
list_add_head( &teb_list, &thread_data->entry );
|
||||||
|
return teb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2896,11 +2911,10 @@ TEB *virtual_alloc_first_teb(void)
|
||||||
MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE );
|
MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE );
|
||||||
teb_block_pos = 30;
|
teb_block_pos = 30;
|
||||||
ptr = (char *)teb_block + 30 * block_size;
|
ptr = (char *)teb_block + 30 * block_size;
|
||||||
teb = (TEB *)((char *)ptr + teb_offset);
|
|
||||||
data_size = 2 * block_size;
|
data_size = 2 * block_size;
|
||||||
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&ptr, 0, &data_size, MEM_COMMIT, PAGE_READWRITE );
|
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&ptr, 0, &data_size, MEM_COMMIT, PAGE_READWRITE );
|
||||||
peb = init_peb( (char *)teb_block + 31 * block_size );
|
peb = init_peb( (char *)teb_block + 31 * block_size );
|
||||||
init_teb( teb, peb );
|
teb = init_teb( ptr, peb );
|
||||||
*(ULONG_PTR *)&peb->CloudFileFlags = get_image_address();
|
*(ULONG_PTR *)&peb->CloudFileFlags = get_image_address();
|
||||||
return teb;
|
return teb;
|
||||||
}
|
}
|
||||||
|
@ -2943,8 +2957,7 @@ NTSTATUS virtual_alloc_teb( TEB **ret_teb )
|
||||||
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&ptr, 0, &block_size,
|
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&ptr, 0, &block_size,
|
||||||
MEM_COMMIT, PAGE_READWRITE );
|
MEM_COMMIT, PAGE_READWRITE );
|
||||||
}
|
}
|
||||||
*ret_teb = teb = (TEB *)((char *)ptr + teb_offset);
|
*ret_teb = teb = init_teb( ptr, NtCurrentTeb()->Peb );
|
||||||
init_teb( teb, NtCurrentTeb()->Peb );
|
|
||||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||||
|
|
||||||
if ((status = signal_alloc_thread( teb )))
|
if ((status = signal_alloc_thread( teb )))
|
||||||
|
@ -2964,7 +2977,7 @@ NTSTATUS virtual_alloc_teb( TEB **ret_teb )
|
||||||
void virtual_free_teb( TEB *teb )
|
void virtual_free_teb( TEB *teb )
|
||||||
{
|
{
|
||||||
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
||||||
void *ptr;
|
void *ptr = teb;
|
||||||
SIZE_T size;
|
SIZE_T size;
|
||||||
sigset_t sigset;
|
sigset_t sigset;
|
||||||
|
|
||||||
|
@ -2982,7 +2995,7 @@ void virtual_free_teb( TEB *teb )
|
||||||
|
|
||||||
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||||
list_remove( &thread_data->entry );
|
list_remove( &thread_data->entry );
|
||||||
ptr = (char *)teb - teb_offset;
|
if (!is_win64) ptr = (char *)ptr - teb_offset;
|
||||||
*(void **)ptr = next_free_teb;
|
*(void **)ptr = next_free_teb;
|
||||||
next_free_teb = ptr;
|
next_free_teb = ptr;
|
||||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||||
|
|
Loading…
Reference in New Issue