[PATCH 4/4] ntdll: Allocate kernel stack below user stack.
Rémi Bernon
rbernon at codeweavers.com
Tue Sep 28 04:22:28 CDT 2021
Gdb otherwise gets confused, as it considers the syscall frame to be
inner to the caller frame, stopping the stack unwinding early.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/ntdll/unix/thread.c | 4 ++--
dlls/ntdll/unix/virtual.c | 18 ++++++++++--------
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index e88a935ca31..9ccf03ceeb7 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -1180,7 +1180,7 @@ NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR zero_bits, SIZE_T reserve_size,
teb->Tib.StackBase = teb->TlsSlots[WOW64_TLS_CPURESERVED] = cpu;
teb->Tib.StackLimit = stack.StackLimit;
teb->DeallocationStack = stack.DeallocationStack;
- thread_data->kernel_stack = stack.StackBase;
+ thread_data->kernel_stack = (char *)stack.DeallocationStack - kernel_stack_size;
return STATUS_SUCCESS;
#else
/* 64-bit stack */
@@ -1201,7 +1201,7 @@ NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR zero_bits, SIZE_T reserve_size,
teb->Tib.StackBase = stack.StackBase;
teb->Tib.StackLimit = stack.StackLimit;
teb->DeallocationStack = stack.DeallocationStack;
- thread_data->kernel_stack = stack.StackBase;
+ thread_data->kernel_stack = (char *)stack.DeallocationStack - kernel_stack_size;
return STATUS_SUCCESS;
}
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 984af2d4a21..eb878171093 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -3135,13 +3135,6 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR zero_bits, SI
VALGRIND_STACK_REGISTER( view->base, (char *)view->base + view->size );
#endif
- /* setup no access guard page */
- set_page_vprot( view->base, page_size, VPROT_COMMITTED );
- set_page_vprot( (char *)view->base + page_size, page_size,
- VPROT_READ | VPROT_WRITE | VPROT_COMMITTED | VPROT_GUARD );
- mprotect_range( view->base, 2 * page_size, 0, 0 );
- VIRTUAL_DEBUG_DUMP_VIEW( view );
-
if (extra_size)
{
struct file_view *extra_view;
@@ -3149,16 +3142,25 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR zero_bits, SI
/* shrink the first view and create a second one for the extra size */
/* this allows the app to free the stack without freeing the thread start portion */
view->size -= extra_size;
- status = create_view( &extra_view, (char *)view->base + view->size, extra_size,
+ view->base = (char *)view->base + extra_size;
+ status = create_view( &extra_view, (char *)view->base - extra_size, extra_size,
VPROT_READ | VPROT_WRITE | VPROT_COMMITTED );
if (status != STATUS_SUCCESS)
{
view->size += extra_size;
+ view->base = (char *)view->base - extra_size;
delete_view( view );
goto done;
}
}
+ /* setup no access guard page */
+ set_page_vprot( view->base, page_size, VPROT_COMMITTED );
+ set_page_vprot( (char *)view->base + page_size, page_size,
+ VPROT_READ | VPROT_WRITE | VPROT_COMMITTED | VPROT_GUARD );
+ mprotect_range( view->base, 2 * page_size, 0, 0 );
+ VIRTUAL_DEBUG_DUMP_VIEW( view );
+
/* note: limit is lower than base since the stack grows down */
stack->OldStackBase = 0;
stack->OldStackLimit = 0;
--
2.33.0
More information about the wine-devel
mailing list