For https://gitlab.winehq.org/wine/wine/-/merge_requests/7512 to use it to locate window shared objects.
--
v14: win32u: Use the session shared object for user handle entries.
win32u: Use the session shared object to implement is_window.
server: Move the user object handle table to the shared memory.
server: Allocate a session shared memory header structure.
server: Use NTUSER_OBJ constants for user object types.
include: Implement ReadAcquire64.
https://gitlab.winehq.org/wine/wine/-/merge_requests/7610
And adjust the return type of CtfImmHideToolbarWnd.
---
As with !7572, the Guild Wars 2 installer wants this (but only sometimes, which is why it wasn't included in that MR).
Testing shows that CtfImmRestoreToolbarWnd consumes one pointer-sized argument and (in my surely broken test calls) returns 0.
Examining the app, it calls CtfImmRestoreToolbarWnd with the return value of CtfImmHideToolbarWnd. That implies to me that the return of CtfImmHideToolbarWnd might be more interesting than a BOOL. I adjusted its return to a DWORD, both for that reason and because a BOOL implies that we know more about this function than we do. Let me know if you'd like me to split that into its own commit, or skip the change entirely.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7718
This is to avoid a crash in UnregisterDeviceNotification when
called a second time for the same handle.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58050
<details>
<summary>ASan Details</summary>
```
=================================================================
==control.exe==536==ERROR: AddressSanitizer: heap-use-after-free on address 0x7f07e3ae0568 at pc 0x6ffffdc6f092 bp 0x7ffffe1fdae0 sp 0x7ffffe1fdb28
READ of size 8 at 0x7f07e3ae0568 thread T0
#0 0x6ffffdc6f091 in list_remove ...\wine\include\wine\list.h:100
#1 0x6ffffdc6efcc in I_ScUnregisterDeviceNotification ...\wine\dlls\sechost\service.c:2193
#2 0x6ffffa5a16e2 in UnregisterDeviceNotification ...\wine\dlls\user32\input.c:594
#3 0x6ffffdbe3a5f in test_di_dialoHWND__ ...\wine\dlls\joy.cpl\dinput.c:809
#4 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#5 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#6 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#7 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#8 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#9 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#10 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#11 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#12 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#13 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#14 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#15 0x6ffffa5aee20 in dispatwin_proc_params ...\wine\dlls\user32\message.c:567
#16 0x6ffffa5aeda4 in SendMessageW ...\wine\dlls\user32\message.c:586
#17 0x6ffffde75873 in PROPSHEET_Cancel ...\wine\dlls\comctl32\propsheet.c:1949
#18 0x6ffffde75b80 in PROPSHEET_DoCommand ...\wine\dlls\comctl32\propsheet.c:3359
#19 0x6ffffde7085e in PROPSHEET_DialogProc ...\wine\dlls\comctl32\propsheet.c:3694
#20 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#21 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#22 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#23 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#24 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#25 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#26 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#27 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#28 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#29 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#30 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#31 0x6ffffa5aee20 in dispatwin_proc_params ...\wine\dlls\user32\message.c:567
#32 0x6ffffa5aeda4 in SendMessageW ...\wine\dlls\user32\message.c:586
#33 0x6ffffdd9a2fb in BUTTON_WindowProc+0x1c7b (C:\windows\winsxs\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef\comctl32.dll+0x18000a2fb)
#34 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#35 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#36 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#37 0x6ffffa5af7db in dispatch_message ...\wine\dlls\user32\message.c:804
#38 0x6ffffa5af881 in DispatchMessageW ...\wine\dlls\user32\message.c:890
#39 0x6ffffa591e90 in IsDialogMessageW ...\wine\dlls\user32\dialog.c:1293
#40 0x6ffffde76a93 in PROPSHEET_IsDialogMessage ...\wine\dlls\comctl32\propsheet.c:2956
#41 0x6ffffde6fd45 in do_loop ...\wine\dlls\comctl32\propsheet.c:2971
#42 0x6ffffde6c938 in PROPSHEET_PropertySheet ...\wine\dlls\comctl32\propsheet.c:3013
#43 0x6ffffde6cddd in PropertySheetW ...\wine\dlls\comctl32\propsheet.c:3124
#44 0x6ffffdbe754c in display_cpl_sheets ...\wine\dlls\joy.cpl\main.c:482
#45 0x6ffffdbe6d2f in CPlApplet ...\wine\dlls\joy.cpl\main.c:570
#46 0x6ffffb98f235 in Control_DoLaunch ...\wine\dlls\shell32\control.c:822
#47 0x6ffffb98e8e4 in Control_RunDLLW ...\wine\dlls\shell32\control.c:847
#48 0x0001400011b6 in launch+0x26 (C:\windows\system32\control.exe+0x1400011b6)
#49 0x000140001044 in STANCE__+0x44 (C:\windows\system32\control.exe+0x140001044)
#50 0x000140001320 in wmain+0xb0 (C:\windows\system32\control.exe+0x140001320)
#51 0x000140001245 in wmainCRTStartup ...\wine\dlls\msvcrt\crt_wmain.c:58
#52 0x6fffffc3565e in BaseThreadInitThunk ...\wine\dlls\kernel32\thread.c:61
#53 0x6fffffdbbb1a (C:\windows\system32\ntdll.dll+0x17004bb1a)
0x7f07e3ae0568 is located 8 bytes inside of 68-byte region [0x7f07e3ae0560,0x7f07e3ae05a4)
freed by thread T0 here:
#0 0x6ffffe84a381 in free+0x81 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a381)
#1 0x6ffffdc6eff8 in I_ScUnregisterDeviceNotification ...\wine\dlls\sechost\service.c:2196
#2 0x6ffffa5a16e2 in UnregisterDeviceNotification ...\wine\dlls\user32\input.c:594
#3 0x6ffffdbe3a5f in test_di_dialoHWND__ ...\wine\dlls\joy.cpl\dinput.c:809
#4 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#5 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#6 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#7 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#8 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#9 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#10 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#11 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#12 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#13 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#14 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#15 0x6ffffa5aee20 in dispatwin_proc_params ...\wine\dlls\user32\message.c:567
#16 0x6ffffa5aeda4 in SendMessageW ...\wine\dlls\user32\message.c:586
#17 0x6ffffde75df3 in PROPSHEET_CanSetCurSel ...\wine\dlls\comctl32\propsheet.c:2120
#18 0x6ffffde702ef in PROPSHEET_DialogProc ...\wine\dlls\comctl32\propsheet.c:3722
#19 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#20 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#21 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#22 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#23 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#24 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#25 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#26 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#27 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
previously allocated by thread T0 here:
#0 0x6ffffe84a5b6 in calloc+0x86 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a5b6)
#1 0x6ffffdc6e50b in I_ScRegisterDeviceNotification ...\wine\dlls\sechost\service.c:2141
#2 0x6ffffa5a1377 in RegisterDeviceNotificationW ...\wine\dlls\user32\input.c
#3 0x6ffffdbe398c in test_di_dialoHWND__ ...\wine\dlls\joy.cpl\dinput.c:795
#4 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#5 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#6 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#7 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#8 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#9 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#10 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#11 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#12 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#13 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#14 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#15 0x6ffffa5aee20 in dispatwin_proc_params ...\wine\dlls\user32\message.c:567
#16 0x6ffffa5aeda4 in SendMessageW ...\wine\dlls\user32\message.c:586
#17 0x6ffffde73e49 in PROPSHEET_SetCurSel ...\wine\dlls\comctl32\propsheet.c:2199
#18 0x6ffffde702c3 in PROPSHEET_DialogProc ...\wine\dlls\comctl32\propsheet.c:3717
#19 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#20 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#21 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#22 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#23 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#24 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#25 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#26 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#27 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
SUMMARY: AddressSanitizer: heap-use-after-free ...\wine\include\wine\list.h:100 in list_remove
Shadow bytes around the buggy address:
0x7f07e3ae0280: fd fd fd fa fa fa fa fa 00 00 00 00 00 00 00 00
0x7f07e3ae0300: 06 fa fa fa fa fa fd fd fd fd fd fd fd fd fd fd
0x7f07e3ae0380: fa fa fa fa fd fd fd fd fd fd fd fd fd fa fa fa
0x7f07e3ae0400: fa fa 00 00 00 00 00 00 00 00 06 fa fa fa fa fa
0x7f07e3ae0480: fd fd fd fd fd fd fd fd fd fd fa fa fa fa 00 00
=>0x7f07e3ae0500: 00 00 00 00 00 00 04 fa fa fa fa fa fd[fd]fd fd
0x7f07e3ae0580: fd fd fd fd fd fa fa fa fa fa fd fd fd fd fd fd
0x7f07e3ae0600: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
0x7f07e3ae0680: fd fa fa fa fa fa fd fd fd fd fd fd fd fd fd fa
0x7f07e3ae0700: fa fa fa fa fd fd fd fd fd fd fd fd fd fa fa fa
0x7f07e3ae0780: fa fa fd fd fd fd fd fd fd fd fd fd fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==control.exe==536==ABORTING
```
</details>
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7719
On Wed Apr 2 01:09:11 2025 +0000, Yeshun Ye wrote:
> Subjectively, I do believe it is indeed an issue with FreeType, as its
> documentation does not explicitly specify how to handle the high 32
> bits. I submitted the patch to Wine simply because I am more familiar
> with Wine. Since you think this approach is inappropriate, I will try
> submitting the patch to FreeType instead. Should I close this merge
> request now?
Yes, let's close this MR. If the freetype folks push back, we can reopen it.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7633#note_99643
x86_64 Windows and macOS both use `%gs` to access thread-specific data (Windows TEB, macOS TSD). To date, Wine has worked around this conflict by filling the most important TEB fields (`0x30`/`Self`, `0x58`/`ThreadLocalStorage`) in the macOS TSD structure (Apple reserved the fields for our use). This was sufficient for most Windows apps.
CrossOver's Wine had an additional hack to handle `0x60`/`ProcessEnvironmentBlock`, and binary patches for certain CEF binaries which directly accessed `0x8`/`StackBase`. Additionally, Apple's libd3dshared could activate a special mode in Rosetta 2 where code executing in certain regions would use the Windows TEB when accessing `%gs`.
Now that the PE separation is complete, GSBASE can be swapped when entering/exiting PE code. This is done in the syscall dispatcher, unix-call dispatcher, and for user-mode callbacks. GSBASE also needs to be set to the macOS TSD when entering signal handlers (in `init_handler()`), and then restored to the Windows TEB when exiting (in `leave_handler()`).
Some changes to the syscall dispatcher were needed to ensure that the TEB is not accessed through `%gs` while on the kernel stack (since a SIGUSR1 while on the kernel stack will result in GSBASE being set to the TSD).
---
I've tested this successfully on macOS 15 (Apple Silicon and Intel) and macOS 10.13 with several apps and games, including the `cefclient.exe` CEF sample.
Encouragingly, in some simple tests I didn't see a noticeable performance regression from this MR.
There are drawbacks though:
- libraries which jump directly from PE code into Unix code (expecting that %gs is always pointing to the macOS TSD) will crash. Notable examples are D3DMetal and DXMT. These will need to be changed to use Unix calls.
- If Windows code uses the `syscall` instruction directly, the stack pointer likely needs to be valid (which is probably not true on Windows). This is due to the syscall dispatcher saving registers onto the user stack and having to call `_thread_set_tsd_base`. I can't say I've ever seen direct syscalls done with an invalid `%rsp`, but it seems like something anticheat code might do.
---
macOS does not have a public API for setting GSBASE, but the private `_thread_set_tsd_base()` works and was added in macOS 10.12.
`_thread_set_tsd_base()` is a small thunk that sets `%esi`, `%eax`, and does the `syscall`: https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57….
The syscall instruction itself clobbers `%rcx` and `%r11`.
I've tried to save as few registers as possible when calling `_thread_set_tsd_base()`, but there may be room for improvement there.
---
I also tested an alternate implementation strategy for this which took advantage of the expanded "full" thread state which is passed to signal handlers when a process has set a user LDT. The full thread state includes GSBASE, so GSBASE is set back to whatever is in the sigcontext on return (like every other field in the context). This would avoid needing to explicitly reset GSBASE in `leave_handler()`.
This strategy was simpler, but I'm not using it for 2 reasons:
- the "full" thread state is only available starting with macOS 10.15, and we still support 10.13.
- more crucially, Rosetta 2 doesn't seem to correctly implement the GS.base field of the full thread state. It's set to 0 on entry, and isn't read on exit.
--
v7: ntdll: Remove x86_64 Mac-specific TEB access workarounds that are no longer needed.
ntdll: On macOS x86_64, swap GSBASE between the TEB and macOS TSD when entering/leaving PE code.
ntdll: Set %rsp to be inside syscall_frame before accessing %gs in x86_64 syscall dispatcher.
ntdll: Don't access the TEB through %gs when using the kernel stack in x86_64 syscall dispatcher.
ntdll: Ensure init_handler runs in signal handlers before any compiler-generated memset calls.
ntdll: Remove ugly fallback method for getting a thread's GSBASE on macOS.
https://gitlab.winehq.org/wine/wine/-/merge_requests/6866