On 8/20/21 2:52 AM, Giovanni Mascellani wrote:
Hi,
Il 19/08/21 17:08, Erich E. Hoover ha scritto:
- 32-bit system libraries are being deprecated by the distros (and
Apple has already discontinued 32-bit support), so converting built-in libraries to PE means that Wine will interface solely with the 64-bit system libraries.
My understanding is that this is not just 32 on 64, but can be useful in general to run any architecture inside any other, with the help of an emulator. Given that ARM already has virtually all mobile devices and it is cutting itself a corner even among laptops and desktops, that could eventually become something we want to do. Arguably, it is already.
As I get it, the main idea here is that PE libraries are meant to be ran in the guest architecture and ELF libraries are meant to be ran in the host architecture. Of course the two must speak to each other, and this happens through a well defined interface, where it is (relatively) easy to do what the two architectures require to understand each other (enter or leave the emulator, change processor mode, convert pointers, endianness, sizes, whatever). In particular, PE modules do not need and cannot interface directly with the operating system's libraries.
For PE libraries that do not need to interface with host libraries, there is little to be done. For PE libraries that have to talk with the host system, they need a corresponding ELF library (which is just a regular host ELF library, so can link against other host libraries at its will). When the PE module is loaded, it calls __wine_init_unix_lib, which is intercepted by ntdll, which loads the corresponding ELF library and calls its __wine_init_unix_lib function, which returns a point to a structure with all the function pointers that the PE library might want to call. Given that ntdll mediates this exchange, it will be able to do whatever thunking is required to make the interface between the two worlds work.
I've heard of a syscall-like mechanism, but I am not sure it is relevant here.
My impression is that there the __wine_init_unix_lib interface is a just an in-between step from the old host-format dlls to the __wine_unix_call-using unix-split dlls. Routing the unix library entry points through syscalls (well, just __wine_unix_call) will make it so that at some point all calls to unix code from PE will be through the syscall enter/exit interface, and we can just add the thunking code there. Looking at the current code, it seems that ntdll will mandate unix libraries carry a second function pointer table (__wine_unix_call_wow64_funcs) to expose to wow64 apps, and these should be what handle 32/64 bit differences in memory layout. (So all the conversion here will have to be done explicitly, unlike the approach taken in Crossover that Ken described on here a few years ago).
I'm less sure on this, but I think the reason there are two different steps for converting DLLs is that since __wine_init_unix_lib interface merely exposes function pointers to the unix library entry points as-is to the PE, you don't have to worry about calling into PE code from the unix library yet, which may ease the transition.
This is what I could understand of this business. I'm happy to take corrections for whatever I mistook.
Giovanni.