From daea0b9b57a8919be0ce1cff5b6cf36bd36b5c94 Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Wed, 6 Mar 2024 11:04:16 +0100
Subject: [PATCH] ntdll: Allocate the data structure and stack for the ARM64EC
 emulator.

---
 dlls/ntdll/unix/thread.c  | 18 ++++++++++++++++++
 dlls/ntdll/unix/virtual.c |  7 +++++++
 2 files changed, 25 insertions(+)

diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index 6a0f2fad346..7f2f1b9a50e 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -1218,6 +1218,24 @@ NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR limit, SIZE_T reserve_size, SIZE
 #endif
     }
 
+#ifdef __aarch64__
+    if (is_arm64ec())
+    {
+        CHPE_V2_CPU_AREA_INFO *cpu_area;
+        const SIZE_T chpev2_stack_size = 0x40000;
+
+        /* emulator stack */
+        if ((status = virtual_alloc_thread_stack( &stack, limit_4g, 0, chpev2_stack_size, chpev2_stack_size, FALSE )))
+            return status;
+
+        cpu_area = stack.DeallocationStack;
+        cpu_area->ContextAmd64 = (ARM64EC_NT_CONTEXT *)&cpu_area->EmulatorDataInline;
+        cpu_area->EmulatorStackBase  = (ULONG_PTR)stack.StackBase;
+        cpu_area->EmulatorStackLimit = (ULONG_PTR)stack.StackLimit + page_size;
+        teb->ChpeV2CpuAreaInfo = cpu_area;
+    }
+#endif
+
     /* native stack */
     if ((status = virtual_alloc_thread_stack( &stack, 0, limit, reserve_size, commit_size, TRUE )))
         return status;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 2b6ce543531..4b23d9954df 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -3758,6 +3758,13 @@ void virtual_free_teb( TEB *teb )
         size = 0;
         NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
     }
+#ifdef __aarch64__
+    if (teb->ChpeV2CpuAreaInfo)
+    {
+        size = 0;
+        NtFreeVirtualMemory( GetCurrentProcess(), (void **)&teb->ChpeV2CpuAreaInfo, &size, MEM_RELEASE );
+    }
+#endif
     if (thread_data->kernel_stack)
     {
         size = 0;