Hello, On Wed, 8 Sep 2021, Zebediah Figura wrote:
Well, if 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 cumbersome.
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".
True.
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 they're stored 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? Ciao, Michael.