1

I am using WINE (on 64-bit Linux) to run a 32-bit Windows application which loads a DLL (LoadLibrary). I would like to re-write the DLL and compile it with winegcc/winebuild for that environment, without modifications to the original program. I am not interested in supporting 32-bit Linux hosts but the DLL itself needs to target 32-bit Windows as, as noted in the answer to another question, it is required for process interoperability:

On 64-bit Windows, a 64-bit process cannot load a 32-bit dynamic-link library (DLL).

Additionally, a 32-bit process cannot load a 64-bit DLL.

However, when building for 32-bit Windows, winegcc (using the -m32 flag) produces an x86 "DLL-wrapping" shared object which links against other 32-bit versions of Linux libraries (e.g. libwinecrt0.a). This is not the desired behavior as it requires the Linux host to have those 32-bit libraries which hinders easy distribution of the DLL. Furthermore, trying to manually link against the 64-bit versions of the libraries is prevented by the linker itself with the expected error:

/usr/bin/ld: relocatable linking with relocations from
format elf64-x86-64 to format elf32-i386 is not supported 

Now, I understand that there is an inherent difference in ISA (even ABI?) between x86 and amd64/x86_64 causing 32-bit Windows applications to be unable to load 64-bit DLLs and the GCC linker to refuse linking 32-bit Linux shared objects to 64-bit libraries. This incompatibility is the reason why modern CPUs are able to be placed in an "x86 mode", allowing 32-bit code to run. That mode switching, in turn, requiring privileges that regular userspace programs do not have, means that having an x86_64-to-x86 compatibility layer in the libraries is not possible (see Why cannot 64-bit shared libraries be used by 32-bit code?); is that right? If not, how would it be done?

Having said that, I notice that 32-bit Windows applications are able to be run by 64-bit WINE without (AFAIK) requiring any 32-bit Linux libraries. Consequently, I guess that WINE performs that through its re-implementation of WoW64 and, by doing so, contains any "32-bit-ness" within the WINE environment. Is there then a way for me to exploit this in my DLL?

The point I am making here is that this is not a regular "calling 64-bit libraries from 32-bit code" problem, as it involves one (even two?) extra layer(s) on top of the OS, which I would like to somehow exploit. The options I have considered, but which do not meet all requirements, are:

  • build the DLL with winegcc -m32 makes LoadLibrary succeed but links against 32-bit Linux libraries
  • build the DLL with winegcc -m64 links against 64-bit Linux libraries but makes it impossible to LoadLibrary from 32-bit Windows
  • build the DLL with MinGW (or any Windows-native compiler) leverages WoW64 so that no 32-bit Linux library is required but prevents me from using Linux code at all, which was the whole point of re-writing the library in the first place

What other options do I have? Wrapper code? Particular syscalls? Specific functionality within WINE? ...?

PiCTo
  • 924
  • 1
  • 11
  • 23

0 Answers0