https://bugs.winehq.org/show_bug.cgi?id=50189
Bug ID: 50189 Summary: Multiple 64-bit applications crash with Wine MinGW PE build due to violation of Windows 64-bit ABI (RSP must be 16-byte aligned when making a call to Win64 API) Product: Wine Version: 5.22 Hardware: x86-64 OS: Linux Status: NEW Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@winehq.org Reporter: focht@gmx.net Distribution: ---
Hello folks,
while revisiting some old bugs I've encountered my old friend bug 27680 but now for LLVM/Clang/LLD based mingw-w64 toolchain.
I don't expect much violators in this "Hall of Shame" #2 though. Most apps/games from bug 27680 were either fixed by their vendors or are not relevant anymore.
Anyway, since Wine is nowadays a PE build there should be one collector bug report for this type of issue.
Example:
SafeNET's Sentinel HASP Runtime v6.6 from bug 45510 (https://bugs.winehq.org/show_bug.cgi?id=45510#c4)
Stable download:
https://web.archive.org/web/20201125113604/http://www.argusone.com/pub/Add_P...
After installation one should set the service to manual start type (3) in registry to avoid the annoying crashes due to default autostart start type (2).
--- snip --- $ wine net start hardlock ... The hardlock service is starting. 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\ntdll.dll" at 000000007BC00000: builtin 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\kernelbase.dll" at 000000007B000000: builtin 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\kernel32.dll" at 000000007B600000: builtin 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\winedevice.exe" at 0000000140000000: builtin 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\ucrtbase.dll" at 0000000000250000: builtin 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\sechost.dll" at 0000000000220000: builtin 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\advapi32.dll" at 0000000180000000: builtin 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\msvcrt.dll" at 0000000000350000: builtin 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\ntoskrnl.exe" at 0000000000300000: builtin 0168:trace:loaddll:build_module Loaded L"C:\windows\system32\rpcrt4.dll" at 0000000000AC0000: builtin 0170:trace:loaddll:build_module Loaded L"C:\windows\system32\HAL.dll" at 0000000000DA0000: builtin 0170:trace:loaddll:build_module Loaded L"C:\windows\system32\drivers\hardlock.sys" at 0000000000D50000: native wine: Unhandled page fault on read access to FFFFFFFFFFFFFFFF at address 000000007B62CC3C (thread 0170), starting debugger... --- snip ---
--- snip --- $ WINEDEBUG=+loaddll,+ntdll,+ntoskrnl wine net start hardlock ... 00dc:trace:ntoskrnl:ZwLoadDriver (L"\Registry\Machine\System\CurrentControlSet\Services\hardlock") 00dc:trace:ntoskrnl:open_driver opened service for driver L"\Registry\Machine\System\CurrentControlSet\Services\hardlock" 00dc:trace:ntoskrnl:IoCreateDriver (L"\Driver\hardlock", 00000000003154B0) 00dc:trace:ntoskrnl:load_driver loading driver L"C:\windows\system32\drivers\hardlock.sys" 00dc:trace:loaddll:build_module Loaded L"C:\windows\system32\HAL.dll" at 0000000000DA0000: builtin 00dc:trace:loaddll:build_module Loaded L"C:\windows\system32\drivers\hardlock.sys" at 0000000000D50000: native 00dc:trace:ntoskrnl:ldr_notify_callback loading L"HAL.dll" 00dc:trace:ntdll:NtQuerySystemInformation (0x00000000,0xc2f3d8,0x00000040,(nil)) 00dc:trace:ntoskrnl:ldr_notify_callback loading L"hardlock.sys" 00dc:trace:ntdll:NtQuerySystemInformation (0x00000000,0xc2f448,0x00000040,(nil)) 00dc:trace:ntoskrnl:MmIsAddressValid wine: Unhandled page fault on read access to FFFFFFFFFFFFFFFF at address 00000000003A7F53 (thread 00dc), starting debugger... ... --- snip ---
Crashes in ntoskrnl.MmIsAddressValid().
Relay debug prevents the crash (different stack layout).
NOTE: The driver is obfuscated, all other exceptions are by design and ok.
--- snip --- ... 0108:Call driver init 0000000000D9E1DE (obj=00000000000431A0,str=L"\Registry\Machine\System\CurrentControlSet\Services\hardlock") 0108:trace:seh:dispatch_exception code=c0000096 flags=0 addr=0000000000D9E0C6 ip=d9e0c6 tid=0108 0108:trace:seh:dispatch_exception rax=0000000000000400 rbx=0000000000d9f150 rcx=0000000000d9e1de rdx=0000000000d9e935 0108:trace:seh:dispatch_exception rsi=0000000000d9e935 rdi=0000000000d9e1de rbp=00000000000417f8 rsp=0000000000c2f7b0 0108:trace:seh:dispatch_exception r8=000000000000081b r9=0000000000d9e1de r10=0000000000000028 r11=0000000000000000 0108:trace:seh:dispatch_exception r12=0000000000c2fc00 r13=00000000000431a0 r14=0000000000043308 r15=0000000000000000 0108:trace:seh:call_vectored_handlers calling handler at 000000000030D2F0 code=c0000096 flags=0 ... 0108:trace:seh:call_vectored_handlers handler at 000000000030D2F0 returned ffffffff 0108:trace:seh:dispatch_exception code=c0000096 flags=0 addr=0000000000D9E27E ip=d9e27e tid=0108 0108:trace:seh:dispatch_exception rax=0000000000000400 rbx=0000000000d9e1de rcx=0000000000000000 rdx=000000005960f005 0108:trace:seh:dispatch_exception rsi=0000000000d9e342 rdi=0000000000d50400 rbp=00000000000417f8 rsp=0000000000c2f7d0 0108:trace:seh:dispatch_exception r8=000000000000081b r9=0000000000d50400 r10=000000005960f005 r11=0000000000000000 0108:trace:seh:dispatch_exception r12=0000000000c2fc00 r13=00000000000431a0 r14=0000000000043308 r15=0000000000000000 0108:trace:seh:call_vectored_handlers calling handler at 000000000030D2F0 code=c0000096 flags=0 0108:trace:seh:call_vectored_handlers handler at 000000000030D2F0 returned ffffffff 0108:Call ntoskrnl.exe.MmIsAddressValid(00307000) ret=00d9e3a9 0108:trace:ntoskrnl:MmIsAddressValid (0000000000307000) 0108:Call KERNEL32.IsBadReadPtr(00307000,00000001) ret=003138c3 0108:Ret KERNEL32.IsBadReadPtr() retval=00000000 ret=003138c3 0108:Ret ntoskrnl.exe.MmIsAddressValid() retval=00000001 ret=00d9e3a9 0108:Call ntoskrnl.exe.MmIsAddressValid(00306000) ret=00d9e3a9 0108:trace:ntoskrnl:MmIsAddressValid (0000000000306000) 0108:Call KERNEL32.IsBadReadPtr(00306000,00000001) ret=003138c3 0108:Ret KERNEL32.IsBadReadPtr() retval=00000000 ret=003138c3 0108:Ret ntoskrnl.exe.MmIsAddressValid() retval=00000001 ret=00d9e3a9 ... --- snip ---
Context in crash case (only run with +seh):
--- snip --- 00dc:trace:seh:dispatch_exception code=c0000005 flags=0 addr=000000007B62CC3C ip=7b62cc3c tid=00dc 00dc:trace:seh:dispatch_exception info[0]=0000000000000000 00dc:trace:seh:dispatch_exception info[1]=00000000ffffffff 00dc:trace:seh:dispatch_exception rax=000000007b62adc3 rbx=0000000000c2f738 rcx=0000000000c2f758 rdx=0000000000c2f738 00dc:trace:seh:dispatch_exception rsi=0000000000313000 rdi=0000000000000001 rbp=0000000000000001 rsp=0000000000c2f700 00dc:trace:seh:dispatch_exception r8=0000000000d9e343 r9=0000000000d50400 r10=000000009a4512ae r11=000000000004f600 00dc:trace:seh:dispatch_exception r12=0000000000c2fce0 r13=0000000000019760 r14=0000000000000000 r15=0000000000313000 00dc:trace:seh:call_vectored_handlers calling handler at 000000000030D2F0 code=c0000005 flags=0 00dc:trace:seh:call_vectored_handlers handler at 000000000030D2F0 returned 0 00dc:trace:seh:call_vectored_handlers calling handler at 000000007B011860 code=c0000005 flags=0 00dc:trace:seh:call_vectored_handlers handler at 000000007B011860 returned 0 --- snip ---
Disassembly to show no realign prologue with mingw:
<ntoskrnl.MmIsAddressValid>:
--- snip --- 0000000180013880 | push rsi | 0000000180013881 | sub rsp,30 | 0000000180013885 | mov rsi,rcx | 0000000180013888 | test byte ptr ds:[<__wine_dbch_ntoskrnl>],8 | 000000018001388F | je ntoskrnl.1800138B5 | 0000000180013891 | mov qword ptr ss:[rsp+20],rsi | 0000000180013896 | lea rdx,qword ptr ds:[<__wine_dbch_ntoskrnl>] | 000000018001389D | lea r8,qword ptr ds:[180024230] | 00000001800138A4 | lea r9,qword ptr ds:[18002383A] | 00000001800138AB | mov ecx,3 | 00000001800138B0 | call <ntoskrnl.wine_dbg_log> | 00000001800138B5 | mov edx,1 | 00000001800138BA | mov rcx,rsi | 00000001800138BD | call qword ptr ds:[<&IsBadReadPtr>] | 00000001800138C3 | test eax,eax | 00000001800138C5 | sete al | 00000001800138C8 | add rsp,30 | 00000001800138CC | pop rsi | 00000001800138CD | ret | --- snip ---
<kernel32.IsBadReadPtr>:
--- snip --- 000000007B62AD70 | push r14 | 000000007B62AD72 | push rsi | 000000007B62AD73 | push rdi | 000000007B62AD74 | push rbp | 000000007B62AD75 | push rbx | 000000007B62AD76 | sub rsp,160 | 000000007B62AD7D | xor r14d,r14d | 000000007B62AD80 | test rdx,rdx | 000000007B62AD83 | je kernel32.7B62AE4F | 000000007B62AD89 | mov rsi,rcx | 000000007B62AD8C | mov ebp,1 | 000000007B62AD91 | test rcx,rcx | 000000007B62AD94 | je kernel32.7B62ADEA | 000000007B62AD96 | mov rdi,rdx | 000000007B62AD99 | lea rax,qword ptr ds:[<__wine_exception_handler>] | 000000007B62ADA0 | mov qword ptr ss:[rsp+38],rax | 000000007B62ADA5 | lea rax,qword ptr ds:[<badptr_handler>] | 000000007B62ADAC | mov qword ptr ss:[rsp+40],rax | 000000007B62ADB1 | lea rcx,qword ptr ss:[rsp+50] | &__f.jmp 000000007B62ADB6 | lea rbx,qword ptr ss:[rsp+30] | &__f.frame 000000007B62ADBB | mov rdx,rbx | &__f.frame 000000007B62ADBE | call <kernel32.__wine_setjmpex> | 000000007B62ADC3 | test eax,eax | 000000007B62ADC5 | je kernel32.7B62ADEE | ... --- snip ---
<kernel32.__wine_setjmpex>:
__wine_setjmpex( &__f.jmp, &__f.frame )
RCX = &__f.jmp = 0x0000000000c2f758 (misaligned) RDX = &__f.frame = 0x0000000000c2f738
--- snip --- 000000007B62CC08 | mov qword ptr ds:[rcx],rdx | 000000007B62CC0B | mov qword ptr ds:[rcx+8],rbx | 000000007B62CC0F | lea rax,qword ptr ss:[rsp+8] | 000000007B62CC14 | mov qword ptr ds:[rcx+10],rax | 000000007B62CC18 | mov qword ptr ds:[rcx+18],rbp | 000000007B62CC1C | mov qword ptr ds:[rcx+20],rsi | 000000007B62CC20 | mov qword ptr ds:[rcx+28],rdi | 000000007B62CC24 | mov qword ptr ds:[rcx+30],r12 | 000000007B62CC28 | mov qword ptr ds:[rcx+38],r13 | 000000007B62CC2C | mov qword ptr ds:[rcx+40],r14 | 000000007B62CC30 | mov qword ptr ds:[rcx+48],r15 | 000000007B62CC34 | mov rax,qword ptr ss:[rsp] | 000000007B62CC38 | mov qword ptr ds:[rcx+50],rax | 000000007B62CC3C | movdqa xmmword ptr ds:[rcx+60],xmm6 | SSE2 *boom* 000000007B62CC41 | movdqa xmmword ptr ds:[rcx+70],xmm7 | 000000007B62CC46 | movdqa xmmword ptr ds:[rcx+80],xmm8 | 000000007B62CC4F | movdqa xmmword ptr ds:[rcx+90],xmm9 | 000000007B62CC58 | movdqa xmmword ptr ds:[rcx+A0],xmm10 | 000000007B62CC61 | movdqa xmmword ptr ds:[rcx+B0],xmm11 | 000000007B62CC6A | movdqa xmmword ptr ds:[rcx+C0],xmm12 | 000000007B62CC73 | movdqa xmmword ptr ds:[rcx+D0],xmm13 | 000000007B62CC7C | movdqa xmmword ptr ds:[rcx+E0],xmm14 | 000000007B62CC85 | movdqa xmmword ptr ds:[rcx+F0],xmm15 | 000000007B62CC8E | xor rax,rax | 000000007B62CC91 | ret | --- snip ---
Wine source:
https://source.winehq.org/git/wine.git/blob/92fb63d7754ba56b2604d253b600284c...
--- snip --- 74 BOOL WINAPI IsBadReadPtr( LPCVOID ptr, UINT_PTR size ) 75 { 76 if (!size) return FALSE; /* handle 0 size case w/o reference */ 77 if (!ptr) return TRUE; 78 __TRY 79 { 80 volatile const char *p = ptr; 81 char dummy __attribute__((unused)); 82 UINT_PTR count = size; 83 84 while (count > system_info.PageSize) 85 { 86 dummy = *p; 87 p += system_info.PageSize; 88 count -= system_info.PageSize; 89 } 90 dummy = p[0]; 91 dummy = p[count - 1]; 92 } 93 __EXCEPT( badptr_handler ) 94 { 95 TRACE("%p caused page fault during read\n", ptr); 96 return TRUE; 97 } 98 __ENDTRY 99 return FALSE; 100 } --- snip ---
https://source.winehq.org/git/wine.git/blob/92fb63d7754ba56b2604d253b600284c...
--- snip --- 136 #define __TRY \ 137 do { __WINE_FRAME __f; \ 138 int __first = 1; \ 139 for (;;) if (!__first) \ 140 { \ 141 do { 142 143 #define __EXCEPT(func) \ 144 } while(0); \ 145 __wine_pop_frame( &__f.frame ); \ 146 break; \ 147 } else { \ 148 __f.frame.Handler = __wine_exception_handler; \ 149 __f.u.filter = (func); \ 150 if (__wine_setjmpex( &__f.jmp, &__f.frame )) { \ 151 const __WINE_FRAME * const __eptr __attribute__((unused)) = &__f; \ 152 do { 153 --- snip ---
https://source.winehq.org/git/wine.git/blob/92fb63d7754ba56b2604d253b600284c...
--- snip --- 57 #if !defined(_MSC_VER) && !defined(__stdcall) 58 # ifdef __i386__ 59 # ifdef __GNUC__ 60 # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || defined(__APPLE__) 61 # define __stdcall __attribute__((__stdcall__)) __attribute__((__force_align_arg_pointer__)) 62 # else 63 # define __stdcall __attribute__((__stdcall__)) 64 # endif 65 # else 66 # error You need to define __stdcall for your compiler 67 # endif 68 # elif defined(__x86_64__) && defined (__GNUC__) 69 # if __has_attribute(__force_align_arg_pointer__) 70 # define __stdcall __attribute__((ms_abi)) __attribute__((__force_align_arg_pointer__)) 71 # else 72 # define __stdcall __attribute__((ms_abi)) 73 # endif 74 # elif defined(__arm__) && defined (__GNUC__) && !defined(__SOFTFP__) 75 # define __stdcall __attribute__((pcs("aapcs-vfp"))) 76 # elif defined(__aarch64__) && defined (__GNUC__) 77 # define __stdcall __attribute__((ms_abi)) 78 # else /* __i386__ */ 79 # define __stdcall 80 # endif /* __i386__ */ 81 #endif /* __stdcall */ --- snip ---
mingw-w64-clang has __stdcall predefined so it doesn't get the gcc treatment.
$ sha1sum HASPUserSetup.exe fa5f85d8dfbef3188087f1b6fb0ec81a16e6a26d HASPUserSetup.exe
$ du -sh HASPUserSetup.exe 14M HASPUserSetup.exe
$ wine --version wine-5.22-64-g92fb63d7754
Regards