From 6c5644442ab05eed7cc48a3c67082f5bcfa399a8 Mon Sep 17 00:00:00 2001 From: Johan Lorensson Date: Thu, 4 Feb 2021 08:53:32 +0100 Subject: [PATCH] Handle NativeLibrary.GetExport/Free on libs not loaded through NativeLibrary.*Load* on Mono. (#47705) Handle NativeLibrary.GetExport on libs loaded with Interop.Kernel32.LoadLibraryEx. https://github.com/dotnet/runtime/pull/47013 changed how kernel32.dll and Ws2_32.dll gets loaded on Windows. Instead of loading using NativeLibrary.Load these system libraries are now loaded directly using LoadLibraryEx, but symbols are still handled through NativeLibrary. This short-circuits some logic in Mono that assumes all libraries gets loaded through NativeLibrary.Load. Fix adds ability to use passed in HMODULE when not finding a matching library in our native library cache and use it directly, inline with CoreClr behavior. * Handle NativeLibrary GetExport/Free using IntPtr library OS handle xplat. * Disable additional System.Drawing.Common tests due to missing COM support. --- .../System.Drawing.Common/tests/IconTests.cs | 11 ++--- src/mono/mono/metadata/native-library.c | 43 +++++++++++-------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/libraries/System.Drawing.Common/tests/IconTests.cs b/src/libraries/System.Drawing.Common/tests/IconTests.cs index bb501fc108f07..2ad23d5f18d5f 100644 --- a/src/libraries/System.Drawing.Common/tests/IconTests.cs +++ b/src/libraries/System.Drawing.Common/tests/IconTests.cs @@ -500,7 +500,7 @@ public void Save_NullOutputStreamIconData_ThrowsNullReferenceException() [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34591", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/47759", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void Save_NullOutputStreamNoIconData_ThrowsArgumentNullException() { using (var source = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"))) @@ -526,6 +526,7 @@ public void Save_ClosedOutputStreamIconData_ThrowsException() } [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/47759", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Save_ClosedOutputStreamNoIconData_DoesNothing() { @@ -688,7 +689,7 @@ private static Icon GetPngIcon() } [ConditionalFact(Helpers.IsDrawingSupported)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34591", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/47759", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void FromHandle_IconHandleOneTime_Success() { using (var icon1 = new Icon(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"))) @@ -701,7 +702,7 @@ public void FromHandle_IconHandleOneTime_Success() } [ConditionalFact(Helpers.IsDrawingSupported)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34591", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/47759", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void FromHandle_IconHandleMultipleTime_Success() { using (var icon1 = new Icon(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"))) @@ -722,7 +723,7 @@ public void FromHandle_IconHandleMultipleTime_Success() } [ConditionalFact(Helpers.IsDrawingSupported)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34591", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/47759", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void FromHandle_BitmapHandleOneTime_Success() { IntPtr handle; @@ -739,7 +740,7 @@ public void FromHandle_BitmapHandleOneTime_Success() } [ConditionalFact(Helpers.IsDrawingSupported)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34591", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/47759", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void FromHandle_BitmapHandleMultipleTime_Success() { IntPtr handle; diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index 2753582d00ae6..c69304ce26ff5 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -1578,16 +1578,19 @@ ves_icall_System_Runtime_InteropServices_NativeLibrary_FreeLib (gpointer lib, Mo native_library_lock (); module = netcore_handle_lookup (lib); - if (!module) - goto leave; - - ref_count = mono_refcount_dec (module); - if (ref_count > 0) - goto leave; - - g_hash_table_remove (native_library_module_map, module->handle); - g_hash_table_add (native_library_module_blocklist, module); - mono_dl_close (module); + if (module) { + ref_count = mono_refcount_dec (module); + if (ref_count > 0) + goto leave; + + g_hash_table_remove (native_library_module_map, module->handle); + g_hash_table_add (native_library_module_blocklist, module); + mono_dl_close (module); + } else { + MonoDl raw_module = { 0 }; + raw_module.handle = lib; + mono_dl_close (&raw_module); + } leave: native_library_unlock (); @@ -1610,16 +1613,18 @@ ves_icall_System_Runtime_InteropServices_NativeLibrary_GetSymbol (gpointer lib, native_library_lock (); module = netcore_handle_lookup (lib); - if (!module) - mono_error_set_generic_error (error, "System", "DllNotFoundException", "%p: %s", lib, symbol_name); - goto_if_nok (error, leave); - - mono_dl_symbol (module, symbol_name, &symbol); - if (!symbol) - mono_error_set_generic_error (error, "System", "EntryPointNotFoundException", "%s: %s", module->full_name, symbol_name); - goto_if_nok (error, leave); + if (module) { + mono_dl_symbol (module, symbol_name, &symbol); + if (!symbol) + mono_error_set_generic_error (error, "System", "EntryPointNotFoundException", "%s: %s", module->full_name, symbol_name); + } else { + MonoDl raw_module = { 0 }; + raw_module.handle = lib; + mono_dl_symbol (&raw_module, symbol_name, &symbol); + if (!symbol) + mono_error_set_generic_error (error, "System", "EntryPointNotFoundException", "%p: %s", lib, symbol_name); + } -leave: native_library_unlock (); leave_nolock: