<pre style='margin:0'>
Perry E. Metzger (pmetzger) pushed a commit to branch master
in repository macports-ports.
</pre>
<p><a href="https://github.com/macports/macports-ports/commit/02ea6cf6990cddae6f72f696f4fa7e1ff1ccfd05">https://github.com/macports/macports-ports/commit/02ea6cf6990cddae6f72f696f4fa7e1ff1ccfd05</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 02ea6cf6990cddae6f72f696f4fa7e1ff1ccfd05
</span>Author: Dean M Greer <38226388+Gcenx@users.noreply.github.com>
AuthorDate: Sun May 26 08:58:18 2024 -0400
<span style='display:block; white-space:pre;color:#404040;'> wine-stable: New Port
</span>---
emulators/wine-stable/Portfile | 188 ++++
.../files/0001-winemac.drv-no-flicker.diff | 60 ++
.../0002-ntdll-workarond-sendmsg-bug-on-macOS.diff | 31 +
...after-free_in_macdrv_copy_pasteboard_types.diff | 26 +
emulators/wine-stable/files/macos_hacks.diff | 941 +++++++++++++++++++++
5 files changed, 1246 insertions(+)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/emulators/wine-stable/Portfile b/emulators/wine-stable/Portfile
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..e1c1ffbfed3
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/emulators/wine-stable/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,188 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortSystem 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortGroup compiler_blacklist_versions 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortGroup github 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortGroup muniversal 1.1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Keep the wine-stable, wine-devel and wine-crossover portfiles as similar as possible.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+github.setup wine-mirror wine 9.0 wine-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+github.tarball_from archive
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+name wine-stable
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+conflicts wine-devel wine-crossover
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set my_name wine
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+platforms {darwin >= 19}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set branch [lindex [split ${version} .] 0].0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+license LGPL-2.1+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+categories emulators
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+supported_archs x86_64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+maintainers {@Gcenx gmail.com:gcenx83}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+homepage https://www.winehq.org
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+dist_subdir ${my_name}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+description \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ A Windows API implementation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+long_description \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Wine is a compatibility layer capable of running \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Windows applications. \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Instead of simulating internal Windows logic like \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ a virtual machine or emulator, Wine translates \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Windows API calls into POSIX calls on-the-fly, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ eliminating the performance and memory penalties \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ of other methods and allowing you to cleanly \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ integrate Windows applications into your desktop.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+checksums \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rmd160 8a74032d3612e613ef5b97e9d2908ac612fa8d93 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sha256 90cd86d1203a7b1d304ae15461bbe0cbf1fd24feb407b551d011cc6d2967eb3f \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ size 48912704
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+depends_build \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:bison \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bin:flex:flex \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:gettext \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:mingw-w64 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ path:bin/pkg-config:pkgconfig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+depends_lib \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:freetype \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:gettext-runtime \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ path:lib/pkgconfig/gnutls.pc:gnutls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ path:lib/libMoltenVK.dylib:MoltenVK \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:libpcap \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:libsdl2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+depends_run \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:mingw-w64-wine-gecko-2.47.4 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:mingw-w64-wine-mono-8.1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+patch.pre_args-replace -p0 -p1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+patchfiles-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 0001-winemac.drv-no-flicker.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 0002-ntdll-workarond-sendmsg-bug-on-macos.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 0003-winemac.drv-fix_use-after-free_in_macdrv_copy_pasteboard_types.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Some required hacks to make wine work better on macOS & Rosetta2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+patchfiles-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macos_hacks.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# wine requires the program specified in INSTALL to create intermediate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# directories; /usr/bin/install doesn't.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# http://bugs.winehq.org/show_bug.cgi?id=35310
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.install \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ${worksrcpath}/tools/install-sh
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.args.x86_64 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --enable-archs=i386,x86_64 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --enable-win64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.args \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --disable-tests \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-alsa \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-capi \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-coreaudio \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-cups \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-dbus \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-fontconfig \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-freetype \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-gettext \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-gettextpo \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-gphoto \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-gnutls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-gssapi \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-gstreamer \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-inotify \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-krb5 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-mingw \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-netapi \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-opencl \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-opengl \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-oss \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-pcap \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-pcsclite \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-pthread \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-pulse \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-sane \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-sdl \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-udev \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-unwind \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-usb \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-v4l2 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --with-vulkan \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-wayland \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ --without-x
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.env.x86_64-append ac_cv_lib_soname_vulkan=
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# We need to tell the linker to add MacPorts to the rpath stack.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.ldflags-append -Wl,-rpath,${compiler.library_path}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# wine requires clang >= 3.8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# FSF GCC cannot compile code using Apple's "blocks" language extensions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+compiler.blacklist-append {*gcc*} {clang < 800} {macports-clang-3.*}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Makes destroot take significantly longer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+variant dev description "Install ${subport} development environment" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ build.target all
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ destroot.target-append install-dev
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+variant gphoto description "Build ${subport} with support for digital cameras" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ depends_lib-append port:libgphoto2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ configure.args-replace --without-gphoto --with-gphoto
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+variant gstreamer description "Build ${subport} with GStreamer, for multimedia support" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ depends_lib-append port:gstreamer1 port:gstreamer1-gst-plugins-base port:gstreamer1-gst-plugins-good \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:gstreamer1-gst-plugins-bad port:gstreamer1-gst-plugins-ugly port:gstreamer1-gst-libav
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ configure.args-replace --without-gstreamer --with-gstreamer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+variant kerberos description "Build ${subport} with Kerberos, for network authentication protocol support" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ depends_lib-append port:kerberos5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ configure.args-replace --without-krb5 --with-krb5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default_variants +gstreamer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+triplet.add_build cross
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+triplet.add_host none
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# macports-base injects a number of flags that now propagate to mingw-gcc this causes the build to fail since, wine-7.21
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# https://gitlab.winehq.org/wine/wine/-/commit/b1f59bc679a8c2dea18a6789a5b9b1a1ae825129
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+compiler.limit_flags yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+muniversal.arch_flag no
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+muniversal.arch_compiler yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.ldflags-delete -L${compiler.library_path}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.optflags -g -O2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.env-append "CROSSCFLAGS=${configure.optflags}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Were only installing wine not the development files
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+destroot.target install-lib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+post-destroot {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set docdir ${prefix}/share/doc/${my_name}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ xinstall -d ${destroot}${docdir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ xinstall -m 0644 -W ${worksrcpath} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ANNOUNCE.md \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ AUTHORS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ COPYING.LIB \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ LICENSE \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ README.md \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ${destroot}${docdir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+pre-activate {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {${os.major} == 19 && ${os.minor} < 4 && ${os.platform} eq "darwin"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_error "You must first update to macOS 10.15.4."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return -code error "You must first update to macOS 10.15.4."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+livecheck.url ${homepage}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+livecheck.type regex
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+livecheck.regex {"/announce/([0-9]+\.0(\.[0-9]+)*)"}
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/emulators/wine-stable/files/0001-winemac.drv-no-flicker.diff b/emulators/wine-stable/files/0001-winemac.drv-no-flicker.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..615b70c751b
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/emulators/wine-stable/files/0001-winemac.drv-no-flicker.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,60 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From 2bb3073bab5575a0a346ed25cde1a52da6f70a36 Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Ken Thomases <ken@codeweavers.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Tue, 22 Jun 2021 07:56:43 +1000
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] winemac.drv: No Flicker patch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dlls/winemac.drv/macdrv.h | 1 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dlls/winemac.drv/macdrv_main.c | 4 ++++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dlls/winemac.drv/opengl.c | 2 +-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 3 files changed, 6 insertions(+), 1 deletion(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index a1cdcc76ebc..14db3930474 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/winemac.drv/macdrv.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/winemac.drv/macdrv.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -44,6 +44,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ extern BOOL allow_set_gamma;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ extern BOOL allow_software_rendering;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ extern BOOL disable_window_decorations;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++extern BOOL force_backing_store;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ extern const char* debugstr_cf(CFTypeRef t);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index b40bf02f267..bc630305175 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/winemac.drv/macdrv_main.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/winemac.drv/macdrv_main.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -60,6 +60,7 @@ int use_precise_scrolling = TRUE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int gl_surface_mode = GL_SURFACE_IN_FRONT_OPAQUE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int retina_enabled = FALSE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int enable_app_nap = FALSE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++BOOL force_backing_store = FALSE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ CFDictionaryRef localized_strings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -378,6 +379,9 @@ static void setup_options(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!get_config_key(hkey, appkey, "EnableAppNap", buffer, sizeof(buffer)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ enable_app_nap = IS_OPTION_TRUE(buffer[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!get_config_key(hkey, appkey, "ForceOpenGLBackingStore", buffer, sizeof(buffer)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ force_backing_store = IS_OPTION_TRUE(buffer[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Don't use appkey. The DPI and monitor sizes should be consistent for all
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ processes in the prefix. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!get_config_key(hkey, NULL, "RetinaMode", buffer, sizeof(buffer)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f78454ed149..205c0816d44 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/winemac.drv/opengl.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/winemac.drv/opengl.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1451,7 +1451,7 @@ static BOOL create_context(struct wgl_context *context, CGLContextObj share, uns
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ attribs[n++] = pf->samples;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (pf->backing_store)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (force_backing_store || pf->backing_store)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ attribs[n++] = kCGLPFABackingStore;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (core)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+2.42.0
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/emulators/wine-stable/files/0002-ntdll-workarond-sendmsg-bug-on-macOS.diff b/emulators/wine-stable/files/0002-ntdll-workarond-sendmsg-bug-on-macOS.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..ea952239f21
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/emulators/wine-stable/files/0002-ntdll-workarond-sendmsg-bug-on-macOS.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,31 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From 174bb7776d3971e1ed91d57a47a7599b14c6eb45 Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Piotr Caban <piotr@codeweavers.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Fri, 8 Mar 2024 13:37:30 +0100
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] ntdll: Workaround sendmsg bug on macOS.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+There's a race on macOS when sending socket fd with sendmsg. The fd may get
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+broken if it's closed before recvmsg is called.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dlls/ntdll/unix/process.c | 2 +-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 1 file changed, 1 insertion(+), 1 deletion(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 4342ac8ac454..2c6dc1b43ccd 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/ntdll/unix/process.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/ntdll/unix/process.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -846,7 +846,6 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ wine_server_send_fd( socketfd[1] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- close( socketfd[1] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* create the process on the server side */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -875,6 +874,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ process_info = wine_server_ptr_handle( reply->info );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ SERVER_END_REQ;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ close( socketfd[1] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free( objattr );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free( handles );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free( jobs );
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/emulators/wine-stable/files/0003-winemac.drv-fix_use-after-free_in_macdrv_copy_pasteboard_types.diff b/emulators/wine-stable/files/0003-winemac.drv-fix_use-after-free_in_macdrv_copy_pasteboard_types.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..57535afc98b
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/emulators/wine-stable/files/0003-winemac.drv-fix_use-after-free_in_macdrv_copy_pasteboard_types.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,26 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From 7935a28d078f677467e68f551fb9c4e73863f25a Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Brendan Shanks <bshanks@codeweavers.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Thu, 2 May 2024 16:02:24 -0700
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] winemac.drv: Fix use-after-free in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ macdrv_copy_pasteboard_types.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Fixes a regression from bb2e02ab66c5c602d635722cf3a5820d6b366006.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dlls/winemac.drv/cocoa_clipboard.m | 1 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 1 file changed, 1 insertion(+)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/winemac.drv/cocoa_clipboard.m b/dlls/winemac.drv/cocoa_clipboard.m
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index a3dca323705..4994442f1df 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/winemac.drv/cocoa_clipboard.m
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/winemac.drv/cocoa_clipboard.m
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -103,6 +103,7 @@ CFArrayRef macdrv_copy_pasteboard_types(CFTypeRef pasteboard)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ @"com.compuserve.gif" : @(NSBitmapImageFileTypeGIF),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ @"public.jpeg" : @(NSBitmapImageFileTypeJPEG),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ [BitmapOutputTypeMap retain];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ OnMainThread(^{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+GitLab
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/emulators/wine-stable/files/macos_hacks.diff b/emulators/wine-stable/files/macos_hacks.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..3133b8ee448
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/emulators/wine-stable/files/macos_hacks.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,941 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 1aeb8f55257..956fd6c679f 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/kernelbase/process.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/kernelbase/process.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -504,6 +504,46 @@ done:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static const WCHAR *hack_append_command_line( const WCHAR *cmd, const WCHAR *cmd_line )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CROSSOVER HACK: bug 13322 (winehq bug 39403)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Insert --no-sandbox in command line of Steam's web helper process to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * work around rendering problems.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * CROSSOVER HACK: bug 17315
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Insert --in-process-gpu in command line of Steam's web helper process to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * work around page rendering problems.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * CROSSOVER HACK: bug 21883
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Insert --disable-gpu as well.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const struct
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const WCHAR *exe_name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const WCHAR *append;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const WCHAR *required_args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const WCHAR *forbidden_args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ options[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {L"steamwebhelper.exe", L" --no-sandbox --in-process-gpu --disable-gpu", NULL, L"--type=crashpad-handler"},
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!cmd) return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < ARRAY_SIZE(options); ++i)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (wcsstr( cmd, options[i].exe_name )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ && (!options[i].required_args || wcsstr(cmd_line, options[i].required_args))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ && (!options[i].forbidden_args || !wcsstr(cmd_line, options[i].forbidden_args)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ FIXME( "HACK: appending %s to command line.\n", debugstr_w(options[i].append) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return options[i].append;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /**********************************************************************
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * CreateProcessInternalW (kernelbase.@)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -520,6 +560,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ RTL_USER_PROCESS_PARAMETERS *params = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ RTL_USER_PROCESS_INFORMATION rtl_info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ HANDLE parent = 0, debug = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const WCHAR *append;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ULONG nt_flags = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ USHORT machine = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ NTSTATUS status;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -545,6 +586,20 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ app_name = name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CROSSOVER HACK */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if ((append = hack_append_command_line( app_name, tidy_cmdline )))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ WCHAR *new_cmdline = RtlAllocateHeap( GetProcessHeap(), 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(WCHAR) * (lstrlenW(cmd_line) + lstrlenW(append) + 1) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ lstrcpyW(new_cmdline, tidy_cmdline);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ lstrcatW(new_cmdline, append);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (tidy_cmdline != cmd_line) RtlFreeHeap( GetProcessHeap(), 0, tidy_cmdline );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tidy_cmdline = new_cmdline;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* end CROSSOVER HACK */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRACE( "app %s cmdline %s after all hacks\n", debugstr_w(app_name), debugstr_w(tidy_cmdline) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Warn if unsupported features are used */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (flags & (IDLE_PRIORITY_CLASS | HIGH_PRIORITY_CLASS | REALTIME_PRIORITY_CLASS |
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 59624bc70f8..99d70a74248 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/ntdll/loader.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/ntdll/loader.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2693,6 +2693,331 @@ static WINE_MODREF *find_existing_module( HMODULE module )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __x86_64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* CW HACK 19487: Patch out %gs:8h accesses in various versions of libcef.dll */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void patch_libcef( const WCHAR* libname, WINE_MODREF** pwm )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char before_85_3_9_0[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x08, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xc3, /* ret */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xec, 0x28, /* sub rsp, 0x28 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x08, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xc0, 0xf8 /* add rax, 0xfffffffffffffff8 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char after_85_3_9_0[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x30] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x40, 0x08, /* mov rax, qword [rax+8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xc3, /* ret */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xec, 0x28, /* sub rsp, 0x28 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xe8, 0xe7, 0xff, 0xff, 0xff, /* call 0xfffffffffffffffe */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xc0, 0xf8 /* add rax,0xfffffffffffffff8 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ C_ASSERT( sizeof(before_85_3_9_0) == sizeof(after_85_3_9_0) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* The first patch needed for 85.3.11 is the same as 85_3_9_0, just at a different offset. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char before_85_3_11_1[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x44, 0x24, 0x28, /* mov rax, qword ptr [rsp + 0x28] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x34, 0x25, 0x08, 0x00, 0x00, 0x00, /* mov rsi, qword ptr gs:[0x8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x85, 0xf6, /* test rsi, rsi */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x74, 0x2e /* jz 0x028c525b */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char after_85_3_11_1[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Taking a cue from after_72_0_3626_121_2 - overwriting the test and jump to make room. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x44, 0x24, 0x28, /* mov rax, qword ptr [rsp + 0x28] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x34, 0x25, 0x30, 0x00, 0x00, 0x00, /* mov rsi, qword ptr gs:[0x30] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x76, 0x08, /* mov rsi, qword ptr [rsi+8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ C_ASSERT( sizeof(before_85_3_11_1) == sizeof(after_85_3_11_1) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char before_72_0_3626_121_1[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x08, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xc3, /* ret */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xec, 0x28, /* sub rsp, 0x28 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x08, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xc0, 0xf8, /* add rax, 0xfffffffffffffff8 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char after_72_0_3626_121_1[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xe8, 0xb7, 0x00, 0x00, 0x00, /* call 0xbc */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xc3, /* ret */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xec, 0x28, /* sub rsp, 0x28 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xe8, 0xa9, 0x00, 0x00, 0x00, /* call 0xae */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xc0, 0xf8, /* add rax, 0xfffffffffffffff8 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ C_ASSERT( sizeof(before_72_0_3626_121_1) == sizeof(after_72_0_3626_121_1) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char before_72_0_3626_121_2[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x46, 0x08, /* mov rax, qword [rsi+8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x34, 0x25, 0x08, 0x00, 0x00, 0x00, /* mov rsi, qword [gs:0x8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x85, 0xf6, /* test rsi, rsi */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x74, 0x2e, /* je 0x30 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char after_72_0_3626_121_2[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x46, 0x08, /* mov rax, qword [rsi+8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x34, 0x25, 0x30, 0x00, 0x00, 0x00, /* mov rsi, qword [gs:0x30] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x76, 0x08, /* mov rsi, qword [rsi+8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ C_ASSERT( sizeof(before_72_0_3626_121_2) == sizeof(after_72_0_3626_121_2) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char before_72_0_3626_121_3[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x0f, 0x0b, /* ud2 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x6a, 0x1c, /* push 0x1c */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x0f, 0x0b, /* ud2 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x0f, 0x0b, /* ud2 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x6a, 0x1d, /* push 0x1d */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x0f, 0x0b /* ud2 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char after_72_0_3626_121_3[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x30] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x40, 0x08, /* mov rax, qword [rax+8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xc3, /* ret */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ C_ASSERT( sizeof(before_72_0_3626_121_3) == sizeof(after_72_0_3626_121_3) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char before_qt_5_15_2_0_1[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x08, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xc3, /* ret */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xec, 0x28, /* sub rsp, 0x28 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x08, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xe8, 0x08 /* sub rax, 0x8 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char after_qt_5_15_2_0_1[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x30] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x40, 0x08, /* mov rax, qword [rax+8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xc3, /* ret */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xcc, /* int3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xec, 0x28, /* sub rsp, 0x28 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xe8, 0xe7, 0xff, 0xff, 0xff, /* call 0xfffffffffffffffe */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x83, 0xe8, 0x08 /* sub rax,0x8 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ C_ASSERT( sizeof(before_qt_5_15_2_0_1) == sizeof(after_qt_5_15_2_0_1) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char before_qt_5_15_2_0_2[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xff, 0x15, 0xd5, 0xb4, 0x6e, 0x02, /* call [KERNEL32.DLL::VirtualQuery] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x65, 0x48, 0x8b, 0x04, 0x25, 0x08, 0x00, 0x00, 0x00, /* mov rax, qword [gs:0x8] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x4c, 0x24, 0x28 /* mov rcx, qword [rsp+0x28] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const char after_qt_5_15_2_0_2[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xff, 0x15, 0xd5, 0xb4, 0x6e, 0x02, /* call [KERNEL32.DLL::VirtualQuery] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0xe8, 0x78, 0xff, 0xff, 0xff, /* call 0xfffffffffffffffe */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x90, /* nop */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x48, 0x8b, 0x4c, 0x24, 0x28 /* mov rcx, qword [rsp+0x28] */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ C_ASSERT( sizeof(before_qt_5_15_2_0_2) == sizeof(after_qt_5_15_2_0_2) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ struct
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const WCHAR *libname;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const char *name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const void *before, *after;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ size_t size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ULONG_PTR offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BOOL stop_patching_after_success;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } static const patches[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 22584L
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * libcef.dll 85.3.11, for an updated Rockstar Games Social Club/Launcher.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"libcef.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "85.3.11-0",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* This patch is identical to the one for 85.3.9, just at a different offset. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_85_3_9_0, after_85_3_9_0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_85_3_9_0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x28c5190,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ FALSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"libcef.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "85.3.11-1",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_85_3_11_1, after_85_3_11_1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_85_3_11_1),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x28c521a,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRUE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 18582:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * libcef.dll 85.3.9.0 used by the Rockstar Games Social Club/Launcher
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * (and downloadable from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * https://cef-builds.spotifycdn.com/index.html#windows64).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"libcef.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "85.3.9.0",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_85_3_9_0, after_85_3_9_0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_85_3_9_0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x28c4b30,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRUE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 19114:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * libcef.dll 72.0.3626.121 used by the game beamNG.drive.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Patch also works for version downloadable from CEF builds.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"libcef.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "72.0.3626.121",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_72_0_3626_121_1, after_72_0_3626_121_1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_72_0_3626_121_1),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x23bb2ad,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ FALSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"libcef.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "72.0.3626.121",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_72_0_3626_121_2, after_72_0_3626_121_2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_72_0_3626_121_2),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x23bb329,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ FALSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"libcef.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "72.0.3626.121",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_72_0_3626_121_3, after_72_0_3626_121_3,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_72_0_3626_121_3),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x23bb369,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRUE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 16900:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * libcef.dll 72.0.3626.96 used by the game Wizard101.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Patch also works for version 3.3626.1886.g162fdec downloadable from CEF builds.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"libcef.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "72.0.3626.96",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* This patch is identical to the one for 72.0.3626.121, just at a different offset. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_72_0_3626_121_1, after_72_0_3626_121_1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_72_0_3626_121_1),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x23bb82d,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ FALSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"libcef.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "72.0.3626.96",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_72_0_3626_121_2, after_72_0_3626_121_2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_72_0_3626_121_2),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x23bb8a9,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ FALSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"libcef.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "72.0.3626.96",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_72_0_3626_121_3, after_72_0_3626_121_3,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_72_0_3626_121_3),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x23bb8e9,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRUE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 21548:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Qt5WebEngineCore.dll 5.15.2.0 used by the EA Launcher.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Based on CEF 83.0.4103.122, but has different offsets.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"Qt5WebEngineCore.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "5.15.2.0",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_qt_5_15_2_0_1, after_qt_5_15_2_0_1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_qt_5_15_2_0_1),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x2810f10,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ FALSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ L"Qt5WebEngineCore.dll",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "5.15.2.0",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ before_qt_5_15_2_0_2, after_qt_5_15_2_0_2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sizeof(before_qt_5_15_2_0_2),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0x2810f8d,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRUE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SIZE_T pagesize = page_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < ARRAY_SIZE(patches); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DWORD old_prot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void *dllbase = (*pwm)->ldr.DllBase;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void *target = (void *)((ULONG_PTR)dllbase + patches[i].offset);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void *target_page = (void *)((ULONG_PTR)target & ~(page_size-1));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (wcscmp( libname, patches[i].libname ))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if ((*pwm)->ldr.SizeOfImage < patches[i].offset)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRACE( "%s too small to be %s\n", debugstr_w(libname), patches[i].name );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (memcmp( target, patches[i].before, patches[i].size ))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRACE( "%s doesn't match %s\n", debugstr_w(libname), patches[i].name );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRACE( "Found %s %s, patching out gs:0x8 accesses\n", debugstr_w(libname), patches[i].name );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NtProtectVirtualMemory( NtCurrentProcess(), &target_page, &pagesize, PAGE_EXECUTE_READWRITE, &old_prot );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memcpy( target, patches[i].after, patches[i].size );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NtProtectVirtualMemory( NtCurrentProcess(), &target_page, &pagesize, old_prot, &old_prot );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (patches[i].stop_patching_after_success)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /******************************************************************************
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * load_native_dll (internal)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3272,6 +3597,10 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, DWORD fl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ case STATUS_SUCCESS: /* valid PE file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ nts = load_native_dll( load_path, &nt_name, mapping, &image_info, &id, flags, system, pwm );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __x86_64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (nts == STATUS_SUCCESS && (!wcscmp( libname, L"libcef.dll" ) || !wcscmp( libname, L"Qt5WebEngineCore.dll" )))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ patch_libcef( libname, pwm );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4260,6 +4589,18 @@ static void release_address_space(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __x86_64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++extern void CDECL wine_get_host_version( const char **sysname, const char **release );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static BOOL is_macos(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const char *sysname;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ wine_get_host_version( &sysname, NULL );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return !strcmp( sysname, "Darwin" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /******************************************************************
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * loader_init
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4337,6 +4678,24 @@ void loader_init( CONTEXT *context, void **entry )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else wm = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __x86_64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (is_macos() && !NtCurrentTeb()->WowTebOffset)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 18756 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Preallocate TlsExpansionSlots. Otherwise, kernelbase will
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ allocate it on demand, but won't be able to do the Mac-specific poking to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ %gs-relative address. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!NtCurrentTeb()->TlsExpansionSlots)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NtCurrentTeb()->TlsExpansionSlots = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, 8 * sizeof(NtCurrentTeb()->Peb->TlsExpansionBitmapBits) * sizeof(void*) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ __asm__ volatile ("movq %0,%%gs:%c1"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ : "r" (NtCurrentTeb()->TlsExpansionSlots), "n" (FIELD_OFFSET(TEB, TlsExpansionSlots)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!attach_done) /* only the first time */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ while (RtlFindClearBitsAndSet(NtCurrentTeb()->Peb->TlsBitmap, 1, 1) != ~0U);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef _WIN64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (NtCurrentTeb()->WowTebOffset) init_wow64( context );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 803d8079213..b1723851e97 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/ntdll/unix/loader.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/ntdll/unix/loader.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1797,6 +1797,48 @@ static ULONG_PTR get_image_address(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if defined(__APPLE__) && defined(__x86_64__)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static __thread struct tm localtime_tls;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct tm *my_localtime(const time_t *timep)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return localtime_r(timep, &localtime_tls);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void hook(void *to_hook, const void *replace)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ size_t offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ struct hooked_function
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ char jmp[8];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const void *dst;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } *hooked_function = to_hook;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ULONG_PTR intval = (UINT_PTR)to_hook;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ intval -= (intval % 4096);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ mprotect((void *)intval, 0x2000, PROT_EXEC | PROT_READ | PROT_WRITE);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* The offset is from the end of the jmp instruction (6 bytes) to the start of the destination. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ offset = offsetof(struct hooked_function, dst) - offsetof(struct hooked_function, jmp) - 0x6;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* jmp *(rip + offset) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hooked_function->jmp[0] = 0xff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hooked_function->jmp[1] = 0x25;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hooked_function->jmp[2] = offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hooked_function->jmp[3] = 0x00;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hooked_function->jmp[4] = 0x00;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hooked_function->jmp[5] = 0x00;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Filler */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hooked_function->jmp[6] = 0xcc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hooked_function->jmp[7] = 0xcc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Dest address absolute */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hooked_function->dst = replace;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ //size = sizeof(*hooked_function);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ //NtProtectVirtualMemory(proc, (void **)hooked_function, &size, old_protect, &old_protect);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /***********************************************************************
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * start_main_thread
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1819,6 +1861,13 @@ static void start_main_thread(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ load_ntdll();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ load_wow64_ntdll( main_image_info.Machine );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ load_apiset_dll();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if defined(__APPLE__) && defined(__x86_64__)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* This is necessary because we poke PEB into pthread TLS at offset 0x60. It is normally in use by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * localtime(), which is called a lot by system libraries. Make localtime() go away. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hook(localtime, my_localtime);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ server_init_process_done();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index ab544908883..e433d69ce97 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/ntdll/unix/signal_x86_64.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/ntdll/unix/signal_x86_64.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1004,7 +1004,11 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = set_thread_context( handle, context, &self, IMAGE_FILE_MACHINE_AMD64 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((flags & CONTEXT_DEBUG_REGISTERS) && (ret == STATUS_UNSUCCESSFUL))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- WARN_(seh)( "Setting debug registers is not supported under Rosetta\n" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 22131 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ WARN_(seh)( "Setting debug registers is not supported under Rosetta, faking success\n" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ret = STATUS_SUCCESS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (ret || !self) return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (flags & CONTEXT_DEBUG_REGISTERS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1214,6 +1218,14 @@ NTSTATUS set_thread_wow64_context( HANDLE handle, const void *ctx, ULONG size )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!self)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ NTSTATUS ret = set_thread_context( handle, context, &self, IMAGE_FILE_MACHINE_I386 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if ((flags & CONTEXT_DEBUG_REGISTERS) && (ret == STATUS_UNSUCCESSFUL))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 22131 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ WARN_(seh)( "Setting debug registers is not supported under Rosetta, faking success\n" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ret = STATUS_SUCCESS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (ret || !self) return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (flags & CONTEXT_I386_DEBUG_REGISTERS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1701,6 +1713,135 @@ NTSTATUS WINAPI NtCallbackReturn( void *ret_ptr, ULONG ret_len, NTSTATUS status
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ user_mode_callback_return( ret_ptr, ret_len, status, NtCurrentTeb() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/***********************************************************************
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * handle_cet_nop
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Check if the fault location is an Intel CET instruction that should be treated as a NOP.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Rosetta on Big Sur throws an exception for this, but is fixed in Monterey.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * CW HACK 20186
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static inline BOOL handle_cet_nop( ucontext_t *sigcontext, CONTEXT *context )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BYTE instr[16];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int i, prefix_count = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int len = virtual_uninterrupted_read_memory( (BYTE *)context->Rip, instr, sizeof(instr) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < len; i++) switch (instr[i])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* instruction prefixes */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x2e: /* %cs: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x36: /* %ss: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x3e: /* %ds: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x26: /* %es: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x40: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x41: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x42: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x43: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x44: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x45: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x46: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x47: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x48: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x49: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4a: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4b: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4c: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4d: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4e: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4f: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x64: /* %fs: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x65: /* %gs: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x66: /* opcode size */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x67: /* addr size */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0xf0: /* lock */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0xf2: /* repne */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0xf3: /* repe */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (++prefix_count >= 15) return FALSE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x0f: /* extended instruction */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (i == len - 1) return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ switch (instr[i + 1])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x1E:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* RDSSPD/RDSSPQ: (prefixes) 0F 1E (modrm) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ RIP_sig(sigcontext) += prefix_count + 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRACE_(seh)( "skipped RDSSPD/RDSSPQ instruction\n" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return TRUE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return FALSE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return FALSE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/***********************************************************************
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * handle_fndisi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Check if the fault location is an x87 FNDISI instruction that should be treated as a NOP.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static inline BOOL handle_fndisi( ucontext_t *sigcontext, CONTEXT *context )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BYTE instr[16];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int i, prefix_count = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int len = virtual_uninterrupted_read_memory( (BYTE *)context->Rip, instr, sizeof(instr) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < len; i++) switch (instr[i])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* instruction prefixes */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x2e: /* %cs: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x36: /* %ss: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x3e: /* %ds: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x26: /* %es: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x40: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x41: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x42: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x43: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x44: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x45: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x46: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x47: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x48: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x49: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4a: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4b: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4c: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4d: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4e: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x4f: /* rex */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x64: /* %fs: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x65: /* %gs: */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x66: /* opcode size */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0x67: /* addr size */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0xf0: /* lock */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0xf2: /* repne */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0xf3: /* repe */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (++prefix_count >= 15) return FALSE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0xdb:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (i == len - 1) return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ switch (instr[i + 1])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case 0xe1:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* RDSSPD/RDSSPQ: (prefixes) DB E1 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ RIP_sig(sigcontext) += prefix_count + 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TRACE_(seh)( "skipped FNDISI instruction\n" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return TRUE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return FALSE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return FALSE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /***********************************************************************
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * is_privileged_instr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1942,7 +2083,14 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ case TRAP_x86_PRIVINFLT: /* Invalid opcode exception */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 20186 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (handle_cet_nop( ucontext, &context.c )) return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (handle_fndisi( ucontext, &context.c )) return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ case TRAP_x86_STKFLT: /* Stack fault */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2492,6 +2640,8 @@ void call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ __asm__ volatile (".byte 0x65\n\tmovq %0,%c1" :: "r" (teb->Tib.Self), "n" (FIELD_OFFSET(TEB, Tib.Self)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ __asm__ volatile (".byte 0x65\n\tmovq %0,%c1" :: "r" (teb->ThreadLocalStoragePointer), "n" (FIELD_OFFSET(TEB, ThreadLocalStoragePointer)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thread_data->pthread_teb = mac_thread_gsbase();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ __asm__ volatile (".byte 0x65\n\tmovq %0,%c1" :: "r" (teb->Peb), "n" (FIELD_OFFSET(TEB, Peb)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ amd64_thread_data()->pthread_teb = mac_thread_gsbase();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* alloc_tls_slot() needs to poke a value to an address relative to each
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thread's gsbase. Have each thread record its gsbase pointer into its
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ TEB so alloc_tls_slot() can find it. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 9e84ec3cc96..95b862a56d7 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/ntdll/unix/thread.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/ntdll/unix/thread.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1084,6 +1084,16 @@ static DECLSPEC_NORETURN void pthread_exit_wrapper( int status )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ close( ntdll_get_thread_data()->wait_fd[1] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ close( ntdll_get_thread_data()->reply_fd );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ close( ntdll_get_thread_data()->request_fd );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if defined(__APPLE__) && defined(__x86_64__)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Remove the PEB from the localtime field in %gs, or MacOS might try
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * to free() the pointer and crash. That happens for processes that are
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * using the alt loader for dock integration. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ __asm__ volatile (".byte 0x65\n\tmovq %q0,%c1"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ : "r" (NULL), "n" (FIELD_OFFSET(TEB, Peb)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ pthread_exit( UIntToPtr(status) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index abe1b4dc4ec..724db5c7862 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/ntdll/unix/virtual.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/ntdll/unix/virtual.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -5906,6 +5906,56 @@ NTSTATUS WINAPI NtReadVirtualMemory( HANDLE process, const void *addr, void *buf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return status;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static int is_apple_silicon(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static int apple_silicon_status, did_check = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!did_check)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* returns 0 for native process or on error, 1 for translated */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int ret = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ size_t size = sizeof(ret);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (sysctlbyname( "sysctl.proc_translated", &ret, &size, NULL, 0 ) == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ apple_silicon_status = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ apple_silicon_status = ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ did_check = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return apple_silicon_status;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* CW HACK 18947
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * If mach_vm_write() is used to modify code cross-process (which is how we implement
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * NtWriteVirtualMemory), Rosetta won't notice the change and will execute the "old" code.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * To work around this, after the write completes,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * toggle the executable bit (from inside the target process) on/off for any executable
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * pages that were modified, to force Rosetta to re-translate it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void toggle_executable_pages_for_rosetta( HANDLE process, void *addr, SIZE_T size )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ MEMORY_BASIC_INFORMATION info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NTSTATUS status;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SIZE_T ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!is_apple_silicon())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ status = NtQueryVirtualMemory( process, addr, MemoryBasicInformation, &info, sizeof(info), &ret );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!status && (info.AllocationProtect & 0xf0))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DWORD origprot, noexec;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ noexec = info.AllocationProtect & ~0xf0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!noexec) noexec = PAGE_NOACCESS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NtProtectVirtualMemory( process, &addr, &size, noexec, &origprot );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NtProtectVirtualMemory( process, &addr, &size, origprot, &noexec );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /***********************************************************************
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * NtWriteVirtualMemory (NTDLL.@)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -5926,6 +5976,10 @@ NTSTATUS WINAPI NtWriteVirtualMemory( HANDLE process, void *addr, const void *bu
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((status = wine_server_call( req ))) size = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ SERVER_END_REQ;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ toggle_executable_pages_for_rosetta( process, addr, size );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/dlls/wow64cpu/cpu.c b/dlls/wow64cpu/cpu.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index a613c73d29f..26c471ff778 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/dlls/wow64cpu/cpu.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/dlls/wow64cpu/cpu.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -38,6 +38,15 @@ struct thunk_32to64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ DWORD op;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ DWORD addr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ WORD cs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BYTE add;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BYTE add_modrm;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BYTE add_op;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BYTE jmp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BYTE jmp_modrm;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DWORD jmp_op;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ULONG64 jmp_addr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ struct thunk_opcodes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -207,7 +216,18 @@ __ASM_GLOBAL_FUNC( syscall_32to64,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "movl %edx,4(%rsp)\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "movl 0xc4(%r13),%r14d\n\t" /* context->Esp */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "xchgq %r14,%rsp\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- "ljmp *(%r14)\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 20760:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Use lretq rather than ljmp to work around a Rosetta SIGUSR1 race condition.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "subq $0x10,%rsp\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "movl 4(%r14),%ebx\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "movq %rbx,0x8(%rsp)\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "movl 0(%r14),%ebx\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "movq %rbx,(%rsp)\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "movl 0xa4(%r13),%ebx\n\t" /* context->Ebx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "lretq\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ".Lsyscall_32to64_return:\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "movq %rsp,%r14\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "movl 0xa8(%r13),%edx\n\t" /* context->Edx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -261,7 +281,16 @@ __ASM_GLOBAL_FUNC( unix_call_32to64,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "movl %edx,4(%rsp)\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "movl 0xc4(%r13),%r14d\n\t" /* context->Esp */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "xchgq %r14,%rsp\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- "ljmp *(%r14)" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 20760:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Use lretq rather than ljmp to work around a Rosetta SIGUSR1 race condition.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "subq $0x10,%rsp\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "movl 4(%r14),%edx\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "movq %rdx,0x8(%rsp)\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "movl 0(%r14),%edx\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "movq %rdx,(%rsp)\n\t"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "lretq" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /**********************************************************************
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -308,22 +337,53 @@ NTSTATUS WINAPI BTCpuProcessInit(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ds64_sel = context.SegDs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fs32_sel = context.SegFs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- thunk->syscall_thunk.ljmp = 0xff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- thunk->syscall_thunk.modrm = 0x2d;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 20760:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Use lcall rather than ljmp to work around a Rosetta SIGUSR1 race condition.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.ljmp = 0xff; /* call far, absolute indirect */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.modrm = 0x1d; /* address=disp32, opcode=3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thunk->syscall_thunk.op = PtrToUlong( &thunk->syscall_thunk.addr );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- thunk->syscall_thunk.addr = PtrToUlong( syscall_32to64 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.addr = PtrToUlong( &thunk->syscall_thunk.add );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thunk->syscall_thunk.cs = cs64_sel;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* We are now in 64-bit. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* add $0x08,%esp to remove the addr/segment pushed on the stack by the lcall */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.add = 0x83;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.add_modrm = 0xc4;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.add_op = 0x08;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* jmp to syscall_32to64 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.jmp = 0xff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.jmp_modrm = 0x25;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.jmp_op = 0x00;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->syscall_thunk.jmp_addr = PtrToUlong( syscall_32to64 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* CW HACK 20760:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Use lcall rather than ljmp to work around a Rosetta SIGUSR1 race condition.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thunk->unix_thunk.pushl = 0x68;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thunk->unix_thunk.dispatcher_high = (ULONG_PTR)*p__wine_unix_call_dispatcher >> 32;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thunk->unix_thunk.pushl2 = 0x68;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thunk->unix_thunk.dispatcher_low = (ULONG_PTR)*p__wine_unix_call_dispatcher;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- thunk->unix_thunk.t.ljmp = 0xff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- thunk->unix_thunk.t.modrm = 0x2d;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.ljmp = 0xff; /* call far, absolute indirect */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.modrm = 0x1d; /* address=disp32, opcode=3 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thunk->unix_thunk.t.op = PtrToUlong( &thunk->unix_thunk.t.addr );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- thunk->unix_thunk.t.addr = PtrToUlong( unix_call_32to64 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.addr = PtrToUlong( &thunk->unix_thunk.t.add );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thunk->unix_thunk.t.cs = cs64_sel;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* We are now in 64-bit. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* add $0x08,%esp to remove the addr/segment pushed on the stack by the lcall */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.add = 0x83;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.add_modrm = 0xc4;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.add_op = 0x08;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* jmp to unix_call_32to64 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.jmp = 0xff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.jmp_modrm = 0x25;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.jmp_op = 0x00;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ thunk->unix_thunk.t.jmp_addr = PtrToUlong( unix_call_32to64 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ NtProtectVirtualMemory( GetCurrentProcess(), (void **)&thunk, &size, PAGE_EXECUTE_READ, &old_prot );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return STATUS_SUCCESS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span></pre><pre style='margin:0'>
</pre>