On 2 May 2020 a series of commits starting with adb45d2294c0b165970a9b7d03713c8bc768ba0a and ending with 7eef40d444b3325f9580ff557afb6bc19c811f5e changed the implementation of the InterlockedCompareExchange64 function to use GCC's builtin __sync_val_compare_and_swap, and fall back to the (kernel32?) InterlockedCompareExchange64 exported function if absent.
0c14b1a962573ee125940f2008c646befe597226 then fixed the problem with ntdll's unix library not linking when GCC lacked the builtin (which both GCC and Clang lack on FreeBSD i386), by (in effect) redefining it as RtlInterlockedCompareExchange64 and linking to ntdll which exports that.
Recently 7571fa87df453e404d8b6ca58e2da95340156849 made ntdll's unix library link with -nodefaultlibs, so it cannot import RtlInterlockedCompareExchange64 from ntdll any more, recreating that linking regression when GCC lacks the builtin.
I made a preliminary patch that reimplements RtlInterlockedCompareExchange64 within the unix library, and it successfully compiles and links to completion, but I discovered there are at least 2 other major regressions affecting FreeBSD, one that makes X11 unusable between 5.14 and 5.15, and one that causes Wine to rapidly crash on startup between 5.15 and 33be7790e57b8f24933929e514e30bad2708d675, so there is more bisecting and debugging to do...
On Sun, Aug 30, 2020 at 7:55 AM Damjan Jovanovic damjan.jov@gmail.com wrote:
7571fa87df453e404d8b6ca58e2da95340156849 is the first bad commit commit 7571fa87df453e404d8b6ca58e2da95340156849 Author: Alexandre Julliard julliard@winehq.org Date: Mon Aug 24 13:30:12 2020 +0200
makefiles: Don't implicitly import the module itself when
-nodefaultlibs is used.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
tools/makedep.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
============== mingw build ============== ./../tools/winegcc/winegcc -o ntdll.so --wine-objdir ../.. -fno-PIC -fasynchronous-unwind-tables -munix \ -shared ntdll.spec -nodefaultlibs unix/cdrom.o unix/debug.o unix/env.o unix/file.o unix/loader.o \ unix/process.o unix/registry.o unix/security.o unix/serial.o unix/server.o unix/signal_arm.o \ unix/signal_arm64.o unix/signal_i386.o unix/signal_x86_64.o unix/sync.o unix/system.o unix/tape.o \ unix/thread.o unix/virtual.o unix/version.o ../../dlls/winecrt0/libwinecrt0.a \ ../../libs/port/libwine_port.a -lwine -lpthread -L/usr/local/lib /usr/local/bin/ld: unix/server.o: in function `interlocked_xchg64': /home/dj/Wine/wine/dlls/ntdll/unix/server.c:124: undefined reference to `RtlInterlockedCompareExchange64' /usr/local/bin/ld: unix/server.o: in function `get_cached_fd': /home/dj/Wine/wine/dlls/ntdll/unix/server.c:946: undefined reference to `RtlInterlockedCompareExchange64' collect2: error: ld returned 1 exit status
The RtlInterlockedCompareExchange64() function is only defined in large_int.c, but that's not listed in the object files to link to, nor can it be, because the unix library uses GCC but ntdll uses mingw.
============== gcc9 build ============== ../../tools/winegcc/winegcc -o ntdll.so --wine-objdir ../.. -fno-PIC -fasynchronous-unwind-tables -munix \ -shared ntdll.spec -nodefaultlibs unix/cdrom.o unix/debug.o unix/env.o unix/file.o unix/loader.o \ unix/process.o unix/registry.o unix/security.o unix/serial.o unix/server.o unix/signal_arm.o \ unix/signal_arm64.o unix/signal_i386.o unix/signal_x86_64.o unix/sync.o unix/system.o unix/tape.o \ unix/thread.o unix/virtual.o unix/version.o ../../dlls/winecrt0/libwinecrt0.a \ ../../libs/port/libwine_port.a -lwine -lpthread -L/usr/local/lib /usr/local/bin/ld: unix/server.o: in function `interlocked_xchg64': /home/dj/Wine/wine/dlls/ntdll/unix/server.c:124: undefined reference to `RtlInterlockedCompareExchange64' /usr/local/bin/ld: unix/server.o: in function `get_cached_fd': /home/dj/Wine/wine/dlls/ntdll/unix/server.c:946: undefined reference to `RtlInterlockedCompareExchange64' collect2: error: ld returned 1 exit status
If I add "large_int.o" to that command, it links, and completes the entire build successfully.
It's unclear how these would work even on Linux.
Damjan
On Sat, Aug 29, 2020 at 11:18 AM Gerald Pfeifer gerald@pfeifer.com wrote:
Sadly, after being fine for those two months since
commit 0c14b1a962573ee125940f2008c646befe597226 Author: Gerald Pfeifer gerald@pfeifer.com Date: Sun Jun 7 00:38:02 2020 +0200
ntdll: Replicate InterlockedCompareExchange64 to the Unix library. This fixes the build on FreeBSD/i386 with GCC 9. Signed-off-by: Gerald Pfeifer <gerald@pfeifer.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
went in, this is now broken again with GCC 9. It broke between Wine 5.15 and 5.16.
Alexandre, does the following ring a bell?
gcc9 -c -o enum_jobs.o enum_jobs.c -I. -I../../include -I../../include/msvcrt -D __WINESRC__ -D_UCRT -D_REENTRANT -fno-PIC -fasynchronous-unwind-tables -fno-builtin -fshort-wchar -Wall -pipe -fcf-protection=none -fno-stack-protector -fno-strict-aliasing -Wdeclaration-after-statement -Wempty-body -Wignored-qualifiers -Wno-packed-not-aligned -Wshift-overflow=2 -Wstrict-prototypes -Wtype-limits -Wunused-but-set-parameter -Wvla -Wwrite-strings -Wpointer-arith -Wlogical-op -fno-omit-frame-pointer -isystem /home/gerald/11-i386/include -O2 -pipe -fstack-protector-strong -Wl,-rpath=/home/gerald/11-i386/lib/gcc9 -isystem /home/gerald/11-i386/include -fno-strict-aliasing unix/server.o: In function `remove_fd_from_cache': server.c:(.text+0x2d0): undefined reference to `RtlInterlockedCompareExchange64' unix/server.o: In function `add_fd_to_cache': server.c:(.text+0x5da): undefined reference to `RtlInterlockedCompareExchange64' unix/server.o: In function `server_get_unix_fd': server.c:(.text+0xae3): undefined reference to `RtlInterlockedCompareExchange64' server.c:(.text+0xc00): undefined reference to `RtlInterlockedCompareExchange64' collect2: error: ld returned 1 exit status winegcc: /home/gerald/11-i386/bin/gcc9 failed gmake[2]: *** [Makefile:1454: ntdll.so] Error 2
Gerald
On Sun, 7 Jun 2020, Gerald Pfeifer wrote:
Between Wine 5.9 and 5.10 many ntdll functions moved to the Unix library. Make the implementation of InterlockedCompareExchange64 via RtlInterlockedCompareExchange64 available there as well for targets without __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8.
This fixes the build on FreeBSD/i386 with GCC 9.
Signed-off-by: Gerald Pfeifer gerald@pfeifer.com
dlls/ntdll/unix/unix_private.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/ntdll/unix/unix_private.h
b/dlls/ntdll/unix/unix_private.h
index a422fd825e..a0485b411d 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -23,6 +23,10 @@
#include "unixlib.h"
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 +#define InterlockedCompareExchange64(dest,xchg,cmp)
RtlInterlockedCompareExchange64(dest,xchg,cmp)
+#endif
struct debug_info { unsigned int str_pos; /* current position in strings buffer
*/