Paul Gofman : ntdll: Preserve rbx register when calling DLL entry point on x64.
Module: wine Branch: master Commit: 7527869fe868834ede7601aa40f11d28cb809f06 URL: https://gitlab.winehq.org/wine/wine/-/commit/7527869fe868834ede7601aa40f11d2... Author: Paul Gofman <pgofman(a)codeweavers.com> Date: Mon Jul 11 17:54:36 2022 -0500 ntdll: Preserve rbx register when calling DLL entry point on x64. --- dlls/ntdll/loader.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 20a96664825..043bce67ea9 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -264,7 +264,7 @@ void WINAPI RtlGetUnloadEventTraceEx(ULONG **size, ULONG **count, void **trace) * that only modifying esi leads to a crash, so use this one to backup * ebp while running the dll entry proc. */ -#ifdef __i386__ +#if defined(__i386__) extern BOOL call_dll_entry_point( DLLENTRYPROC proc, void *module, UINT reason, void *reserved ); __ASM_GLOBAL_FUNC(call_dll_entry_point, "pushl %ebp\n\t" @@ -298,13 +298,36 @@ __ASM_GLOBAL_FUNC(call_dll_entry_point, __ASM_CFI(".cfi_def_cfa %esp,4\n\t") __ASM_CFI(".cfi_same_value %ebp\n\t") "ret" ) -#else /* __i386__ */ +#elif defined(__x86_64__) +extern BOOL CDECL call_dll_entry_point( DLLENTRYPROC proc, void *module, UINT reason, void *reserved ); +/* Some apps modify rbx in TLS entry point. */ +__ASM_GLOBAL_FUNC(call_dll_entry_point, + "pushq %rbx\n\t" + __ASM_SEH(".seh_pushreg %rbx\n\t") + __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") + __ASM_CFI(".cfi_rel_offset %rbx,0\n\t") + "subq $48,%rsp\n\t" + __ASM_SEH(".seh_stackalloc 48\n\t") + __ASM_SEH(".seh_endprologue\n\t") + __ASM_CFI(".cfi_adjust_cfa_offset 48\n\t") + "mov %rcx,%r10\n\t" + "mov %rdx,%rcx\n\t" + "mov %r8d,%edx\n\t" + "mov %r9,%r8\n\t" + "call *%r10\n\t" + "addq $48,%rsp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset -48\n\t") + "popq %rbx\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t") + __ASM_CFI(".cfi_same_value %rbx\n\t") + "ret" ) +#else static inline BOOL call_dll_entry_point( DLLENTRYPROC proc, void *module, UINT reason, void *reserved ) { return proc( module, reason, reserved ); } -#endif /* __i386__ */ +#endif #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
participants (1)
-
Alexandre Julliard