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 a415e51ee10..440fba739f4 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 @@ -5,55 +5,55 @@ "Size": 3032 }, "assemblies/Java.Interop.dll": { - "Size": 58990 + "Size": 58920 }, "assemblies/Mono.Android.dll": { - "Size": 87490 + "Size": 87624 }, "assemblies/Mono.Android.Runtime.dll": { - "Size": 5860 + "Size": 5862 }, "assemblies/rc.bin": { "Size": 1182 }, "assemblies/System.Console.dll": { - "Size": 6627 + "Size": 6594 }, "assemblies/System.Linq.dll": { - "Size": 9252 + "Size": 9259 }, "assemblies/System.Private.CoreLib.dll": { - "Size": 470830 + "Size": 478515 }, "assemblies/System.Runtime.dll": { - "Size": 2626 + "Size": 2632 }, "assemblies/System.Runtime.InteropServices.dll": { - "Size": 2267 + "Size": 2272 }, "assemblies/UnnamedProject.dll": { - "Size": 3629 + "Size": 3633 }, "classes.dex": { "Size": 18968 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 434632 + "Size": 379008 }, "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 3076080 + "Size": 3077928 }, "lib/arm64-v8a/libSystem.IO.Compression.Native.so": { "Size": 723840 }, "lib/arm64-v8a/libSystem.Native.so": { - "Size": 94136 + "Size": 94232 }, "lib/arm64-v8a/libSystem.Security.Cryptography.Native.Android.so": { "Size": 149552 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 16128 + "Size": 16336 }, "META-INF/BNDLTOOL.RSA": { "Size": 1213 @@ -65,19 +65,19 @@ "Size": 2667 }, "res/drawable-hdpi-v4/icon.png": { - "Size": 4762 + "Size": 2178 }, "res/drawable-mdpi-v4/icon.png": { - "Size": 2200 + "Size": 1490 }, "res/drawable-xhdpi-v4/icon.png": { - "Size": 7462 + "Size": 3098 }, "res/drawable-xxhdpi-v4/icon.png": { - "Size": 13092 + "Size": 4674 }, "res/drawable-xxxhdpi-v4/icon.png": { - "Size": 20118 + "Size": 6832 }, "res/layout/main.xml": { "Size": 544 @@ -89,5 +89,5 @@ "Size": 1904 } }, - "PackageSize": 2590859 + "PackageSize": 2549899 } \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc index cb7562922f1..3ad34c64338 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc @@ -8,19 +8,19 @@ "Size": 68913 }, "assemblies/Mono.Android.dll": { - "Size": 265169 + "Size": 265160 }, "assemblies/mscorlib.dll": { - "Size": 769018 + "Size": 769019 }, "assemblies/System.Core.dll": { - "Size": 28199 + "Size": 28198 }, "assemblies/System.dll": { - "Size": 9180 + "Size": 9179 }, "assemblies/UnnamedProject.dll": { - "Size": 2882 + "Size": 2880 }, "classes.dex": { "Size": 370828 @@ -32,7 +32,7 @@ "Size": 750976 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 332936 + "Size": 277520 }, "lib/arm64-v8a/libmonosgen-2.0.so": { "Size": 4039176 @@ -74,5 +74,5 @@ "Size": 1724 } }, - "PackageSize": 4003540 + "PackageSize": 3987156 } \ No newline at end of file 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 1ba0e20a20c..6fa5f4b1cae 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 @@ -8,19 +8,19 @@ "Size": 7314 }, "assemblies/Java.Interop.dll": { - "Size": 66843 + "Size": 66793 }, "assemblies/Mono.Android.dll": { - "Size": 444299 + "Size": 444690 }, "assemblies/Mono.Android.Runtime.dll": { - "Size": 5921 + "Size": 5862 }, "assemblies/mscorlib.dll": { - "Size": 3860 + "Size": 3859 }, "assemblies/netstandard.dll": { - "Size": 5576 + "Size": 5575 }, "assemblies/rc.bin": { "Size": 1182 @@ -29,106 +29,106 @@ "Size": 10725 }, "assemblies/System.Collections.dll": { - "Size": 15465 + "Size": 15460 }, "assemblies/System.Collections.NonGeneric.dll": { - "Size": 7638 + "Size": 7633 }, "assemblies/System.ComponentModel.dll": { - "Size": 2158 + "Size": 2157 }, "assemblies/System.ComponentModel.Primitives.dll": { - "Size": 2649 + "Size": 2648 }, "assemblies/System.ComponentModel.TypeConverter.dll": { - "Size": 6206 + "Size": 6205 }, "assemblies/System.Console.dll": { - "Size": 6760 + "Size": 6759 }, "assemblies/System.Core.dll": { - "Size": 1988 + "Size": 1987 }, "assemblies/System.Diagnostics.TraceSource.dll": { - "Size": 6745 + "Size": 6742 }, "assemblies/System.dll": { - "Size": 2344 + "Size": 2343 }, "assemblies/System.Drawing.dll": { - "Size": 2029 + "Size": 2028 }, "assemblies/System.Drawing.Primitives.dll": { - "Size": 12160 + "Size": 12095 }, "assemblies/System.IO.Compression.dll": { - "Size": 16797 + "Size": 16984 }, "assemblies/System.IO.IsolatedStorage.dll": { - "Size": 10155 + "Size": 10162 }, "assemblies/System.Linq.dll": { - "Size": 19493 + "Size": 19494 }, "assemblies/System.Linq.Expressions.dll": { - "Size": 163967 + "Size": 163942 }, "assemblies/System.Net.Http.dll": { - "Size": 67013 + "Size": 65586 }, "assemblies/System.Net.Primitives.dll": { "Size": 22021 }, "assemblies/System.Net.Requests.dll": { - "Size": 3745 + "Size": 3743 }, "assemblies/System.ObjectModel.dll": { - "Size": 8173 + "Size": 8166 }, "assemblies/System.Private.CoreLib.dll": { - "Size": 775898 + "Size": 780751 }, "assemblies/System.Private.DataContractSerialization.dll": { - "Size": 192465 + "Size": 192055 }, "assemblies/System.Private.Uri.dll": { - "Size": 42550 + "Size": 42554 }, "assemblies/System.Private.Xml.dll": { - "Size": 215747 + "Size": 215680 }, "assemblies/System.Private.Xml.Linq.dll": { - "Size": 16813 + "Size": 16807 }, "assemblies/System.Runtime.dll": { "Size": 2794 }, "assemblies/System.Runtime.InteropServices.dll": { - "Size": 2273 + "Size": 2272 }, "assemblies/System.Runtime.Serialization.dll": { - "Size": 1950 + "Size": 1949 }, "assemblies/System.Runtime.Serialization.Formatters.dll": { - "Size": 2683 + "Size": 2681 }, "assemblies/System.Runtime.Serialization.Primitives.dll": { - "Size": 3856 + "Size": 3854 }, "assemblies/System.Security.Cryptography.dll": { - "Size": 7949 + "Size": 7947 }, "assemblies/System.Text.RegularExpressions.dll": { - "Size": 154213 + "Size": 155427 }, "assemblies/System.Xml.dll": { "Size": 1837 }, "assemblies/System.Xml.Linq.dll": { - "Size": 1862 + "Size": 1861 }, "assemblies/UnnamedProject.dll": { - "Size": 117372 + "Size": 117398 }, "assemblies/Xamarin.AndroidX.Activity.dll": { "Size": 5872 @@ -200,22 +200,22 @@ "Size": 3090508 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 434632 + "Size": 379008 }, "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 3078808 + "Size": 3077928 }, "lib/arm64-v8a/libSystem.IO.Compression.Native.so": { "Size": 723840 }, "lib/arm64-v8a/libSystem.Native.so": { - "Size": 94136 + "Size": 94232 }, "lib/arm64-v8a/libSystem.Security.Cryptography.Native.Android.so": { "Size": 149552 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 333376 + "Size": 333336 }, "META-INF/android.support.design_material.version": { "Size": 12 @@ -782,7 +782,7 @@ "Size": 470 }, "res/drawable-hdpi-v4/icon.png": { - "Size": 4762 + "Size": 2178 }, "res/drawable-hdpi-v4/notification_bg_low_normal.9.png": { "Size": 212 @@ -992,7 +992,7 @@ "Size": 309 }, "res/drawable-mdpi-v4/icon.png": { - "Size": 2200 + "Size": 1490 }, "res/drawable-mdpi-v4/notification_bg_low_normal.9.png": { "Size": 215 @@ -1220,7 +1220,7 @@ "Size": 593 }, "res/drawable-xhdpi-v4/icon.png": { - "Size": 7462 + "Size": 3098 }, "res/drawable-xhdpi-v4/notification_bg_low_normal.9.png": { "Size": 221 @@ -1385,7 +1385,7 @@ "Size": 868 }, "res/drawable-xxhdpi-v4/icon.png": { - "Size": 13092 + "Size": 4674 }, "res/drawable-xxxhdpi-v4/abc_btn_check_to_on_mtrl_000.png": { "Size": 275 @@ -1472,7 +1472,7 @@ "Size": 1155 }, "res/drawable-xxxhdpi-v4/icon.png": { - "Size": 20118 + "Size": 6832 }, "res/drawable/abc_btn_borderless_material.xml": { "Size": 588 @@ -1970,5 +1970,5 @@ "Size": 341228 } }, - "PackageSize": 7971397 + "PackageSize": 7930437 } \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc index ac496de717d..e7d03c442f3 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc @@ -11,25 +11,25 @@ "Size": 69956 }, "assemblies/Mono.Android.dll": { - "Size": 572709 + "Size": 572698 }, "assemblies/Mono.Security.dll": { - "Size": 68432 + "Size": 68433 }, "assemblies/mscorlib.dll": { - "Size": 915408 + "Size": 915407 }, "assemblies/System.Core.dll": { - "Size": 164046 + "Size": 164047 }, "assemblies/System.dll": { - "Size": 388864 + "Size": 388865 }, "assemblies/System.Drawing.Common.dll": { "Size": 12365 }, "assemblies/System.Net.Http.dll": { - "Size": 110693 + "Size": 110692 }, "assemblies/System.Numerics.dll": { "Size": 15683 @@ -38,13 +38,13 @@ "Size": 186660 }, "assemblies/System.ServiceModel.Internals.dll": { - "Size": 26594 + "Size": 26593 }, "assemblies/System.Xml.dll": { - "Size": 395656 + "Size": 395657 }, "assemblies/UnnamedProject.dll": { - "Size": 116899 + "Size": 116985 }, "assemblies/Xamarin.AndroidX.Activity.dll": { "Size": 7697 @@ -65,19 +65,19 @@ "Size": 131930 }, "assemblies/Xamarin.AndroidX.DrawerLayout.dll": { - "Size": 15426 + "Size": 15425 }, "assemblies/Xamarin.AndroidX.Fragment.dll": { "Size": 43135 }, "assemblies/Xamarin.AndroidX.Legacy.Support.Core.UI.dll": { - "Size": 6715 + "Size": 6714 }, "assemblies/Xamarin.AndroidX.Lifecycle.Common.dll": { "Size": 7062 }, "assemblies/Xamarin.AndroidX.Lifecycle.LiveData.Core.dll": { - "Size": 7193 + "Size": 7194 }, "assemblies/Xamarin.AndroidX.Lifecycle.ViewModel.dll": { "Size": 4873 @@ -92,7 +92,7 @@ "Size": 6268 }, "assemblies/Xamarin.AndroidX.SwipeRefreshLayout.dll": { - "Size": 11271 + "Size": 11272 }, "assemblies/Xamarin.AndroidX.ViewPager.dll": { "Size": 19424 @@ -107,7 +107,7 @@ "Size": 56878 }, "assemblies/Xamarin.Forms.Xaml.dll": { - "Size": 55801 + "Size": 55799 }, "assemblies/Xamarin.Google.Android.Material.dll": { "Size": 43497 @@ -122,7 +122,7 @@ "Size": 750976 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 332936 + "Size": 277520 }, "lib/arm64-v8a/libmonosgen-2.0.so": { "Size": 4039176 @@ -1883,5 +1883,5 @@ "Size": 341040 } }, - "PackageSize": 9521310 + "PackageSize": 9504926 } \ No newline at end of file diff --git a/src/monodroid/CMakeLists.txt b/src/monodroid/CMakeLists.txt index 7f45848792b..8a6951991f9 100644 --- a/src/monodroid/CMakeLists.txt +++ b/src/monodroid/CMakeLists.txt @@ -486,6 +486,7 @@ set(XAMARIN_MONODROID_SOURCES ${SOURCES_DIR}/embedded-assemblies.cc ${SOURCES_DIR}/embedded-assemblies-zip.cc ${SOURCES_DIR}/globals.cc + ${SOURCES_DIR}/helpers.cc ${SOURCES_DIR}/logger.cc ${SOURCES_DIR}/jni-remapping.cc ${SOURCES_DIR}/monodroid-glue.cc @@ -564,6 +565,7 @@ set(XAMARIN_DEBUG_APP_HELPER_SOURCES ${SOURCES_DIR}/basic-utilities.cc ${SOURCES_DIR}/cpu-arch-detect.cc ${SOURCES_DIR}/debug-app-helper.cc + ${SOURCES_DIR}/helpers.cc ${SOURCES_DIR}/new_delete.cc ${SOURCES_DIR}/shared-constants.cc ) diff --git a/src/monodroid/jni/cpp-util.hh b/src/monodroid/jni/cpp-util.hh index 55d4505bb1a..641e506d256 100644 --- a/src/monodroid/jni/cpp-util.hh +++ b/src/monodroid/jni/cpp-util.hh @@ -17,6 +17,7 @@ #include "cppcompat.hh" #include "platform-compat.hh" +#include "helpers.hh" static inline void do_abort_unless (const char* fmt, ...) @@ -32,7 +33,7 @@ do_abort_unless (const char* fmt, ...) #endif // ndef ANDROID va_end (ap); - std::abort (); + xamarin::android::Helpers::abort_application (); } #define abort_unless(_condition_, _fmt_, ...) \ diff --git a/src/monodroid/jni/cxx-abi/terminate.cc b/src/monodroid/jni/cxx-abi/terminate.cc index 3379cbbcaef..e38da64b034 100644 --- a/src/monodroid/jni/cxx-abi/terminate.cc +++ b/src/monodroid/jni/cxx-abi/terminate.cc @@ -6,11 +6,13 @@ #include #include +#include "helpers.hh" + namespace std { [[noreturn]] void terminate () noexcept { __android_log_write (ANDROID_LOG_FATAL, "monodroid", "std::terminate() called. Aborting."); - abort (); + xamarin::android::Helpers::abort_application (); } } diff --git a/src/monodroid/jni/debug-app-helper.cc b/src/monodroid/jni/debug-app-helper.cc index e47daf8bdef..e79c62b238d 100644 --- a/src/monodroid/jni/debug-app-helper.cc +++ b/src/monodroid/jni/debug-app-helper.cc @@ -91,7 +91,7 @@ Java_mono_android_DebugRuntime_init (JNIEnv *env, [[maybe_unused]] jclass klass, void *monosgen = dlopen (monosgen_path, RTLD_LAZY | RTLD_GLOBAL); if (monosgen == nullptr) { log_fatal (LOG_DEFAULT, "Failed to dlopen Mono runtime from %s: %s", monosgen_path, dlerror ()); - exit (FATAL_EXIT_CANNOT_FIND_LIBMONOSGEN); + Helpers::abort_application (); } } @@ -276,7 +276,7 @@ get_libmonosgen_path () log_fatal (LOG_DEFAULT, "Do you have a shared runtime build of your app with AndroidManifest.xml android:minSdkVersion < 10 while running on a 64-bit Android 5.0 target? This combination is not supported."); log_fatal (LOG_DEFAULT, "Please either set android:minSdkVersion >= 10 or use a build without the shared runtime (like default Release configuration)."); - exit (FATAL_EXIT_CANNOT_FIND_LIBMONOSGEN); + Helpers::abort_application (); return libmonoso; } diff --git a/src/monodroid/jni/debug.cc b/src/monodroid/jni/debug.cc index d3959e44033..3b911106a99 100644 --- a/src/monodroid/jni/debug.cc +++ b/src/monodroid/jni/debug.cc @@ -248,7 +248,7 @@ Debug::start_debugging_and_profiling () DebuggerConnectionStatus res = start_connection (connect_args); if (res == DebuggerConnectionStatus::Error) { log_fatal (LOG_DEBUGGER, "Could not start a connection to the debugger with connection args '%s'.", connect_args); - exit (FATAL_EXIT_DEBUGGER_CONNECT); + Helpers::abort_application (); } else if (res == DebuggerConnectionStatus::Connected) { /* Wait for XS to configure debugging/profiling */ gettimeofday(&wait_tv, nullptr); @@ -655,7 +655,7 @@ xamarin::android::conn_thread (void *arg) res = instance->handle_server_connection (); if (res && res != 3) { log_fatal (LOG_DEBUGGER, "Error communicating with the IDE, exiting..."); - exit (FATAL_EXIT_DEBUGGER_CONNECT); + Helpers::abort_application (); } return nullptr; diff --git a/src/monodroid/jni/embedded-assemblies-zip.cc b/src/monodroid/jni/embedded-assemblies-zip.cc index d44a8344f7b..f7be28a631e 100644 --- a/src/monodroid/jni/embedded-assemblies-zip.cc +++ b/src/monodroid/jni/embedded-assemblies-zip.cc @@ -47,12 +47,12 @@ EmbeddedAssemblies::zip_load_entry_common (size_t entry_index, std::vector { if (number_of_mapped_assembly_stores >= application_config.number_of_assembly_store_files) { log_fatal (LOG_ASSEMBLY, "Too many assembly stores. Expected at most %u", application_config.number_of_assembly_store_files); - abort (); + Helpers::abort_application (); } md_mmap_info assembly_store_map = md_mmap_apk_file (state.apk_fd, state.data_offset, state.file_size, entry_name.get ()); @@ -182,12 +182,12 @@ EmbeddedAssemblies::map_assembly_store (dynamic_local_string if (header->magic != ASSEMBLY_STORE_MAGIC) { log_fatal (LOG_ASSEMBLY, "Assembly store '%s' is not a valid Xamarin.Android assembly store file", entry_name.get ()); - abort (); + Helpers::abort_application (); } if (header->version > ASSEMBLY_STORE_FORMAT_VERSION) { log_fatal (LOG_ASSEMBLY, "Assembly store '%s' uses format v%u which is not understood by this version of Xamarin.Android", entry_name.get (), header->version); - abort (); + Helpers::abort_application (); } if (header->store_id >= application_config.number_of_assembly_store_files) { @@ -198,13 +198,13 @@ EmbeddedAssemblies::map_assembly_store (dynamic_local_string header->store_id, application_config.number_of_assembly_store_files ); - abort (); + Helpers::abort_application (); } AssemblyStoreRuntimeData &rd = assembly_stores[header->store_id]; if (rd.data_start != nullptr) { log_fatal (LOG_ASSEMBLY, "Assembly store '%s' has a duplicate ID (%u)", entry_name.get (), header->store_id); - abort (); + Helpers::abort_application (); } constexpr size_t header_size = sizeof(AssemblyStoreHeader); @@ -277,7 +277,7 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unus if (!zip_read_cd_info (fd, cd_offset, cd_size, cd_entries)) { log_fatal (LOG_ASSEMBLY, "Failed to read the EOCD record from APK file %s", apk_name); - exit (FATAL_EXIT_NO_ASSEMBLIES); + Helpers::abort_application (); } #ifdef DEBUG log_info (LOG_ASSEMBLY, "Central directory offset: %u", cd_offset); @@ -287,7 +287,7 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unus off_t retval = ::lseek (fd, static_cast(cd_offset), SEEK_SET); if (retval < 0) { log_fatal (LOG_ASSEMBLY, "Failed to seek to central directory position in the APK file %s. %s (result: %d; errno: %d)", apk_name, std::strerror (errno), retval, errno); - exit (FATAL_EXIT_NO_ASSEMBLIES); + Helpers::abort_application (); } std::vector buf (cd_size); @@ -306,7 +306,7 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unus ssize_t nread = read (fd, buf.data (), static_cast(buf.size ())); if (static_cast(nread) != cd_size) { log_fatal (LOG_ASSEMBLY, "Failed to read Central Directory from the APK archive %s. %s (nread: %d; errno: %d)", apk_name, std::strerror (errno), nread, errno); - exit (FATAL_EXIT_NO_ASSEMBLIES); + Helpers::abort_application (); } if (application_config.have_assembly_store) { diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/monodroid/jni/embedded-assemblies.cc index de453cd2990..82b7607f437 100644 --- a/src/monodroid/jni/embedded-assemblies.cc +++ b/src/monodroid/jni/embedded-assemblies.cc @@ -35,6 +35,7 @@ #include "mono-image-loader.hh" #include "xamarin-app.hh" #include "cpp-util.hh" +#include "monodroid-glue-internal.hh" #include "startup-aware-lock.hh" #include "timing-internal.hh" #include "search.hh" @@ -73,6 +74,13 @@ void EmbeddedAssemblies::set_assemblies_prefix (const char *prefix) assemblies_prefix_override = prefix != nullptr ? utils.strdup_new (prefix) : nullptr; } +force_inline void +EmbeddedAssemblies::set_assembly_data_and_size (uint8_t* source_assembly_data, uint32_t source_assembly_data_size, uint8_t*& dest_assembly_data, uint32_t& dest_assembly_data_size) noexcept +{ + dest_assembly_data = source_assembly_data; + dest_assembly_data_size = source_assembly_data_size; +} + force_inline void EmbeddedAssemblies::get_assembly_data (uint8_t *data, uint32_t data_size, [[maybe_unused]] const char *name, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept { @@ -81,31 +89,32 @@ EmbeddedAssemblies::get_assembly_data (uint8_t *data, uint32_t data_size, [[mayb if (header->magic == COMPRESSED_DATA_MAGIC) { if (XA_UNLIKELY (compressed_assemblies.descriptors == nullptr)) { log_fatal (LOG_ASSEMBLY, "Compressed assembly found but no descriptor defined"); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + Helpers::abort_application (); } if (XA_UNLIKELY (header->descriptor_index >= compressed_assemblies.count)) { log_fatal (LOG_ASSEMBLY, "Invalid compressed assembly descriptor index %u", header->descriptor_index); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + Helpers::abort_application (); } CompressedAssemblyDescriptor &cad = compressed_assemblies.descriptors[header->descriptor_index]; assembly_data_size = data_size - sizeof(CompressedAssemblyHeader); if (!cad.loaded) { - if (XA_UNLIKELY (cad.data == nullptr)) { - log_fatal (LOG_ASSEMBLY, "Invalid compressed assembly descriptor at %u: no data", header->descriptor_index); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + StartupAwareLock decompress_lock (assembly_decompress_mutex); + + if (cad.loaded) { + set_assembly_data_and_size (reinterpret_cast(cad.data), cad.uncompressed_file_size, assembly_data, assembly_data_size); + return; } - bool log_timing = FastTiming::enabled () && !FastTiming::is_bare_mode (); - size_t decompress_time_index; - if (XA_UNLIKELY (log_timing)) { - decompress_time_index = internal_timing->start_event (TimingEventKind::AssemblyDecompression); + if (XA_UNLIKELY (cad.data == nullptr)) { + log_fatal (LOG_ASSEMBLY, "Invalid compressed assembly descriptor at %u: no data", header->descriptor_index); + Helpers::abort_application (); } if (header->uncompressed_length != cad.uncompressed_file_size) { if (header->uncompressed_length > cad.uncompressed_file_size) { log_fatal (LOG_ASSEMBLY, "Compressed assembly '%s' is larger than when the application was built (expected at most %u, got %u). Assemblies don't grow just like that!", name, cad.uncompressed_file_size, header->uncompressed_length); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + Helpers::abort_application (); } else { log_debug (LOG_ASSEMBLY, "Compressed assembly '%s' is smaller than when the application was built. Adjusting accordingly.", name); } @@ -115,29 +124,23 @@ EmbeddedAssemblies::get_assembly_data (uint8_t *data, uint32_t data_size, [[mayb const char *data_start = reinterpret_cast(data + sizeof(CompressedAssemblyHeader)); int ret = LZ4_decompress_safe (data_start, reinterpret_cast(cad.data), static_cast(assembly_data_size), static_cast(cad.uncompressed_file_size)); - if (XA_UNLIKELY (log_timing)) { - internal_timing->end_event (decompress_time_index, true /* uses_more_info */); - internal_timing->add_more_info (decompress_time_index, name); - } - if (ret < 0) { log_fatal (LOG_ASSEMBLY, "Decompression of assembly %s failed with code %d", name, ret); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + Helpers::abort_application (); } if (static_cast(ret) != cad.uncompressed_file_size) { log_debug (LOG_ASSEMBLY, "Decompression of assembly %s yielded a different size (expected %lu, got %u)", name, cad.uncompressed_file_size, static_cast(ret)); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + Helpers::abort_application (); } cad.loaded = true; } - assembly_data = reinterpret_cast(cad.data); - assembly_data_size = cad.uncompressed_file_size; + + set_assembly_data_and_size (reinterpret_cast(cad.data), cad.uncompressed_file_size, assembly_data, assembly_data_size); } else #endif { - assembly_data = data; - assembly_data_size = data_size; + set_assembly_data_and_size (data, data_size, assembly_data, assembly_data_size); } } @@ -357,9 +360,6 @@ EmbeddedAssemblies::assembly_store_open_from_bundles (dynamic_local_stringmapping_index >= application_config.number_of_assemblies_in_apk) { log_fatal (LOG_ASSEMBLY, "Invalid assembly index %u, exceeds the maximum index of %u", hash_entry->mapping_index, application_config.number_of_assemblies_in_apk - 1); - abort (); + Helpers::abort_application (); } AssemblyStoreSingleAssemblyRuntimeData &assembly_runtime_info = assembly_store_bundled_assemblies[hash_entry->mapping_index]; if (assembly_runtime_info.image_data == nullptr) { if (hash_entry->store_id >= application_config.number_of_assembly_store_files) { log_fatal (LOG_ASSEMBLY, "Invalid assembly store ID %u, exceeds the maximum of %u", hash_entry->store_id, application_config.number_of_assembly_store_files - 1); - abort (); + Helpers::abort_application (); } AssemblyStoreRuntimeData &rd = assembly_stores[hash_entry->store_id]; if (hash_entry->local_store_index >= rd.assembly_count) { log_fatal (LOG_ASSEMBLY, "Invalid index %u into local store assembly descriptor array", hash_entry->local_store_index); - abort (); + Helpers::abort_application (); } AssemblyStoreAssemblyDescriptor *bba = &rd.assemblies[hash_entry->local_store_index]; @@ -411,14 +411,15 @@ EmbeddedAssemblies::assembly_store_open_from_bundles (dynamic_local_stringdata_size, assembly_runtime_info.descriptor->debug_data_size, - assembly_runtime_info.descriptor->config_data_size + assembly_runtime_info.descriptor->config_data_size, + name.get () ); } @@ -553,7 +554,7 @@ EmbeddedAssemblies::binary_search (const Key *key, const Entry *base, size_t nme // This is a coding error on our part, crash! if (base == nullptr) { log_fatal (LOG_ASSEMBLY, "Map address not passed to binary_search"); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + Helpers::abort_application (); } [[maybe_unused]] @@ -912,7 +913,7 @@ EmbeddedAssemblies::md_mmap_apk_file (int fd, uint32_t offset, size_t size, cons if (mmap_info.area == MAP_FAILED) { log_fatal (LOG_DEFAULT, "Could not `mmap` apk fd %d entry `%s`: %s", fd, filename, strerror (errno)); - exit (FATAL_EXIT_CANNOT_FIND_APK); + Helpers::abort_application (); } mmap_info.size = offsetSize; @@ -933,7 +934,7 @@ EmbeddedAssemblies::gather_bundled_assemblies_from_apk (const char* apk, monodro if ((fd = open (apk, O_RDONLY)) < 0) { log_error (LOG_DEFAULT, "ERROR: Unable to load application package %s.", apk); - exit (FATAL_EXIT_NO_ASSEMBLIES); + Helpers::abort_application (); } log_info (LOG_ASSEMBLY, "APK %s FD: %d", apk, fd); @@ -1202,7 +1203,7 @@ EmbeddedAssemblies::try_load_typemaps_from_directory (const char *path) std::unique_ptr index_data = typemap_load_index (dir_fd, dir_path.get (), index_name); if (!index_data) { log_fatal (LOG_ASSEMBLY, "typemap: unable to load TypeMap data index from '%s/%s'", dir_path.get (), index_name); - exit (FATAL_EXIT_NO_ASSEMBLIES); // TODO: use a new error code here + Helpers::abort_application (); } for (size_t i = 0; i < type_map_count; i++) { diff --git a/src/monodroid/jni/embedded-assemblies.hh b/src/monodroid/jni/embedded-assemblies.hh index 58f12334e49..4b4c3324dae 100644 --- a/src/monodroid/jni/embedded-assemblies.hh +++ b/src/monodroid/jni/embedded-assemblies.hh @@ -223,9 +223,10 @@ namespace xamarin::android::internal { #else // def NET static MonoAssembly* open_from_bundles_refonly (MonoAssemblyName *aname, char **assemblies_path, void *user_data); #endif // ndef NET - static void get_assembly_data (uint8_t *data, uint32_t data_size, const char *name, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; - static void get_assembly_data (XamarinAndroidBundledAssembly const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; - static void get_assembly_data (AssemblyStoreSingleAssemblyRuntimeData const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; + void set_assembly_data_and_size (uint8_t* source_assembly_data, uint32_t source_assembly_data_size, uint8_t*& dest_assembly_data, uint32_t& dest_assembly_data_size) noexcept; + void get_assembly_data (uint8_t *data, uint32_t data_size, const char *name, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; + void get_assembly_data (XamarinAndroidBundledAssembly const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; + void get_assembly_data (AssemblyStoreSingleAssemblyRuntimeData const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; void zip_load_entries (int fd, const char *apk_name, monodroid_should_register should_register); void zip_load_individual_assembly_entries (std::vector const& buf, uint32_t num_entries, monodroid_should_register should_register, ZipEntryLoadState &state) noexcept; @@ -333,6 +334,7 @@ namespace xamarin::android::internal { AssemblyStoreHeader *index_assembly_store_header = nullptr; AssemblyStoreHashEntry *assembly_store_hashes; + std::mutex assembly_decompress_mutex; }; } diff --git a/src/monodroid/jni/helpers.cc b/src/monodroid/jni/helpers.cc new file mode 100644 index 00000000000..e3103c04597 --- /dev/null +++ b/src/monodroid/jni/helpers.cc @@ -0,0 +1,9 @@ +#include "helpers.hh" + +using namespace xamarin::android; + +[[noreturn]] void +Helpers::abort_application () noexcept +{ + std::abort (); +} diff --git a/src/monodroid/jni/helpers.hh b/src/monodroid/jni/helpers.hh index 2ea8f8ca197..2725b4d428c 100644 --- a/src/monodroid/jni/helpers.hh +++ b/src/monodroid/jni/helpers.hh @@ -2,6 +2,7 @@ #define __HELPERS_HH #include +#include #include "java-interop-util.h" #include "platform-compat.hh" @@ -21,8 +22,7 @@ namespace xamarin::android if (XA_UNLIKELY (__builtin_add_overflow (a, b, &ret))) { log_fatal (LOG_DEFAULT, "Integer overflow on addition at %s:%u", file, line); - exit (FATAL_EXIT_OUT_OF_MEMORY); - return static_cast(0); + abort_application (); } return ret; @@ -46,12 +46,13 @@ namespace xamarin::android if (XA_UNLIKELY (__builtin_mul_overflow (a, b, &ret))) { log_fatal (LOG_DEFAULT, "Integer overflow on multiplication at %s:%u", file, line); - exit (FATAL_EXIT_OUT_OF_MEMORY); - return static_cast(0); + abort_application (); } return ret; } + + [[noreturn]] static void abort_application () noexcept; }; } #endif // __HELPERS_HH diff --git a/src/monodroid/jni/mono-log-adapter.cc b/src/monodroid/jni/mono-log-adapter.cc index beda04c2c6f..da8e4ee3a52 100644 --- a/src/monodroid/jni/mono-log-adapter.cc +++ b/src/monodroid/jni/mono-log-adapter.cc @@ -43,7 +43,7 @@ MonodroidRuntime::mono_log_handler (const char *log_domain, const char *log_leve __android_log_write (prio, log_domain, message); if (fatal) { - abort (); + Helpers::abort_application (); } } diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc index 7fb2a67dcb3..18e13c1a016 100644 --- a/src/monodroid/jni/monodroid-glue.cc +++ b/src/monodroid/jni/monodroid-glue.cc @@ -205,7 +205,7 @@ MonodroidRuntime::setup_bundled_app (const char *dso_name) log_info (LOG_DEFAULT, "No libapp!"); if (!androidSystem.is_embedded_dso_mode_enabled ()) { log_fatal (LOG_BUNDLE, "bundled app initialization error"); - exit (FATAL_EXIT_CANNOT_LOAD_BUNDLE); + Helpers::abort_application (); } else { log_info (LOG_BUNDLE, "bundled app not found in the APK, ignoring."); return; @@ -236,7 +236,7 @@ MonodroidRuntime::thread_start ([[maybe_unused]] MonoProfiler *prof, [[maybe_unu if (r != JNI_OK) { #if DEBUG log_fatal (LOG_DEFAULT, "ERROR: Unable to attach current thread to the Java VM!"); - exit (FATAL_EXIT_ATTACH_JVM_FAILED); + Helpers::abort_application (); #endif } } @@ -733,7 +733,7 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] dynamic_local_stringhandle_type, info->refs_added, info->weak_handle); - abort (); + Helpers::abort_application (); } } @@ -1291,7 +1291,7 @@ MonodroidRuntime::init_internal_api_dso (void *handle) { if (handle == nullptr) { log_fatal (LOG_DEFAULT, "Internal API library is required"); - exit (FATAL_EXIT_MONO_MISSING_SYMBOLS); + Helpers::abort_application (); } // There's a very, very small chance of a race condition here, but it should be acceptable and we can save some time @@ -1314,7 +1314,7 @@ MonodroidRuntime::init_internal_api_dso (void *handle) // We COULD ignore this situation, but if the function is missing it means we messed something up and thus // it *is* a fatal error. log_fatal (LOG_DEFAULT, "Unable to properly close Internal API library, shutdown function '%s' not found in the module", MonoAndroidInternalCalls::SHUTDOWN_FUNCTION_NAME); - exit (FATAL_EXIT_MONO_MISSING_SYMBOLS); + Helpers::abort_application (); } api_shutdown (); } @@ -1324,13 +1324,13 @@ MonodroidRuntime::init_internal_api_dso (void *handle) auto api_init = reinterpret_cast(java_interop_lib_symbol (handle, MonoAndroidInternalCalls::INIT_FUNCTION_NAME, nullptr)); if (api_init == nullptr) { log_fatal (LOG_DEFAULT, "Unable to initialize Internal API library, init function '%s' not found in the module", MonoAndroidInternalCalls::INIT_FUNCTION_NAME); - exit (FATAL_EXIT_MONO_MISSING_SYMBOLS); + Helpers::abort_application (); } log_debug (LOG_DEFAULT, "Initializing Internal API library %p", handle); if (!api_init (api)) { log_fatal (LOG_DEFAULT, "Failed to initialize Internal API library"); - exit (FATAL_EXIT_MONO_MISSING_SYMBOLS); + Helpers::abort_application (); } } #endif // ndef NET diff --git a/src/monodroid/jni/new_delete.cc b/src/monodroid/jni/new_delete.cc index 2e853a501f6..074dfe35610 100644 --- a/src/monodroid/jni/new_delete.cc +++ b/src/monodroid/jni/new_delete.cc @@ -1,5 +1,7 @@ #include +#include "helpers.hh" + namespace std { struct nothrow_t {}; @@ -21,7 +23,7 @@ operator new (size_t size) void* p = do_alloc (size); if (p == nullptr) { log_fatal (LOG_DEFAULT, "Out of memory in the `new` operator"); - exit (FATAL_EXIT_OUT_OF_MEMORY); + xamarin::android::Helpers::abort_application (); } return p; diff --git a/src/monodroid/jni/pinvoke-override-api.cc b/src/monodroid/jni/pinvoke-override-api.cc index 8b82f971541..ab808b33646 100644 --- a/src/monodroid/jni/pinvoke-override-api.cc +++ b/src/monodroid/jni/pinvoke-override-api.cc @@ -531,7 +531,7 @@ MonodroidRuntime::monodroid_pinvoke_override (const char *library_name, const ch PinvokeEntry const& e = internal_pinvokes[i]; log_fatal (LOG_ASSEMBLY, "\t'%s'=%p (hash: 0x%zx)", e.name, e.func, e.hash); } - abort (); + Helpers::abort_application (); } return entry->func; diff --git a/src/monodroid/jni/strings.hh b/src/monodroid/jni/strings.hh index dc9c718f633..bf41b519b44 100644 --- a/src/monodroid/jni/strings.hh +++ b/src/monodroid/jni/strings.hh @@ -541,7 +541,7 @@ namespace xamarin::android::internal size_t slen = strlen (s); if (offset + count > slen) { log_fatal (LOG_DEFAULT, "Attempt to assign data from a string exceeds the source string length"); - exit (1); + Helpers::abort_application (); } } @@ -746,7 +746,7 @@ namespace xamarin::android::internal "Index %u is out of range (0 - %u)", access_index, idx ); - exit (1); + Helpers::abort_application (); } force_inline void ensure_have_extra (size_t length) noexcept @@ -758,7 +758,7 @@ namespace xamarin::android::internal "Attempt to store too much data in a buffer (capacity: %u; exceeded by: %u)", buffer.size (), needed_space - buffer.size () ); - abort (); + Helpers::abort_application (); } } diff --git a/src/monodroid/jni/timezones.cc b/src/monodroid/jni/timezones.cc index 4d04351e20a..4e8a31df37f 100644 --- a/src/monodroid/jni/timezones.cc +++ b/src/monodroid/jni/timezones.cc @@ -40,7 +40,7 @@ init () if (AndroidEnvironment_NotifyTimeZoneChanged == nullptr) { log_fatal (LOG_DEFAULT, "Unable to find Android.Runtime.AndroidEnvironment.NotifyTimeZoneChanged()!"); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + Helpers::abort_application (); } } diff --git a/src/monodroid/jni/util.cc b/src/monodroid/jni/util.cc index 7f9d4930487..ecc4a8f05f0 100644 --- a/src/monodroid/jni/util.cc +++ b/src/monodroid/jni/util.cc @@ -158,7 +158,7 @@ Util::monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const if (assm == nullptr || status != MonoImageOpenStatus::MONO_IMAGE_OK) { log_fatal (LOG_DEFAULT, "Unable to find assembly '%s'.", basename); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + Helpers::abort_application (); } return assm; } @@ -186,7 +186,7 @@ Util::monodroid_load_assembly (MonoDomain *domain, const char *basename) if (!assm) { log_fatal (LOG_DEFAULT, "Unable to find assembly '%s'.", basename); - exit (FATAL_EXIT_MISSING_ASSEMBLY); + Helpers::abort_application (); } return assm; } diff --git a/src/monodroid/jni/xamarin-android-app-context.cc b/src/monodroid/jni/xamarin-android-app-context.cc index e54ae912b06..3654491b944 100644 --- a/src/monodroid/jni/xamarin-android-app-context.cc +++ b/src/monodroid/jni/xamarin-android-app-context.cc @@ -52,7 +52,7 @@ MonodroidRuntime::get_function_pointer (uint32_t mono_image_index, uint32_t clas marshal_methods_number_of_classes - 1, class_index ); - abort (); + Helpers::abort_application (); } // We need to do that, as Mono APIs cannot be invoked from threads that aren't attached to the runtime. @@ -111,7 +111,7 @@ MonodroidRuntime::get_function_pointer (uint32_t mono_image_index, uint32_t clas } } - abort (); + Helpers::abort_application (); } void