https://bugs.winehq.org/show_bug.cgi?id=47097
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |FIXED Component|user32 |build-env Status|NEW |RESOLVED Summary|Multiple Steam games crash |Multiple Steam games crash |on startup (Steam Game |on startup (Steam Game |Overlay Renderer hook |Overlay Renderer hook |engine needs |engine engine can't cope |DECLSPEC_HOTPATCH for |with GOT/ PIC register load |user32.RegisterDeviceNotifi |code)(Counter-Strike, Black |cationA/W)(Counter-Strike, |Mesa, The Superlatives: |Black Mesa, The |Shattered Worlds) |Superlatives: Shattered | |Worlds) | Fixed by SHA1| |8f732c66ab37b54c30d63c74f78 | |22ba1d4f04996
--- Comment #4 from Anastasius Focht focht@gmx.net --- Hello folks,
technically all the DECLSPEC_HOTPATCH bug reports/patches related to crashes with Steam Game Overlay Renderer are not needed anymore. Like other hook engines, it can cope with various opcode sequences in prologue code as well, except GOT/PIC register load sequence which is gone now.
* https://source.winehq.org/git/wine.git/commitdiff/8f732c66ab37b54c30d63c74f7... ("makefiles: Build with -fno-PIC on i386.")
* https://source.winehq.org/git/wine.git/commitdiff/8039941c52758113955d376bd7... ("makefiles: Also pass -fPIC flag when linking.")
Thanks Zebediah and Alexandre.
Explanation:
wine-4.7 release ('-fPIC' default for i386):
--- snip --- $ objdump -d /home/focht/projects/wine/mainline-install-4.7-x86_64/lib/wine/user32.dll.so | awk -F"\n" -v RS="\n\n" '$1 ~ /RegisterDeviceNotificationW/'
00088060 <RegisterDeviceNotificationW>: 88060: e8 dc 29 fa ff call 2aa41 <__x86.get_pc_thunk.ax> 88065: 05 9b bf 08 00 add $0x8bf9b,%eax 8806a: 8d 4c 24 04 lea 0x4(%esp),%ecx 8806e: 83 e4 f0 and $0xfffffff0,%esp 88071: ff 71 fc pushl -0x4(%ecx) 88074: 55 push %ebp 88075: 89 e5 mov %esp,%ebp 88077: 53 push %ebx 88078: 51 push %ecx 88079: 8b 11 mov (%ecx),%edx 8807b: 8b 59 04 mov 0x4(%ecx),%ebx 8807e: 8b 49 08 mov 0x8(%ecx),%ecx 88081: f6 80 78 b7 0e 00 01 testb $0x1,0xeb778(%eax) 88088: 75 16 jne 880a0 <RegisterDeviceNotificationW+0x40> 8808a: 8d 65 f8 lea -0x8(%ebp),%esp 8808d: b8 fe af fe ca mov $0xcafeaffe,%eax 88092: 59 pop %ecx 88093: 5b pop %ebx 88094: 5d pop %ebp 88095: 8d 61 fc lea -0x4(%ecx),%esp 88098: c2 0c 00 ret $0xc 8809b: 90 nop 8809c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi 880a0: 83 ec 04 sub $0x4,%esp 880a3: 51 push %ecx 880a4: 53 push %ebx 880a5: 52 push %edx 880a6: 8d 90 9c e5 fb ff lea -0x41a64(%eax),%edx 880ac: 52 push %edx 880ad: 8d 90 c8 e8 fb ff lea -0x41738(%eax),%edx 880b3: 8d 80 78 b7 0e 00 lea 0xeb778(%eax),%eax 880b9: 52 push %edx 880ba: 50 push %eax 880bb: 6a 00 push $0x0 880bd: e8 ee f4 ff ff call 875b0 <wine_dbg_log.constprop.3> 880c2: 83 c4 20 add $0x20,%esp 880c5: eb c3 jmp 8808a <RegisterDeviceNotificationW+0x2a> --- snip ---
Current Git -> wine-4.7-66-g8039941c52 ('-fno-PIC' default for i386):
--- snip --- $ objdump -d /home/focht/projects/wine/mainline-install-x86_64/lib/wine/user32.dll.so | awk -F"\n" -v RS="\n\n" '$1 ~ /RegisterDeviceNotificationW/'
00096130 <RegisterDeviceNotificationW>: 96130: 8d 4c 24 04 lea 0x4(%esp),%ecx 96134: 83 e4 f0 and $0xfffffff0,%esp 96137: ff 71 fc pushl -0x4(%ecx) 9613a: 55 push %ebp 9613b: 89 e5 mov %esp,%ebp 9613d: 51 push %ecx 9613e: 83 ec 04 sub $0x4,%esp 96141: 8b 01 mov (%ecx),%eax 96143: 8b 51 04 mov 0x4(%ecx),%edx 96146: 8b 49 08 mov 0x8(%ecx),%ecx 96149: f6 05 68 87 20 00 01 testb $0x1,0x208768 96150: 75 16 jne 96168 <RegisterDeviceNotificationW+0x38> 96152: 8b 4d fc mov -0x4(%ebp),%ecx 96155: b8 fe af fe ca mov $0xcafeaffe,%eax 9615a: c9 leave 9615b: 8d 61 fc lea -0x4(%ecx),%esp 9615e: c2 0c 00 ret $0xc 96161: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi 96168: 83 ec 04 sub $0x4,%esp 9616b: 51 push %ecx 9616c: 52 push %edx 9616d: 50 push %eax 9616e: 68 5c c2 0d 00 push $0xdc25c 96173: 68 a8 c5 0d 00 push $0xdc5a8 96178: 68 68 87 20 00 push $0x208768 9617d: 6a 00 push $0x0 9617f: e8 3c f6 ff ff call 957c0 <wine_dbg_log.constprop.3> --- snip ---
-> GOT/PIC register load gone.
How does it look like at runtime:
HANDLE user32.RegisterDeviceNotificationA(hRecipient,pFilter,Flags)
--- snip --- 7E69C0C0 E9 07469600 JMP 7F0006CC ; to Trampoline1 7E69C0C5 E4 F0 IN AL,0F0 7E69C0C7 FF71 FC PUSH DWORD PTR DS:[ECX-4] ; continuation 7E69C0CA 55 PUSH EBP 7E69C0CB 89E5 MOV EBP,ESP 7E69C0CD 51 PUSH ECX 7E69C0CE 83EC 04 SUB ESP,4 7E69C0D1 8B01 MOV EAX,DWORD PTR DS:[ECX] 7E69C0D3 8B51 04 MOV EDX,DWORD PTR DS:[ECX+4] 7E69C0D6 8B49 08 MOV ECX,DWORD PTR DS:[ECX+8] 7E69C0D9 F605 68E7807E 01 TEST BYTE PTR DS:[7E80E768],01 ... --- snip ---
Trampoline1:
--- snip --- ... 7F0006CC E9 DF396585 JMP 046540B0 ; Gameoverlayrenderer hook ... --- snip ---
Gameoverlayrenderer hook:
--- snip --- 046540B0 55 PUSH EBP 046540B1 8BEC MOV EBP,ESP 046540B3 53 PUSH EBX 046540B4 8B5D 10 MOV EBX,DWORD PTR SS:[EBP+10] 046540B7 56 PUSH ESI 046540B8 8B75 0C MOV ESI,DWORD PTR SS:[EBP+0C] 046540BB 57 PUSH EDI 046540BC 53 PUSH EBX 046540BD 56 PUSH ESI 046540BE FF75 08 PUSH DWORD PTR SS:[EBP+8] ; call org Wine impl via Trampoline2 046540C1 FF15 EC1B7004 CALL DWORD PTR DS:[4701BEC] ; 0x7F0006C0 046540C7 8BF8 MOV EDI,EAX 046540C9 85FF TEST EDI,EDI 046540CB 74 73 JE SHORT 04654140 --- snip ---
Trampoline2 with original prologue and continuation into original Wine impl
--- snip --- 7F0006C0 8D4C24 04 LEA ECX,[ESP+4] 7F0006C4 83E4 F0 AND ESP,FFFFFFF0 7F0006C7 E9 FBB969FF JMP 7E69C0C7 ; continue to Wine impl. --- snip ---
I propose instead of duplicating all issues into a single catch-all-collector ticket ("Many games / multiple hook engines/DRM schemes: DRM1, DRM2, hook engine1...") we collect tickets per hook-engine, even the underlying problem is the same (GOT/PIC loads). Make it easier for end-users who care only about their favourite content distribution platform (Steam, EA/Origin, ...) and release notes.
Regards