Broken again (was: [PATCH] ntdll: Replicate InterlockedCompareExchange64 to the Unix library.)

Damjan Jovanovic damjan.jov at gmail.com
Fri Sep 11 02:28:53 CDT 2020


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 at gmail.com>
wrote:

> 7571fa87df453e404d8b6ca58e2da95340156849 is the first bad commit
> commit 7571fa87df453e404d8b6ca58e2da95340156849
> Author: Alexandre Julliard <julliard at 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 at 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 at pfeifer.com>
> wrote:
>
>> Sadly, after being fine for those two months since
>>
>>   commit 0c14b1a962573ee125940f2008c646befe597226
>>   Author: Gerald Pfeifer <gerald at 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 at pfeifer.com>
>>     Signed-off-by: Alexandre Julliard <julliard at 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 at 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
>> */
>> >
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20200911/a5cfdf81/attachment.htm>


More information about the wine-devel mailing list