[mono] Linking statically ICU shim on mono (#35790)
authorThays Grazia <thaystg@gmail.com>
Mon, 18 May 2020 14:02:32 +0000 (11:02 -0300)
committerGitHub <noreply@github.com>
Mon, 18 May 2020 14:02:32 +0000 (11:02 -0300)
Linking statically ICU shim on mono for windows, linux, macOs and android.

23 files changed:
src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs
src/libraries/Common/src/Interop/Interop.Libraries.cs
src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c
src/libraries/System.Globalization/tests/IcuTests.cs
src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs
src/mono/configure.ac
src/mono/mono/metadata/Makefile.am
src/mono/mono/metadata/native-library.c
src/mono/mono/mini/monovm.c
src/mono/mono/utils/mono-dl-posix.c
src/mono/mono/utils/mono-dl.c
src/mono/mono/utils/mono-dl.h
src/mono/msvc/libmono-dynamic.vcxproj
src/mono/msvc/libmonoruntime.targets
src/mono/msvc/libmonoruntime.targets.filters
src/mono/msvc/libmonoruntime.vcxproj
src/mono/msvc/mono.props
src/mono/msvc/shimglobalization.targets [new file with mode: 0644]
src/mono/msvc/shimglobalization.targets.filters [new file with mode: 0644]
src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs

index 7b49411..997fa49 100644 (file)
@@ -95,6 +95,16 @@ namespace System.Runtime.Loader
         }
 #endif
 
+        // This method is invoked by the VM to resolve a satellite assembly reference
+        // after trying assembly resolution via Load override without success.
+        private static Assembly? ResolveSatelliteAssembly(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
+        {
+            AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!;
+
+            // Invoke the ResolveSatelliteAssembly method
+            return context.ResolveSatelliteAssembly(assemblyName);
+        }
+
         // This method is invoked by the VM when using the host-provided assembly load context
         // implementation.
         private static IntPtr ResolveUnmanagedDll(string unmanagedDllName, IntPtr gchManagedAssemblyLoadContext)
index 4fee38a..9a64a90 100644 (file)
@@ -6,6 +6,10 @@ internal static partial class Interop
 {
     internal static partial class Libraries
     {
+#if MONO
+        internal const string GlobalizationNative = "__Internal";
+#else
         internal const string GlobalizationNative = "libSystem.Globalization.Native";
+#endif
     }
 }
index 1a594c4..093188b 100644 (file)
@@ -3,6 +3,9 @@
 // See the LICENSE file in the project root for more information.
 //
 
+#include <stdlib.h>
+#include "pal_icushim_internal.h"
+
 #if defined(TARGET_UNIX)
 #include <dlfcn.h>
 #elif defined(TARGET_WINDOWS)
 #include <libloaderapi.h>
 #include <errhandlingapi.h>
 #endif
-#include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
 
-#include "pal_icushim_internal.h"
 #include "pal_icushim.h"
 
 // Define pointers to all the used ICU functions
index 8e862c9..80533da 100644 (file)
@@ -11,8 +11,7 @@ namespace System.Globalization.Tests
     public class IcuTests
     {
         private static bool IsIcuCompatiblePlatform => PlatformDetection.IsNotWindows ||
-                                                       (!PlatformDetection.IsMonoRuntime &&
-                                                       PlatformDetection.IsWindows10Version1903OrGreater);
+                                                       PlatformDetection.IsWindows10Version1903OrGreater;
 
         [ConditionalFact(nameof(IsIcuCompatiblePlatform))]
         public static void IcuShouldBeUsedByDefault()
index c958169..80d7c00 100644 (file)
@@ -564,16 +564,6 @@ namespace System.Runtime.Loader
             return context.ResolveUsingLoad(assemblyName);
         }
 
-        // This method is invoked by the VM to resolve a satellite assembly reference
-        // after trying assembly resolution via Load override without success.
-        private static Assembly? ResolveSatelliteAssembly(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
-        {
-            AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!;
-
-            // Invoke the ResolveSatelliteAssembly method
-            return context.ResolveSatelliteAssembly(assemblyName);
-        }
-
         private Assembly? GetFirstResolvedAssemblyFromResolvingEvent(AssemblyName assemblyName)
         {
             Assembly? resolvedAssembly = null;
index 42ceddb..94c228b 100644 (file)
@@ -6795,6 +6795,46 @@ AC_COMPILE_IFELSE(
                AC_MSG_RESULT(no)
        ])
 
+# for icu shim
+ICU_SHIM_PATH=.
+if test x$with_core = xonly; then
+       if test x$cross_compiling = xno; then
+               AC_CHECK_FILE($srcdir/../libraries/Native/Unix/System.Globalization.Native/pal_icushim.h, [have_shim_globalization=yes], [have_shim_globalization=no])
+       fi
+       if test x$have_shim_globalization = xyes || test x$cross_compiling = xyes; then
+               ICU_SHIM_PATH=../../../libraries/Native/Unix/System.Globalization.Native
+               if test x$target_osx = xyes; then
+                       ORIG_CPPFLAGS=$CPPFLAGS
+                       # adding icu path to pkg_config_path
+                       PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig
+                       export PKG_CONFIG_PATH
+                       CPPFLAGS="`pkg-config --cflags-only-I icu-uc`"
+                       AC_CHECK_LIB(icucore, ucol_open, LIBS=$LIBS,
+                               [AC_MSG_ERROR([Cannot find libicucore, skipping build for System.Globalization.Native. .NET globalization is not expected to function.])])
+                       AC_CHECK_HEADER(unicode/utypes.h, [have_sys_icu=yes], [have_sys_icu=no])
+                       if test x$have_sys_icu = xyes; then
+                               ICU_CFLAGS="$CPPFLAGS -DOSX_ICU_LIBRARY_PATH=AS_ESCAPE(\"/usr/lib/libicucore.dylib\", '\"') -DTARGET_UNIX -DU_DISABLE_RENAMING -Wno-reserved-id-macro -Wno-documentation -Wno-documentation-unknown-command -Wno-switch-enum -Wno-covered-switch-default -Wno-covered-switch-default -Wno-extra-semi-stmt -Wno-unknown-warning-option -Wno-deprecated-declarations"
+                       fi
+                       CPPFLAGS=$ORIG_CPPFLAGS
+               elif test x$platform_android = xyes; then 
+                       ICU_CFLAGS="-DHAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS -DHAVE_SET_MAX_VARIABLE -DTARGET_UNIX -DTARGET_ANDROID -Wno-reserved-id-macro -Wno-documentation -Wno-documentation-unknown-command -Wno-switch-enum -Wno-covered-switch-default -Wno-covered-switch-default -Wno-extra-semi-stmt -Wno-unknown-warning-option"
+                       have_sys_icu=yes 
+               elif test x$host_linux = xyes; then
+                       AC_CHECK_LIB(icuuc, main, LIBS=$LIBS,
+                               [AC_MSG_ERROR([Cannot find libicuuc, try installing libicu-dev (or the appropriate package for your platform).])])
+                       AC_CHECK_LIB(icui18n, main, LIBS=$LIBS,
+                               [AC_MSG_ERROR([Cannot find libicui18n, try installing libicu-dev (or the appropriate package for your platform).])])
+                       AC_CHECK_HEADER(unicode/utypes.h, [have_sys_icu=yes], [have_sys_icu=no])
+                       if test x$have_sys_icu = xyes; then
+                               ICU_CFLAGS="-DTARGET_UNIX -Wno-reserved-id-macro -Wno-documentation -Wno-documentation-unknown-command -Wno-switch-enum -Wno-covered-switch-default -Wno-covered-switch-default -Wno-extra-semi-stmt -Wno-unknown-warning-option"
+                       fi
+               fi
+               AC_SUBST(ICU_CFLAGS)
+       fi
+fi
+AC_SUBST(ICU_SHIM_PATH)
+AM_CONDITIONAL(HAVE_SYS_ICU, test x$have_sys_icu = xyes)
+
 AC_SUBST(CFLAGS)
 AC_SUBST(CPPFLAGS)
 AC_SUBST(LDFLAGS)
index 0415d87..6a4bf4e 100644 (file)
@@ -103,7 +103,7 @@ Z_LIBS=$(BUNDLE_ZLIB_PATH)
 endif
 endif
 
-noinst_LTLIBRARIES = libmonoruntime-config.la $(support_libraries) $(boehm_libraries) $(sgen_libraries)
+noinst_LTLIBRARIES = libmonoruntime-config.la $(support_libraries) $(boehm_libraries) $(sgen_libraries) $(shim_libraries)
 
 lib_LTLIBRARIES = $(icall_table_libraries) $(ilgen_libraries)
 
@@ -136,6 +136,26 @@ libmonoruntime_support_la_SOURCES = support.c
 libmonoruntime_support_la_LDFLAGS = $(Z_LIBS)
 libmonoruntime_support_la_CFLAGS = $(filter-out @CXX_REMOVE_CFLAGS@, @CFLAGS@) @ZLIB_CFLAGS@
 
+if ENABLE_NETCORE
+if HAVE_SYS_ICU
+shim_libraries = libmonoruntime-shimglobalization.la
+
+libmonoruntime_shimglobalization_la_SOURCES = \
+                                                                       @ICU_SHIM_PATH@/pal_calendarData.c \
+                                                                       @ICU_SHIM_PATH@/pal_casing.c \
+                                                                       @ICU_SHIM_PATH@/pal_collation.c \
+                                                                       @ICU_SHIM_PATH@/pal_idna.c \
+                                                                       @ICU_SHIM_PATH@/pal_locale.c \
+                                                                       @ICU_SHIM_PATH@/pal_localeNumberData.c \
+                                                                       @ICU_SHIM_PATH@/pal_localeStringData.c \
+                                                                       @ICU_SHIM_PATH@/pal_normalization.c \
+                                                                       @ICU_SHIM_PATH@/pal_timeZoneInfo.c \
+                                                                       @ICU_SHIM_PATH@/pal_icushim.c
+
+libmonoruntime_shimglobalization_la_CFLAGS = @ICU_CFLAGS@ -I$(top_srcdir)/../libraries/Native/Unix/Common/
+endif
+endif
+
 #
 # This library contains the icall tables if the runtime was configured with --disable-icall-tables
 #
@@ -424,12 +444,12 @@ if !ENABLE_MSVC_ONLY
 libmonoruntime_la_SOURCES = $(common_sources) $(icall_tables_sources) $(ilgen_sources) $(gc_dependent_sources) $(null_gc_sources) $(boehm_sources)
 # Add CXX_ADD_CFLAGS per-library until/unless https://github.com/dotnet/corefx/pull/31342.
 libmonoruntime_la_CFLAGS = $(BOEHM_DEFINES) @CXX_ADD_CFLAGS@
-libmonoruntime_la_LIBADD = libmonoruntime-config.la $(support_libraries)
+libmonoruntime_la_LIBADD = libmonoruntime-config.la $(support_libraries) $(shim_libraries)
 
 libmonoruntimesgen_la_SOURCES = $(common_sources) $(icall_tables_sources) $(ilgen_sources) $(gc_dependent_sources) $(sgen_sources)
 # Add CXX_ADD_CFLAGS per-library until/unless https://github.com/dotnet/corefx/pull/31342.
 libmonoruntimesgen_la_CFLAGS = $(SGEN_DEFINES) @CXX_ADD_CFLAGS@
-libmonoruntimesgen_la_LIBADD = libmonoruntime-config.la $(support_libraries)
+libmonoruntimesgen_la_LIBADD = libmonoruntime-config.la $(support_libraries) $(shim_libraries)
 
 endif # !ENABLE_MSVC_ONLY
 
index 91b88a7..2b04f0d 100644 (file)
@@ -758,7 +758,7 @@ netcore_lookup_native_library (MonoAssemblyLoadContext *alc, MonoImage *image, c
        // We allow a special name to dlopen from the running process namespace, which is not present in CoreCLR
        if (strcmp (scope, "__Internal") == 0) {
                if (!internal_module)
-                       internal_module = mono_dl_open (NULL, MONO_DL_LAZY, &error_msg);
+                       internal_module = mono_dl_open_self (&error_msg);
                module = internal_module;
 
                if (!module) {
@@ -1240,6 +1240,9 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou
 #endif
 
 #ifdef ENABLE_NETCORE
+#ifndef HOST_WIN32
+retry_with_libcoreclr:
+#endif
        // FIXME: these flags are not getting passed correctly
        module = netcore_lookup_native_library (alc, image, new_scope, 0);
 #else
@@ -1262,6 +1265,21 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou
        addr = pinvoke_probe_for_symbol (module, piinfo, new_import, &error_msg);
 
        if (!addr) {
+#if defined(ENABLE_NETCORE) && !defined(HOST_WIN32)
+               if (strcmp (new_scope, "__Internal") == 0) {
+                       g_free ((char *)new_scope);
+#if defined(TARGET_OSX)
+                       new_scope = g_strdup ("libcoreclr.dylib");
+#else                  
+#if defined(TARGET_ANDROID)
+                       new_scope = g_strdup ("libmonosgen-2.0.so");
+#else
+                       new_scope = g_strdup ("libcoreclr.so");
+#endif
+#endif                 
+                       goto retry_with_libcoreclr;
+               }
+#endif         
                status_out->err_code = LOOKUP_PINVOKE_ERR_NO_SYM;
                status_out->err_arg = g_strdup (new_import);
                goto exit;
index d1aff44..3218564 100644 (file)
@@ -181,6 +181,9 @@ parse_properties (int propertyCount, const char **propertyKeys, const char **pro
                } else if (prop_len == 30 && !strncmp (propertyKeys [i], "System.Globalization.Invariant", 30)) {
                        // TODO: Ideally we should propagate this through AppContext options
                        g_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", propertyValues [i], TRUE);
+               } else if (prop_len == 27 && !strncmp (propertyKeys [i], "System.Globalization.UseNls", 27)) {
+                       // TODO: Ideally we should propagate this through AppContext options
+                       g_setenv ("DOTNET_SYSTEM_GLOBALIZATION_USENLS", propertyValues [i], TRUE);
                } else {
 #if 0
                        // can't use mono logger, it's not initialized yet.
index 1900a1a..a6c767c 100644 (file)
@@ -136,10 +136,10 @@ mono_dl_convert_flags (int flags)
 
 #ifdef ENABLE_NETCORE
        // Specifying both will default to LOCAL
-       if (flags & MONO_DL_LOCAL)
-               lflags |= RTLD_LOCAL;
-       else if (flags & MONO_DL_GLOBAL)
+       if (flags & MONO_DL_GLOBAL && !(flags & MONO_DL_LOCAL))
                lflags |= RTLD_GLOBAL;
+       else 
+               lflags |= RTLD_LOCAL;
 #else
        lflags = flags & MONO_DL_LOCAL ? RTLD_LOCAL : RTLD_GLOBAL;
 #endif
index 8b4aedd..32fc1da 100644 (file)
@@ -21,6 +21,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <glib.h>
+#if defined(ENABLE_NETCORE) && defined(TARGET_ANDROID)
+#include <dlfcn.h>
+#endif
 
 // Contains LIBC_SO definition
 #ifdef HAVE_GNU_LIB_NAMES_H
@@ -169,6 +172,37 @@ fix_libc_name (const char *name)
 #endif
 
 /**
+ * mono_dl_open_self:
+ * \param error_msg pointer for error message on failure
+ *
+ * Returns a handle to the main program, on android x86 it's not possible to 
+ * call dl_open(null), it returns a null handle, so this function returns RTLD_DEFAULT
+ * handle in this platform.
+ */
+MonoDl*
+mono_dl_open_self (char **error_msg)
+{
+#if defined(ENABLE_NETCORE) && defined(TARGET_ANDROID)
+       MonoDl *module;
+       if (error_msg)
+               *error_msg = NULL;
+       module = (MonoDl *) g_malloc (sizeof (MonoDl));
+       if (!module) {
+               if (error_msg)
+                       *error_msg = g_strdup ("Out of memory");
+               return NULL;
+       }
+       mono_refcount_init (module, NULL);
+       module->handle = RTLD_DEFAULT;
+       module->dl_fallback = NULL;
+       module->full_name = NULL;
+       return module;
+#else 
+       return mono_dl_open (NULL, MONO_DL_LAZY, error_msg);
+#endif 
+}
+
+/**
  * mono_dl_open:
  * \param name name of file containing shared module
  * \param flags flags
index 6236d98..6efee6f 100644 (file)
@@ -43,6 +43,8 @@ char*       mono_dl_build_path (const char *directory, const char *name, void **
 
 MonoDl*     mono_dl_open_runtime_lib (const char *lib_name, int flags, char **error_msg);
 
+MonoDl*     mono_dl_open_self (char **error_msg);
+
 
 //Platform API for mono_dl
 const char* mono_dl_get_so_prefix (void);
index 3b1fab1..c63be2c 100644 (file)
@@ -96,8 +96,8 @@
     <ClCompile>
       <AdditionalOptions>/D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions)</AdditionalOptions>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <DisableSpecificWarnings>4996;4018;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <WarningLevel>Level3</WarningLevel>
     </ClCompile>
     <ClCompile>
       <AdditionalOptions>/D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions)</AdditionalOptions>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <DisableSpecificWarnings>4996;4018;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <WarningLevel>Level3</WarningLevel>
     </ClCompile>
     <ClCompile>
       <AdditionalOptions>/D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions)</AdditionalOptions>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <WarningLevel>Level3</WarningLevel>
       <WholeProgramOptimization>true</WholeProgramOptimization>
     <ClCompile>
       <AdditionalOptions>/D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions)</AdditionalOptions>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <WarningLevel>Level3</WarningLevel>
       <WholeProgramOptimization>true</WholeProgramOptimization>
index ba371e2..7b797ee 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildThisFileDirectory)monozlib.targets" />
+  <Import Project="$(MSBuildThisFileDirectory)shimglobalization.targets" Condition="'$(MONO_ENABLE_NETCORE)'=='true'"/>
   <Import Project="$(MSBuildThisFileDirectory)libmonoruntime-common.targets" />
   <Import Project="$(MSBuildThisFileDirectory)libmonoruntime-win32.targets" />
   <Import Project="$(MSBuildThisFileDirectory)libmonoruntime-posix.targets" />
index 870a2b1..d59ba5b 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildThisFileDirectory)monozlib.targets.filters" />
+  <Import Project="$(MSBuildThisFileDirectory)shimglobalization.targets.filters"/>
   <Import Project="$(MSBuildThisFileDirectory)libmonoruntime-common.targets.filters" />
   <Import Project="$(MSBuildThisFileDirectory)libmonoruntime-win32.targets.filters" />
   <Import Project="$(MSBuildThisFileDirectory)libmonoruntime-posix.targets.filters" />
index 4c009ed..2541712 100644 (file)
@@ -97,8 +97,8 @@
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);$(SHIM_GLOBALIZATION_DEFINES);_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);$(SHIM_GLOBALIZATION_DEFINES);WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);$(SHIM_GLOBALIZATION_DEFINES);NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
       <StringPooling>true</StringPooling>
     </ClCompile>
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);$(SHIM_GLOBALIZATION_DEFINES);WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
       <StringPooling>true</StringPooling>
     </ClCompile>
index e71f2cc..502c539 100644 (file)
@@ -45,6 +45,9 @@
     <LIBGC_CPPFLAGS_INCLUDE>$(MONO_LIBGC_INCLUDE_DIR)</LIBGC_CPPFLAGS_INCLUDE>
     <GLIB_CFLAGS_INCLUDE>$(MONO_EGLIB_SOURCE_DIR)</GLIB_CFLAGS_INCLUDE>
     <MONO_LLVM_DEFAULT_API_VERSION>610</MONO_LLVM_DEFAULT_API_VERSION>
+    <SHIM_GLOBALIZATION Condition="'$(MONO_ENABLE_NETCORE)'=='true'">$(top_srcdir)/../libraries/Native/Unix/System.Globalization.Native</SHIM_GLOBALIZATION>
+    <SHIM_GLOBALIZATION_COMMON Condition="'$(MONO_ENABLE_NETCORE)'=='true'">$(top_srcdir)/../libraries/Native/Unix/Common</SHIM_GLOBALIZATION_COMMON>
+    <SHIM_GLOBALIZATION_INCLUDE_DIR Condition="'$(MONO_ENABLE_NETCORE)'=='true'">$(SHIM_GLOBALIZATION_COMMON);$(SHIM_GLOBALIZATION)</SHIM_GLOBALIZATION_INCLUDE_DIR>
     <MONO_LLVM_DEFAULT_INCLUDE_DIR>$(MONO_DIR)/external/llvm-project/llvm/include</MONO_LLVM_DEFAULT_INCLUDE_DIR>
   </PropertyGroup>
   <PropertyGroup Label="Static-C-Runtime" Condition="'$(MONO_USE_STATIC_C_RUNTIME)'=='true'">
@@ -58,6 +61,7 @@
   <PropertyGroup Label="MonoSGEN" Condition="'$(MONO_TARGET_GC)'=='sgen' Or '$(MONO_TARGET_GC)'!='boehm'">
     <SGEN_DEFINES>HAVE_SGEN_GC;HAVE_MOVING_COLLECTOR;HAVE_WRITE_BARRIERS;HAVE_CONC_GC_AS_DEFAULT</SGEN_DEFINES>
     <GC_DEFINES>$(SGEN_DEFINES)</GC_DEFINES>
+    <SHIM_GLOBALIZATION_DEFINES Condition="'$(MONO_ENABLE_NETCORE)'=='true'">TARGET_WINDOWS;PALEXPORT=extern "C" __declspec(dllexport)</SHIM_GLOBALIZATION_DEFINES>
     <GC_LIB>libgcmonosgen.lib</GC_LIB>
     <MONO_TARGET_SUFFIX Condition="'$(MONO_USE_TARGET_SUFFIX)'=='true'">-sgen</MONO_TARGET_SUFFIX>
     <MONO_BUILD_DIR_PREFIX Condition="'$(MONO_USE_SEPARATE_BUILD_DIR)'=='true'">$(MONO_BUILD_DIR_PREFIX)sgen/</MONO_BUILD_DIR_PREFIX>
diff --git a/src/mono/msvc/shimglobalization.targets b/src/mono/msvc/shimglobalization.targets
new file mode 100644 (file)
index 0000000..19bc337
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="shim_libraries">
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_calendarData.c">
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_casing.c">
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_collation.c">
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_idna.c">
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile> 
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_locale.c">
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_localeNumberData.c">
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile> 
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_localeStringData.c">
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_normalization.c">
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile>
+      <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_icushim.c">
+        <CompileAs>CompileAsCpp</CompileAs>
+      </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_timeZoneInfo.c">
+      <CompileAs>CompileAsCpp</CompileAs>
+    </ClCompile>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_calendarData.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_casing.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_collation.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_errors.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_errors_internal.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_icushim.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_icushim_internal.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_icushim_internal_android.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_idna.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_locale.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_localeNumberData.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_localeStringData.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_locale_internal.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_normalization.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_timeZoneInfo.h" />
+    <ClInclude Include="$(SHIM_GLOBALIZATION_COMMON)\pal_compiler.h" />
+  </ItemGroup>
+</Project>
diff --git a/src/mono/msvc/shimglobalization.targets.filters b/src/mono/msvc/shimglobalization.targets.filters
new file mode 100644 (file)
index 0000000..106d7b8
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="shim_libraries">
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_calendarData.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_casing.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_collation.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_idna.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_locale.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_localeNumberData.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_localeStringData.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_normalization.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_timeZoneInfo.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>             
+    <ClCompile Include="$(SHIM_GLOBALIZATION)\pal_icushim.c">
+      <Filter>Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClCompile>      
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_calendarData.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_casing.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_collation.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_errors.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_errors_internal.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_icushim.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_icushim_internal.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_icushim_internal_android.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_idna.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_locale.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_localeNumberData.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_localeStringData.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_locale_internal.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_normalization.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION)\pal_timeZoneInfo.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SHIM_GLOBALIZATION_COMMON)\pal_compiler.h">
+      <Filter>Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization</Filter>
+    </ClInclude>                        
+  </ItemGroup>
+  <ItemGroup>
+    <Filter Include="Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization"/>
+    <Filter Include="Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization"/>
+  </ItemGroup>
+</Project>
index 911499e..3d7b5ca 100644 (file)
@@ -6,14 +6,18 @@ namespace System.Globalization
 {
     internal static partial class GlobalizationMode
     {
-        internal static bool Invariant { get; } = GetGlobalizationInvariantMode();
+        private static bool GetInvariantSwitchValue() =>
+            GetSwitchValue("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT");
 
-        private static bool GetInvariantSwitchValue()
+        private static bool GetSwitchValue(string envVariable)
         {
-            string? val = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT");
-            if (val != null)
-                return bool.IsTrueStringIgnoreCase(val) || val.Equals("1");
-            return false;
+            bool ret = false;
+            string? switchValue = Environment.GetEnvironmentVariable(envVariable);
+            if (switchValue != null)
+            {
+                ret = bool.IsTrueStringIgnoreCase(switchValue) || switchValue.Equals("1");
+            }
+            return ret;
         }
     }
 }
index e3ca7ce..70d7e7e 100644 (file)
@@ -8,6 +8,7 @@ namespace System.Globalization
 {
     internal partial class GlobalizationMode
     {
+        internal static bool Invariant { get; } = GetGlobalizationInvariantMode();
         internal static bool UseNls => false;
 
         private static bool GetGlobalizationInvariantMode()
index 5aaa143..abf2a60 100644 (file)
@@ -6,11 +6,9 @@ namespace System.Globalization
 {
     internal partial class GlobalizationMode
     {
-        internal static bool UseNls => true;
-
-        private static bool GetGlobalizationInvariantMode()
-        {
-            return GetInvariantSwitchValue();
-        }
+        internal static bool Invariant { get; } = GetInvariantSwitchValue();
+        internal static bool UseNls { get; } = !Invariant &&
+            (GetSwitchValue("DOTNET_SYSTEM_GLOBALIZATION_USENLS") ||
+                Interop.Globalization.LoadICU() == 0);
     }
 }
index 5e58b1b..4a35247 100644 (file)
@@ -130,7 +130,13 @@ namespace System.Runtime.Loader
         // Invoked by Mono to resolve requests to load satellite assemblies.
         private static Assembly? MonoResolveUsingResolveSatelliteAssembly(IntPtr gchALC, string assemblyName)
         {
-            return ResolveSatelliteAssembly(gchALC, new AssemblyName(assemblyName));
+            AssemblyLoadContext context;
+            // This check exists because the function can be called early in startup, before the default ALC is initialized
+            if (gchALC == IntPtr.Zero)
+                context = Default;
+            else
+                context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchALC).Target)!;
+            return context.ResolveSatelliteAssembly(new AssemblyName(assemblyName));
         }
 
         private static AssemblyLoadContext GetAssemblyLoadContext(IntPtr gchManagedAssemblyLoadContext)