On 4/18/22 22:37, Derek Lesho wrote:
On 16.04.22 03:58, Jinoh Kang wrote:
On 4/15/22 00:26, Eric Pouech wrote:
For modules requiring linking to .so files, the scheme has to be extended by generating an additional ELF library, tied to the PE module. +-----------------+ +-----------------+ +-----------+ | FOOBAR.dll (PE) | | FOOBAR.so (ELF) | -------------> | helper.so | | | --------> | (unixlib) | ELF dyn link +-----------+ | | | | +-----------------+ +-----------------+
Addind this extra module in the middle allows to:
- do the translation from a entities defined in PE world into entities
defined in the ELF world (ABI are different, structures layout are different)
- this provides an abstraction of the library for the PE world.
- decide what to migrate from the existing code into the PE part (remember
existing library in old model lives in the ELF world)
One can see the FOOBAR.so like a Wine-"system driver" for providing the required support from the host.
But, it brings constraints too. The ELF part cannot call back into the PE part of the module, nor into other PE modules.
To clarify: the ELF part cannot call back into PE modules *without performance penalty or interference with stack unwinding*.
ELF modules calls back into user-supplied functions just fine, think e.g. window procedures. This however involves KeUserModeCallback(), accompanied by its context-switching overhead.
Perhaps we intend to say: "The ELF part cannot link directly to dlls. Also, calling back to the PE side comes with performance penalty or interferes with stack unwinding, depending on which callback approach is used."
Can you describe the two approaches you're referring to? I'm aware of KeUserModeCallback, and I assume the other method is to create a win32 PE thread which waits on callbacks from the unixlib?
I meant calling it directly. Which (kind of) messes with syscall frame state.
As far as I know, KeUserModeCallback doesn't involve context switching, just the usual context saving/restoring required for syscalls in general.
Oh, maybe not a context switch per se. It's actually:
1. __wine_setjmp: save Unix-side state 2. emulated syscall return: divert into KiUserCallbackDispatcher 3. syscall: call into NtCallbackReturn 4. __wine_longjmp: restore Unix-side state
So it's still a lot of work.
If this ELF parts requires some Wine "kernel features", the it can (using ELF dynamic linking) use the APIs provided by ntdll.so ELF library.
+-----------------+ +-----------------+ +-----------+ | FOOBAR.dll (PE) | | FOOBAR.so (ELF) | -------------> | ntdll.so | | | --------> | (unixlib) | ELF dyn link +-----------+ | | | | -------------> | helper.so | +-----------------+ +-----------------+ +-----------+
Note: likely some other modules .so should be available too (like win32u) (to be confirmed)
I confirm that win32u.so also exists.
Here is a list of other Unixlibs:
I think what Eric was getting at here was what base unix libraries all other unix libraries can be linked against. (For example, using win32u.so from winevulkan.so).
Pretty much every Unix library can link to one another if they want to, barring abstraction layer issues. I think this aligns with what Eric is trying to convey.
avicap32.so, bcrypt.so, capi2032.so, crypt32.so, ctapi32.so, dnsapi.so, dwrite.so, gphoto2.so, kerberos.so, mountmgr.so, msv1_0.so, netapi32.so, nsiproxy.so, odbc32.so, opencl.so, qcap.so, sane.so, secur32.so, winealsa.so, winebus.so, winecoreaudio.so, winegstreamer.so, wineoss.so, winepulse.so, winevulkan.so, winspool.so, wldap32.so, wpcap.so, ws2_32.so
- exception handling?
To accurately mimic stack unwinding as it happens on Windows, one should stick to the syscall interface instead of the unixlib interface.
Assuming you're referring to the __wine_init_unix_lib approach, the unixlib interface doesn't even exist anymore. (Was removed right before wine 7.0-rc1)
I really meant __wine_unix_call. There's no syscall gate in-between, exposing DWARF frames that could confuse Win32 debuggers/monitors (probably as part of some DRM/obfuscation/anti-RE)
This way, unix-side stack frames will never appear in RtlVirtualUnwind() output (since they are effectively kernel-mode frames, not user-mode ones).