diff --git a/src/native/monodroid/debug.cc b/src/native/monodroid/debug.cc index 139e8a24aae..db787268f41 100644 --- a/src/native/monodroid/debug.cc +++ b/src/native/monodroid/debug.cc @@ -515,7 +515,7 @@ Debug::start_debugging (void) if (sdb_fd == 0) return; - embeddedAssemblies.set_register_debug_symbols (true); + EmbeddedAssemblies::set_register_debug_symbols (true); char *debug_arg = Util::monodroid_strdup_printf ("--debugger-agent=transport=socket-fd,address=%d,embedding=1", sdb_fd); std::array debug_options = { @@ -603,7 +603,7 @@ Debug::enable_soft_breakpoints (void) void* xamarin::android::conn_thread (void *arg) { - abort_if_invalid_pointer_argument (arg); + abort_if_invalid_pointer_argument (arg, "arg"); int res; Debug *instance = static_cast (arg); diff --git a/src/native/monodroid/embedded-assemblies-zip.cc b/src/native/monodroid/embedded-assemblies-zip.cc index 3f91b71dc9a..d807c633a23 100644 --- a/src/native/monodroid/embedded-assemblies-zip.cc +++ b/src/native/monodroid/embedded-assemblies-zip.cc @@ -257,7 +257,7 @@ EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector const& dynamic_local_string entry_name; bool assembly_store_found = false; - log_debug (LOG_ASSEMBLY, "Looking for assembly stores in APK ('%s)", assembly_store_file_path.data ()); + log_debug (LOG_ASSEMBLY, "Looking for assembly stores in APK ('%s')", assembly_store_file_path.data ()); for (size_t i = 0uz; i < num_entries; i++) { if (all_required_zip_entries_found ()) { need_to_scan_more_apks = false; @@ -298,7 +298,7 @@ EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector const& } void -EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unused]] monodroid_should_register should_register) +EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unused]] monodroid_should_register should_register) noexcept { uint32_t cd_offset; uint32_t cd_size; @@ -412,7 +412,7 @@ EmbeddedAssemblies::set_debug_entry_data (XamarinAndroidBundledAssembly &entry, } bool -EmbeddedAssemblies::zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) +EmbeddedAssemblies::zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept { // The simplest case - no file comment off_t ret = ::lseek (fd, -ZIP_EOCD_LEN, SEEK_END); @@ -478,7 +478,7 @@ EmbeddedAssemblies::zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_ } bool -EmbeddedAssemblies::zip_adjust_data_offset (int fd, ZipEntryLoadState &state) +EmbeddedAssemblies::zip_adjust_data_offset (int fd, ZipEntryLoadState &state) noexcept { static constexpr size_t LH_FILE_NAME_LENGTH_OFFSET = 26uz; static constexpr size_t LH_EXTRA_LENGTH_OFFSET = 28uz; @@ -530,7 +530,7 @@ EmbeddedAssemblies::zip_adjust_data_offset (int fd, ZipEntryLoadState &state) template bool -EmbeddedAssemblies::zip_extract_cd_info (std::array const& buf, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) +EmbeddedAssemblies::zip_extract_cd_info (std::array const& buf, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept { constexpr size_t EOCD_TOTAL_ENTRIES_OFFSET = 10uz; constexpr size_t EOCD_CD_SIZE_OFFSET = 12uz; @@ -558,7 +558,7 @@ EmbeddedAssemblies::zip_extract_cd_info (std::array const& buf template force_inline bool -EmbeddedAssemblies::zip_ensure_valid_params (T const& buf, size_t index, size_t to_read) const noexcept +EmbeddedAssemblies::zip_ensure_valid_params (T const& buf, size_t index, size_t to_read) noexcept { if (index + to_read > buf.size ()) { log_error (LOG_ASSEMBLY, "Buffer too short to read %u bytes of data", to_read); @@ -570,7 +570,7 @@ EmbeddedAssemblies::zip_ensure_valid_params (T const& buf, size_t index, size_t template bool -EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint16_t& dst) const noexcept +EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint16_t& dst) noexcept { if (!zip_ensure_valid_params (src, source_index, sizeof (dst))) { return false; @@ -583,7 +583,7 @@ EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint16_t& template bool -EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint32_t& dst) const noexcept +EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint32_t& dst) noexcept { if (!zip_ensure_valid_params (src, source_index, sizeof (dst))) { return false; @@ -600,7 +600,7 @@ EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint32_t& template bool -EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, std::array& dst_sig) const noexcept +EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, std::array& dst_sig) noexcept { if (!zip_ensure_valid_params (src, source_index, dst_sig.size ())) { return false; @@ -612,7 +612,7 @@ EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, std::arra template bool -EmbeddedAssemblies::zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string& characters) const noexcept +EmbeddedAssemblies::zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string& characters) noexcept { if (!zip_ensure_valid_params (buf, index, count)) { return false; @@ -623,7 +623,7 @@ EmbeddedAssemblies::zip_read_field (T const& buf, size_t index, size_t count, dy } bool -EmbeddedAssemblies::zip_read_entry_info (std::vector const& buf, dynamic_local_string& file_name, ZipEntryLoadState &state) +EmbeddedAssemblies::zip_read_entry_info (std::vector const& buf, dynamic_local_string& file_name, ZipEntryLoadState &state) noexcept { constexpr size_t CD_COMPRESSION_METHOD_OFFSET = 10uz; constexpr size_t CD_UNCOMPRESSED_SIZE_OFFSET = 24uz; diff --git a/src/native/monodroid/embedded-assemblies.cc b/src/native/monodroid/embedded-assemblies.cc index 6a20df0bc59..db3704f160f 100644 --- a/src/native/monodroid/embedded-assemblies.cc +++ b/src/native/monodroid/embedded-assemblies.cc @@ -65,7 +65,7 @@ class MonoGuidString final char *guid = nullptr; }; -void EmbeddedAssemblies::set_assemblies_prefix (const char *prefix) +void EmbeddedAssemblies::set_assemblies_prefix (const char *prefix) noexcept { if (assemblies_prefix_override != nullptr) delete[] assemblies_prefix_override; @@ -493,7 +493,7 @@ MonoAssembly* EmbeddedAssemblies::open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, [[maybe_unused]] char **assemblies_path, [[maybe_unused]] void *user_data, MonoError *error) { constexpr bool ref_only = false; - return embeddedAssemblies.open_from_bundles (aname, alc_gchandle, error, ref_only); + return EmbeddedAssemblies::open_from_bundles (aname, alc_gchandle, error, ref_only); } MonoAssembly* @@ -501,17 +501,17 @@ EmbeddedAssemblies::open_from_bundles_full (MonoAssemblyName *aname, [[maybe_unu { constexpr bool ref_only = false; - return embeddedAssemblies.open_from_bundles (aname, ref_only /* loader_data */, nullptr /* error */, ref_only); + return EmbeddedAssemblies::open_from_bundles (aname, ref_only /* loader_data */, nullptr /* error */, ref_only); } void -EmbeddedAssemblies::install_preload_hooks_for_appdomains () +EmbeddedAssemblies::install_preload_hooks_for_appdomains () noexcept { mono_install_assembly_preload_hook (open_from_bundles_full, nullptr); } void -EmbeddedAssemblies::install_preload_hooks_for_alc () +EmbeddedAssemblies::install_preload_hooks_for_alc () noexcept { mono_install_assembly_preload_hook_v3 ( open_from_bundles, @@ -679,7 +679,7 @@ EmbeddedAssemblies::typemap_java_to_managed (hash_t hash, const MonoString *java } else { MonoAssemblyLoadContextGCHandle alc_gchandle = mono_alc_get_default_gchandle (); MonoError mono_error; - assm = embeddedAssemblies.open_from_bundles (assembly_name, alc_gchandle, &mono_error, false /* ref_only */); + assm = EmbeddedAssemblies::open_from_bundles (assembly_name, alc_gchandle, &mono_error, false /* ref_only */); } if (assm == nullptr) { @@ -912,7 +912,7 @@ EmbeddedAssemblies::md_mmap_apk_file (int fd, uint32_t offset, size_t size, cons } void -EmbeddedAssemblies::gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register) +EmbeddedAssemblies::gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register) noexcept { int fd; @@ -1284,12 +1284,10 @@ EmbeddedAssemblies::register_from_filesystem (const char *lib_dir_path,bool look } auto register_fn = - application_config.have_assembly_store ? std::mem_fn (&EmbeddedAssemblies::maybe_register_blob_from_filesystem) : + application_config.have_assembly_store ? &EmbeddedAssemblies::maybe_register_blob_from_filesystem : (look_for_mangled_names ? - std::mem_fn (&EmbeddedAssemblies::maybe_register_assembly_from_filesystem) : - std::mem_fn (&EmbeddedAssemblies::maybe_register_assembly_from_filesystem - ) - ); + &EmbeddedAssemblies::maybe_register_assembly_from_filesystem : + &EmbeddedAssemblies::maybe_register_assembly_from_filesystem); size_t assembly_count = 0uz; do { @@ -1334,7 +1332,7 @@ EmbeddedAssemblies::register_from_filesystem (const char *lib_dir_path,bool look } // We get `true` if it's time to terminate - if (register_fn (this, should_register, assembly_count, cur, state)) { + if (register_fn (should_register, assembly_count, cur, state)) { break; } } while (true); diff --git a/src/native/monodroid/embedded-assemblies.hh b/src/native/monodroid/embedded-assemblies.hh index 1bf6b358705..ff153942724 100644 --- a/src/native/monodroid/embedded-assemblies.hh +++ b/src/native/monodroid/embedded-assemblies.hh @@ -26,6 +26,7 @@ #include "cppcompat.hh" #include "shared-constants.hh" #include "xxhash.hh" +#include "util.hh" #include @@ -87,23 +88,33 @@ namespace xamarin::android::internal { static constexpr std::string_view zip_path_separator { "/" }; static constexpr std::string_view apk_lib_dir_name { "lib" }; + static constexpr size_t assemblies_prefix_size = calc_size(apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); - static constexpr auto assemblies_prefix = concat_string_views (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); + static constexpr auto assemblies_prefix_array = concat_string_views (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); + + // .data() must be used otherwise string_view length will include the trailing \0 in the array + static constexpr std::string_view assemblies_prefix { assemblies_prefix_array.data () }; // We have two records for each assembly, for names with and without the extension static constexpr uint32_t assembly_store_index_entries_per_assembly = 2; static constexpr uint32_t number_of_assembly_store_files = 1; static constexpr std::string_view dso_suffix { ".so" }; - static constexpr auto apk_lib_prefix = assemblies_prefix; // concat_const (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); + static constexpr std::string_view apk_lib_prefix = assemblies_prefix; // concat_const (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); static constexpr std::string_view assembly_store_prefix { "libassemblies." }; static constexpr std::string_view assembly_store_extension { ".blob" }; static constexpr size_t assembly_store_file_name_size = calc_size (assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); - static constexpr auto assembly_store_file_name = concat_string_views (assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); + static constexpr auto assembly_store_file_name_array = concat_string_views (assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); + + // .data() must be used otherwise string_view length will include the trailing \0 in the array + static constexpr std::string_view assembly_store_file_name { assembly_store_file_name_array.data () }; static constexpr size_t assembly_store_file_path_size = calc_size(apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); - static constexpr auto assembly_store_file_path = concat_string_views (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); + static constexpr auto assembly_store_file_path_array = concat_string_views (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); + // .data() must be used otherwise string_view length will include the trailing \0 in the array + static constexpr std::string_view assembly_store_file_path { assembly_store_file_path_array.data () }; + static constexpr size_t dso_size_overhead = ArchiveDSOStubConfig::PayloadSectionOffset + (ArchiveDSOStubConfig::SectionHeaderEntryCount * ArchiveDSOStubConfig::SectionHeaderEntrySize); public: @@ -116,22 +127,22 @@ namespace xamarin::android::internal { {} #endif // def RELEASE - STATIC_IN_ANDROID_RELEASE const char* typemap_managed_to_java (MonoReflectionType *type, const uint8_t *mvid) noexcept; + static const char* typemap_managed_to_java (MonoReflectionType *type, const uint8_t *mvid) noexcept; - void install_preload_hooks_for_appdomains (); - void install_preload_hooks_for_alc (); - STATIC_IN_ANDROID_RELEASE MonoReflectionType* typemap_java_to_managed (MonoString *java_type) noexcept; + static void install_preload_hooks_for_appdomains () noexcept; + static void install_preload_hooks_for_alc () noexcept; + static MonoReflectionType* typemap_java_to_managed (MonoString *java_type) noexcept; /* returns current number of *all* assemblies found from all invocations */ template - size_t register_from_apk (const char *apk_file) noexcept + static size_t register_from_apk (const char *apk_file) noexcept { static_assert (should_register_fn != nullptr, "should_register_fn is a required template parameter"); return register_from_apk (apk_file, should_register_fn); } template - size_t register_from_filesystem () noexcept + static size_t register_from_filesystem () noexcept { static_assert (should_register_fn != nullptr, "should_register_fn is a required template parameter"); return register_from_filesystem (should_register_fn); @@ -142,27 +153,33 @@ namespace xamarin::android::internal { return assemblies_prefix; } - bool get_register_debug_symbols () const + static bool get_register_debug_symbols () noexcept { return register_debug_symbols; } - void set_register_debug_symbols (bool value) + static void set_register_debug_symbols (bool value) noexcept { register_debug_symbols = value; } - void set_assemblies_prefix (const char *prefix); + static void set_assemblies_prefix (const char *prefix) noexcept; - void get_runtime_config_blob (const char *& area, uint32_t& size) const + static void get_runtime_config_blob (const char *& area, uint32_t& size) noexcept { area = static_cast(runtime_config_data); - abort_unless (runtime_config_data_size < std::numeric_limits::max (), "Runtime config binary blob size exceeds %u bytes", std::numeric_limits::max ()); + abort_unless ( + runtime_config_data_size < std::numeric_limits::max (), + [] { + return detail::_format_message ("Runtime config binary blob size exceeds %u bytes", + std::numeric_limits::max ()); + } + ); size = static_cast(runtime_config_data_size); } - void unmap_runtime_config_blob () + static void unmap_runtime_config_blob () noexcept { if (runtime_config_blob_mmap.area == nullptr) { return; @@ -170,20 +187,22 @@ namespace xamarin::android::internal { munmap (runtime_config_blob_mmap.area, runtime_config_blob_mmap.size); runtime_config_blob_mmap.area = nullptr; - runtime_config_blob_mmap.size = 0; + runtime_config_blob_mmap.size = 0uz; + runtime_config_data = nullptr; + runtime_config_data_size = 0uz; } - bool have_runtime_config_blob () const noexcept + static bool have_runtime_config_blob () noexcept { return application_config.have_runtime_config_blob && runtime_config_blob_mmap.area != nullptr; } - bool keep_scanning () const noexcept + static bool keep_scanning () noexcept { return need_to_scan_more_apks; } - void ensure_valid_assembly_stores () const noexcept + static void ensure_valid_assembly_stores () noexcept { if (!application_config.have_assembly_store) { return; @@ -193,34 +212,34 @@ namespace xamarin::android::internal { } private: - STATIC_IN_ANDROID_RELEASE const char* typemap_managed_to_java (MonoType *type, MonoClass *klass, const uint8_t *mvid) noexcept; - STATIC_IN_ANDROID_RELEASE MonoReflectionType* typemap_java_to_managed (hash_t hash, const MonoString *java_type_name) noexcept; - size_t register_from_apk (const char *apk_file, monodroid_should_register should_register) noexcept; - size_t register_from_filesystem (monodroid_should_register should_register) noexcept; - size_t register_from_filesystem (const char *dir, bool look_for_mangled_names, monodroid_should_register should_register) noexcept; + static const char* typemap_managed_to_java (MonoType *type, MonoClass *klass, const uint8_t *mvid) noexcept; + static MonoReflectionType* typemap_java_to_managed (hash_t hash, const MonoString *java_type_name) noexcept; + static size_t register_from_apk (const char *apk_file, monodroid_should_register should_register) noexcept; + static size_t register_from_filesystem (monodroid_should_register should_register) noexcept; + static size_t register_from_filesystem (const char *dir, bool look_for_mangled_names, monodroid_should_register should_register) noexcept; template - bool maybe_register_assembly_from_filesystem (monodroid_should_register should_register, size_t& assembly_count, const dirent* dir_entry, ZipEntryLoadState& state) noexcept; - bool maybe_register_blob_from_filesystem (monodroid_should_register should_register, size_t& assembly_count, const dirent* dir_entry, ZipEntryLoadState& state) noexcept; + static bool maybe_register_assembly_from_filesystem (monodroid_should_register should_register, size_t& assembly_count, const dirent* dir_entry, ZipEntryLoadState& state) noexcept; + static bool maybe_register_blob_from_filesystem (monodroid_should_register should_register, size_t& assembly_count, const dirent* dir_entry, ZipEntryLoadState& state) noexcept; - void gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register); + static void gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register) noexcept; template - MonoAssembly* individual_assemblies_open_from_bundles (dynamic_local_string& name, TLoaderData loader_data, bool ref_only) noexcept; + static MonoAssembly* individual_assemblies_open_from_bundles (dynamic_local_string& name, TLoaderData loader_data, bool ref_only) noexcept; template - MonoAssembly* assembly_store_open_from_bundles (dynamic_local_string& name, TLoaderData loader_data, bool ref_only) noexcept; + static MonoAssembly* assembly_store_open_from_bundles (dynamic_local_string& name, TLoaderData loader_data, bool ref_only) noexcept; template - MonoAssembly* open_from_bundles (MonoAssemblyName* aname, TLoaderData loader_data, MonoError *error, bool ref_only) noexcept; + static MonoAssembly* open_from_bundles (MonoAssemblyName* aname, TLoaderData loader_data, MonoError *error, bool ref_only) noexcept; template - void map_runtime_file (XamarinAndroidBundledAssembly& file) noexcept; - void map_assembly (XamarinAndroidBundledAssembly& file) noexcept; - void map_debug_data (XamarinAndroidBundledAssembly& file) noexcept; + static void map_runtime_file (XamarinAndroidBundledAssembly& file) noexcept; + static void map_assembly (XamarinAndroidBundledAssembly& file) noexcept; + static void map_debug_data (XamarinAndroidBundledAssembly& file) noexcept; template - MonoAssembly* load_bundled_assembly ( + static MonoAssembly* load_bundled_assembly ( XamarinAndroidBundledAssembly& assembly, dynamic_local_string const& name, dynamic_local_string const& abi_name, @@ -235,44 +254,44 @@ namespace xamarin::android::internal { bool typemap_load_file (int dir_fd, const char *dir_path, const char *file_path, TypeMap &module); bool typemap_load_file (BinaryTypeMapHeader &header, const char *dir_path, const char *file_path, int file_fd, TypeMap &module); static ssize_t do_read (int fd, void *buf, size_t count); - const TypeMapEntry *typemap_managed_to_java (const char *managed_type_name) noexcept; + static const TypeMapEntry *typemap_managed_to_java (const char *managed_type_name) noexcept; #endif // DEBUG static md_mmap_info md_mmap_apk_file (int fd, uint32_t offset, size_t size, const char* filename); static MonoAssembly* open_from_bundles_full (MonoAssemblyName *aname, char **assemblies_path, void *user_data); static MonoAssembly* open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, char **assemblies_path, void *user_data, MonoError *error); - 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; + static 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; + 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 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; - void zip_load_assembly_store_entries (std::vector const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept; - bool zip_load_entry_common (size_t entry_index, std::vector const& buf, dynamic_local_string &entry_name, ZipEntryLoadState &state) noexcept; - bool zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries); - bool zip_adjust_data_offset (int fd, ZipEntryLoadState &state); + static void zip_load_entries (int fd, const char *apk_name, monodroid_should_register should_register) noexcept; + static void zip_load_individual_assembly_entries (std::vector const& buf, uint32_t num_entries, monodroid_should_register should_register, ZipEntryLoadState &state) noexcept; + static void zip_load_assembly_store_entries (std::vector const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept; + static bool zip_load_entry_common (size_t entry_index, std::vector const& buf, dynamic_local_string &entry_name, ZipEntryLoadState &state) noexcept; + static bool zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept; + static bool zip_adjust_data_offset (int fd, ZipEntryLoadState &state) noexcept; template - bool zip_extract_cd_info (std::array const& buf, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries); + static bool zip_extract_cd_info (std::array const& buf, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept; template - bool zip_ensure_valid_params (T const& buf, size_t index, size_t to_read) const noexcept; + static bool zip_ensure_valid_params (T const& buf, size_t index, size_t to_read) noexcept; template - bool zip_read_field (T const& src, size_t source_index, uint16_t& dst) const noexcept; + static bool zip_read_field (T const& src, size_t source_index, uint16_t& dst) noexcept; template - bool zip_read_field (T const& src, size_t source_index, uint32_t& dst) const noexcept; + static bool zip_read_field (T const& src, size_t source_index, uint32_t& dst) noexcept; template - bool zip_read_field (T const& src, size_t source_index, std::array& dst_sig) const noexcept; + static bool zip_read_field (T const& src, size_t source_index, std::array& dst_sig) noexcept; template - bool zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string& characters) const noexcept; + static bool zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string& characters) noexcept; - bool zip_read_entry_info (std::vector const& buf, dynamic_local_string& file_name, ZipEntryLoadState &state); + static bool zip_read_entry_info (std::vector const& buf, dynamic_local_string& file_name, ZipEntryLoadState &state) noexcept; [[gnu::always_inline]] static std::tuple get_wrapper_dso_payload_pointer_and_size (md_mmap_info const& map_info, const char *file_name) noexcept @@ -306,7 +325,7 @@ namespace xamarin::android::internal { } [[gnu::always_inline]] - void store_mapped_runtime_config_data (md_mmap_info const& map_info, const char *file_name) noexcept + static void store_mapped_runtime_config_data (md_mmap_info const& map_info, const char *file_name) noexcept { auto [payload_start, payload_size] = get_wrapper_dso_payload_pointer_and_size (map_info, file_name); log_debug (LOG_ASSEMBLY, "Runtime config: payload pointer %p ; size %zu", payload_start, payload_size); @@ -315,20 +334,20 @@ namespace xamarin::android::internal { runtime_config_blob_found = true; } - std::tuple get_assemblies_prefix_and_length () const noexcept + static std::tuple get_assemblies_prefix_and_length () noexcept { if (assemblies_prefix_override != nullptr) { return { assemblies_prefix_override, static_cast(strlen (assemblies_prefix_override)) }; } if (application_config.have_assembly_store) { - return { apk_lib_prefix.data (), apk_lib_prefix.size () - 1 }; + return { apk_lib_prefix.data (), apk_lib_prefix.size () }; } - return {assemblies_prefix.data (), assemblies_prefix.size () - 1}; + return {assemblies_prefix.data (), assemblies_prefix.size () }; } - bool all_required_zip_entries_found () const noexcept + static bool all_required_zip_entries_found () noexcept { return number_of_mapped_assembly_stores == number_of_assembly_store_files && number_of_zip_dso_entries >= application_config.number_of_shared_libraries @@ -350,21 +369,21 @@ namespace xamarin::android::internal { static const TypeMapModuleEntry* binary_search (uint32_t key, const TypeMapModuleEntry *arr, uint32_t n) noexcept; #endif template - void set_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; - void set_assembly_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; - void set_debug_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; - void map_assembly_store (dynamic_local_string const& entry_name, ZipEntryLoadState &state) noexcept; - 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 () + static void set_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; + static void set_assembly_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; + static void set_debug_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; + static void map_assembly_store (dynamic_local_string const& entry_name, ZipEntryLoadState &state) noexcept; + static const AssemblyStoreIndexEntry* find_assembly_store_entry (hash_t hash, const AssemblyStoreIndexEntry *entries, size_t entry_count) noexcept; + static void store_individual_assembly_data (dynamic_local_string const& entry_name, ZipEntryLoadState const& state, monodroid_should_register should_register) noexcept; + + constexpr static size_t get_mangled_name_max_size_overhead () { return SharedConstants::MANGLED_ASSEMBLY_NAME_EXT.size() + std::max (SharedConstants::MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER.size(), SharedConstants::MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER.size()) + 1; // For the extra `-` char in the culture portion of satellite assembly's name } - void configure_state_for_individual_assembly_load (ZipEntryLoadState& state) noexcept + static 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; @@ -418,13 +437,13 @@ namespace xamarin::android::internal { static inline constexpr bool UnmangleSatelliteAssembly = true; static inline constexpr bool UnmangleRegularAssembly = false; - std::vector *bundled_debug_data = nullptr; - std::vector *extra_bundled_assemblies = nullptr; + static inline std::vector *bundled_debug_data = nullptr; + static inline std::vector *extra_bundled_assemblies = nullptr; - bool register_debug_symbols; - bool have_and_want_debug_symbols; - size_t bundled_assembly_index = 0uz; - size_t number_of_found_assemblies = 0uz; + static inline bool register_debug_symbols; + static inline bool have_and_want_debug_symbols; + static inline size_t bundled_assembly_index = 0uz; + static inline size_t number_of_found_assemblies = 0uz; #if defined (DEBUG) TypeMappingInfo *java_to_managed_maps; @@ -432,18 +451,18 @@ namespace xamarin::android::internal { TypeMap *type_maps; size_t type_map_count; #endif // DEBUG - const char *assemblies_prefix_override = nullptr; - - md_mmap_info runtime_config_blob_mmap{}; - void *runtime_config_data = nullptr; - size_t runtime_config_data_size = 0uz; - bool runtime_config_blob_found = false; - uint32_t number_of_mapped_assembly_stores = 0u; - uint32_t number_of_zip_dso_entries = 0u; - bool need_to_scan_more_apks = true; - - AssemblyStoreIndexEntry *assembly_store_hashes; - xamarin::android::mutex assembly_decompress_mutex; + static inline const char *assemblies_prefix_override = nullptr; + + static inline md_mmap_info runtime_config_blob_mmap{}; + static inline void *runtime_config_data = nullptr; + static inline size_t runtime_config_data_size = 0uz; + static inline bool runtime_config_blob_found = false; + static inline uint32_t number_of_mapped_assembly_stores = 0u; + static inline uint32_t number_of_zip_dso_entries = 0u; + static inline bool need_to_scan_more_apks = true; + + static inline AssemblyStoreIndexEntry *assembly_store_hashes = nullptr; + static inline xamarin::android::mutex assembly_decompress_mutex {}; }; } diff --git a/src/native/monodroid/globals.cc b/src/native/monodroid/globals.cc index eb1a2c87fe4..d5fdf4d08e4 100644 --- a/src/native/monodroid/globals.cc +++ b/src/native/monodroid/globals.cc @@ -3,11 +3,7 @@ using namespace xamarin::android; using namespace xamarin::android::internal; -Util utils; -AndroidSystem androidSystem; OSBridge osBridge; -EmbeddedAssemblies embeddedAssemblies; -MonodroidRuntime monodroidRuntime; Timing *timing = nullptr; Debug debug; diff --git a/src/native/monodroid/globals.hh b/src/native/monodroid/globals.hh index 7717ec2ec79..046a0ff770f 100644 --- a/src/native/monodroid/globals.hh +++ b/src/native/monodroid/globals.hh @@ -11,8 +11,6 @@ extern xamarin::android::Debug debug; extern xamarin::android::internal::OSBridge osBridge; -extern xamarin::android::internal::EmbeddedAssemblies embeddedAssemblies; -extern xamarin::android::internal::MonodroidRuntime monodroidRuntime; extern xamarin::android::Timing *timing; #endif // !__GLOBALS_H diff --git a/src/native/monodroid/internal-pinvokes.cc b/src/native/monodroid/internal-pinvokes.cc index 0df3d868715..81367aaea29 100644 --- a/src/native/monodroid/internal-pinvokes.cc +++ b/src/native/monodroid/internal-pinvokes.cc @@ -21,8 +21,8 @@ monodroid_get_system_property (const char *name, char **value) int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) { - embeddedAssemblies.set_assemblies_prefix (prefix); - return 0; + EmbeddedAssemblies::set_assemblies_prefix (prefix); + return 0; } void @@ -135,13 +135,13 @@ _monodroid_gc_wait_for_bridge_processing () void monodroid_clear_gdb_wait () { - monodroidRuntime.set_monodroid_gdb_wait (false); + MonodroidRuntime::set_monodroid_gdb_wait (false); } void* _monodroid_get_identity_hash_code (JNIEnv *env, void *v) { - intptr_t rv = env->CallStaticIntMethod (monodroidRuntime.get_java_class_System (), monodroidRuntime.get_java_class_method_System_identityHashCode (), v); + intptr_t rv = env->CallStaticIntMethod (MonodroidRuntime::get_java_class_System (), MonodroidRuntime::get_java_class_method_System_identityHashCode (), v); return (void*) rv; } @@ -149,9 +149,9 @@ void* _monodroid_timezone_get_default_id () { JNIEnv *env = osBridge.ensure_jnienv (); - jmethodID getDefault = env->GetStaticMethodID (monodroidRuntime.get_java_class_TimeZone (), "getDefault", "()Ljava/util/TimeZone;"); - jmethodID getID = env->GetMethodID (monodroidRuntime.get_java_class_TimeZone (), "getID", "()Ljava/lang/String;"); - jobject d = env->CallStaticObjectMethod (monodroidRuntime.get_java_class_TimeZone (), getDefault); + jmethodID getDefault = env->GetStaticMethodID (MonodroidRuntime::get_java_class_TimeZone (), "getDefault", "()Ljava/util/TimeZone;"); + jmethodID getID = env->GetMethodID (MonodroidRuntime::get_java_class_TimeZone (), "getID", "()Ljava/lang/String;"); + jobject d = env->CallStaticObjectMethod (MonodroidRuntime::get_java_class_TimeZone (), getDefault); jstring id = reinterpret_cast (env->CallObjectMethod (d, getID)); const char *mutf8 = env->GetStringUTFChars (id, nullptr); @@ -175,7 +175,7 @@ void _monodroid_counters_dump ([[maybe_unused]] const char *format, [[maybe_unused]] va_list args) { #if !defined (NET) - monodroidRuntime.dump_counters_v (format, args); + MonodroidRuntime::dump_counters_v (format, args); #endif // ndef NET } @@ -234,7 +234,7 @@ monodroid_strdup_printf (const char *format, ...) char* monodroid_TypeManager_get_java_class_name (jclass klass) { - return monodroidRuntime.get_java_class_name_for_TypeManager (klass); + return MonodroidRuntime::get_java_class_name_for_TypeManager (klass); } int @@ -333,5 +333,5 @@ monodroid_log_traces (uint32_t kind, const char *first_line) JNIEnv *env = osBridge.ensure_jnienv (); auto tk = static_cast(kind); - monodroidRuntime.log_traces (env, tk, first_line); + MonodroidRuntime::log_traces (env, tk, first_line); } diff --git a/src/native/monodroid/monodroid-glue-internal.hh b/src/native/monodroid/monodroid-glue-internal.hh index abbd8a8d4c6..59f00ceffd2 100644 --- a/src/native/monodroid/monodroid-glue-internal.hh +++ b/src/native/monodroid/monodroid-glue-internal.hh @@ -115,45 +115,45 @@ namespace xamarin::android::internal static constexpr int XA_LOG_COUNTERS = MONO_COUNTER_JIT | MONO_COUNTER_METADATA | MONO_COUNTER_GC | MONO_COUNTER_GENERICS | MONO_COUNTER_INTERP; public: - void Java_mono_android_Runtime_register (JNIEnv *env, jstring managedType, jclass nativeClass, jstring methods); - void Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, + static void Java_mono_android_Runtime_register (JNIEnv *env, jstring managedType, jclass nativeClass, jstring methods) noexcept; + static void Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, jobject loader, jobjectArray assembliesJava, jboolean isEmulator, - jboolean haveSplitApks); + jboolean haveSplitApks) noexcept; - jint Java_JNI_OnLoad (JavaVM *vm, void *reserved); + static jint Java_JNI_OnLoad (JavaVM *vm, void *reserved) noexcept; - jclass get_java_class_System () const + static jclass get_java_class_System () noexcept { return java_System; } - jmethodID get_java_class_method_System_identityHashCode () const + static jmethodID get_java_class_method_System_identityHashCode () noexcept { return java_System_identityHashCode; } - jclass get_java_class_TimeZone () const + static jclass get_java_class_TimeZone () noexcept { return java_TimeZone; } - void set_monodroid_gdb_wait (bool yes_no) + static void set_monodroid_gdb_wait (bool yes_no) noexcept { monodroid_gdb_wait = yes_no; } - void propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException); - char* get_java_class_name_for_TypeManager (jclass klass); - void log_traces (JNIEnv *env, TraceKind kind, const char *first_line) noexcept; + static void propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException) noexcept; + static char* get_java_class_name_for_TypeManager (jclass klass) noexcept; + static void log_traces (JNIEnv *env, TraceKind kind, const char *first_line) noexcept; private: static void mono_log_handler (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data); static void mono_log_standard_streams_handler (const char *str, mono_bool is_stdout); // A reference to unique_ptr is not the best practice ever, but it's faster this way - void setup_mono_tracing (std::unique_ptr const& mono_log_mask, bool have_log_assembly, bool have_log_gc); - void install_logging_handlers (); + static void setup_mono_tracing (std::unique_ptr const& mono_log_mask, bool have_log_assembly, bool have_log_gc) noexcept; + static void install_logging_handlers () noexcept; unsigned int convert_dl_flags (int flags); @@ -174,45 +174,45 @@ namespace xamarin::android::internal fnptr = reinterpret_cast(symptr); } - void create_xdg_directory (jstring_wrapper& home, size_t home_len, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept; - void create_xdg_directories_and_environment (jstring_wrapper &homeDir); - void lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info); - void lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info); - void load_assembly (MonoDomain *domain, jstring_wrapper &assembly); - void load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly); - void load_assemblies (load_assemblies_context_type ctx, bool preload, jstring_array_wrapper &assemblies); - - void set_debug_options (); - void parse_gdb_options (); - void mono_runtime_init (JNIEnv *env, dynamic_local_string& runtime_args); - void init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader); - void set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode); - - void set_environment_variable_for_directory (const char *name, jstring_wrapper &value) + static void create_xdg_directory (jstring_wrapper& home, size_t home_len, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept; + static void create_xdg_directories_and_environment (jstring_wrapper &homeDir) noexcept; + static void lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) noexcept; + static void lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) noexcept; + static void load_assembly (MonoDomain *domain, jstring_wrapper &assembly) noexcept; + static void load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly) noexcept; + static void load_assemblies (load_assemblies_context_type ctx, bool preload, jstring_array_wrapper &assemblies) noexcept; + + static void set_debug_options () noexcept; + static void parse_gdb_options () noexcept; + static void mono_runtime_init (JNIEnv *env, dynamic_local_string& runtime_args) noexcept; + static void init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader) noexcept; + static void set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode) noexcept; + + static void set_environment_variable_for_directory (const char *name, jstring_wrapper &value) noexcept { set_environment_variable_for_directory (name, value, true, DEFAULT_DIRECTORY_MODE); } - void set_environment_variable (const char *name, jstring_wrapper &value) + static void set_environment_variable (const char *name, jstring_wrapper &value) noexcept { set_environment_variable_for_directory (name, value, false, 0); } static void monodroid_unhandled_exception (MonoObject *java_exception); - MonoClass* get_android_runtime_class (); + static MonoClass* get_android_runtime_class () noexcept; - MonoDomain* create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain, bool have_split_apks); - MonoDomain* create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, + static MonoDomain* create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain, bool have_split_apks) noexcept; + static MonoDomain* create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, jstring_array_wrapper &assemblies, jobjectArray assembliesBytes, jstring_array_wrapper &assembliesPaths, jobject loader, bool is_root_domain, bool force_preload_assemblies, - bool have_split_apks); + bool have_split_apks) noexcept; - void gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks); + static void gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks) noexcept; static bool should_register_file (const char *filename); - void set_trace_options (); - void set_profile_options (); + static void set_trace_options () noexcept; + static void set_profile_options () noexcept; - void log_jit_event (MonoMethod *method, const char *event_name); + static void log_jit_event (MonoMethod *method, const char *event_name) noexcept; static void jit_begin (MonoProfiler *prof, MonoMethod *method); static void jit_failed (MonoProfiler *prof, MonoMethod *method); static void jit_done (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo); @@ -236,44 +236,36 @@ namespace xamarin::android::internal #endif // def RELEASE #if defined (DEBUG) - void set_debug_env_vars (void); - bool parse_runtime_args (dynamic_local_string &runtime_args, RuntimeOptions *options); - int monodroid_debug_connect (int sock, struct sockaddr_in addr); - int monodroid_debug_accept (int sock, struct sockaddr_in addr); + static inline void set_debug_env_vars (void) noexcept; + static inline bool parse_runtime_args (dynamic_local_string &runtime_args, RuntimeOptions *options) noexcept; + static inline int monodroid_debug_connect (int sock, struct sockaddr_in addr) noexcept; + static inline int monodroid_debug_accept (int sock, struct sockaddr_in addr) noexcept; #endif // DEBUG #if !defined (RELEASE) static MonoAssembly* open_from_update_dir (MonoAssemblyName *aname, char **assemblies_path, void *user_data); #endif private: - MonoMethod *registerType = nullptr; - volatile bool monodroid_gdb_wait = true; - jclass java_System; - jmethodID java_System_identityHashCode; - jmethodID Class_getName; - jclass java_TimeZone; - timing_period jit_time; - FILE *jit_log; - MonoProfilerHandle profiler_handle; + static inline MonoMethod *registerType = nullptr; + static inline bool monodroid_gdb_wait = true; + static inline jclass java_System; + static inline jmethodID java_System_identityHashCode; + static inline jmethodID Class_getName; + static inline jclass java_TimeZone; + static inline timing_period jit_time; + static inline FILE *jit_log = nullptr; + static inline MonoProfilerHandle profiler_handle; /* * If set, monodroid will spin in a loop until the debugger breaks the wait by * clearing monodroid_gdb_wait. */ - bool wait_for_gdb; - - /* The context (mapping to a Mono AppDomain) that is currently selected as the - * active context from the point of view of Java. We cannot rely on the value - * of `mono_domain_get` for this as it's stored per-thread and we want to be - * able to switch our different contexts from different threads. - */ - int current_context_id = -1; - - jnienv_register_jni_natives_fn jnienv_register_jni_natives = nullptr; - MonoAssemblyLoadContextGCHandle default_alc = nullptr; + static inline bool wait_for_gdb = false; + static inline jnienv_register_jni_natives_fn jnienv_register_jni_natives = nullptr; + static inline MonoAssemblyLoadContextGCHandle default_alc = nullptr; static MonoCoreRuntimeProperties monovm_core_properties; - MonovmRuntimeConfigArguments runtime_config_args; + static inline MonovmRuntimeConfigArguments runtime_config_args; }; } #endif diff --git a/src/native/monodroid/monodroid-glue.cc b/src/native/monodroid/monodroid-glue.cc index cd8d899a35d..a90e239e83f 100644 --- a/src/native/monodroid/monodroid-glue.cc +++ b/src/native/monodroid/monodroid-glue.cc @@ -102,7 +102,7 @@ MonodroidRuntime::thread_end ([[maybe_unused]] MonoProfiler *prof, [[maybe_unuse } inline void -MonodroidRuntime::log_jit_event (MonoMethod *method, const char *event_name) +MonodroidRuntime::log_jit_event (MonoMethod *method, const char *event_name) noexcept { jit_time.mark_end (); @@ -120,19 +120,19 @@ MonodroidRuntime::log_jit_event (MonoMethod *method, const char *event_name) void MonodroidRuntime::jit_begin ([[maybe_unused]] MonoProfiler *prof, MonoMethod *method) { - monodroidRuntime.log_jit_event (method, "begin"); + MonodroidRuntime::log_jit_event (method, "begin"); } void MonodroidRuntime::jit_failed ([[maybe_unused]] MonoProfiler *prof, MonoMethod *method) { - monodroidRuntime.log_jit_event (method, "failed"); + MonodroidRuntime::log_jit_event (method, "failed"); } void MonodroidRuntime::jit_done ([[maybe_unused]] MonoProfiler *prof, MonoMethod *method, [[maybe_unused]] MonoJitInfo* jinfo) { - monodroidRuntime.log_jit_event (method, "done"); + MonodroidRuntime::log_jit_event (method, "done"); } #ifndef RELEASE @@ -225,10 +225,10 @@ MonodroidRuntime::should_register_file ([[maybe_unused]] const char *filename) } inline void -MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks) +MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks) noexcept { if (!AndroidSystem::is_embedded_dso_mode_enabled ()) { - *out_user_assemblies_count = embeddedAssemblies.register_from_filesystem (); + *out_user_assemblies_count = EmbeddedAssemblies::register_from_filesystem (); return; } @@ -256,22 +256,22 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, } } - size_t cur_num_assemblies = embeddedAssemblies.register_from_apk (apk_file.get_cstr ()); + size_t cur_num_assemblies = EmbeddedAssemblies::register_from_apk (apk_file.get_cstr ()); *out_user_assemblies_count += (cur_num_assemblies - prev_num_assemblies); prev_num_assemblies = cur_num_assemblies; - if (!embeddedAssemblies.keep_scanning ()) { + if (!EmbeddedAssemblies::keep_scanning ()) { break; } } - embeddedAssemblies.ensure_valid_assembly_stores (); + EmbeddedAssemblies::ensure_valid_assembly_stores (); } #if defined (DEBUG) int -MonodroidRuntime::monodroid_debug_connect (int sock, struct sockaddr_in addr) +MonodroidRuntime::monodroid_debug_connect (int sock, struct sockaddr_in addr) noexcept { long flags = fcntl (sock, F_GETFL, nullptr); flags |= O_NONBLOCK; @@ -316,7 +316,7 @@ MonodroidRuntime::monodroid_debug_connect (int sock, struct sockaddr_in addr) } int -MonodroidRuntime::monodroid_debug_accept (int sock, struct sockaddr_in addr) +MonodroidRuntime::monodroid_debug_accept (int sock, struct sockaddr_in addr) noexcept { ssize_t res = bind (sock, (struct sockaddr *) &addr, sizeof (addr)); if (res < 0) @@ -342,7 +342,7 @@ MonodroidRuntime::monodroid_debug_accept (int sock, struct sockaddr_in addr) #endif inline jint -MonodroidRuntime::Java_JNI_OnLoad (JavaVM *vm, [[maybe_unused]] void *reserved) +MonodroidRuntime::Java_JNI_OnLoad (JavaVM *vm, [[maybe_unused]] void *reserved) noexcept { JNIEnv *env; @@ -355,7 +355,7 @@ MonodroidRuntime::Java_JNI_OnLoad (JavaVM *vm, [[maybe_unused]] void *reserved) } void -MonodroidRuntime::parse_gdb_options () +MonodroidRuntime::parse_gdb_options () noexcept { dynamic_local_string val; @@ -389,7 +389,7 @@ MonodroidRuntime::parse_gdb_options () #if defined (DEBUG) bool -MonodroidRuntime::parse_runtime_args (dynamic_local_string &runtime_args, RuntimeOptions *options) +MonodroidRuntime::parse_runtime_args (dynamic_local_string &runtime_args, RuntimeOptions *options) noexcept { if (runtime_args.length () == 0) { log_warn (LOG_DEFAULT, "runtime args empty"); @@ -490,17 +490,17 @@ MonodroidRuntime::parse_runtime_args (dynamic_local_string& runtime_args) +MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unused]] dynamic_local_string& runtime_args) noexcept { #if defined (DEBUG) RuntimeOptions options{}; @@ -513,7 +513,7 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse } else if (options.debug && cur_time > options.timeout_time) { log_warn (LOG_DEBUGGER, "Not starting the debugger as the timeout value has been reached; current-time: %lli timeout: %lli", cur_time, options.timeout_time); } else if (options.debug && cur_time <= options.timeout_time) { - embeddedAssemblies.set_register_debug_symbols (true); + EmbeddedAssemblies::set_register_debug_symbols (true); int loglevel; if (Logger::have_debugger_log_level ()) @@ -687,7 +687,7 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse * Looking for assemblies from the update dir takes precedence over * everything else, and thus must go LAST. */ - embeddedAssemblies.install_preload_hooks_for_appdomains (); + EmbeddedAssemblies::install_preload_hooks_for_appdomains (); #ifndef RELEASE mono_install_assembly_preload_hook (open_from_update_dir, nullptr); #endif @@ -702,24 +702,24 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse void MonodroidRuntime::cleanup_runtime_config ([[maybe_unused]] MonovmRuntimeConfigArguments *args, [[maybe_unused]] void *user_data) { - embeddedAssemblies.unmap_runtime_config_blob (); + EmbeddedAssemblies::unmap_runtime_config_blob (); } MonoDomain* -MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain, bool have_split_apks) +MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain, bool have_split_apks) noexcept { size_t user_assemblies_count = 0uz; gather_bundled_assemblies (runtimeApks, &user_assemblies_count, have_split_apks); - if (embeddedAssemblies.have_runtime_config_blob ()) { + if (EmbeddedAssemblies::have_runtime_config_blob ()) { size_t blob_time_index; if (FastTiming::enabled ()) [[unlikely]] { blob_time_index = internal_timing->start_event (TimingEventKind::RuntimeConfigBlob); } runtime_config_args.kind = 1; - embeddedAssemblies.get_runtime_config_blob (runtime_config_args.runtimeconfig.data.data, runtime_config_args.runtimeconfig.data.data_len); + EmbeddedAssemblies::get_runtime_config_blob (runtime_config_args.runtimeconfig.data.data, runtime_config_args.runtimeconfig.data.data_len); monovm_runtimeconfig_initialize (&runtime_config_args, cleanup_runtime_config, nullptr); if (FastTiming::enabled ()) [[unlikely]] { @@ -773,7 +773,7 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks } force_inline void -MonodroidRuntime::lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) +MonodroidRuntime::lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) noexcept { info->klass = klass; info->handle = mono_class_get_field_from_name (info->klass, const_cast ("handle")); @@ -798,7 +798,7 @@ MonodroidRuntime::lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJava } force_inline void -MonodroidRuntime::lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) +MonodroidRuntime::lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) noexcept { lookup_bridge_info ( mono_class_from_name (image, type->_namespace, type->_typename), @@ -814,7 +814,7 @@ MonodroidRuntime::monodroid_debugger_unhandled_exception (MonoException *ex) } void -MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader) +MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader) noexcept { constexpr std::string_view icall_typemap_java_to_managed { "Java.Interop.TypeManager::monodroid_typemap_java_to_managed" }; constexpr std::string_view icall_typemap_managed_to_java { "Android.Runtime.JNIEnv::monodroid_typemap_managed_to_java" }; @@ -912,7 +912,15 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec jnienv_register_jni_natives = reinterpret_cast(mono_method_get_unmanaged_callers_only_ftnptr (registerType, &error)); } } - abort_unless (registerType != nullptr, "INTERNAL ERROR: Unable to find Android.Runtime.JNIEnvInit.RegisterJniNatives! %s", mono_error_get_message (&error)); + abort_unless ( + registerType != nullptr, + [&error] { + return detail::_format_message ( + "INTERNAL ERROR: Unable to find Android.Runtime.JNIEnvInit.RegisterJniNatives! %s", + mono_error_get_message (&error) + ); + } + ); jclass lrefLoaderClass = env->GetObjectClass (loader); init.Loader_loadClass = env->GetMethodID (lrefLoaderClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); @@ -937,8 +945,12 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec abort_unless ( initialize != nullptr, - "Failed to obtain unmanaged-callers-only pointer to the Android.Runtime.JNIEnvInit.Initialize method. %s", - mono_error_get_message (&error) + [&error] { + return detail::_format_message ( + "Failed to obtain unmanaged-callers-only pointer to the Android.Runtime.JNIEnvInit.Initialize method. %s", + mono_error_get_message (&error) + ); + } ); initialize (&init); @@ -948,7 +960,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec } MonoClass* -MonodroidRuntime::get_android_runtime_class () +MonodroidRuntime::get_android_runtime_class () noexcept { MonoAssembly *assm = Util::monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); MonoImage *image = mono_assembly_get_image (assm); @@ -956,7 +968,7 @@ MonodroidRuntime::get_android_runtime_class () } inline void -MonodroidRuntime::propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException) +MonodroidRuntime::propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException) noexcept { MonoClass *runtime = get_android_runtime_class (); MonoMethod *method = mono_class_get_method_from_name (runtime, "PropagateUncaughtException", 3); @@ -979,7 +991,7 @@ setup_gc_logging (void) } inline void -MonodroidRuntime::set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode) +MonodroidRuntime::set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode) noexcept { if (createDirectory) { int rv = Util::create_directory (value.get_cstr (), mode); @@ -1004,7 +1016,7 @@ MonodroidRuntime::create_xdg_directory (jstring_wrapper& home, size_t home_len, } inline void -MonodroidRuntime::create_xdg_directories_and_environment (jstring_wrapper &homeDir) +MonodroidRuntime::create_xdg_directories_and_environment (jstring_wrapper &homeDir) noexcept { size_t home_len = strlen (homeDir.get_cstr ()); @@ -1019,7 +1031,7 @@ MonodroidRuntime::create_xdg_directories_and_environment (jstring_wrapper &homeD #if DEBUG void -MonodroidRuntime::set_debug_env_vars (void) +MonodroidRuntime::set_debug_env_vars (void) noexcept { dynamic_local_string value; if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_ENV_PROPERTY, value) == 0) @@ -1059,7 +1071,7 @@ MonodroidRuntime::set_debug_env_vars (void) #endif /* DEBUG */ inline void -MonodroidRuntime::set_trace_options (void) +MonodroidRuntime::set_trace_options (void) noexcept { dynamic_local_string value; if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_TRACE_PROPERTY, value) == 0) @@ -1069,7 +1081,7 @@ MonodroidRuntime::set_trace_options (void) } inline void -MonodroidRuntime::set_profile_options () +MonodroidRuntime::set_profile_options () noexcept { // We want to avoid dynamic allocation, thus let’s create a buffer that can take both the property value and a // path without allocation @@ -1134,7 +1146,7 @@ MonodroidRuntime::set_profile_options () } inline void -MonodroidRuntime::load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly) +MonodroidRuntime::load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly) noexcept { size_t total_time_index; if (FastTiming::enabled ()) [[unlikely]] { @@ -1166,7 +1178,7 @@ MonodroidRuntime::load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jst } inline void -MonodroidRuntime::load_assembly (MonoDomain *domain, jstring_wrapper &assembly) +MonodroidRuntime::load_assembly (MonoDomain *domain, jstring_wrapper &assembly) noexcept { size_t total_time_index; if (FastTiming::enabled ()) [[unlikely]] { @@ -1204,7 +1216,7 @@ MonodroidRuntime::load_assembly (MonoDomain *domain, jstring_wrapper &assembly) } inline void -MonodroidRuntime::load_assemblies (load_assemblies_context_type ctx, bool preload, jstring_array_wrapper &assemblies) +MonodroidRuntime::load_assemblies (load_assemblies_context_type ctx, bool preload, jstring_array_wrapper &assemblies) noexcept { size_t total_time_index; if (FastTiming::enabled ()) [[unlikely]] { @@ -1239,7 +1251,7 @@ MonoDomain* MonodroidRuntime::create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, jstring_array_wrapper &assemblies, [[maybe_unused]] jobjectArray assembliesBytes, [[maybe_unused]] jstring_array_wrapper &assembliesPaths, jobject loader, bool is_root_domain, - bool force_preload_assemblies, bool have_split_apks) + bool force_preload_assemblies, bool have_split_apks) noexcept { MonoDomain* domain = create_domain (env, runtimeApks, is_root_domain, have_split_apks); // Asserting this on desktop apparently breaks a Designer test @@ -1255,7 +1267,7 @@ MonodroidRuntime::create_and_initialize_domain (JNIEnv* env, jclass runtimeClass default_alc = mono_alc_get_default_gchandle (); abort_unless (default_alc != nullptr, "Default AssemblyLoadContext not found"); - embeddedAssemblies.install_preload_hooks_for_alc (); + EmbeddedAssemblies::install_preload_hooks_for_alc (); log_debug (LOG_ASSEMBLY, "ALC hooks installed"); bool preload = (AndroidSystem::is_assembly_preload_enabled () || (is_running_on_desktop && force_preload_assemblies)); @@ -1277,18 +1289,18 @@ MonodroidRuntime::monodroid_unhandled_exception (MonoObject *java_exception) MonoReflectionType* MonodroidRuntime::typemap_java_to_managed (MonoString *java_type_name) noexcept { - return embeddedAssemblies.typemap_java_to_managed (java_type_name); + return EmbeddedAssemblies::typemap_java_to_managed (java_type_name); } const char* MonodroidRuntime::typemap_managed_to_java (MonoReflectionType *type, const uint8_t *mvid) noexcept { - return embeddedAssemblies.typemap_managed_to_java (type, mvid); + return EmbeddedAssemblies::typemap_managed_to_java (type, mvid); } #endif // !def RELEASE force_inline void -MonodroidRuntime::setup_mono_tracing (std::unique_ptr const& mono_log_mask, bool have_log_assembly, bool have_log_gc) +MonodroidRuntime::setup_mono_tracing (std::unique_ptr const& mono_log_mask, bool have_log_assembly, bool have_log_gc) noexcept { constexpr std::string_view MASK_ASM { "asm" }; constexpr std::string_view MASK_DLL { "dll" }; @@ -1361,7 +1373,7 @@ MonodroidRuntime::setup_mono_tracing (std::unique_ptr const& mono_log_ma } force_inline void -MonodroidRuntime::install_logging_handlers () +MonodroidRuntime::install_logging_handlers () noexcept { mono_trace_set_log_handler (mono_log_handler, nullptr); mono_trace_set_print_handler (mono_log_standard_streams_handler); @@ -1372,7 +1384,7 @@ inline void MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, jobject loader, jobjectArray assembliesJava, jboolean isEmulator, - jboolean haveSplitApks) + jboolean haveSplitApks) noexcept { char *mono_log_mask_raw = nullptr; char *mono_log_level_raw = nullptr; @@ -1546,7 +1558,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM *vm, void *reserved) { Util::initialize (); - return monodroidRuntime.Java_JNI_OnLoad (vm, reserved); + return MonodroidRuntime::Java_JNI_OnLoad (vm, reserved); } /* !DO NOT REMOVE! Used by the Android Designer */ @@ -1556,7 +1568,7 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject [[maybe_unused]] jobjectArray externalStorageDirs, jobjectArray assembliesJava, [[maybe_unused]] jstring packageName, [[maybe_unused]] jint apiLevel, [[maybe_unused]] jobjectArray environmentVariables) { - monodroidRuntime.Java_mono_android_Runtime_initInternal ( + MonodroidRuntime::Java_mono_android_Runtime_initInternal ( env, klass, lang, @@ -1577,7 +1589,7 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray assembliesJava, jboolean isEmulator, jboolean haveSplitApks) { - monodroidRuntime.Java_mono_android_Runtime_initInternal ( + MonodroidRuntime::Java_mono_android_Runtime_initInternal ( env, klass, lang, @@ -1593,7 +1605,7 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, } force_inline void -MonodroidRuntime::Java_mono_android_Runtime_register (JNIEnv *env, jstring managedType, jclass nativeClass, jstring methods) +MonodroidRuntime::Java_mono_android_Runtime_register (JNIEnv *env, jstring managedType, jclass nativeClass, jstring methods) noexcept { size_t total_time_index; @@ -1637,11 +1649,11 @@ JNICALL Java_mono_android_Runtime_dumpTimingData ([[maybe_unused]] JNIEnv *env, JNIEXPORT void JNICALL Java_mono_android_Runtime_register (JNIEnv *env, [[maybe_unused]] jclass klass, jstring managedType, jclass nativeClass, jstring methods) { - monodroidRuntime.Java_mono_android_Runtime_register (env, managedType, nativeClass, methods); + MonodroidRuntime::Java_mono_android_Runtime_register (env, managedType, nativeClass, methods); } char* -MonodroidRuntime::get_java_class_name_for_TypeManager (jclass klass) +MonodroidRuntime::get_java_class_name_for_TypeManager (jclass klass) noexcept { if (klass == nullptr || Class_getName == nullptr) return nullptr; @@ -1682,5 +1694,5 @@ get_jnienv (void) JNIEXPORT void JNICALL Java_mono_android_Runtime_propagateUncaughtException (JNIEnv *env, [[maybe_unused]] jclass klass, jobject javaThread, jthrowable javaException) { - monodroidRuntime.propagate_uncaught_exception (env, javaThread, javaException); + MonodroidRuntime::propagate_uncaught_exception (env, javaThread, javaException); } diff --git a/src/native/monodroid/osbridge.cc b/src/native/monodroid/osbridge.cc index fe68ce59d06..d2725d278e2 100644 --- a/src/native/monodroid/osbridge.cc +++ b/src/native/monodroid/osbridge.cc @@ -683,7 +683,7 @@ OSBridge::target_from_jobject (jobject jobj) int OSBridge::scc_get_stashed_index (MonoGCBridgeSCC *scc) { - abort_if_invalid_pointer_argument (scc); + abort_if_invalid_pointer_argument (scc, "scc"); abort_unless (scc->num_objs < 0, "Attempted to load stashed index from an object which does not contain one."); return -scc->num_objs - 1; @@ -862,8 +862,12 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri mono_field_get_value (obj, bridge_info->handle, &jref); if (jref) { alive++; - if (j > 0) - abort_unless (sccs [i]->is_alive, "Bridge SCC at index %d must be alive", i); + if (j > 0) { + abort_unless ( + sccs [i]->is_alive, + [&i] { return detail::_format_message ("Bridge SCC at index %d must be alive", i); } + ); + } sccs [i]->is_alive = 1; mono_field_get_value (obj, bridge_info->refs_added, &refs_added); if (refs_added) { @@ -885,7 +889,10 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri } } } else { - abort_unless (!sccs [i]->is_alive, "Bridge SCC at index %d must NOT be alive", i); + abort_unless ( + !sccs [i]->is_alive, + [&i] { return detail::_format_message ("Bridge SCC at index %d must NOT be alive", i); } + ); } } } @@ -993,8 +1000,8 @@ OSBridge::ensure_jnienv (void) void OSBridge::initialize_on_onload (JavaVM *vm, JNIEnv *env) { - abort_if_invalid_pointer_argument (env); - abort_if_invalid_pointer_argument (vm); + abort_if_invalid_pointer_argument (env, "env"); + abort_if_invalid_pointer_argument (vm, "vm"); jvm = vm; jclass lref = env->FindClass ("java/lang/Runtime"); @@ -1018,7 +1025,7 @@ OSBridge::initialize_on_onload (JavaVM *vm, JNIEnv *env) void OSBridge::initialize_on_runtime_init (JNIEnv *env, jclass runtimeClass) { - abort_if_invalid_pointer_argument (env); + abort_if_invalid_pointer_argument (env, "env"); GCUserPeer_class = RuntimeUtil::get_class_from_runtime_field(env, runtimeClass, "mono_android_GCUserPeer", true); GCUserPeer_ctor = env->GetMethodID (GCUserPeer_class, "", "()V"); abort_unless (GCUserPeer_class != nullptr && GCUserPeer_ctor != nullptr, "Failed to load mono.android.GCUserPeer!"); diff --git a/src/native/monodroid/xamarin_getifaddrs.cc b/src/native/monodroid/xamarin_getifaddrs.cc index 17f0f8a7ba6..9f071132976 100644 --- a/src/native/monodroid/xamarin_getifaddrs.cc +++ b/src/native/monodroid/xamarin_getifaddrs.cc @@ -370,8 +370,8 @@ get_ifaddrs_impl (int (**getifaddrs_implementation) (struct _monodroid_ifaddrs * { void *libc; - abort_if_invalid_pointer_argument (getifaddrs_implementation); - abort_if_invalid_pointer_argument (freeifaddrs_implementation); + abort_if_invalid_pointer_argument (getifaddrs_implementation, "getifaddrs_implementation"); + abort_if_invalid_pointer_argument (freeifaddrs_implementation, "freeifaddrs_implementation"); libc = dlopen ("libc.so", RTLD_NOW); if (libc) { @@ -416,7 +416,7 @@ free_single_xamarin_ifaddrs (struct _monodroid_ifaddrs **ifap) static int open_netlink_session (netlink_session *session) { - abort_if_invalid_pointer_argument (session); + abort_if_invalid_pointer_argument (session, "session"); memset (session, 0, sizeof (*session)); session->sock_fd = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); @@ -488,9 +488,9 @@ send_netlink_dump_request (netlink_session *session, int type) static int append_ifaddr (struct _monodroid_ifaddrs *addr, struct _monodroid_ifaddrs **ifaddrs_head, struct _monodroid_ifaddrs **last_ifaddr) { - abort_if_invalid_pointer_argument (addr); - abort_if_invalid_pointer_argument (ifaddrs_head); - abort_if_invalid_pointer_argument (last_ifaddr); + abort_if_invalid_pointer_argument (addr, "addr"); + abort_if_invalid_pointer_argument (ifaddrs_head, "ifaddrs_head"); + abort_if_invalid_pointer_argument (last_ifaddr, "last_ifaddr"); if (!*ifaddrs_head) { *ifaddrs_head = *last_ifaddr = addr; @@ -524,9 +524,9 @@ parse_netlink_reply (netlink_session *session, struct _monodroid_ifaddrs **ifadd int ret = -1; unsigned char *response = NULL; - abort_if_invalid_pointer_argument (session); - abort_if_invalid_pointer_argument (ifaddrs_head); - abort_if_invalid_pointer_argument (last_ifaddr); + abort_if_invalid_pointer_argument (session, "session"); + abort_if_invalid_pointer_argument (ifaddrs_head, "ifaddrs_head"); + abort_if_invalid_pointer_argument (last_ifaddr, "last_ifaddr"); size_t buf_size = static_cast(getpagesize ()); log_debug (LOG_NETLINK, "receive buffer size == %d", buf_size); @@ -626,9 +626,9 @@ parse_netlink_reply (netlink_session *session, struct _monodroid_ifaddrs **ifadd static int fill_sa_address (struct sockaddr **sa, struct ifaddrmsg *net_address, void *rta_data, size_t rta_payload_length) { - abort_if_invalid_pointer_argument (sa); - abort_if_invalid_pointer_argument (net_address); - abort_if_invalid_pointer_argument (rta_data); + abort_if_invalid_pointer_argument (sa, "sa"); + abort_if_invalid_pointer_argument (net_address, "net_address"); + abort_if_invalid_pointer_argument (rta_data, "rta_data"); switch (net_address->ifa_family) { case AF_INET: { @@ -688,8 +688,8 @@ fill_sa_address (struct sockaddr **sa, struct ifaddrmsg *net_address, void *rta_ static int fill_ll_address (struct sockaddr_ll_extended **sa, struct ifinfomsg *net_interface, void *rta_data, size_t rta_payload_length) { - abort_if_invalid_pointer_argument (sa); - abort_if_invalid_pointer_argument (net_interface); + abort_if_invalid_pointer_argument (sa, "sa"); + abort_if_invalid_pointer_argument (net_interface, "net_interface"); /* Always allocate, do not free - caller may reuse the same variable */ *sa = reinterpret_cast(calloc (1, sizeof (**sa))); @@ -845,7 +845,7 @@ get_link_address (const struct nlmsghdr *message, struct _monodroid_ifaddrs **if struct sockaddr **sa; size_t payload_size; - abort_if_invalid_pointer_argument (message); + abort_if_invalid_pointer_argument (message, "message"); net_address = reinterpret_cast (NLMSG_DATA (message)); length = static_cast(IFA_PAYLOAD (message)); log_debug (LOG_NETLINK, " address data length: %u", length); @@ -995,7 +995,7 @@ get_link_info (const struct nlmsghdr *message) struct _monodroid_ifaddrs *ifa = NULL; struct sockaddr_ll_extended *sa = NULL; - abort_if_invalid_pointer_argument (message); + abort_if_invalid_pointer_argument (message, "message"); net_interface = reinterpret_cast (NLMSG_DATA (message)); length = static_cast(message->nlmsg_len - NLMSG_LENGTH (sizeof (*net_interface))); if (length <= 0) { diff --git a/src/native/runtime-base/android-system.cc b/src/native/runtime-base/android-system.cc index 025362628ae..44745a7f34f 100644 --- a/src/native/runtime-base/android-system.cc +++ b/src/native/runtime-base/android-system.cc @@ -323,7 +323,7 @@ AndroidSystem::load_dso (const char *path, unsigned int dl_flags, bool skip_exis void* AndroidSystem::load_dso_from_specified_dirs (const char **directories, size_t num_entries, const char *dso_name, unsigned int dl_flags) noexcept { - abort_if_invalid_pointer_argument (directories); + abort_if_invalid_pointer_argument (directories, "directories"); if (dso_name == nullptr) return nullptr; diff --git a/src/native/runtime-base/android-system.hh b/src/native/runtime-base/android-system.hh index 3afe52debb3..4ff2afe982d 100644 --- a/src/native/runtime-base/android-system.hh +++ b/src/native/runtime-base/android-system.hh @@ -174,13 +174,15 @@ namespace xamarin::android::internal { static bool is_interpreter_enabled () noexcept { - return get_mono_aot_mode () == MonoAotMode::MONO_AOT_MODE_INTERP_ONLY; - } - - // Hack, see comment for `aot_mode_last_is_interpreter` at the bottom of the class declaration - static bool is_aot_mode_last_really_interpreter_mode () noexcept - { - return false; + switch (get_mono_aot_mode ()) { + case MonoAotMode::MONO_AOT_MODE_INTERP: + case MonoAotMode::MONO_AOT_MODE_INTERP_ONLY: + case MonoAotMode::MONO_AOT_MODE_INTERP_LLVMONLY: + return true; + + default: + return false; + } } static void set_running_in_emulator (bool yesno) noexcept diff --git a/src/native/runtime-base/cpu-arch-detect.cc b/src/native/runtime-base/cpu-arch-detect.cc index d8bcb7dd5fc..7a7a47b0059 100644 --- a/src/native/runtime-base/cpu-arch-detect.cc +++ b/src/native/runtime-base/cpu-arch-detect.cc @@ -10,7 +10,7 @@ static inline constexpr size_t BUF_SIZE = 512uz; static int find_in_maps (const char *str) { - abort_if_invalid_pointer_argument (str); + abort_if_invalid_pointer_argument (str, "str"); FILE *maps = fopen ("/proc/self/maps", "r"); char *line; @@ -112,9 +112,9 @@ get_running_on_cpu (unsigned short *running_on_cpu) void _monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit) { - abort_if_invalid_pointer_argument (built_for_cpu); - abort_if_invalid_pointer_argument (running_on_cpu); - abort_if_invalid_pointer_argument (is64bit); + abort_if_invalid_pointer_argument (built_for_cpu, "built_for_cpu"); + abort_if_invalid_pointer_argument (running_on_cpu, "running_on_cpu"); + abort_if_invalid_pointer_argument (is64bit, "is64bit"); *is64bit = is_64_bit (); get_built_for_cpu (built_for_cpu); diff --git a/src/native/runtime-base/jni-wrappers.hh b/src/native/runtime-base/jni-wrappers.hh index afe95e25b7b..e9dde0eb083 100644 --- a/src/native/runtime-base/jni-wrappers.hh +++ b/src/native/runtime-base/jni-wrappers.hh @@ -20,21 +20,21 @@ namespace xamarin::android : env (_env), jstr (nullptr) { - abort_if_invalid_pointer_argument (_env); + abort_if_invalid_pointer_argument (_env, "_env"); } explicit jstring_wrapper (JNIEnv *_env, const jobject jo) noexcept : env (_env), jstr (reinterpret_cast (jo)) { - abort_if_invalid_pointer_argument (_env); + abort_if_invalid_pointer_argument (_env, "_env"); } explicit jstring_wrapper (JNIEnv *_env, const jstring js) noexcept : env (_env), jstr (js) { - abort_if_invalid_pointer_argument (_env); + abort_if_invalid_pointer_argument (_env, "_env"); } jstring_wrapper (const jstring_wrapper&) = delete; @@ -137,7 +137,7 @@ namespace xamarin::android : env (_env), arr (_arr) { - abort_if_invalid_pointer_argument (_env); + abort_if_invalid_pointer_argument (_env, "_env"); if (_arr != nullptr) { len = static_cast(_env->GetArrayLength (_arr)); if (len > sizeof (static_wrappers) / sizeof (jstring_wrapper)) diff --git a/src/native/runtime-base/shared-constants.hh b/src/native/runtime-base/shared-constants.hh index 001a53651e9..0b7264d5ce4 100644 --- a/src/native/runtime-base/shared-constants.hh +++ b/src/native/runtime-base/shared-constants.hh @@ -40,10 +40,14 @@ namespace xamarin::android::internal static constexpr std::string_view DLL_EXTENSION { ".dll" }; static constexpr std::string_view PDB_EXTENSION { ".pdb" }; + private: static constexpr std::string_view RUNTIME_CONFIG_BLOB_BASE_NAME { "libarc.bin" }; static constexpr size_t runtime_config_blob_name_size = calc_size (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); - static constexpr auto RUNTIME_CONFIG_BLOB_NAME = concat_string_views (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); + static constexpr auto RUNTIME_CONFIG_BLOB_NAME_ARRAY = concat_string_views (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); + public: + // .data() must be used otherwise string_view length will include the trailing \0 in the array + static constexpr std::string_view RUNTIME_CONFIG_BLOB_NAME { RUNTIME_CONFIG_BLOB_NAME_ARRAY.data () }; static constexpr std::string_view MONO_SGEN_SO { "libmonosgen-2.0.so" }; static constexpr std::string_view MONO_SGEN_ARCH_SO { "libmonosgen-" __BITNESS__ "-2.0.so" }; static constexpr std::string_view OVERRIDE_DIRECTORY_NAME { ".__override__" }; diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh index 8dd7f432664..97db495dbea 100644 --- a/src/native/runtime-base/util.hh +++ b/src/native/runtime-base/util.hh @@ -47,9 +47,6 @@ namespace xamarin::android { class Util { - static constexpr std::array hex_chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - static constexpr uint32_t ms_in_nsec = 1000000ULL; - public: static void initialize () noexcept; @@ -197,13 +194,6 @@ namespace xamarin::android return p != nullptr && p [N - 1] == '\0'; } - template - static bool ends_with (const char *str, helper_char_array const& end) noexcept - { - char *p = const_cast (strstr (str, end.data ())); - return p != nullptr && p [N - 1] == '\0'; - } - template static bool ends_with (internal::string_base const& str, const char (&end)[N]) noexcept { @@ -230,19 +220,6 @@ namespace xamarin::android return memcmp (str.get () + len - end_length, end.data (), end_length) == 0; } - template - static bool ends_with (internal::string_base const& str, helper_char_array const& end) noexcept - { - constexpr size_t end_length = N - 1uz; - - size_t len = str.length (); - if (len < end_length) [[unlikely]] { - return false; - } - - return memcmp (str.get () + len - end_length, end.data (), end_length) == 0; - } - template static const TChar* find_last (internal::string_base const& str, const char ch) noexcept { diff --git a/src/native/shared/cpp-util.hh b/src/native/shared/cpp-util.hh index 160fa844e36..a4546971a29 100644 --- a/src/native/shared/cpp-util.hh +++ b/src/native/shared/cpp-util.hh @@ -4,36 +4,139 @@ #include #include #include +#include +#include #include +#include #include +#include #include #include +#include #include #include #include "helpers.hh" +namespace xamarin::android::detail { + [[gnu::always_inline, gnu::flatten]] + static inline const char* + _format_message (const char *format, ...) noexcept + { + va_list ap; + va_start (ap, format); + + char *message; + int ret = vasprintf (&message, format, ap); + + va_end (ap); + return ret == -1 ? "Out of memory" : message; + } + + [[gnu::always_inline]] + static inline std::string get_function_name (const char *signature) + { + using std::operator""sv; + + std::string_view sig { signature }; + if (sig.length () == 0) { + return ""; + } + + auto splitSignature = sig | std::views::split ("::"sv) | std::ranges::to> (); + + std::string ret; + if (splitSignature.size () > 1) { + ret.append (splitSignature [splitSignature.size () - 2]); + ret.append ("::"sv); + } + std::string_view func_name { splitSignature[splitSignature.size () - 1] }; + std::string_view::size_type args_pos = func_name.find ('('); + std::string_view::size_type name_start_pos = func_name.find (' '); + + if (name_start_pos == std::string_view::npos) { + name_start_pos = 0; + } else { + name_start_pos++; // point to after the space which separates return type from name + if (name_start_pos >= func_name.length ()) [[unlikely]] { + name_start_pos = 0; + } + } + + if (args_pos == std::string_view::npos) { + ret.append (func_name.substr (name_start_pos)); + } else { + // If there's a snafu with positions, start from 0 + if (name_start_pos >= args_pos || name_start_pos > func_name.length ()) [[unlikely]] { + name_start_pos = 0; + } + + ret.append (func_name.substr (name_start_pos, args_pos - name_start_pos)); + } + + return ret; + } +} + +template F> +[[gnu::always_inline, gnu::flatten]] static inline void -do_abort_unless (const char* fmt, ...) +abort_unless (bool condition, F&& get_message, std::source_location sloc = std::source_location::current ()) noexcept { - va_list ap; + static_assert (std::is_same::type, const char*>::value, "get_message must return 'const char*'"); - va_start (ap, fmt); - char *message = nullptr; - int n = vasprintf (&message, fmt, ap); - va_end (ap); + if (condition) [[likely]] { + return; + } - xamarin::android::Helpers::abort_application (n == -1 ? "Unable to allocate memory for abort message" : message); + xamarin::android::Helpers::abort_application (std::invoke (get_message), true /* log_location */, sloc); } -#define abort_unless(_condition_, _fmt_, ...) \ - if (!(_condition_)) [[unlikely]] { \ - do_abort_unless ("%s:%d (%s): " _fmt_, __FILE__, __LINE__, __FUNCTION__, ## __VA_ARGS__); \ +[[gnu::always_inline, gnu::flatten]] +static inline void +abort_unless (bool condition, const char *message, std::source_location sloc = std::source_location::current ()) noexcept +{ + if (condition) [[likely]] { + return; } + xamarin::android::Helpers::abort_application (message, true /* log_location */, sloc); +} + +template +[[gnu::always_inline, gnu::flatten]] +static inline void +abort_if_invalid_pointer_argument (T *ptr, const char *ptr_name, std::source_location sloc = std::source_location::current ()) noexcept +{ + abort_unless ( + ptr != nullptr, + [&ptr_name, &sloc] { + return xamarin::android::detail::_format_message ( + "%s: parameter '%s' must be a valid pointer", + xamarin::android::detail::get_function_name (sloc.function_name ()).c_str (), + ptr_name + ); + }, + sloc + ); +} -#define abort_if_invalid_pointer_argument(_ptr_) abort_unless ((_ptr_) != nullptr, "Parameter '%s' must be a valid pointer", #_ptr_) -#define abort_if_negative_integer_argument(_arg_) abort_unless ((_arg_) > 0, "Parameter '%s' must be larger than 0", #_arg_) +[[gnu::always_inline, gnu::flatten]] +static inline void +abort_if_negative_integer_argument (int arg, const char *arg_name, std::source_location sloc = std::source_location::current ()) noexcept +{ + abort_unless ( + arg > 0, + [&arg_name, &sloc] { + return xamarin::android::detail::_format_message ( + "%s: parameter '%s' must be a valid pointer", + xamarin::android::detail::get_function_name (sloc.function_name ()).c_str (), + arg_name + ); + }, + sloc + ); +} // Helper to use in "printf debugging". Normally not used in code anywhere. No code should be shipped with any // of the calls present. @@ -66,32 +169,6 @@ namespace xamarin::android template using c_unique_ptr = std::unique_ptr>; - template - struct helper_char_array final - { - constexpr char* data () noexcept - { - return _elems; - } - - constexpr const char* data () const noexcept - { - return _elems; - } - - constexpr char const& operator[] (size_t n) const noexcept - { - return _elems[n]; - } - - constexpr char& operator[] (size_t n) noexcept - { - return _elems[n]; - } - - char _elems[Size]{}; - }; - template using char_array = std::array;