On Wed, 8 Sep 2021, Zebediah Figura wrote:
you're fearing that, then you should also fear symbol
clashes, right? I.e. you not only need to rename the lib basename,
but also all exported symbols from your version. (After all, programs
could also crawl the export lists). At that point it all becomes
How do deal with that problem currently? Why would that change with
the file format of your helper libs? Why should the libfreetype that
wine is using for internal purposes be loaded visibly into the process
image at all? After all the whole purpose of an emulator is to, well,
emulate the target as faithfully as possible, and one of those things
would be to provide the target process with only the list of loaded
DLLs it would also see on a normal Windows system. I.e. one without
freetype or any other libs that you mentioned. The code and data of
those libs can of course be loaded if you need them in-target-process,
but all the meta data of it should not be readily linked into the
normal data structures available to the target process.
Like any problem of emulation, it's a matter of trying to figure out
what's "good enough".
And the root of the problem here, what we're
concerned about, is that
the amount of work required to make dynamic libraries "good enough"—by
our estimation—is a lot more than it is for static libraries.
I might see that, but is it really the case? You're saying static libs
would work for you. That means static ELF libs linked into the wine
executable. They aren't seen by the target PE process then, and whatever
makes use of the code in those static libs (i.e. code in wine itself) also
directly refers to symbols within them with the link editor resolving
those references. I.e. I assume that you don't expose any of those
symbols to the target process (would require trampolines and custom loader
code when you link statically).
Now, for some reason that I don't see right now you don't want to use
dynamic ELF libs anymore. What is that reason? Linking the
wine executable(s) dynamically to the system ELF libs that are static
above and would be dynamic then (or are already) has exactly the same
properties: symbols and lib metadata stays internal to the wine
executable and isn't exposed directly to the target process, which is
exactly what you should want.
Your solution to this wish of avoiding ELF libs is to instead create and
load PE libs into the wine executable. That immediately creates the
problem you're worried about, namely namespace pollution for the target
process. Now, you also don't want to adjust your PE loader to support
something like an internal namespace for those wine-internal libs, because
of complexity (I wouldn't call such internal namespace a hack, btw). But
it seems all this complexity only comes from your wish of loading PE libs
when that doesn't seem necessary. My normal answer to that would be
"don't do that then". It also avoids the need to actually create PE libs
with a mingw toolchain and the necessary maintenance of everything needed
to cross compile those libraries.
Think of it this way: assume for a moment the target process is a
different architecture, i.e. that wine wouldn't only be an API emulator
but also a CPU emulator, say for aarch64 with wine running on x86_64.
Now your idea would be equivalent to compiling libfreetype for aarch64,
and then implementing all kinds of complexity within wine to actually run
that code on x86_64 just to make use of the facilities provided by
libfreetype for wine purposes, instead of just using a libfreetype
compiled for x86_64 to start with.
Your current train of thoughts seems to go from a working and natural
solution (link against system libs in host format for the host
executables) to complex and unnatural solutions (create host code in
target file format, but load it into the host program with the target
loader but also somewhat hide it from the target process).
So, what, _exactly_ is the reason that you don't want to link against ELF
system libraries for the wine executables that are ELF files themself? I
clearly must be missing something of the picture to see why going through
these hoops even occurred to you :-)
Currently host libraries are loaded in ELF format, and
somewhere in wine internals. win32 code can see them, if they knew how
to look for them, but of course they don't. The idea with PE libraries
is that, since we of course already have a PE loader, we just use it for
the code we can.
But why? You also have an ELF loader that you don't even need to maintain
yourself (in ld.so), why would you want to use the target object loader
(PE) for the host binaries (the wine code) when you can load host files
perfectly fine already?