From: trcrsired <uwgghhbcad@gmail.com> NtCurrentTeb is defined by the ABI as reading the x18 register, so drop the custom PE-side implementation, the exported arm64 NtCurrentTeb() entry, and the unixcall fallback that pointed at it. LdrInitializeThunk now sets x18 and tpidr_el0 from the thread context at load time. win32u/message.c reads the KUSER_SHARED_DATA page through the user_shared_data symbol exported by ntdll.so, gated by HAVE_DYNAMIC_USER_SHARED_DATA instead of the __APPLE__/__aarch64__ compiler macros. --- dlls/ntdll/ntdll.spec | 1 - dlls/ntdll/signal_arm64.c | 48 +-------------------------------------- dlls/win32u/message.c | 8 ++++--- include/winnt.h | 6 ----- 4 files changed, 6 insertions(+), 57 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 1b74402a4b1..c245d56e2f4 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -214,7 +214,6 @@ @ stdcall -syscall NtCreateUserProcess(ptr ptr long long ptr ptr long long ptr ptr ptr) # @ stub NtCreateWaitablePort @ stdcall -arch=i386 NtCurrentTeb() -@ stdcall -arch=arm64 NtCurrentTeb() @ stdcall -syscall NtDebugActiveProcess(long long) @ stdcall -syscall NtDebugContinue(long ptr long) @ stdcall -syscall=0x0034 NtDelayExecution(long ptr) diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index 82a1dbf2c0e..5a2800ebe3d 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -837,56 +837,10 @@ __ASM_GLOBAL_FUNC( RtlUserThreadStart, /****************************************************************** * LdrInitializeThunk (NTDLL.@) */ -volatile ULONG_PTR __wine_current_teb; - -#ifdef __WINE_PE_BUILD -/*********************************************************************** - * NtCurrentTeb (NTDLL.@) - */ -struct _TEB * WINAPI NtCurrentTeb(void) -{ - ULONG_PTR t, sp; - struct _TEB *teb; - - __asm__ volatile( "mrs %0, tpidr_el0" : "=r"(t) ); - if (t > 0x100000000) /* per-thread TEB in the EL0 thread ID register */ - { - if (t > 0x800000000000ULL || t != (ULONG_PTR)__wine_current_teb) - FIXME( "tpidr_el0=%#lx cached=%#lx sp=%#lx\n", t, (ULONG_PTR)__wine_current_teb, (ULONG_PTR)__builtin_frame_address(0) ); - __wine_current_teb = t; - return (struct _TEB *)t; - } - - __asm__ volatile( "mov %0, sp" : "=r"(sp) ); - teb = (struct _TEB *)__wine_current_teb; - if (teb && sp >= (ULONG_PTR)teb->Tib.StackLimit && sp <= (ULONG_PTR)teb->Tib.StackBase) - return teb; /* cached TEB belongs to the current thread */ - - /* tpidr_el0 was reset (fresh code page or signal) and the cached TEB - * belongs to another thread; ask the unix side for the current one. */ - { - struct _TEB *current = NULL; - struct get_current_teb_params params = { ¤t }; - WINE_UNIX_CALL( unix_get_current_teb, ¶ms ); - if (current) - { - __wine_current_teb = (ULONG_PTR)current; - return current; - } - } - return (struct _TEB *)__wine_current_teb; -} -#endif - void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unk2, ULONG_PTR unk3, ULONG_PTR unk4 ) { - extern volatile ULONG_PTR __wine_current_teb; - __wine_current_teb = context->X18; + __asm__ volatile( "mov x18, %0" :: "r"(context->X18) ); __asm__ volatile( "msr tpidr_el0, %0" :: "r"(context->X18) ); - { - struct register_teb_ptr_params params = { (struct _TEB **)&__wine_current_teb }; - WINE_UNIX_CALL( unix_register_teb_ptr, ¶ms ); - } loader_init( context, (void **)&context->X0 ); TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", (void *)context->X0, (void *)context->X1 ); NtContinue( context, TRUE ); diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index d04e1e5daa7..63129799098 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -25,6 +25,7 @@ #endif #include <assert.h> +#include "config.h" #include "ntstatus.h" #include "winternl.h" #include "ddk/wdm.h" @@ -45,9 +46,10 @@ WINE_DECLARE_DEBUG_CHANNEL(relay); #define QS_HARDWARE 0x40000000 #define QS_INTERNAL (QS_DRIVER | QS_HARDWARE) -#if defined(__APPLE__) && defined(__aarch64__) -/* On Apple Silicon the fixed Windows address 0x7ffe0000 cannot be mapped; - * use the address chosen by the unix side (exported by ntdll.so). */ +#ifdef HAVE_DYNAMIC_USER_SHARED_DATA +/* On Apple Silicon the fixed Windows address 0x7ffe0000 is inside the kernel + * page zero and cannot be mapped; use the address chosen by the unix side + * (exported by ntdll.so). */ extern const struct _KUSER_SHARED_DATA *user_shared_data; #else static const struct _KUSER_SHARED_DATA *user_shared_data = (struct _KUSER_SHARED_DATA *)0x7ffe0000; diff --git a/include/winnt.h b/include/winnt.h index 04ae1fa961a..f25ce5170b9 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -2596,12 +2596,6 @@ static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) { return (struct _TEB *)__readfsdword( 0x18 ); } -#elif defined(__aarch64__) && !defined(__arm64ec__) -/* On Apple Silicon the TEB register (x18) is clobbered when the CPU enters - * freshly executed code pages, and the EL0 thread ID register is only - * reliable until the next such transition, so fetch the TEB through ntdll's - * export, which combines both with a per-thread fallback. */ -NTSYSAPI struct _TEB * WINAPI NtCurrentTeb(void); #elif (defined(__aarch64__) || defined(__arm64ec__)) && defined(__GNUC__) register struct _TEB *__wine_current_teb __asm__("x18"); static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11638