[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Wine MinGW system libraries

On 9/8/21 3:13 AM, Simon McVittie wrote:
On Wed, 08 Sep 2021 at 07:31:59 +0000, Bastien ROUCARIES wrote:
Simon, do you think you could implement a version of libcapasule for PE object ?

Given that libcapsule is very glibc- and ELF-specific, doesn't work
properly without new glibc feature work that isn't in Debian yet (I've
lost track of whether/when it got merged upstream, it might be in 2.34)
and wasn't written by me, the answer is likely to be no.

As far as I understand it, the PE loader used for Wine is part of Wine,
so it has total control over the libraries that it loads and how it loads
them. This means that if Wine developers (the experts on this codebase)
have decided a libcapsule-like approach isn't feasible or isn't desirable,
they are probably right.

More generally, if Wine developers wanted Wine's dependency libraries
to be in one version of reality, and Windows DLLs to be in a different
version of reality, then there's a straightforward way to do that:
use ELF .so dependency libraries, like older versions of Wine did, and
don't give them a representation in the PE layer. Presumably they have
put in the work to move from ELF to PE dependency libraries because it
has some compelling advantage, rather than creating work for themselves
for no reason!

Yeah, basically :-)

The basic reason is that Wine is essentially trying to split itself into "PE" and "Unix" parts. The idea is that all of the "user" code is built in PE format, and only calls into unix code by making a sort of fake syscall. The "kernel" code is built in ELF format.

There are a few basic reasons for doing this:

* Many applications, mostly anti-cheat and anti-tamper engines, depend on our libraries actually being in PE format on disk, and matching that in memory. We used to have "fake" DLLs for this, but they weren't verisimilar enough.

* Some of the important hosts for Wine have dropped support for 32-bit libraries or are going to drop it. Mac is the obvious example here, but many commercial Linux distributions also want to drop support. By limiting the surface through which code can transition between PE and Unix code, it becomes feasible to do 32-to-64 translation, where previously this was quite infeasible.

* There's some demand for running Win32 debuggers under wine. These have always worked more than a little tenuously, but a couple of them are causing problems when they try to break in and unwind from Unix code. By acting like we're making actual syscalls, things work much better.

Of the several dozen modules we have that currently call into Unix libraries, about half of them aren't going to use PE dependencies. Most of these have already been fully split into PE and Unix parts, including things like the socket layer and winegstreamer. This raises the question: why not just call into Unix for the other half as well? There are a few reasons:

* Making fake syscalls is, like real syscalls, not cheap. It involves a full context switch into and out of Unix code.

* Making callbacks from Unix code is difficult, and not cheap either. For some libraries this doesn't matter, but for others it really does.

* Writing the wrappers between Unix and PE code involves some nontrivial work in itself. The smaller the interface is, the easier things are for us.

Reply to: