Patch to fix build without optimization

Pavel Roskin proski at gnu.org
Wed Sep 17 12:03:32 CDT 2003


Hello!

Before I send it to wine-patches I'd like developers to look at it because
it's an important issue and I'm not 100% sure that it's the best fix.

I'm trying to compile CVS with without optimization and it fails:

make[1]: Entering directory `/usr/local/src/wine/miscemu'
gcc -o wine -Wl,--section-start,.interp=0x3c000100 main.o  -L../dlls
-lntdll.dll -L../libs/wine -lwine -L../libs/unicode -lwine_unicode
-L../libs/port -lwine_port
../dlls/libntdll.dll.so: undefined reference to
`InterlockedCompareExchange'

InterlockedCompareExchange() is defined as extern inline in
include/winbase.h for i386 and PowerPC.  It's defined extern for other
architectures.

It's implemented in dlls/kernel/sync.c for all architectures, either in
assembly code or as a call to interlocked_cmpxchg().  The implementation
is linked into kernel32.dll.

interlocked_cmpxchg() is declared in include/wine/port.h and implemented
in libs/port/interlocked.c.  It's exported by libwine_port.a.

The unresolved call to InterlockedCompareExchange comes from
wine/win32/device.c, which is linked into ntdll.dll.  Actually, device.c
calls InterlockedCompareExchangePointer(), which is a static inline
function that calls InterlockedCompareExchange().

If optimization if off, InterlockedCompareExchangePointer() is used as a
static function in wine/win32/device.c, and it calls external function
InterlockedCompareExchange().

When the wine executable is linked, it's linked against ntdll.dll, but not
against kernel32.dll.  Therefore, the reference to
InterlockedCompareExchange() in ntdll.dll is not satisfied.

I see two solutions.  One is to link wine executable against kernel32.dll.
Another is to use the low-level function interlocked_cmpxchg_ptr(), which
is what other code linked with "wine" does.

I prefer the second solution for its simplicity and consistency.  But I
don't know, maybe dependency of ntdll.dll and wine executable on
kernel32.dll is OK.  Then we could eliminate low-level
interlocked_cmpxchg() and use Win32 API functions for interlocking.

Anyway, here's the patch.  It works for me (Linux 2.4.23-pre4, gcc 3.2.2
from Red Hat 9, AMD Athlon).  Tested with winemine, notepad and Windows
Commander under Wine compiled with CFLAGS=-g

=================================
--- win32/device.c
+++ win32/device.c
@@ -611,7 +611,7 @@ static HKEY create_special_root_hkey( HK
         if (NtCreateKey( &hkey, access, &attr, 0, NULL, 0, NULL )) return 0;
     }

-    if (!(ret = InterlockedCompareExchangePointer( (PVOID) &special_root_keys[idx], hkey, 0 )))
+    if (!(ret = interlocked_cmpxchg_ptr( (PVOID) &special_root_keys[idx], hkey, 0 )))
         ret = hkey;
     else
         NtClose( hkey );  /* somebody beat us to it */
=================================

-- 
Regards,
Pavel Roskin



More information about the wine-devel mailing list