diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs b/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs index 7b68539fdf4..61fb264cf22 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs @@ -421,8 +421,8 @@ void AddAssemblies (ZipArchiveEx apk, bool debug, bool compress, IDictionary contents = ListArchiveContents (assembliesRootDir, forceRefresh, arch); - // We must count only .dll.so entries starting with the '#' character, as they are the actual managed assemblies. + // We must count only .dll.so entries starting with the '-' and '_' characters, as they are the actual managed assemblies. // Other entries in `lib/{arch}` might be AOT shared libraries, which will also have the .dll.so extension. var dlls = contents.Where (x => { string fileName = Path.GetFileName (x); - return fileName[0] == '#' && fileName.EndsWith (".dll.so", StringComparison.OrdinalIgnoreCase); + if (!fileName.EndsWith (".dll.so", StringComparison.OrdinalIgnoreCase)) { + return false; + } + + return fileName.StartsWith (MonoAndroidHelper.MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER, StringComparison.OrdinalIgnoreCase) || + fileName.StartsWith (MonoAndroidHelper.MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER, StringComparison.OrdinalIgnoreCase); }); return dlls.Count (); @@ -319,7 +324,7 @@ public int GetNumberOfAssemblies (bool forceRefresh = false, AndroidTargetArch a break; } - char fileTypeMarker = '#'; + string fileTypeMarker = MonoAndroidHelper.MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER; var abis = new List (); if (!String.IsNullOrEmpty (abi)) { abis.Add (abi); @@ -334,8 +339,8 @@ public int GetNumberOfAssemblies (bool forceRefresh = false, AndroidTargetArch a if (!String.IsNullOrEmpty (culture)) { // Android doesn't allow us to put satellite assemblies in lib/{CULTURE}/assembly.dll.so, we must instead // mangle the name. - fileName = $"{culture}%{fileName}"; - fileTypeMarker = '%'; + fileTypeMarker = MonoAndroidHelper.MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER; + fileName = $"{culture}{fileTypeMarker}-{fileName}"; } var ret = new List (); @@ -479,23 +484,6 @@ IEnumerable GetAdditionalFilesForAbi (string abi, List existingF (string prefixAssemblies, string prefixLib) = GetArchivePrefixes (abi); return existingFiles.Where (x => !fileNames.Contains (x.Replace (prefixAssemblies, string.Empty)) && !fileNames.Contains (x.Replace (prefixLib, String.Empty))); } - - string GetUnmangledFileName (string fullName) - { - string fileName = Path.GetFileName (fullName); - switch(fileName[0]) { - case '#': - // Drop the '#' prefix and the .so extension - return Path.GetFileNameWithoutExtension (fileName.Substring (1)); - - case '%': - // Drop the '%' prefix, replace the following '%s' with `/` to get a culture/Assembly file name and drop the .so extension - return Path.GetFileNameWithoutExtension (fileName.Substring (1).Replace ('%', '/')); - - default: - return fileName; - } - } } void StoreContains (ICollection fileNames, out List existingFiles, out List missingFiles, out List additionalFiles, IEnumerable? targetArches = null) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc index 699b4ef502e..a4c7fd0f980 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc @@ -7,37 +7,37 @@ "classes.dex": { "Size": 377856 }, - "lib/arm64-v8a/#_Microsoft.Android.Resource.Designer.dll.so": { + "lib/arm64-v8a/lib__Microsoft.Android.Resource.Designer.dll.so": { "Size": 1027 }, - "lib/arm64-v8a/#Java.Interop.dll.so": { + "lib/arm64-v8a/lib_Java.Interop.dll.so": { "Size": 61443 }, - "lib/arm64-v8a/#Mono.Android.dll.so": { + "lib/arm64-v8a/lib_Mono.Android.dll.so": { "Size": 90421 }, - "lib/arm64-v8a/#Mono.Android.Runtime.dll.so": { + "lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": { "Size": 5143 }, - "lib/arm64-v8a/#System.Console.dll.so": { + "lib/arm64-v8a/lib_System.Console.dll.so": { "Size": 6537 }, - "lib/arm64-v8a/#System.Linq.dll.so": { + "lib/arm64-v8a/lib_System.Linq.dll.so": { "Size": 8540 }, - "lib/arm64-v8a/#System.Private.CoreLib.dll.so": { + "lib/arm64-v8a/lib_System.Private.CoreLib.dll.so": { "Size": 552396 }, - "lib/arm64-v8a/#System.Runtime.dll.so": { + "lib/arm64-v8a/lib_System.Runtime.dll.so": { "Size": 2541 }, - "lib/arm64-v8a/#System.Runtime.InteropServices.dll.so": { + "lib/arm64-v8a/lib_System.Runtime.InteropServices.dll.so": { "Size": 4019 }, - "lib/arm64-v8a/#UnnamedProject.dll.so": { + "lib/arm64-v8a/lib_UnnamedProject.dll.so": { "Size": 2931 }, - "lib/arm64-v8a/arc.bin.so": { + "lib/arm64-v8a/libarc.bin.so": { "Size": 1512 }, "lib/arm64-v8a/libmono-component-marshal-ilgen.so": { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc index e8987e68712..f248afc59e9 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc @@ -31,208 +31,208 @@ "kotlin/reflect/reflect.kotlin_builtins": { "Size": 2396 }, - "lib/arm64-v8a/#_Microsoft.Android.Resource.Designer.dll.so": { + "lib/arm64-v8a/lib__Microsoft.Android.Resource.Designer.dll.so": { "Size": 2279 }, - "lib/arm64-v8a/#FormsViewGroup.dll.so": { + "lib/arm64-v8a/lib_FormsViewGroup.dll.so": { "Size": 8090 }, - "lib/arm64-v8a/#Java.Interop.dll.so": { + "lib/arm64-v8a/lib_Java.Interop.dll.so": { "Size": 69523 }, - "lib/arm64-v8a/#Mono.Android.dll.so": { + "lib/arm64-v8a/lib_Mono.Android.dll.so": { "Size": 456123 }, - "lib/arm64-v8a/#Mono.Android.Runtime.dll.so": { + "lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": { "Size": 5147 }, - "lib/arm64-v8a/#mscorlib.dll.so": { + "lib/arm64-v8a/lib_mscorlib.dll.so": { "Size": 3994 }, - "lib/arm64-v8a/#netstandard.dll.so": { + "lib/arm64-v8a/lib_netstandard.dll.so": { "Size": 5628 }, - "lib/arm64-v8a/#System.Collections.Concurrent.dll.so": { + "lib/arm64-v8a/lib_System.Collections.Concurrent.dll.so": { "Size": 11516 }, - "lib/arm64-v8a/#System.Collections.dll.so": { + "lib/arm64-v8a/lib_System.Collections.dll.so": { "Size": 15411 }, - "lib/arm64-v8a/#System.Collections.NonGeneric.dll.so": { + "lib/arm64-v8a/lib_System.Collections.NonGeneric.dll.so": { "Size": 7443 }, - "lib/arm64-v8a/#System.ComponentModel.dll.so": { + "lib/arm64-v8a/lib_System.ComponentModel.dll.so": { "Size": 1935 }, - "lib/arm64-v8a/#System.ComponentModel.Primitives.dll.so": { + "lib/arm64-v8a/lib_System.ComponentModel.Primitives.dll.so": { "Size": 2547 }, - "lib/arm64-v8a/#System.ComponentModel.TypeConverter.dll.so": { + "lib/arm64-v8a/lib_System.ComponentModel.TypeConverter.dll.so": { "Size": 6028 }, - "lib/arm64-v8a/#System.Console.dll.so": { + "lib/arm64-v8a/lib_System.Console.dll.so": { "Size": 6575 }, - "lib/arm64-v8a/#System.Core.dll.so": { + "lib/arm64-v8a/lib_System.Core.dll.so": { "Size": 1970 }, - "lib/arm64-v8a/#System.Diagnostics.DiagnosticSource.dll.so": { + "lib/arm64-v8a/lib_System.Diagnostics.DiagnosticSource.dll.so": { "Size": 9060 }, - "lib/arm64-v8a/#System.Diagnostics.TraceSource.dll.so": { + "lib/arm64-v8a/lib_System.Diagnostics.TraceSource.dll.so": { "Size": 6545 }, - "lib/arm64-v8a/#System.dll.so": { + "lib/arm64-v8a/lib_System.dll.so": { "Size": 2326 }, - "lib/arm64-v8a/#System.Drawing.dll.so": { + "lib/arm64-v8a/lib_System.Drawing.dll.so": { "Size": 1934 }, - "lib/arm64-v8a/#System.Drawing.Primitives.dll.so": { + "lib/arm64-v8a/lib_System.Drawing.Primitives.dll.so": { "Size": 11961 }, - "lib/arm64-v8a/#System.IO.Compression.Brotli.dll.so": { + "lib/arm64-v8a/lib_System.IO.Compression.Brotli.dll.so": { "Size": 11185 }, - "lib/arm64-v8a/#System.IO.Compression.dll.so": { + "lib/arm64-v8a/lib_System.IO.Compression.dll.so": { "Size": 15862 }, - "lib/arm64-v8a/#System.IO.IsolatedStorage.dll.so": { + "lib/arm64-v8a/lib_System.IO.IsolatedStorage.dll.so": { "Size": 9866 }, - "lib/arm64-v8a/#System.Linq.dll.so": { + "lib/arm64-v8a/lib_System.Linq.dll.so": { "Size": 19573 }, - "lib/arm64-v8a/#System.Linq.Expressions.dll.so": { + "lib/arm64-v8a/lib_System.Linq.Expressions.dll.so": { "Size": 164633 }, - "lib/arm64-v8a/#System.Net.Http.dll.so": { + "lib/arm64-v8a/lib_System.Net.Http.dll.so": { "Size": 67537 }, - "lib/arm64-v8a/#System.Net.Primitives.dll.so": { + "lib/arm64-v8a/lib_System.Net.Primitives.dll.so": { "Size": 22414 }, - "lib/arm64-v8a/#System.Net.Requests.dll.so": { + "lib/arm64-v8a/lib_System.Net.Requests.dll.so": { "Size": 3591 }, - "lib/arm64-v8a/#System.ObjectModel.dll.so": { + "lib/arm64-v8a/lib_System.ObjectModel.dll.so": { "Size": 8687 }, - "lib/arm64-v8a/#System.Private.CoreLib.dll.so": { + "lib/arm64-v8a/lib_System.Private.CoreLib.dll.so": { "Size": 847454 }, - "lib/arm64-v8a/#System.Private.DataContractSerialization.dll.so": { + "lib/arm64-v8a/lib_System.Private.DataContractSerialization.dll.so": { "Size": 193441 }, - "lib/arm64-v8a/#System.Private.Uri.dll.so": { + "lib/arm64-v8a/lib_System.Private.Uri.dll.so": { "Size": 42797 }, - "lib/arm64-v8a/#System.Private.Xml.dll.so": { + "lib/arm64-v8a/lib_System.Private.Xml.dll.so": { "Size": 215575 }, - "lib/arm64-v8a/#System.Private.Xml.Linq.dll.so": { + "lib/arm64-v8a/lib_System.Private.Xml.Linq.dll.so": { "Size": 16618 }, - "lib/arm64-v8a/#System.Runtime.dll.so": { + "lib/arm64-v8a/lib_System.Runtime.dll.so": { "Size": 2703 }, - "lib/arm64-v8a/#System.Runtime.InteropServices.dll.so": { + "lib/arm64-v8a/lib_System.Runtime.InteropServices.dll.so": { "Size": 4022 }, - "lib/arm64-v8a/#System.Runtime.Serialization.dll.so": { + "lib/arm64-v8a/lib_System.Runtime.Serialization.dll.so": { "Size": 1860 }, - "lib/arm64-v8a/#System.Runtime.Serialization.Formatters.dll.so": { + "lib/arm64-v8a/lib_System.Runtime.Serialization.Formatters.dll.so": { "Size": 2482 }, - "lib/arm64-v8a/#System.Runtime.Serialization.Primitives.dll.so": { + "lib/arm64-v8a/lib_System.Runtime.Serialization.Primitives.dll.so": { "Size": 3750 }, - "lib/arm64-v8a/#System.Security.Cryptography.dll.so": { + "lib/arm64-v8a/lib_System.Security.Cryptography.dll.so": { "Size": 8102 }, - "lib/arm64-v8a/#System.Text.RegularExpressions.dll.so": { + "lib/arm64-v8a/lib_System.Text.RegularExpressions.dll.so": { "Size": 158797 }, - "lib/arm64-v8a/#System.Xml.dll.so": { + "lib/arm64-v8a/lib_System.Xml.dll.so": { "Size": 1755 }, - "lib/arm64-v8a/#System.Xml.Linq.dll.so": { + "lib/arm64-v8a/lib_System.Xml.Linq.dll.so": { "Size": 1770 }, - "lib/arm64-v8a/#UnnamedProject.dll.so": { + "lib/arm64-v8a/lib_UnnamedProject.dll.so": { "Size": 5007 }, - "lib/arm64-v8a/#Xamarin.AndroidX.Activity.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.Activity.dll.so": { "Size": 16116 }, - "lib/arm64-v8a/#Xamarin.AndroidX.AppCompat.AppCompatResources.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.AppCompat.AppCompatResources.dll.so": { "Size": 6216 }, - "lib/arm64-v8a/#Xamarin.AndroidX.AppCompat.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.AppCompat.dll.so": { "Size": 137971 }, - "lib/arm64-v8a/#Xamarin.AndroidX.CardView.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.CardView.dll.so": { "Size": 6959 }, - "lib/arm64-v8a/#Xamarin.AndroidX.CoordinatorLayout.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.CoordinatorLayout.dll.so": { "Size": 17857 }, - "lib/arm64-v8a/#Xamarin.AndroidX.Core.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.Core.dll.so": { "Size": 126882 }, - "lib/arm64-v8a/#Xamarin.AndroidX.CursorAdapter.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.CursorAdapter.dll.so": { "Size": 8978 }, - "lib/arm64-v8a/#Xamarin.AndroidX.DrawerLayout.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.DrawerLayout.dll.so": { "Size": 15286 }, - "lib/arm64-v8a/#Xamarin.AndroidX.Fragment.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.Fragment.dll.so": { "Size": 51498 }, - "lib/arm64-v8a/#Xamarin.AndroidX.Legacy.Support.Core.UI.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.Legacy.Support.Core.UI.dll.so": { "Size": 6233 }, - "lib/arm64-v8a/#Xamarin.AndroidX.Lifecycle.Common.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.Lifecycle.Common.dll.so": { "Size": 6890 }, - "lib/arm64-v8a/#Xamarin.AndroidX.Lifecycle.LiveData.Core.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.Lifecycle.LiveData.Core.dll.so": { "Size": 6733 }, - "lib/arm64-v8a/#Xamarin.AndroidX.Lifecycle.ViewModel.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.Lifecycle.ViewModel.dll.so": { "Size": 7002 }, - "lib/arm64-v8a/#Xamarin.AndroidX.Loader.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.Loader.dll.so": { "Size": 13063 }, - "lib/arm64-v8a/#Xamarin.AndroidX.RecyclerView.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.RecyclerView.dll.so": { "Size": 93516 }, - "lib/arm64-v8a/#Xamarin.AndroidX.SavedState.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.SavedState.dll.so": { "Size": 5107 }, - "lib/arm64-v8a/#Xamarin.AndroidX.SwipeRefreshLayout.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.SwipeRefreshLayout.dll.so": { "Size": 13946 }, - "lib/arm64-v8a/#Xamarin.AndroidX.ViewPager.dll.so": { + "lib/arm64-v8a/lib_Xamarin.AndroidX.ViewPager.dll.so": { "Size": 19014 }, - "lib/arm64-v8a/#Xamarin.Forms.Core.dll.so": { + "lib/arm64-v8a/lib_Xamarin.Forms.Core.dll.so": { "Size": 563905 }, - "lib/arm64-v8a/#Xamarin.Forms.Platform.Android.dll.so": { + "lib/arm64-v8a/lib_Xamarin.Forms.Platform.Android.dll.so": { "Size": 373374 }, - "lib/arm64-v8a/#Xamarin.Forms.Platform.dll.so": { + "lib/arm64-v8a/lib_Xamarin.Forms.Platform.dll.so": { "Size": 18753 }, - "lib/arm64-v8a/#Xamarin.Forms.Xaml.dll.so": { + "lib/arm64-v8a/lib_Xamarin.Forms.Xaml.dll.so": { "Size": 63542 }, - "lib/arm64-v8a/#Xamarin.Google.Android.Material.dll.so": { + "lib/arm64-v8a/lib_Xamarin.Google.Android.Material.dll.so": { "Size": 66088 }, - "lib/arm64-v8a/arc.bin.so": { + "lib/arm64-v8a/libarc.bin.so": { "Size": 1512 }, "lib/arm64-v8a/libmono-component-marshal-ilgen.so": { diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsNativeAssemblyGenerator.cs b/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsNativeAssemblyGenerator.cs index e9263f4bec6..db698528d32 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsNativeAssemblyGenerator.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsNativeAssemblyGenerator.cs @@ -990,11 +990,11 @@ void AddAssemblyImageCache (LlvmIrModule module, out AssemblyCacheState acs) string inArchiveName; if (cultureName.Length == 0) { - // Regular assemblies get the '#' prefix - inArchiveName = $"#{name}.so"; + // Regular assemblies get the 'lib_' prefix + inArchiveName = $"{MonoAndroidHelper.MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER}{name}{MonoAndroidHelper.MANGLED_ASSEMBLY_NAME_EXT}"; } else { - // Satellite assemblies get the '%{CULTURE}%' prefix - inArchiveName = $"%{cultureName}%{Path.GetFileName (name)}.so"; + // Satellite assemblies get the 'lib-{CULTURE}-' prefix + inArchiveName = $"{MonoAndroidHelper.MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER}{cultureName}-{Path.GetFileName (name)}{MonoAndroidHelper.MANGLED_ASSEMBLY_NAME_EXT}"; } ulong hashFull32 = MonoAndroidHelper.GetXxHash (name, is64Bit: false); diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.Basic.cs b/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.Basic.cs index 42f9d64dfa3..6d9019b081b 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.Basic.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.Basic.cs @@ -185,7 +185,10 @@ public static string MakeZipArchivePath (string part1, ICollection? path return String.Join ("/", parts); } - const string MANGLED_ASSEMBLY_NAME_EXT = ".so"; + // These 3 MUST be the same as the like-named constants in src/monodroid/jni/shared-constants.hh + public const string MANGLED_ASSEMBLY_NAME_EXT = ".so"; + public const string MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER = "lib_"; + public const string MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER = "lib-"; /// /// Mangles APK/AAB entry name for assembly and their associated pdb and config entries in the @@ -195,13 +198,23 @@ public static string MakeZipArchivePath (string part1, ICollection? path public static string MakeDiscreteAssembliesEntryName (string name, string? culture = null) { if (!String.IsNullOrEmpty (culture)) { - return $"_{culture}_{name}{MANGLED_ASSEMBLY_NAME_EXT}"; + return $"{MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER}{culture}-{name}{MANGLED_ASSEMBLY_NAME_EXT}"; } - return $"__{name}{MANGLED_ASSEMBLY_NAME_EXT}"; + return $"{MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER}{name}{MANGLED_ASSEMBLY_NAME_EXT}"; } - public static ulong GetMangledAssemblyNameSizeOverhead () => (ulong)MANGLED_ASSEMBLY_NAME_EXT.Length + 1; + /// + /// Returns size of the extension + length of the prefix for mangled assembly names. This is + /// used to pre-allocate space for assembly names in `libxamarin-app.so` + /// + /// + public static ulong GetMangledAssemblyNameSizeOverhead () + { + // Satellite marker is one character more, for the `-` closing the culture part + return (ulong)MANGLED_ASSEMBLY_NAME_EXT.Length + + (ulong)Math.Max (MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER.Length + 1, MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER.Length); + } public static byte[] Utf8StringToBytes (string str) => Encoding.UTF8.GetBytes (str); diff --git a/src/monodroid/jni/basic-utilities.hh b/src/monodroid/jni/basic-utilities.hh index 996df263b3b..de4645cb4b7 100644 --- a/src/monodroid/jni/basic-utilities.hh +++ b/src/monodroid/jni/basic-utilities.hh @@ -193,9 +193,10 @@ namespace xamarin::android return nullptr; } - for (size_t i = str.length () - 1; i >= 0; i--) { - if (str[i] == ch) { - return str.get () + i; + for (size_t i = str.length (); i > 0; i--) { + const size_t index = i - 1; + if (str[index] == ch) { + return str.get () + index; } } diff --git a/src/monodroid/jni/embedded-assemblies-zip.cc b/src/monodroid/jni/embedded-assemblies-zip.cc index 068ebd70c31..bc63941fcaa 100644 --- a/src/monodroid/jni/embedded-assemblies-zip.cc +++ b/src/monodroid/jni/embedded-assemblies-zip.cc @@ -150,14 +150,18 @@ EmbeddedAssemblies::zip_load_individual_assembly_entries (std::vector c // // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) for (size_t i = 0; i < num_entries; i++) { + if (entry_name.length () <= SharedConstants::REGULAR_ASSEMBLY_PREFIX_LEN) { + continue; + } + bool interesting_entry = zip_load_entry_common (i, buf, entry_name, state); if (!interesting_entry) { continue; } - if (entry_name[state.prefix_len] == '#') { + if (entry_name[state.prefix_len + SharedConstants::REGULAR_ASSEMBLY_MARKER_INDEX] == SharedConstants::REGULAR_ASSEMBLY_MARKER_CHAR) { unmangle_name (entry_name, state.prefix_len); - } else if (entry_name[state.prefix_len] == '%') { + } else if (entry_name[state.prefix_len + SharedConstants::SATELLITE_ASSEMBLY_MARKER_INDEX] == SharedConstants::SATELLITE_ASSEMBLY_MARKER_CHAR) { unmangle_name (entry_name, state.prefix_len); } else { continue; // Can't be an assembly, the name's not mangled @@ -324,6 +328,7 @@ template force_inline void EmbeddedAssemblies::set_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept { + log_debug (LOG_ASSEMBLY, __PRETTY_FUNCTION__); entry.file_fd = state.file_fd; if constexpr (NeedsNameAlloc) { entry.name = utils.strdup_new (entry_name.get () + state.prefix_len); diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/monodroid/jni/embedded-assemblies.cc index 036377f682d..82537621577 100644 --- a/src/monodroid/jni/embedded-assemblies.cc +++ b/src/monodroid/jni/embedded-assemblies.cc @@ -1256,13 +1256,23 @@ EmbeddedAssemblies::maybe_register_assembly_from_filesystem ( state.file_name = dir_entry->d_name; }; + // We check whether dir_entry->d_name is an array with a fixed size and whether it's + // big enough so that we can index the array below without having to worry about buffer + // overflows. These are compile-time checks and the status of the field won't change at + // runtime unless Android breaks compatibility (unlikely). + // + // Currently (Jan 2024), dir_try->d_name is declared as `char[256]` by Bionic + static_assert (std::is_bounded_array_vd_name)>); + static_assert (sizeof(dir_entry->d_name) > SharedConstants::REGULAR_ASSEMBLY_PREFIX_LEN); + static_assert (sizeof(dir_entry->d_name) > SharedConstants::SATELLITE_ASSEMBLY_PREFIX_LEN); + if constexpr (MangledNamesMode) { - // We're only interested in "mangled" file names, namely those starting with either the `#` or the `%` characters - if (dir_entry->d_name[0] == '#') { + // We're only interested in "mangled" file names, namely those starting with either the `lib_` or `lib-` prefixes + if (dir_entry->d_name[SharedConstants::REGULAR_ASSEMBLY_MARKER_INDEX] == SharedConstants::REGULAR_ASSEMBLY_MARKER_CHAR) { assembly_count++; copy_dentry_and_update_state (entry_name, state, dir_entry); unmangle_name (entry_name); - } else if (dir_entry->d_name[0] == '%') { + } else if (dir_entry->d_name[SharedConstants::SATELLITE_ASSEMBLY_MARKER_INDEX] == SharedConstants::SATELLITE_ASSEMBLY_MARKER_CHAR) { assembly_count++; copy_dentry_and_update_state (entry_name, state, dir_entry); unmangle_name (entry_name); @@ -1270,7 +1280,14 @@ EmbeddedAssemblies::maybe_register_assembly_from_filesystem ( return false; } } else { - // TODO: check for .dll and .pdb extensions + if (utils.ends_with (dir_entry->d_name, SharedConstants::DLL_EXTENSION) || + utils.ends_with (dir_entry->d_name, SharedConstants::PDB_EXTENSION)) { + assembly_count++; + copy_dentry_and_update_state (entry_name, state, dir_entry); + } else { + return false; + } + } state.data_offset = 0; @@ -1292,11 +1309,16 @@ EmbeddedAssemblies::maybe_register_blob_from_filesystem ( const dirent* dir_entry, ZipEntryLoadState& state) noexcept { + log_debug (LOG_ASSEMBLY, __PRETTY_FUNCTION__); + log_debug (LOG_ASSEMBLY, " entry: %s", dir_entry->d_name); + if (dir_entry->d_name[0] != assembly_store_file_name[0]) { + log_debug (LOG_ASSEMBLY, " here 001"); return false; // keep going } if (strncmp (dir_entry->d_name, assembly_store_file_name.data (), assembly_store_file_name.size ()) != 0) { + log_debug (LOG_ASSEMBLY, " here 002"); return false; // keep going } @@ -1365,6 +1387,7 @@ EmbeddedAssemblies::register_from_filesystem (const char *lib_dir_path,bool look break; // No more entries, we're done } + log_debug (LOG_ASSEMBLY, " entry: %s", cur->d_name); // We can ignore the obvious entries here... if (cur->d_name[0] == '.') { continue; @@ -1378,7 +1401,7 @@ EmbeddedAssemblies::register_from_filesystem (const char *lib_dir_path,bool look #endif // def DEBUG // ...and we can handle the runtime config entry - if (!runtime_config_blob_found && std::strncmp (cur->d_name, SharedConstants::RUNTIME_CONFIG_BLOB_NAME, sizeof (SharedConstants::RUNTIME_CONFIG_BLOB_NAME) - 1) == 0) { + if (!runtime_config_blob_found && std::strncmp (cur->d_name, SharedConstants::RUNTIME_CONFIG_BLOB_NAME.data (), SharedConstants::RUNTIME_CONFIG_BLOB_NAME.size ()) == 0) { log_debug (LOG_ASSEMBLY, "Mapping runtime config blob from '%s'", cur->d_name); auto file_size = Util::get_file_size_at (state.file_fd, cur->d_name); if (!file_size) { diff --git a/src/monodroid/jni/embedded-assemblies.hh b/src/monodroid/jni/embedded-assemblies.hh index 9ea28fa3792..8bb691c2a3d 100644 --- a/src/monodroid/jni/embedded-assemblies.hh +++ b/src/monodroid/jni/embedded-assemblies.hh @@ -106,11 +106,9 @@ namespace xamarin::android::internal { static constexpr uint32_t number_of_assembly_store_files = 1; static constexpr char dso_suffix[] = ".so"; static constexpr char apk_lib_dir_name[] = "lib"; - static constexpr char regular_assembly_marker = '#'; - static constexpr char satellite_assembly_marker = '%'; static constexpr auto apk_lib_prefix = concat_const (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); - static constexpr auto assembly_store_file_name = concat_const ("assemblies.", SharedConstants::android_lib_abi, ".blob.so"); - static constexpr auto assembly_store_file_path = concat_const (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, "assemblies.", SharedConstants::android_lib_abi, ".blob.so"); + static constexpr auto assembly_store_file_name = concat_const ("libassemblies.", SharedConstants::android_lib_abi, ".blob.so"); + static constexpr auto assembly_store_file_path = concat_const (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, "libassemblies.", SharedConstants::android_lib_abi, ".blob.so"); #if defined (DEBUG) || !defined (ANDROID) static constexpr char override_typemap_entry_name[] = ".__override__"; @@ -339,26 +337,55 @@ namespace xamarin::android::internal { const AssemblyStoreIndexEntry* find_assembly_store_entry (hash_t hash, const AssemblyStoreIndexEntry *entries, size_t entry_count) noexcept; void store_individual_assembly_data (dynamic_local_string const& entry_name, ZipEntryLoadState const& state, monodroid_should_register should_register) noexcept; + constexpr size_t get_mangled_name_max_size_overhead () + { + return SharedConstants::MANGLED_ASSEMBLY_NAME_EXT_LEN + + std::max (SharedConstants::REGULAR_ASSEMBLY_PREFIX_LEN, SharedConstants::SATELLITE_ASSEMBLY_PREFIX_LEN) + + 1; // For the extra `-` char in the culture portion of satellite assembly's name + } + void configure_state_for_individual_assembly_load (ZipEntryLoadState& state) noexcept { state.bundled_assemblies_slow_path = bundled_assembly_index >= application_config.number_of_assemblies_in_apk; state.max_assembly_name_size = application_config.bundled_assembly_name_width - 1; // Enough room for the mangle character at the start, plus the extra extension - state.max_assembly_file_name_size = state.max_assembly_name_size + MANGLED_ASSEMBLY_NAME_EXT.length () + 1; + state.max_assembly_file_name_size = static_cast(state.max_assembly_name_size + get_mangled_name_max_size_overhead ()); + } + + template + static constexpr size_t get_mangled_prefix_length () + { + if constexpr (IsSatelliteAssembly) { + return SharedConstants::SATELLITE_ASSEMBLY_PREFIX_LEN; + } else { + return SharedConstants::REGULAR_ASSEMBLY_PREFIX_LEN; + } + } + + template + static constexpr size_t get_mangled_data_size () + { + return SharedConstants::MANGLED_ASSEMBLY_NAME_EXT_LEN + get_mangled_prefix_length (); } template static void unmangle_name (dynamic_local_string &name, size_t start_idx = 0) noexcept { - size_t new_size = name.length () - 4; // Includes the first ("marker") character and the .so extension - memmove (name.get () + start_idx, name.get () + start_idx + 1, new_size); + constexpr size_t mangled_data_size = get_mangled_data_size (); + if (name.length () <= mangled_data_size) { + // Nothing to do, the name is too short + return; + } + + size_t new_size = name.length () - mangled_data_size; + memmove (name.get () + start_idx, name.get () + start_idx + get_mangled_prefix_length (), new_size); name.set_length (new_size); if constexpr (IsSatelliteAssembly) { // Make sure assembly name is {CULTURE}/assembly.dll for (size_t idx = start_idx; idx < name.length (); idx++) { - if (name[idx] == '%') { + if (name[idx] == SharedConstants::SATELLITE_ASSEMBLY_MARKER_CHAR) { name[idx] = '/'; break; } diff --git a/src/monodroid/jni/shared-constants.hh b/src/monodroid/jni/shared-constants.hh index dea2d55c95c..f1f057c7c8f 100644 --- a/src/monodroid/jni/shared-constants.hh +++ b/src/monodroid/jni/shared-constants.hh @@ -17,6 +17,20 @@ namespace xamarin::android::internal class SharedConstants { public: + // These three MUST be the same as like-named constants in src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.Basic.cs + static constexpr char MANGLED_ASSEMBLY_NAME_EXT[] = ".so"; + static constexpr size_t MANGLED_ASSEMBLY_NAME_EXT_LEN = sizeof(MANGLED_ASSEMBLY_NAME_EXT) - 1; + + static constexpr char MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER[] = "lib_"; + static constexpr size_t REGULAR_ASSEMBLY_MARKER_INDEX = 3; // this ☝️ + static constexpr size_t REGULAR_ASSEMBLY_PREFIX_LEN = sizeof(SharedConstants::MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER) - 1; + static constexpr char REGULAR_ASSEMBLY_MARKER_CHAR = MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER[REGULAR_ASSEMBLY_MARKER_INDEX]; + + static constexpr char MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER[] = "lib-"; + static constexpr size_t SATELLITE_ASSEMBLY_MARKER_INDEX = 3; // this ☝️ + static constexpr size_t SATELLITE_ASSEMBLY_PREFIX_LEN = sizeof(SharedConstants::MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER) - 1; + static constexpr char SATELLITE_ASSEMBLY_MARKER_CHAR = MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER[SATELLITE_ASSEMBLY_MARKER_INDEX]; + #if defined (NET) static constexpr char MONO_ANDROID_RUNTIME_ASSEMBLY_NAME[] = "Mono.Android.Runtime"; #endif @@ -32,7 +46,7 @@ namespace xamarin::android::internal static constexpr char DLL_EXTENSION[] = ".dll"; static constexpr char PDB_EXTENSION[] = ".pdb"; #if defined (NET) - static constexpr char RUNTIME_CONFIG_BLOB_NAME[] = "arc.bin.so"; + static constexpr auto RUNTIME_CONFIG_BLOB_NAME = concat_const("libarc.bin", MANGLED_ASSEMBLY_NAME_EXT); #endif // def NET #if defined (ANDROID) || defined (__linux__) || defined (__linux) diff --git a/src/monodroid/jni/xamarin-app.hh b/src/monodroid/jni/xamarin-app.hh index 1443080f773..5b077941a3f 100644 --- a/src/monodroid/jni/xamarin-app.hh +++ b/src/monodroid/jni/xamarin-app.hh @@ -40,9 +40,6 @@ static constexpr uint32_t MODULE_MAGIC_NAMES = 0x53544158; // 'XATS', little-end static constexpr uint32_t MODULE_INDEX_MAGIC = 0x49544158; // 'XATI', little-endian static constexpr uint8_t MODULE_FORMAT_VERSION = 2; // Keep in sync with the value in src/Xamarin.Android.Build.Tasks/Utilities/TypeMapGenerator.cs -// Must be identical to MonoAndroidHelper.MANGLED_ASSEMBLY_NAME_EXT -inline static constexpr std::string_view MANGLED_ASSEMBLY_NAME_EXT { ".so" }; - #if defined (DEBUG) || !defined (ANDROID) struct BinaryTypeMapHeader { diff --git a/tools/assembly-store-reader-mk2/AssemblyStore/StoreReader_V2.cs b/tools/assembly-store-reader-mk2/AssemblyStore/StoreReader_V2.cs index 45e74e22752..f434139387a 100644 --- a/tools/assembly-store-reader-mk2/AssemblyStore/StoreReader_V2.cs +++ b/tools/assembly-store-reader-mk2/AssemblyStore/StoreReader_V2.cs @@ -81,7 +81,7 @@ public StoreReader_V2 (Stream store, string path) }; } - static string GetBlobName (string abi) => $"assemblies.{abi}.blob.so"; + static string GetBlobName (string abi) => $"libassemblies.{abi}.blob.so"; protected override bool IsSupported () {