This allows libmono to load extra libraries (notably win-iconv) from system_dllpath.
For example, Fedora's wine-mono is built against a shared win-iconv installed in system_dllpath, but wine will not search there unless it's explicitly instructed to do so since bfbccf1a038e (ntdll: Prevent loading Wine system dependencies in place of identically named application DLLs.).
From: Zephyr Lykos git@mochaa.ws
This allows libmono to load extra libraries (notably win-iconv) from system_dllpath.
For example, Fedora's wine-mono is built against a shared win-iconv installed in system_dllpath, but wine will not search there unless it's explicitly instructed to do so since bfbccf1a038e (ntdll: Prevent loading Wine system dependencies in place of identically named application DLLs.).
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54573 Signed-off-by: Zephyr Lykos git@mochaa.ws --- dlls/mscoree/metahost.c | 2 +- dlls/ntdll/loader.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/mscoree/metahost.c b/dlls/mscoree/metahost.c index e1dd00656e9..49850e69f91 100644 --- a/dlls/mscoree/metahost.c +++ b/dlls/mscoree/metahost.c @@ -192,7 +192,7 @@ static HRESULT load_mono(LPCWSTR mono_path)
if (!find_mono_dll(mono_path, mono_dll_path)) goto fail;
- mono_handle = LoadLibraryW(mono_dll_path); + mono_handle = LoadLibraryExW(mono_dll_path, NULL, LDR_WINE_INTERNAL);
if (!mono_handle) goto fail;
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 0c25fe14133..c7a9a979868 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3374,7 +3374,8 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
RtlEnterCriticalSection( &loader_section );
- nts = load_dll( path_name, dllname ? dllname : libname->Buffer, flags, &wm, FALSE ); + nts = load_dll( path_name, dllname ? dllname : libname->Buffer, flags, &wm, + (flags & LDR_WINE_INTERNAL) != 0 );
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) {
I won't be able to review this properly until at least January 3, but an immediate concern is that other dll's shipped with Wine Mono in the lib/x86 and lib/x86_64 directories may have a similar issue.
Can this information be embedded into the dll itself instead of having to pass a flag to LoadLibraryEx?
I don't think this is possible. There's no way to specify a loader flag in the PE headers - specifically the Import Directory Table. Marking it as a wine builtin dll with `-Wl,--wine-builtin` would introduce winegcc to the wine-mono compilation process, which is likely what we don't want.
Also, this concern is likely invalid since the `system` flag is recursively set during early binding. I haven't checked whether libmono loads those libraries with LoadLibrary or Ldr* APIs, will do a quick grep. In that case, those calls also need to be updated.
Marking it builtin would be a simple change to the binary.
Those libraries are called by DllImports generally, and Mono doesn't have a way to distinguish them from the application's libraries. That's why I'd prefer to embed the information in the binaries.
FWIW, the way it's supposed to work is that any *linked* dependency of a builtin or system library [which isn't itself marked builtin] is system. Obviously we can't do that with manually loaded libraries.
Making libmono.dll itself builtin would solve this immediate problem.
I don't think it makes much sense to make libmono system, or anything shipped with it. The point of system libraries is that they don't conflict with native libraries with the same name, but I think that only makes sense for libraries that aren't actually in the prefix, that would be loaded when in the default search path. libmono isn't that and neither would be any of its dependencies *except* iconv.
So if there's a "correct" solution, marking things builtin is probably it, and more importantly I suspect it'll be viewed more favourably than adding internal flags into loader APIs.
So we have to overwrite the DOS stub in the `INSTALL_PE_$(1)` step (maybe **only** for `libmono-2.0-*.dll`), right?
btw, I didn't find any ways to set the DOS stub with objcopy, is writing to a hardcoded offset (0x40) ok?
```diff diff --git a/mono.make b/mono.make index 845c95b0..02dfb3df 100644 --- a/mono.make +++ b/mono.make @@ -48,6 +48,7 @@ IMAGEDIR_BUILD_TARGETS += $$(BUILDDIR)/mono-$(1)/support/.built libmono-2.0-$(1).dll: $$(BUILDDIR)/mono-$(1)/mono/mini/.built mkdir -p "$$(IMAGEDIR)/bin" $$(INSTALL_PE_$(1)) "$$(BUILDDIR)/mono-$(1)/mono/mini/.libs/libmonosgen-2.0.dll" "$$(IMAGEDIR)/bin/libmono-2.0-$(1).dll" + tools/mark-wine-builtin.sh "$$(IMAGEDIR)/bin/libmono-2.0-$(1).dll" if test x1 = x$(ENABLE_DEBUG_SYMBOLS) -a x1 != x$(PREFER_DWARF_SYMBOLS); then cp "$$(BUILDDIR)/mono-$(1)/mono/mini/libmono-2.0-$(1).pdb" "$$(IMAGEDIR)/bin/libmono-2.0-$(1).pdb"; fi
.PHONY: libmono-2.0-$(1).dll diff --git a/tools/mark-wine-builtin.sh b/tools/mark-wine-builtin.sh new file mode 100755 index 00000000..5846221b --- /dev/null +++ b/tools/mark-wine-builtin.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +printf 'Wine builtin DLL\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' | dd if=/dev/stdin of="$1" bs=1 seek=64 count=32 conv=notrunc ```
This should work, but I haven't tested it extensively.
I would do that in the INSTALL_PE step for all dll's. Any of them could, in theory, end up linked to a system library.