diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/monodroid/jni/embedded-assemblies.cc index f82cfb4f3d4..b4e33371e72 100644 --- a/src/monodroid/jni/embedded-assemblies.cc +++ b/src/monodroid/jni/embedded-assemblies.cc @@ -16,77 +16,67 @@ extern "C" { #include "monodroid.h" #include "dylib-mono.h" #include "util.h" -#include "unzip.h" -#include "ioapi.h" #include "embedded-assemblies.h" #include "globals.h" #include "monodroid-glue.h" +namespace xamarin { namespace android { namespace internal { + struct TypeMappingInfo { + char *source_apk; + char *source_entry; + int num_entries; + int entry_length; + int value_offset; + const char *mapping; + TypeMappingInfo *next; + }; + + struct md_mmap_info { + void *area; + size_t size; + }; +}}} + using namespace xamarin::android; using namespace xamarin::android::internal; -struct TypeMappingInfo { - char *source_apk; - char *source_entry; - int num_entries; - int entry_length; - int value_offset; - const char *mapping; - struct TypeMappingInfo *next; +const char *EmbeddedAssemblies::suffixes[] = { + "", + ".dll", + ".exe", }; -static MonoBundledAssembly **bundled_assemblies; -static int bundled_assemblies_count; -static monodroid_should_register should_register; -static void *should_register_data; -static int register_debug_symbols; -static char *assemblies_prefix; +constexpr char EmbeddedAssemblies::assemblies_prefix[]; -static struct TypeMappingInfo *java_to_managed_maps; -static struct TypeMappingInfo *managed_to_java_maps; -MONO_API void -monodroid_embedded_assemblies_set_should_register (monodroid_should_register r, void *d) +void EmbeddedAssemblies::set_assemblies_prefix (const char *prefix) { - should_register = r; - should_register_data = d; + if (assemblies_prefix_override != nullptr) + delete[] assemblies_prefix_override; + assemblies_prefix_override = prefix != nullptr ? strdup (prefix) : nullptr; } -MONO_API int -monodroid_embedded_assemblies_set_register_debug_symbols (int new_value) +MonoAssembly* +EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, bool ref_only) { - int cur = register_debug_symbols; - register_debug_symbols = new_value; - return cur; -} - -static MonoAssembly* -open_from_bundles (MonoAssemblyName *aname, char **assemblies_path, void *user_data, mono_bool ref_only) -{ - DylibMono *mono = reinterpret_cast (user_data); - const char *culture = reinterpret_cast (mono->assembly_name_get_culture (aname)); - char *name; - char *ename; - size_t si; - - MonoAssembly *a = nullptr; + const char *culture = monoFunctions.assembly_name_get_culture (aname); + const char *asmname = monoFunctions.assembly_name_get_name (aname); int name_len = culture == nullptr ? 0 : strlen (culture) + 1; - name_len += strlen (reinterpret_cast (mono->assembly_name_get_name (aname))); - name = static_cast (utils.xmalloc (name_len + sizeof (".exe") + 1)); - if (culture != nullptr && strlen (culture) > 0) - sprintf (name, "%s/%s", culture, (const char*) mono->assembly_name_get_name (aname)); - else - sprintf (name, "%s", (const char*) mono->assembly_name_get_name (aname)); - ename = name + strlen (name); - - static const char *suffixes[] = { - "", - ".dll", - ".exe", - }; + name_len += sizeof (".exe"); + name_len += strlen (asmname); + char *name = new char [name_len + 1]; + name [0] = '\0'; + + if (culture != nullptr && *culture != '\0') { + strcat (name, culture); + strcat (name, "/"); + } + strcat (name, asmname); + char *ename = name + strlen (name); - for (si = 0; si < sizeof (suffixes)/sizeof (suffixes [0]) && a == nullptr; ++si) { + MonoAssembly *a = nullptr; + for (size_t si = 0; si < sizeof (suffixes)/sizeof (suffixes [0]) && a == nullptr; ++si) { MonoBundledAssembly **p; *ename = '\0'; @@ -100,53 +90,50 @@ open_from_bundles (MonoAssemblyName *aname, char **assemblies_path, void *user_d const MonoBundledAssembly *e = *p; if (strcmp (e->name, name) == 0 && - (image = mono->image_open_from_data_with_name ((char*) e->data, e->size, 0, nullptr, ref_only, name)) != nullptr && - (a = mono->assembly_load_from_full (image, name, &status, ref_only)) != nullptr) { - mono->config_for_assembly (image); + (image = monoFunctions.image_open_from_data_with_name ((char*) e->data, e->size, 0, nullptr, ref_only, name)) != nullptr && + (a = monoFunctions.assembly_load_from_full (image, name, &status, ref_only)) != nullptr) { + monoFunctions.config_for_assembly (image); break; } } } - free (name); + delete[] name; + if (a && utils.should_log (LOG_ASSEMBLY)) { log_info_nocheck (LOG_ASSEMBLY, "open_from_bundles: loaded assembly: %p\n", a); } return a; } -static MonoAssembly* -open_from_bundles_full (MonoAssemblyName *aname, char **assemblies_path, void *user_data) +MonoAssembly* +EmbeddedAssemblies::open_from_bundles_full (MonoAssemblyName *aname, UNUSED_ARG char **assemblies_path, UNUSED_ARG void *user_data) { - return open_from_bundles (aname, assemblies_path, user_data, 0); + return embeddedAssemblies.open_from_bundles (aname, false); } -static MonoAssembly* -open_from_bundles_refonly (MonoAssemblyName *aname, char **assemblies_path, void *user_data) +MonoAssembly* +EmbeddedAssemblies::open_from_bundles_refonly (MonoAssemblyName *aname, UNUSED_ARG char **assemblies_path, UNUSED_ARG void *user_data) { - return open_from_bundles (aname, assemblies_path, user_data, 1); + return embeddedAssemblies.open_from_bundles (aname, true); } -MONO_API int -monodroid_embedded_assemblies_install_preload_hook (DylibMono *imports) +void +EmbeddedAssemblies::install_preload_hooks () { - if (!imports) - return FALSE; - imports->install_assembly_preload_hook (open_from_bundles_full, imports); - imports->install_assembly_refonly_preload_hook (open_from_bundles_refonly, imports); - return TRUE; + monoFunctions.install_assembly_preload_hook (open_from_bundles_full, nullptr); + monoFunctions.install_assembly_refonly_preload_hook (open_from_bundles_refonly, nullptr); } -static int -TypeMappingInfo_compare_key (const void *a, const void *b) +int +EmbeddedAssemblies::TypeMappingInfo_compare_key (const void *a, const void *b) { return strcmp (reinterpret_cast (a), reinterpret_cast (b)); } -MONO_API const char * -monodroid_typemap_java_to_managed (const char *java) +inline const char* +EmbeddedAssemblies::typemap_java_to_managed (const char *java) { - struct TypeMappingInfo *info; - for (info = java_to_managed_maps; info != nullptr; info = info->next) { + for (TypeMappingInfo *info = java_to_managed_maps; info != nullptr; info = info->next) { /* log_warn (LOG_DEFAULT, "# jonp: checking file: %s!%s for type '%s'", info->source_apk, info->source_entry, java); */ const char *e = reinterpret_cast (bsearch (java, info->mapping, info->num_entries, info->entry_length, TypeMappingInfo_compare_key)); if (e == nullptr) @@ -156,11 +143,10 @@ monodroid_typemap_java_to_managed (const char *java) return nullptr; } -MONO_API const char * -monodroid_typemap_managed_to_java (const char *managed) +inline const char* +EmbeddedAssemblies::typemap_managed_to_java (const char *managed) { - struct TypeMappingInfo *info; - for (info = managed_to_java_maps; info != nullptr; info = info->next) { + for (TypeMappingInfo *info = managed_to_java_maps; info != nullptr; info = info->next) { /* log_warn (LOG_DEFAULT, "# jonp: checking file: %s!%s for type '%s'", info->source_apk, info->source_entry, managed); */ const char *e = reinterpret_cast (bsearch (managed, info->mapping, info->num_entries, info->entry_length, TypeMappingInfo_compare_key)); if (e == nullptr) @@ -170,13 +156,25 @@ monodroid_typemap_managed_to_java (const char *managed) return nullptr; } -static void -extract_int (const char **header, const char *source_apk, const char *source_entry, const char *key_name, int *value) +MONO_API const char * +monodroid_typemap_java_to_managed (const char *java) { - int read = 0; - int consumed = 0; - int key_name_len = 0; - char scanf_format [20] = { 0, }; + return embeddedAssemblies.typemap_java_to_managed (java); +} + +MONO_API const char * +monodroid_typemap_managed_to_java (const char *managed) +{ + return embeddedAssemblies.typemap_managed_to_java (managed); +} + +void +EmbeddedAssemblies::extract_int (const char **header, const char *source_apk, const char *source_entry, const char *key_name, int *value) +{ + int read = 0; + int consumed = 0; + size_t key_name_len = 0; + char scanf_format [20] = { 0, }; if (header == nullptr || *header == nullptr) return; @@ -199,15 +197,12 @@ extract_int (const char **header, const char *source_apk, const char *source_ent *header = *header + consumed + 1; } -static bool -add_type_mapping (struct TypeMappingInfo **info, const char *source_apk, const char *source_entry, const char *addr) +bool +EmbeddedAssemblies::add_type_mapping (TypeMappingInfo **info, const char *source_apk, const char *source_entry, const char *addr) { - struct TypeMappingInfo *p = new TypeMappingInfo (); // calloc (1, sizeof (struct TypeMappingInfo)); - int version = 0; - const char *data = addr; - - if (!p) - return false; + TypeMappingInfo *p = new TypeMappingInfo (); // calloc (1, sizeof (struct TypeMappingInfo)); + int version = 0; + const char *data = addr; extract_int (&data, source_apk, source_entry, "version", &version); if (version != 1) { @@ -230,8 +225,8 @@ add_type_mapping (struct TypeMappingInfo **info, const char *source_apk, const c return false; } - p->source_apk = utils.monodroid_strdup_printf ("%s", source_apk); - p->source_entry = utils.monodroid_strdup_printf ("%s", source_entry); + p->source_apk = strdup (source_apk); + p->source_entry = strdup (source_entry); if (*info) { (*info)->next = p; } else { @@ -240,13 +235,8 @@ add_type_mapping (struct TypeMappingInfo **info, const char *source_apk, const c return true; } -struct md_mmap_info { - void *area; - size_t size; -}; - -static md_mmap_info -md_mmap_apk_file (int fd, uLong offset, uLong size, const char* filename, const char* apk) +md_mmap_info +EmbeddedAssemblies::md_mmap_apk_file (int fd, uLong offset, uLong size, const char* filename, const char* apk) { md_mmap_info file_info; md_mmap_info mmap_info; @@ -273,30 +263,30 @@ md_mmap_apk_file (int fd, uLong offset, uLong size, const char* filename, const return file_info; } -static void* -md_mmap_open_file (void *opaque, const char *filename, int mode) +void* +EmbeddedAssemblies::md_mmap_open_file (UNUSED_ARG void *opaque, UNUSED_ARG const char *filename, int mode) { if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) return utils.xcalloc (1, sizeof (int)); return nullptr; } -static uLong -md_mmap_read_file (void *opaque, void *stream, void *buf, uLong size) +uLong +EmbeddedAssemblies::md_mmap_read_file (void *opaque, UNUSED_ARG void *stream, void *buf, uLong size) { int fd = *reinterpret_cast(opaque); return read (fd, buf, size); } -static long -md_mmap_tell_file (void *opaque, void *stream) +long +EmbeddedAssemblies::md_mmap_tell_file (void *opaque, UNUSED_ARG void *stream) { int fd = *reinterpret_cast(opaque); return lseek (fd, 0, SEEK_CUR); } -static long -md_mmap_seek_file (void *opaque, void *stream, uLong offset, int origin) +long +EmbeddedAssemblies::md_mmap_seek_file (void *opaque, UNUSED_ARG void *stream, uLong offset, int origin) { int fd = *reinterpret_cast(opaque); @@ -316,21 +306,21 @@ md_mmap_seek_file (void *opaque, void *stream, uLong offset, int origin) return 0; } -static int -md_mmap_close_file (void *opaque, void *stream) +int +EmbeddedAssemblies::md_mmap_close_file (UNUSED_ARG void *opaque, void *stream) { free (stream); return 0; } -static int -md_mmap_error_file (void *opaque, void *stream) +int +EmbeddedAssemblies::md_mmap_error_file (UNUSED_ARG void *opaque, UNUSED_ARG void *stream) { return 0; } -static mono_bool -register_debug_symbols_for_assembly (DylibMono *mono, const char *entry_name, MonoBundledAssembly *assembly, const mono_byte *debug_contents, int debug_size) +bool +EmbeddedAssemblies::register_debug_symbols_for_assembly (const char *entry_name, MonoBundledAssembly *assembly, const mono_byte *debug_contents, int debug_size) { const char *entry_basename = strrchr (entry_name, '/') + 1; // System.dll, System.dll.mdb case @@ -338,41 +328,20 @@ register_debug_symbols_for_assembly (DylibMono *mono, const char *entry_name, Mo // That failed; try for System.dll, System.pdb case const char *eb_ext = strrchr (entry_basename, '.'); if (eb_ext == nullptr) - return 0; + return false; int basename_len = eb_ext - entry_basename; assert (basename_len > 0 && "basename must have a length!"); if (strncmp (assembly->name, entry_basename, basename_len) != 0) - return 0; + return false; } - mono->register_symfile_for_assembly (assembly->name, debug_contents, debug_size); + monoFunctions.register_symfile_for_assembly (assembly->name, debug_contents, debug_size); - return 1; -} - -MONO_API int -monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) -{ - free (assemblies_prefix); - assemblies_prefix = strdup (prefix); - return 0; -} - -static const char * -get_assemblies_prefix (void) -{ - if (!assemblies_prefix) { - assemblies_prefix = strdup ("assemblies/"); - } - return assemblies_prefix; + return true; } -static int -gather_bundled_assemblies_from_apk ( - DylibMono *mono, - const char *apk, - MonoBundledAssembly ***bundle, - int *bundle_count) +bool +EmbeddedAssemblies::gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register) { int fd; unzFile file; @@ -390,8 +359,7 @@ gather_bundled_assemblies_from_apk ( if ((fd = open (apk, O_RDONLY)) < 0) { log_error (LOG_DEFAULT, "ERROR: Unable to load application package %s.", apk); - // TODO: throw - return -1; + return false; } funcs.opaque = &fd; @@ -403,7 +371,6 @@ gather_bundled_assemblies_from_apk ( unsigned int *psize; char cur_entry_name [256]; MonoBundledAssembly *cur; - int entry_is_overridden = FALSE; cur_entry_name [0] = 0; if (unzGetCurrentFileInfo (file, &info, cur_entry_name, sizeof (cur_entry_name)-1, nullptr, 0, nullptr, 0) != UNZ_OK || @@ -436,28 +403,26 @@ gather_bundled_assemblies_from_apk ( exit (FATAL_EXIT_MISSING_ZIPALIGN); } - if (should_register) - entry_is_overridden = !should_register (strrchr (cur_entry_name, '/') + 1, should_register_data); + bool entry_is_overridden = !should_register (strrchr (cur_entry_name, '/') + 1); if ((utils.ends_with (cur_entry_name, ".mdb") || utils.ends_with (cur_entry_name, ".pdb")) && register_debug_symbols && !entry_is_overridden && - *bundle != nullptr) { + bundled_assemblies != nullptr) { md_mmap_info map_info = md_mmap_apk_file(fd, offset, info.uncompressed_size, cur_entry_name, apk); - if (register_debug_symbols_for_assembly (mono, cur_entry_name, (*bundle) [*bundle_count-1], + if (register_debug_symbols_for_assembly (cur_entry_name, (bundled_assemblies) [bundled_assemblies_count - 1], (const mono_byte*)map_info.area, info.uncompressed_size)) continue; } - if (utils.ends_with (cur_entry_name, ".config") && - *bundle != nullptr) { - char *assembly_name = utils.monodroid_strdup_printf ("%s", basename (cur_entry_name)); + if (utils.ends_with (cur_entry_name, ".config") && bundled_assemblies != nullptr) { + char *assembly_name = strdup (basename (cur_entry_name)); // Remove '.config' suffix *strrchr (assembly_name, '.') = '\0'; md_mmap_info map_info = md_mmap_apk_file(fd, offset, info.uncompressed_size, cur_entry_name, apk); - mono->register_config_for_assembly (assembly_name, (const char*)map_info.area); + monoFunctions.register_config_for_assembly (assembly_name, (const char*)map_info.area); continue; } @@ -468,11 +433,11 @@ gather_bundled_assemblies_from_apk ( if (entry_is_overridden) continue; - *bundle = reinterpret_cast (utils.xrealloc (*bundle, sizeof(void*)*(*bundle_count + 1))); - cur = (*bundle) [*bundle_count] = reinterpret_cast (utils.xcalloc (1, sizeof (MonoBundledAssembly))); - ++*bundle_count; + bundled_assemblies = reinterpret_cast (utils.xrealloc (bundled_assemblies, sizeof(void*) * (bundled_assemblies_count + 1))); + cur = bundled_assemblies [bundled_assemblies_count] = reinterpret_cast (utils.xcalloc (1, sizeof (MonoBundledAssembly))); + ++bundled_assemblies_count; - md_mmap_info map_info = md_mmap_apk_file(fd, offset, info.uncompressed_size, cur_entry_name, apk); + md_mmap_info map_info = md_mmap_apk_file (fd, offset, info.uncompressed_size, cur_entry_name, apk); cur->name = utils.monodroid_strdup_printf ("%s", strstr (cur_entry_name, prefix) + strlen (prefix)); cur->data = (const unsigned char*)map_info.area; @@ -484,8 +449,7 @@ gather_bundled_assemblies_from_apk ( const char *p = (const char*) cur->data; char header[9]; - int i; - for (i = 0; i < sizeof(header)-1; ++i) + for (size_t i = 0; i < sizeof(header)-1; ++i) header[i] = isprint (p [i]) ? p [i] : '.'; header [sizeof(header)-1] = '\0'; @@ -501,30 +465,29 @@ gather_bundled_assemblies_from_apk ( close(fd); - return 0; + return true; } -int -try_load_typemaps_from_directory (const char *path) +void +EmbeddedAssemblies::try_load_typemaps_from_directory (const char *path) { // read the entire typemap file into a string // process the string using the add_type_mapping - char *val = nullptr; - monodroid_dir_t *dir; - monodroid_dirent_t b, *e; char *dir_path = utils.path_combine (path, "typemaps"); if (dir_path == nullptr || !utils.directory_exists (dir_path)) { log_warn (LOG_DEFAULT, "directory does not exist: `%s`", dir_path); free (dir_path); - return 0; + return; } + monodroid_dir_t *dir; if ((dir = utils.monodroid_opendir (dir_path)) == nullptr) { log_warn (LOG_DEFAULT, "could not open directory: `%s`", dir_path); free (dir_path); - return 0; + return; } + monodroid_dirent_t b, *e; while (androidSystem.readdir (dir, &b, &e) == 0 && e) { #if WINDOWS char *file_name = utils.utf16_to_utf8 (e->d_name); @@ -533,6 +496,7 @@ try_load_typemaps_from_directory (const char *path) #endif /* ndef WINDOWS */ char *file_path = utils.path_combine (dir_path, file_name); if (utils.monodroid_dirent_hasextension (e, ".mj") || utils.monodroid_dirent_hasextension (e, ".jm")) { + char *val = nullptr; int len = androidSystem.monodroid_read_file_into_memory (file_path, &val); if (len > 0 && val != nullptr) { if (utils.monodroid_dirent_hasextension (e, ".mj")) { @@ -547,21 +511,15 @@ try_load_typemaps_from_directory (const char *path) } utils.monodroid_closedir (dir); free (dir_path); - return 0; + return; } -MONO_API int -monodroid_embedded_assemblies_register_from ( - DylibMono *imports, - const char *apk_file) +size_t +EmbeddedAssemblies::register_from (const char *apk_file, monodroid_should_register should_register) { int prev = bundled_assemblies_count; - gather_bundled_assemblies_from_apk ( - imports, - apk_file, - &bundled_assemblies, - &bundled_assemblies_count); + gather_bundled_assemblies_from_apk (apk_file, should_register); log_info (LOG_ASSEMBLY, "Package '%s' contains %i assemblies", apk_file, bundled_assemblies_count - prev); @@ -572,3 +530,9 @@ monodroid_embedded_assemblies_register_from ( return bundled_assemblies_count; } + +MONO_API int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) +{ + embeddedAssemblies.set_assemblies_prefix (prefix); + return 0; +} diff --git a/src/monodroid/jni/embedded-assemblies.h b/src/monodroid/jni/embedded-assemblies.h index 9b12dc0603b..ae0486d3a06 100644 --- a/src/monodroid/jni/embedded-assemblies.h +++ b/src/monodroid/jni/embedded-assemblies.h @@ -2,31 +2,86 @@ #ifndef INC_MONODROID_EMBEDDED_ASSEMBLIES_H #define INC_MONODROID_EMBEDDED_ASSEMBLIES_H +#include #include "dylib-mono.h" +#include "unzip.h" +#include "ioapi.h" -/* filename is e.g. System.dll, System.dll.mdb, System.pdb */ -typedef int (*monodroid_should_register)(const char *filename, void *user_data); +namespace xamarin { namespace android { namespace internal { + struct TypeMappingInfo; + struct md_mmap_info; -/* invoked for each assembly/debug symbol file to determine if the apk_file entry should be used */ -MONO_API void monodroid_embedded_assemblies_set_should_register ( - monodroid_should_register should_register, - void *user_data -); + class EmbeddedAssemblies + { + private: + static constexpr char assemblies_prefix[] = "assemblies/"; + static const char *suffixes[]; -/* mono_bool; returns previous value */ -MONO_API int monodroid_embedded_assemblies_set_register_debug_symbols ( - int /* mono_bool */ register_debug_symbols -); + public: + /* filename is e.g. System.dll, System.dll.mdb, System.pdb */ + using monodroid_should_register = bool (*)(const char *filename); -/* returns current number of *all* assemblies found from all invocations */ -MONO_API int monodroid_embedded_assemblies_register_from ( - xamarin::android::DylibMono *imports, - const char *apk_file -); + public: + void try_load_typemaps_from_directory (const char *path); + void install_preload_hooks (); + const char* typemap_java_to_managed (const char *java); + const char* typemap_managed_to_java (const char *managed); -/* mono_bool; returns TRUE if the install succeeded. */ -MONO_API int monodroid_embedded_assemblies_install_preload_hook (xamarin::android::DylibMono *imports); + /* returns current number of *all* assemblies found from all invocations */ + template + size_t register_from (const char *apk_file) + { + static_assert (should_register_fn != nullptr, "should_register_fn is a required template parameter"); + return register_from (apk_file, should_register_fn); + } -int try_load_typemaps_from_directory (const char *path); + bool get_register_debug_symbols () const + { + return register_debug_symbols; + } + + void set_register_debug_symbols (bool value) + { + register_debug_symbols = value; + } + + void set_assemblies_prefix (const char *prefix); + + private: + size_t register_from (const char *apk_file, monodroid_should_register should_register); + bool gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register); + MonoAssembly* open_from_bundles (MonoAssemblyName* aname, bool ref_only); + void extract_int (const char **header, const char *source_apk, const char *source_entry, const char *key_name, int *value); + bool add_type_mapping (TypeMappingInfo **info, const char *source_apk, const char *source_entry, const char *addr); + bool register_debug_symbols_for_assembly (const char *entry_name, MonoBundledAssembly *assembly, const mono_byte *debug_contents, int debug_size); + + static md_mmap_info md_mmap_apk_file (int fd, uLong offset, uLong size, const char* filename, const char* apk); + static void* md_mmap_open_file (void *opaque, const char *filename, int mode); + static uLong md_mmap_read_file (void *opaque, void *stream, void *buf, uLong size); + static long md_mmap_tell_file (void *opaque, void *stream); + static long md_mmap_seek_file (void *opaque, void *stream, uLong offset, int origin); + static int md_mmap_close_file (void *opaque, void *stream); + static int md_mmap_error_file (void *opaque, void *stream); + + static MonoAssembly* open_from_bundles_full (MonoAssemblyName *aname, char **assemblies_path, void *user_data); + static MonoAssembly* open_from_bundles_refonly (MonoAssemblyName *aname, char **assemblies_path, void *user_data); + static int TypeMappingInfo_compare_key (const void *a, const void *b); + + const char* get_assemblies_prefix () const + { + return assemblies_prefix_override != nullptr ? assemblies_prefix_override : assemblies_prefix; + } + + private: + bool register_debug_symbols; + MonoBundledAssembly **bundled_assemblies; + size_t bundled_assemblies_count; + TypeMappingInfo *java_to_managed_maps; + TypeMappingInfo *managed_to_java_maps; + const char *assemblies_prefix_override = nullptr; + }; +}}} + +MONO_API int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix); #endif /* INC_MONODROID_EMBEDDED_ASSEMBLIES_H */ diff --git a/src/monodroid/jni/globals.cc b/src/monodroid/jni/globals.cc index ae06fd62214..9d2f869d3c5 100644 --- a/src/monodroid/jni/globals.cc +++ b/src/monodroid/jni/globals.cc @@ -7,6 +7,7 @@ DylibMono monoFunctions; Util utils; AndroidSystem androidSystem; OSBridge osBridge; +EmbeddedAssemblies embeddedAssemblies; #ifdef DEBUG Debug debug; diff --git a/src/monodroid/jni/globals.h b/src/monodroid/jni/globals.h index a759a47bbbd..43acd4b90f6 100644 --- a/src/monodroid/jni/globals.h +++ b/src/monodroid/jni/globals.h @@ -5,6 +5,7 @@ #include "dylib-mono.h" #include "util.h" #include "debug.h" +#include "embedded-assemblies.h" #include "monodroid-glue-internal.h" #include "cppcompat.h" @@ -12,6 +13,7 @@ extern xamarin::android::DylibMono monoFunctions; extern xamarin::android::Util utils; extern xamarin::android::internal::AndroidSystem androidSystem; extern xamarin::android::internal::OSBridge osBridge; +extern xamarin::android::internal::EmbeddedAssemblies embeddedAssemblies; #ifdef DEBUG extern xamarin::android::Debug debug; diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc index f703e294c7b..3c840b4cad8 100644 --- a/src/monodroid/jni/monodroid-glue.cc +++ b/src/monodroid/jni/monodroid-glue.cc @@ -95,7 +95,6 @@ static struct timeval wait_tv; static struct timespec wait_ts; #endif // def DEBUG char *xamarin::android::internal::runtime_libdir; -static int register_debug_symbols; static MonoMethod* registerType; /* * If set, monodroid will spin in a loop until the debugger breaks the wait by @@ -438,21 +437,17 @@ open_from_update_dir (MonoAssemblyName *aname, char **assemblies_path, void *use } #endif -int -should_register_file (const char *filename, void *user_data) +bool +should_register_file (const char *filename) { #ifndef RELEASE - int i; - for (i = 0; i < AndroidSystem::MAX_OVERRIDES; ++i) { - int exists; - char *p; - + for (size_t i = 0; i < AndroidSystem::MAX_OVERRIDES; ++i) { const char *odir = androidSystem.get_override_dir (i); if (odir == nullptr) continue; - p = utils.path_combine (odir, filename); - exists = utils.file_exists (p); + char *p = utils.path_combine (odir, filename); + bool exists = utils.file_exists (p); free (p); if (exists) { @@ -461,30 +456,28 @@ should_register_file (const char *filename, void *user_data) } } #endif - return 1; + return true; } static void -gather_bundled_assemblies (JNIEnv *env, jstring_array_wrapper &runtimeApks, mono_bool register_debug_symbols, int *out_user_assemblies_count) +gather_bundled_assemblies (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool register_debug_symbols, int *out_user_assemblies_count) { - monodroid_embedded_assemblies_set_register_debug_symbols (register_debug_symbols); - monodroid_embedded_assemblies_set_should_register (should_register_file, nullptr); #ifndef RELEASE for (size_t i = 0; i < AndroidSystem::MAX_OVERRIDES; ++i) { const char *p = androidSystem.get_override_dir (i); if (!utils.directory_exists (p)) continue; log_info (LOG_ASSEMBLY, "Loading TypeMaps from %s", p); - try_load_typemaps_from_directory (p); + embeddedAssemblies.try_load_typemaps_from_directory (p); } #endif int prev_num_assemblies = 0; for (int32_t i = runtimeApks.get_length () - 1; i >= 0; --i) { - int cur_num_assemblies; + size_t cur_num_assemblies; jstring_wrapper &apk_file = runtimeApks [i]; - cur_num_assemblies = monodroid_embedded_assemblies_register_from (&monoFunctions, apk_file.get_cstr ()); + cur_num_assemblies = embeddedAssemblies.register_from (apk_file.get_cstr ()); if (strstr (apk_file.get_cstr (), "/Mono.Android.DebugRuntime") == nullptr && strstr (apk_file.get_cstr (), "/Mono.Android.Platform.ApiLevel_") == nullptr) @@ -722,7 +715,7 @@ set_debug_options (void) if (utils.monodroid_get_namespaced_system_property (Debug::DEBUG_MONO_DEBUG_PROPERTY, nullptr) == 0) return; - register_debug_symbols = 1; + embeddedAssemblies.set_register_debug_symbols (true); monoFunctions.debug_init (MONO_DEBUG_FORMAT_MONO); } @@ -801,7 +794,7 @@ mono_runtime_init (char *runtime_args) char *debug_arg; char *debug_options [2]; - register_debug_symbols = 1; + embeddedAssemblies.set_register_debug_symbols (true); debug_arg = utils.monodroid_strdup_printf ("--debugger-agent=transport=dt_socket,loglevel=%d,address=%s:%d,%sembedding=1", options.loglevel, options.host, options.sdb_port, options.server ? "server=y," : ""); @@ -938,7 +931,7 @@ mono_runtime_init (char *runtime_args) * Looking for assemblies from the update dir takes precedence over * everything else, and thus must go LAST. */ - monodroid_embedded_assemblies_install_preload_hook (&monoFunctions); + embeddedAssemblies.install_preload_hooks (); #ifndef RELEASE monoFunctions.install_assembly_preload_hook (open_from_update_dir, nullptr); #endif @@ -950,7 +943,7 @@ create_domain (JNIEnv *env, jclass runtimeClass, jstring_array_wrapper &runtimeA MonoDomain *domain; int user_assemblies_count = 0;; - gather_bundled_assemblies (env, runtimeApks, register_debug_symbols, &user_assemblies_count); + gather_bundled_assemblies (env, runtimeApks, embeddedAssemblies.get_register_debug_symbols (), &user_assemblies_count); if (!mono_mkbundle_init && user_assemblies_count == 0 && androidSystem.count_override_assemblies () == 0) { log_fatal (LOG_DEFAULT, "No assemblies found in '%s' or '%s'. Assuming this is part of Fast Deployment. Exiting...", @@ -1648,7 +1641,7 @@ start_debugging (void) if (!sdb_fd) return; - register_debug_symbols = 1; + embeddedAssemblies.set_register_debug_symbols (true); debug_arg = utils.monodroid_strdup_printf ("--debugger-agent=transport=socket-fd,address=%d,embedding=1", sdb_fd); debug_options[0] = debug_arg; diff --git a/src/monodroid/jni/util.h b/src/monodroid/jni/util.h index e6dbc1ca9b8..5088458f8a6 100644 --- a/src/monodroid/jni/util.h +++ b/src/monodroid/jni/util.h @@ -63,6 +63,16 @@ extern "C" { #define DEFAULT_DIRECTORY_MODE S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH #define XA_UNLIKELY(expr) (__builtin_expect ((expr) != 0, 0)) +#if __cplusplus >= 201703L +#define UNUSED_ARG [[maybe_unused]] +#else +#if defined (__GNUC__) +#define UNUSED_ARG __attribute__((__unused__)) +#else +#define UNUSED_ARG +#endif +#endif + #ifdef __cplusplus extern "C" { #endif // __cplusplus