From e9592e97581447d8ddf5c815579054a6313be902 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Fri, 10 Jul 2020 22:32:53 +0200 Subject: [PATCH 1/7] Work around an Android 9 dlopen bug on x86 Fixes: https://github.com/xamarin/xamarin-android/issues/4893 This commit fixes an issue in Android 9 (API 28) 32-bit (ONLY) dynamic loader issue where if the same library is loaded more than once, instead of returning a handle to the already loaded copy, `dlopen` will reinitialize the library thus resetting its state (BSS section is cleared, global instances of C++ classes are re-instantiated etc). When the library is reinitalized, however, our runtime is not - since the Java `Runtime.initialize`, which ends up in our native code, is *not* called because the library load is not part of the process startup, when `Runtime.initialize` is invoked. This in turn leads to situation when certain class members initialized in `Runtime.initialize` and assumed to be correct throughout the application life are, in fact, invalid and lead to crashes. In the instance of issue #4893, the problem was that the `MonodroidRuntime::Class_getName` field was not initialized to point to the `Java.Lang.Class.getName` Java method and that, in turn, led to Xamarin.Android not being able to look up Java types during application execution time. `libmonodroid.so` is reloaded whenever Mono tries to resolve an `__Internal` p/invoke (via a call to Xamarin.Android's `monodroid_dlopen` fallback handler) - these p/invokes are assumed to live in `libmonodroid` so we need to return a handle to it, so that Mono can subsequently use `dlsym` to look up the required symbol. Given the situation described in the previous paragraph, we need a way to not reload `libmonodroid` or do something else to avoid it being reinitialized. Since there's no portable way to check whether a DSO is already loaded we need to resort to "something else", implemented in this commit. We move all the functions used in `__Internal` p/invokes to a separate DSO which can be reloaded & reinitialized over and over again without shredding our global state. This is done by way of introducing a C++ interface class, `MonoAndroidExternalAPI` which is passed to the new DSO on load time, thus giving it a way to invoke all the necessary internal Xamarin.Android functions the `__Internal` p/invokes need in order to work as expected. --- .../Microsoft.Android.Runtime.proj | 1 + .../installers/create-installers.targets | 3 + .../HelloWorld/Properties/AndroidManifest.xml | 2 +- .../Xamarin.Android.Common.targets | 1 + src/monodroid/CMakeLists.txt | 20 +- src/monodroid/jni/cpu-arch-detect.cc | 2 +- src/monodroid/jni/embedded-assemblies.cc | 2 +- src/monodroid/jni/external-api.cc | 307 ---------------- src/monodroid/jni/internal-pinvoke-api.cc | 336 ++++++++++++++++++ src/monodroid/jni/logger.cc | 62 +--- src/monodroid/jni/logger.hh | 13 + src/monodroid/jni/monodroid-glue-internal.hh | 18 +- src/monodroid/jni/monodroid-glue.cc | 141 +++++++- src/monodroid/jni/monodroid-networkinfo.cc | 11 +- src/monodroid/jni/util.cc | 12 + src/monodroid/jni/util.hh | 1 + src/monodroid/jni/xa-internal-api-impl.hh | 53 +++ src/monodroid/jni/xa-internal-api.cc | 335 +++++++++++++++++ src/monodroid/jni/xa-internal-api.hh | 71 ++++ src/monodroid/jni/xamarin_getifaddrs.h | 1 + 20 files changed, 1001 insertions(+), 391 deletions(-) delete mode 100644 src/monodroid/jni/external-api.cc create mode 100644 src/monodroid/jni/internal-pinvoke-api.cc create mode 100644 src/monodroid/jni/xa-internal-api-impl.hh create mode 100644 src/monodroid/jni/xa-internal-api.cc create mode 100644 src/monodroid/jni/xa-internal-api.hh diff --git a/build-tools/create-packs/Microsoft.Android.Runtime.proj b/build-tools/create-packs/Microsoft.Android.Runtime.proj index 6712bd2137d..1d5dfc4083a 100644 --- a/build-tools/create-packs/Microsoft.Android.Runtime.proj +++ b/build-tools/create-packs/Microsoft.Android.Runtime.proj @@ -38,6 +38,7 @@ projects that use the Microsoft.Android framework in .NET 5. <_AndroidRuntimePackAssets Include="$(XamarinAndroidSourcePath)bin\$(Configuration)\lib\xamarin.android\xbuild\Xamarin\Android\lib\$(AndroidABI)\libmono-android.debug.so" /> <_AndroidRuntimePackAssets Include="$(XamarinAndroidSourcePath)bin\$(Configuration)\lib\xamarin.android\xbuild\Xamarin\Android\lib\$(AndroidABI)\libmono-android.release.so" /> + <_AndroidRuntimePackAssets Include="$(XamarinAndroidSourcePath)bin\$(Configuration)\lib\xamarin.android\xbuild\Xamarin\Android\lib\$(AndroidABI)\libxa-internal-api.so" /> <_AndroidRuntimePackAssets Include="$(XamarinAndroidSourcePath)bin\$(Configuration)\lib\xamarin.android\xbuild\Xamarin\Android\lib\$(AndroidABI)\libsqlite3_xamarin.so" /> <_AndroidRuntimePackAssets Include="$(XamarinAndroidSourcePath)bin\$(Configuration)\lib\xamarin.android\xbuild\Xamarin\Android\lib\$(AndroidABI)\libxamarin-debug-app-helper.so" /> diff --git a/build-tools/installers/create-installers.targets b/build-tools/installers/create-installers.targets index 226b63465db..680509fe76e 100644 --- a/build-tools/installers/create-installers.targets +++ b/build-tools/installers/create-installers.targets @@ -159,6 +159,7 @@ <_MSBuildFiles Include="$(MSBuildSrcDir)\LayoutBinding.cs" /> <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libmono-android.debug.so')" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libmono-android.release.so')" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> + <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libxa-internal-api.so')" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libmono-btls-shared.so')" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libmono-profiler-aot.so')" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libmono-profiler-log.so')" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> @@ -294,6 +295,7 @@ <_MSBuildLibHostFilesWin Include="$(MSBuildSrcDir)\lib\host-mxe-Win64\libMonoPosixHelper.dll" /> <_MSBuildLibHostFilesWin Include="$(MSBuildSrcDir)\lib\host-mxe-Win64\libmonosgen-2.0.dll" /> <_MSBuildLibHostFilesWin Include="$(MSBuildSrcDir)\lib\host-mxe-Win64\libxamarin-app.dll" Condition=" '$(HostOS)' != 'Windows' " /> + <_MSBuildLibHostFilesWin Include="$(MSBuildSrcDir)\lib\host-mxe-Win64\libxa-internal-api.dll" Condition=" '$(HostOS)' != 'Windows' " /> <_MSBuildFilesUnixSign> @@ -333,6 +335,7 @@ <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\lib\host-$(HostOS)\libMonoPosixHelper.$(LibExtension)" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\lib\host-$(HostOS)\libmonosgen-2.0.$(LibExtension)" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\lib\host-$(HostOS)\libxamarin-app.$(LibExtension)" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> + <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\lib\host-$(HostOS)\libxa-internal-api.$(LibExtension)" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\libzip.$(LibExtension)" /> <_MSBuildFilesUnix Include="$(MSBuildSrcDir)\proguard\bin\proguard.sh" /> diff --git a/samples/HelloWorld/Properties/AndroidManifest.xml b/samples/HelloWorld/Properties/AndroidManifest.xml index dd591420769..3561f38df32 100644 --- a/samples/HelloWorld/Properties/AndroidManifest.xml +++ b/samples/HelloWorld/Properties/AndroidManifest.xml @@ -1,6 +1,6 @@  - + diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index b62574e2e5a..dbcc8433efe 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -1890,6 +1890,7 @@ because xbuild doesn't support framework reference assemblies. <_AndroidNativeLibraryForFastDev Condition=" '$(_InstantRunEnabled)' == 'True' And '$(AndroidUseDebugRuntime)' == 'True' " Include="%(_TargetLibDir.Identity)\libxamarin-debug-app-helper.so" /> + diff --git a/src/monodroid/CMakeLists.txt b/src/monodroid/CMakeLists.txt index b889ea33694..191a4e2f55f 100644 --- a/src/monodroid/CMakeLists.txt +++ b/src/monodroid/CMakeLists.txt @@ -228,6 +228,8 @@ else() endif() endif() +string(STRIP "${EXTRA_LINKER_FLAGS}" EXTRA_LINKER_FLAGS) + if (ENABLE_TIMING) add_definitions("-DMONODROID_TIMING=1") endif() @@ -285,11 +287,10 @@ set(MONODROID_SOURCES ${SOURCES_DIR}/debug-constants.cc ${SOURCES_DIR}/embedded-assemblies.cc ${SOURCES_DIR}/embedded-assemblies-zip.cc - ${SOURCES_DIR}/external-api.cc ${SOURCES_DIR}/globals.cc - ${SOURCES_DIR}/jni.c ${SOURCES_DIR}/logger.cc ${SOURCES_DIR}/monodroid-glue.cc + ${SOURCES_DIR}/xa-internal-api.cc ${SOURCES_DIR}/osbridge.cc ${SOURCES_DIR}/shared-constants.cc ${SOURCES_DIR}/timezones.cc @@ -299,6 +300,12 @@ set(MONODROID_SOURCES ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc ) +set(XA_INTERNAL_API_SOURCES + ${SOURCES_DIR}/jni.c + ${SOURCES_DIR}/internal-pinvoke-api.cc + ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc + ) + if(ENABLE_NDK) set(MONODROID_SOURCES ${MONODROID_SOURCES} @@ -314,6 +321,15 @@ if(UNIX) ) endif() +add_library(xa-internal-api SHARED ${XA_INTERNAL_API_SOURCES}) +target_link_libraries(xa-internal-api ${EXTRA_LINKER_FLAGS}) +set_target_properties( + xa-internal-api + PROPERTIES + COMPILE_FLAGS -fvisibility=default + LINK_FLAGS -fvisibility=default + ) + set(XAMARIN_APP_STUB_SOURCES ${SOURCES_DIR}/application_dso_stub.cc) add_library(xamarin-app SHARED ${XAMARIN_APP_STUB_SOURCES}) if (ENABLE_NDK) diff --git a/src/monodroid/jni/cpu-arch-detect.cc b/src/monodroid/jni/cpu-arch-detect.cc index 2112e159788..e93d2daea84 100644 --- a/src/monodroid/jni/cpu-arch-detect.cc +++ b/src/monodroid/jni/cpu-arch-detect.cc @@ -225,7 +225,7 @@ get_running_on_cpu (unsigned short *running_on_cpu) *running_on_cpu = CPU_KIND_UNKNOWN; } -MONO_API void +void _monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit) { assert (built_for_cpu); diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/monodroid/jni/embedded-assemblies.cc index 4b861355eaf..5477dbc7c43 100644 --- a/src/monodroid/jni/embedded-assemblies.cc +++ b/src/monodroid/jni/embedded-assemblies.cc @@ -597,7 +597,7 @@ EmbeddedAssemblies::md_mmap_apk_file (int fd, uint32_t offset, uint32_t size, co md_mmap_info file_info; md_mmap_info mmap_info; - size_t pageSize = static_cast(monodroid_getpagesize()); + size_t pageSize = static_cast(utils.monodroid_getpagesize ()); uint32_t offsetFromPage = static_cast(offset % pageSize); uint32_t offsetPage = offset - offsetFromPage; uint32_t offsetSize = size + offsetFromPage; diff --git a/src/monodroid/jni/external-api.cc b/src/monodroid/jni/external-api.cc deleted file mode 100644 index a835d4a8ca3..00000000000 --- a/src/monodroid/jni/external-api.cc +++ /dev/null @@ -1,307 +0,0 @@ -#ifdef WINDOWS -#include -#include -#include -#include -#include -#include -#endif - -#include "globals.hh" -#include "timing.hh" - -using namespace xamarin::android; -using namespace xamarin::android::internal; - -/* Invoked by System.Core.dll!System.IO.MemoryMappedFiles.MemoryMapImpl.getpagesize */ -MONO_API int -monodroid_getpagesize (void) -{ -#ifndef WINDOWS - return getpagesize (); -#else - SYSTEM_INFO info; - GetSystemInfo (&info); - return info.dwPageSize; -#endif -} - -/* Invoked by: - - System.Core.dll!System.TimeZoneInfo.Android.GetDefaultTimeZoneName - - Mono.Android.dll!Android.Runtime.AndroidEnvironment.GetDefaultTimeZone -*/ - -MONO_API void -monodroid_free (void *ptr) -{ - free (ptr); -} - -MONO_API int -monodroid_get_system_property (const char *name, char **value) -{ - return androidSystem.monodroid_get_system_property (name, value); -} - -MONO_API int -_monodroid_max_gref_get (void) -{ - return static_cast(androidSystem.get_max_gref_count ()); -} - -MONO_API int -_monodroid_gref_get (void) -{ - return osBridge.get_gc_gref_count (); -} - -MONO_API void -_monodroid_gref_log (const char *message) -{ - osBridge._monodroid_gref_log (message); -} - -MONO_API int -_monodroid_gref_log_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) -{ - return osBridge._monodroid_gref_log_new (curHandle, curType, newHandle, newType, threadName, threadId, from, from_writable); -} - -MONO_API void -_monodroid_gref_log_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) -{ - osBridge._monodroid_gref_log_delete (handle, type, threadName, threadId, from, from_writable); -} - -MONO_API void -_monodroid_weak_gref_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) -{ - osBridge._monodroid_weak_gref_new (curHandle, curType, newHandle, newType, threadName, threadId, from, from_writable); -} - -MONO_API void -_monodroid_weak_gref_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) -{ - osBridge._monodroid_weak_gref_delete (handle, type, threadName, threadId, from, from_writable); -} - -MONO_API void -_monodroid_lref_log_new (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) -{ - osBridge._monodroid_lref_log_new (lrefc, handle, type, threadName, threadId, from, from_writable); -} - -MONO_API void -_monodroid_lref_log_delete (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) -{ - osBridge._monodroid_lref_log_delete (lrefc, handle, type, threadName, threadId, from, from_writable); -} - -MONO_API void -_monodroid_gc_wait_for_bridge_processing (void) -{ - mono_gc_wait_for_bridge_processing (); -} - -/* !DO NOT REMOVE! Used by Mono BCL */ -MONO_API int -_monodroid_get_android_api_level (void) -{ - return monodroidRuntime.get_android_api_level (); -} - -/* Can be called by a native debugger to break the wait on startup */ -MONO_API void -monodroid_clear_gdb_wait (void) -{ - monodroidRuntime.set_monodroid_gdb_wait (false); -} - -MONO_API 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); - return (void*) rv; -} - -MONO_API void* -_monodroid_timezone_get_default_id (void) -{ - 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); - jstring id = reinterpret_cast (env->CallObjectMethod (d, getID)); - const char *mutf8 = env->GetStringUTFChars (id, nullptr); - char *def_id = strdup (mutf8); - - env->ReleaseStringUTFChars (id, mutf8); - env->DeleteLocalRef (id); - env->DeleteLocalRef (d); - - return def_id; -} - -MONO_API void -_monodroid_counters_dump (const char *format, ...) -{ - va_list args; - va_start (args, format); - monodroidRuntime.dump_counters_v (format, args); - va_end (args); -} - -/* !DO NOT REMOVE! Used by libgdiplus.so */ -MONO_API int -_monodroid_get_display_dpi (float *x_dpi, float *y_dpi) -{ - return monodroidRuntime.get_display_dpi (x_dpi, y_dpi); -} - -MONO_API int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) -{ - embeddedAssemblies.set_assemblies_prefix (prefix); - return 0; -} - -MONO_API managed_timing_sequence* -monodroid_timing_start (const char *message) -{ - if (timing == nullptr) - return nullptr; - - managed_timing_sequence *ret = timing->get_available_sequence (); - if (message != nullptr) { - log_info (LOG_TIMING, message); - } - ret->period.mark_start (); - - return ret; -} - -MONO_API void -monodroid_timing_stop (managed_timing_sequence *sequence, const char *message) -{ - static constexpr const char DEFAULT_MESSAGE[] = "Managed Timing"; - - if (sequence == nullptr) - return; - - sequence->period.mark_end (); - Timing::info (sequence->period, message == nullptr ? DEFAULT_MESSAGE : message); - timing->release_sequence (sequence); -} - -MONO_API void -monodroid_strfreev (char **str_array) -{ - utils.monodroid_strfreev (str_array); -} - -MONO_API char** -monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) -{ - return utils.monodroid_strsplit (str, delimiter, max_tokens); -} - -MONO_API char* -monodroid_strdup_printf (const char *format, ...) -{ - va_list args; - - va_start (args, format); - char *ret = utils.monodroid_strdup_vprintf (format, args); - va_end (args); - - return ret; -} - -MONO_API char* -monodroid_TypeManager_get_java_class_name (jclass klass) -{ - return monodroidRuntime.get_java_class_name_for_TypeManager (klass); -} - -MONO_API void -monodroid_store_package_name (const char *name) -{ - utils.monodroid_store_package_name (name); -} - -MONO_API int -monodroid_get_namespaced_system_property (const char *name, char **value) -{ - return static_cast(androidSystem.monodroid_get_system_property (name, value)); -} - -MONO_API FILE* -monodroid_fopen (const char* filename, const char* mode) -{ - return utils.monodroid_fopen (filename, mode); -} - -MONO_API int -send_uninterrupted (int fd, void *buf, int len) -{ - if (len < 0) - len = 0; - return utils.send_uninterrupted (fd, buf, static_cast(len)); -} - -MONO_API int -recv_uninterrupted (int fd, void *buf, int len) -{ - if (len < 0) - len = 0; - return static_cast(utils.recv_uninterrupted (fd, buf, static_cast(len))); -} - -MONO_API void -set_world_accessable (const char *path) -{ - utils.set_world_accessable (path); -} - -MONO_API void -create_public_directory (const char *dir) -{ - utils.create_public_directory (dir); -} - -MONO_API char* -path_combine (const char *path1, const char *path2) -{ - return utils.path_combine (path1, path2); -} - -MONO_API void* -monodroid_dylib_mono_new ([[maybe_unused]] const char *libmono_path) -{ - return nullptr; -} - -MONO_API void -monodroid_dylib_mono_free ([[maybe_unused]] void *mono_imports) -{ - // no-op -} - -/* - this function is used from JavaInterop and should be treated as public API - https://github.com/xamarin/java.interop/blob/master/src/java-interop/java-interop-gc-bridge-mono.c#L266 - - it should also accept libmono_path = nullptr parameter -*/ -MONO_API int -monodroid_dylib_mono_init (void *mono_imports, [[maybe_unused]] const char *libmono_path) -{ - if (mono_imports == nullptr) - return FALSE; - return TRUE; -} - -MONO_API void* -monodroid_get_dylib (void) -{ - return nullptr; -} diff --git a/src/monodroid/jni/internal-pinvoke-api.cc b/src/monodroid/jni/internal-pinvoke-api.cc new file mode 100644 index 00000000000..d5218de566d --- /dev/null +++ b/src/monodroid/jni/internal-pinvoke-api.cc @@ -0,0 +1,336 @@ +#include +#include +#include + +#include "xa-internal-api.hh" + +constexpr int TRUE = 1; +constexpr int FALSE = 0; + +using namespace xamarin::android; + +static MonoAndroidInternalCalls *internal_calls = nullptr; + +MONO_API bool +_monodroid_init_internal_api (MonoAndroidInternalCalls *api) +{ + if (api == nullptr) + return false; + + delete internal_calls; + internal_calls = api; + return true; +} + +MONO_API void +_monodroid_shutdown_internal_api () +{ + if (internal_calls == nullptr) + return; + + delete internal_calls; + internal_calls = nullptr; +} + +MONO_API int +_monodroid_getifaddrs (struct _monodroid_ifaddrs **ifap) +{ + return internal_calls->monodroid_getifaddrs (ifap); +} + +MONO_API void +_monodroid_freeifaddrs (struct _monodroid_ifaddrs *ifa) +{ + internal_calls->monodroid_freeifaddrs (ifa); +} + +MONO_API void +_monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit) +{ + internal_calls->monodroid_detect_cpu_and_architecture (built_for_cpu, running_on_cpu, is64bit); +} + +// !DO NOT REMOVE! Used by Mono BCL (System.Net.NetworkInformation.NetworkInterface) +// https://github.com/mono/mono/blob/e59c1cd70f4a7171a0ff5e1f9f4937985d6a4d8d/mcs/class/System/System.Net.NetworkInformation/LinuxNetworkInterface.cs#L250-L261 +MONO_API mono_bool +_monodroid_get_network_interface_up_state (const char *ifname, mono_bool *is_up) +{ + return internal_calls->monodroid_get_network_interface_up_state (ifname, is_up); +} + +/* !DO NOT REMOVE! Used by Mono BCL (System.Net.NetworkInformation.NetworkInterface) */ +MONO_API mono_bool +_monodroid_get_network_interface_supports_multicast (const char *ifname, mono_bool *supports_multicast) +{ + return internal_calls->monodroid_get_network_interface_supports_multicast (ifname, supports_multicast); +} + +/* !DO NOT REMOVE! Used by Mono BCL (System.Net.NetworkInformation.UnixIPInterfaceProperties) */ +MONO_API int +_monodroid_get_dns_servers (void **dns_servers_array) +{ + return internal_calls->monodroid_get_dns_servers (dns_servers_array); +} + +// +// DO NOT REMOVE: used by Android.Runtime.Logger +// +MONO_API unsigned int +monodroid_get_log_categories () +{ + return internal_calls->monodroid_get_log_categories (); +} + +// +// DO NOT REMOVE: used by Android.Runtime.JNIEnv +// +MONO_API void +monodroid_log (LogLevel level, LogCategories category, const char *message) +{ + internal_calls->monodroid_log (level, category, message); +} + +/* Invoked by: + - System.Core.dll!System.TimeZoneInfo.Android.GetDefaultTimeZoneName + https://github.com/mono/mono/blob/e59c1cd70f4a7171a0ff5e1f9f4937985d6a4d8d/mcs/class/corlib/System/TimeZoneInfo.Android.cs#L569-L594 + - Mono.Android.dll!Android.Runtime.AndroidEnvironment.GetDefaultTimeZone +*/ + +MONO_API void +monodroid_free (void *ptr) +{ + free (ptr); +} + +// Used by https://github.com/mono/mono/blob/e59c1cd70f4a7171a0ff5e1f9f4937985d6a4d8d/mcs/class/corlib/System/TimeZoneInfo.Android.cs#L569-L594 +MONO_API int +monodroid_get_system_property (const char *name, char **value) +{ + return internal_calls->monodroid_get_system_property (name, value); +} + +// Used by Mono.Android.dll!Java.Interop.Runtime.MaxGlobalReferenceCount +MONO_API int +_monodroid_max_gref_get (void) +{ + return internal_calls->monodroid_max_gref_get (); +} + +// Used by Mono.Android.dll!Java.Interop.Runtime.GlobalReferenceCount +MONO_API int +_monodroid_gref_get (void) +{ + return internal_calls->monodroid_gref_get (); +} + +// Used by Mono.Android.dll!Android.Runtime.JNIEnv +MONO_API void +_monodroid_gref_log (const char *message) +{ + internal_calls->monodroid_gref_log (message); +} + +MONO_API int +_monodroid_gref_log_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) +{ + return internal_calls->monodroid_gref_log_new (curHandle, curType, newHandle, newType, threadName, threadId, from, from_writable); +} + +MONO_API void +_monodroid_gref_log_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) +{ + internal_calls->monodroid_gref_log_delete (handle, type, threadName, threadId, from, from_writable); +} + +MONO_API void +_monodroid_weak_gref_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) +{ + internal_calls->monodroid_weak_gref_new (curHandle, curType, newHandle, newType, threadName, threadId, from, from_writable); +} + +MONO_API void +_monodroid_weak_gref_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) +{ + internal_calls->monodroid_weak_gref_delete (handle, type, threadName, threadId, from, from_writable); +} + +MONO_API void +_monodroid_lref_log_new (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) +{ + internal_calls->monodroid_lref_log_new (lrefc, handle, type, threadName, threadId, from, from_writable); +} + +MONO_API void +_monodroid_lref_log_delete (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) +{ + internal_calls->monodroid_lref_log_delete (lrefc, handle, type, threadName, threadId, from, from_writable); +} + +MONO_API void +_monodroid_gc_wait_for_bridge_processing (void) +{ + internal_calls->monodroid_gc_wait_for_bridge_processing (); +} + +/* !DO NOT REMOVE! Used by Mono BCL */ +MONO_API int +_monodroid_get_android_api_level (void) +{ + return internal_calls->monodroid_get_android_api_level (); +} + +/* Can be called by a native debugger to break the wait on startup */ +MONO_API void +monodroid_clear_gdb_wait (void) +{ + internal_calls->monodroid_clear_gdb_wait (); +} + +MONO_API void* +_monodroid_get_identity_hash_code (JNIEnv *env, void *v) +{ + return internal_calls->monodroid_get_identity_hash_code (env, v); +} + +MONO_API void* +_monodroid_timezone_get_default_id (void) +{ + return internal_calls->monodroid_timezone_get_default_id (); +} + +MONO_API void +_monodroid_counters_dump (const char *format, ...) +{ + va_list args; + va_start (args, format); + internal_calls->dump_counters (format, args); + va_end (args); +} + +MONO_API int +monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) +{ + return internal_calls->monodroid_embedded_assemblies_set_assemblies_prefix (prefix); +} + +MONO_API managed_timing_sequence* +monodroid_timing_start (const char *message) +{ + return internal_calls->monodroid_timing_start (message); +} + +MONO_API void +monodroid_timing_stop (managed_timing_sequence *sequence, const char *message) +{ + internal_calls->monodroid_timing_stop (sequence, message); +} + +MONO_API void +monodroid_strfreev (char **str_array) +{ + internal_calls->monodroid_strfreev (str_array); +} + +MONO_API char** +monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) +{ + return internal_calls->monodroid_strsplit (str, delimiter, max_tokens); +} + +MONO_API char* +monodroid_strdup_printf (const char *format, ...) +{ + va_list args; + + va_start (args, format); + char *ret = internal_calls->monodroid_strdup_printf (format, args); + va_end (args); + + return ret; +} + +MONO_API char* +monodroid_TypeManager_get_java_class_name (jclass klass) +{ + return internal_calls->monodroid_TypeManager_get_java_class_name (klass); +} + +MONO_API void +monodroid_store_package_name (const char *name) +{ + internal_calls->monodroid_store_package_name (name); +} + +MONO_API int +monodroid_get_namespaced_system_property (const char *name, char **value) +{ + return internal_calls->monodroid_get_namespaced_system_property (name, value); +} + +MONO_API FILE* +monodroid_fopen (const char* filename, const char* mode) +{ + return internal_calls->monodroid_fopen (filename, mode); +} + +MONO_API int +send_uninterrupted (int fd, void *buf, int len) +{ + return internal_calls->send_uninterrupted (fd, buf, len); +} + +MONO_API int +recv_uninterrupted (int fd, void *buf, int len) +{ + return internal_calls->recv_uninterrupted (fd, buf, len); +} + +MONO_API void +set_world_accessable (const char *path) +{ + internal_calls->set_world_accessable (path); +} + +MONO_API void +create_public_directory (const char *dir) +{ + internal_calls->create_public_directory (dir); +} + +MONO_API char* +path_combine (const char *path1, const char *path2) +{ + return internal_calls->path_combine (path1, path2); +} + +MONO_API void* +monodroid_dylib_mono_new ([[maybe_unused]] const char *libmono_path) +{ + return nullptr; +} + +MONO_API void +monodroid_dylib_mono_free ([[maybe_unused]] void *mono_imports) +{ + // no-op +} + +/* + this function is used from JavaInterop and should be treated as public API + https://github.com/xamarin/java.interop/blob/master/src/java-interop/java-interop-gc-bridge-mono.c#L266 + + it should also accept libmono_path = nullptr parameter +*/ +MONO_API int +monodroid_dylib_mono_init (void *mono_imports, [[maybe_unused]] const char *libmono_path) +{ + if (mono_imports == nullptr) + return FALSE; + return TRUE; +} + +MONO_API void* +monodroid_get_dylib (void) +{ + return nullptr; +} diff --git a/src/monodroid/jni/logger.cc b/src/monodroid/jni/logger.cc index c027d74d3d4..1742de28c80 100644 --- a/src/monodroid/jni/logger.cc +++ b/src/monodroid/jni/logger.cc @@ -41,20 +41,6 @@ static const char* log_names[] = { "*error*", }; -// Keep in sync with LogLevel defined in JNIEnv.cs -enum class LogLevel : unsigned int -{ - Unknown = 0x00, - Default = 0x01, - Verbose = 0x02, - Debug = 0x03, - Info = 0x04, - Warn = 0x05, - Error = 0x06, - Fatal = 0x07, - Silent = 0x08 -}; - #if defined(__i386__) && defined(__GNUC__) #define ffs(__value__) __builtin_ffs ((__value__)) #elif defined(__x86_64__) && defined(__GNUC__) @@ -145,7 +131,7 @@ init_logging_categories () log_categories = LOG_DEFAULT; #endif log_timing_categories = LOG_TIMING_DEFAULT; - if (monodroid_get_namespaced_system_property (Debug::DEBUG_MONO_LOG_PROPERTY, &value) == 0) + if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_LOG_PROPERTY, &value) == 0) return; args = utils.monodroid_strsplit (value, ",", 0); @@ -253,49 +239,3 @@ log_debug_nocheck (LogCategories category, const char *format, ...) DO_LOG (ANDROID_LOG_DEBUG, category, format, args); } - -// -// DO NOT REMOVE: used by Android.Runtime.Logger -// -MONO_API unsigned int -monodroid_get_log_categories () -{ - return log_categories; -} - -// -// DO NOT REMOVE: used by Android.Runtime.JNIEnv -// -MONO_API void -monodroid_log (LogLevel level, LogCategories category, const char *message) -{ - switch (level) { - case LogLevel::Verbose: - case LogLevel::Debug: - log_debug_nocheck (category, message); - break; - - case LogLevel::Info: - log_info_nocheck (category, message); - break; - - case LogLevel::Warn: - case LogLevel::Silent: // warn is always printed - log_warn (category, message); - break; - - case LogLevel::Error: - log_error (category, message); - break; - - case LogLevel::Fatal: - log_fatal (category, message); - break; - - default: - case LogLevel::Unknown: - case LogLevel::Default: - log_info_nocheck (category, message); - break; - } -} diff --git a/src/monodroid/jni/logger.hh b/src/monodroid/jni/logger.hh index 75ee3f4a705..8691ab04750 100644 --- a/src/monodroid/jni/logger.hh +++ b/src/monodroid/jni/logger.hh @@ -32,4 +32,17 @@ extern unsigned int log_timing_categories; extern int gc_spew_enabled; #endif +// Keep in sync with LogLevel defined in JNIEnv.cs +enum class LogLevel : unsigned int +{ + Unknown = 0x00, + Default = 0x01, + Verbose = 0x02, + Debug = 0x03, + Info = 0x04, + Warn = 0x05, + Error = 0x06, + Fatal = 0x07, + Silent = 0x08 +}; #endif diff --git a/src/monodroid/jni/monodroid-glue-internal.hh b/src/monodroid/jni/monodroid-glue-internal.hh index 0ca8a35f271..116f1bfa717 100644 --- a/src/monodroid/jni/monodroid-glue-internal.hh +++ b/src/monodroid/jni/monodroid-glue-internal.hh @@ -61,7 +61,14 @@ namespace xamarin::android::internal #else true; #endif - +#define MAKE_API_DSO_NAME(_ext_) "libxa-internal-api." # _ext_ +#if defined (WINDOWS) + static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (dll); +#elif defined (APPLE_OS_X) + static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (dylib); +#else + static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (so); +#endif public: static constexpr int XA_LOG_COUNTERS = MONO_COUNTER_JIT | MONO_COUNTER_METADATA | MONO_COUNTER_GC | MONO_COUNTER_GENERICS | MONO_COUNTER_INTERP; @@ -131,9 +138,13 @@ namespace xamarin::android::internal private: int convert_dl_flags (int flags); +#if defined (WINDOWS) || defined (APPLE_OS_X) + static const char* get_my_location (); +#endif static void* monodroid_dlopen (const char *name, int flags, char **err, void *user_data); static void* monodroid_dlsym (void *handle, const char *name, char **err, void *user_data); - static void* monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory); + static void* monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory, bool need_api_init = false); + static void init_internal_api_dso (void *handle); int LocalRefsAreIndirect (JNIEnv *env, jclass runtimeClass, int version); void create_xdg_directory (jstring_wrapper& home, const char *relativePath, const char *environmentVariableName); void create_xdg_directories_and_environment (jstring_wrapper &homeDir); @@ -218,6 +229,9 @@ namespace xamarin::android::internal * able to switch our different contexts from different threads. */ int current_context_id = -1; + + static std::mutex api_init_lock; + static void *api_dso_handle; }; } #endif diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc index 181f9d0b36a..659b19d832c 100644 --- a/src/monodroid/jni/monodroid-glue.cc +++ b/src/monodroid/jni/monodroid-glue.cc @@ -40,6 +40,10 @@ #include #endif +#if defined (APPLE_OS_X) +#include +#endif + #ifndef WINDOWS #include #include @@ -70,6 +74,7 @@ #include "globals.hh" #include "xamarin-app.hh" #include "timing.hh" +#include "xa-internal-api-impl.hh" #ifndef WINDOWS #include "xamarin_getifaddrs.h" @@ -87,6 +92,9 @@ using namespace xamarin::android::internal; #include "config.include" #include "machine.config.include" +std::mutex MonodroidRuntime::api_init_lock; +void *MonodroidRuntime::api_dso_handle = nullptr; + #ifdef WINDOWS static const char* get_xamarin_android_msbuild_path (void); const char *BasicAndroidSystem::SYSTEM_LIB_PATH = get_xamarin_android_msbuild_path(); @@ -1056,7 +1064,7 @@ setup_gc_logging (void) } #endif -inline int +force_inline int MonodroidRuntime::convert_dl_flags (int flags) { int lflags = flags & static_cast (MONO_DL_LOCAL) ? 0: RTLD_GLOBAL; @@ -1068,8 +1076,56 @@ MonodroidRuntime::convert_dl_flags (int flags) return lflags; } -inline void* -MonodroidRuntime::monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory) +force_inline void +MonodroidRuntime::init_internal_api_dso (void *handle) +{ + if (handle == nullptr) { + log_fatal (LOG_DEFAULT, "Internal API library is required"); + exit (FATAL_EXIT_MONO_MISSING_SYMBOLS); + } + + // There's a very, very small chance of a race condition here, but it should be acceptable and we can save some time + // by not acquiring the lock on Android systems which don't have the dlopen bug we worked around in + // https://github.com/xamarin/xamarin-android/pull/4914 + // + // The race condition will exist only on systems with the above dynamic loader bug and would become a problem only + // if an application were loading managed assemblies with p/invokes very quickly from different threads. All in all, + // not a very likely scenario. + // + if (handle == api_dso_handle) { + log_debug (LOG_DEFAULT, "Internal API library already loaded, initialization not necessary"); + return; + } + + std::lock_guard lock (api_init_lock); + if (api_dso_handle != nullptr) { + auto api_shutdown = reinterpret_cast (dlsym (api_dso_handle, MonoAndroidInternalCalls::SHUTDOWN_FUNCTION_NAME)); + if (api_shutdown == nullptr) { + // We COULD ignore this situation, but if the function is missing it means we messed something up and thus + // it *is* a fatal error. + log_fatal (LOG_DEFAULT, "Unable to properly close Internal API library, shutdown function '%s' not found in the module", MonoAndroidInternalCalls::SHUTDOWN_FUNCTION_NAME); + exit (FATAL_EXIT_MONO_MISSING_SYMBOLS); + } + api_shutdown (); + } + + api_dso_handle = handle; + auto api = new MonoAndroidInternalCalls_Impl (); + auto api_init = reinterpret_cast(dlsym (handle, MonoAndroidInternalCalls::INIT_FUNCTION_NAME)); + if (api_init == nullptr) { + log_fatal (LOG_DEFAULT, "Unable to initialize Internal API library, init function '%s' not found in the module", MonoAndroidInternalCalls::INIT_FUNCTION_NAME); + exit (FATAL_EXIT_MONO_MISSING_SYMBOLS); + } + + log_debug (LOG_DEFAULT, "Initializing Internal API library %p", handle); + if (!api_init (api)) { + log_fatal (LOG_DEFAULT, "Failed to initialize Internal API library"); + exit (FATAL_EXIT_MONO_MISSING_SYMBOLS); + } +} + +force_inline void* +MonodroidRuntime::monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory, bool need_api_init) { if (handle == nullptr && err != nullptr) { *err = utils.monodroid_strdup_printf ("Could not load library: Library '%s' not found.", full_name); @@ -1079,6 +1135,11 @@ MonodroidRuntime::monodroid_dlopen_log_and_return (void *handle, char **err, con delete[] full_name; } + if (!need_api_init) + return handle; + + init_internal_api_dso (handle); + return handle; } @@ -1088,21 +1149,22 @@ MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err, [[m int dl_flags = monodroidRuntime.convert_dl_flags (flags); bool libmonodroid_fallback = false; - /* name is nullptr when we're P/Invoking __Internal, so remap to libmonodroid */ + /* name is nullptr when we're P/Invoking __Internal, so remap to libxa-internal-api */ if (name == nullptr) { - name = "libmonodroid.so"; - libmonodroid_fallback = TRUE; + name = API_DSO_NAME; + libmonodroid_fallback = true; } void *h = androidSystem.load_dso_from_any_directories (name, dl_flags); + if (h != nullptr) { - return monodroid_dlopen_log_and_return (h, err, name, false); + return monodroid_dlopen_log_and_return (h, err, name, false, libmonodroid_fallback); } if (libmonodroid_fallback) { - char *full_name = utils.path_combine (AndroidSystem::SYSTEM_LIB_PATH, "libmonodroid.so"); + char *full_name = utils.path_combine (AndroidSystem::SYSTEM_LIB_PATH, API_DSO_NAME); h = androidSystem.load_dso (full_name, dl_flags, false); - return monodroid_dlopen_log_and_return (h, err, full_name, true); + return monodroid_dlopen_log_and_return (h, err, full_name, true, true); } if (!utils.ends_with (name, ".dll.so") && !utils.ends_with (name, ".exe.so")) { @@ -1418,6 +1480,44 @@ MonodroidRuntime::typemap_managed_to_java (MonoReflectionType *type, const uint8 return embeddedAssemblies.typemap_managed_to_java (type, mvid); } +#if defined (WINDOWS) +const char* +MonodroidRuntime::get_my_location () +{ + HMODULE hm = NULL; + + DWORD handle_flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; + if (GetModuleHandleExW (handle_flags, (LPCWSTR) &get_xamarin_android_msbuild_path, &hm) == 0) { + int ret = GetLastError (); + log_warn (LOG_DEFAULT, "Unable to get HANDLE to `libmono-android.debug.dll`; GetModuleHandleExW returned %d\n", ret); + return nullptr; + } + + WCHAR path[MAX_PATH * 2]; + if (GetModuleFileNameW (hm, path, sizeof(path)) == 0) { + int ret = GetLastError (); + log_warn (LOG_DEFAULT, "Unable to get filename to `libmono-android.debug.dll`; GetModuleFileNameW returned %d\n", ret); + return nullptr; + } + + PathRemoveFileSpecW (path); + + return utils.utf16_to_utf8 (path); +} +#elif defined (APPLE_OS_X) +const char* +MonodroidRuntime::get_my_location () +{ + Dl_info info; + if (dladdr (reinterpret_cast(&MonodroidRuntime::get_my_location), &info) == 0) { + log_warn (LOG_DEFAULT, "Could not lookup library containing `MonodroidRuntime::get_my_location()`; dladdr failed: %s", dlerror ()); + return nullptr; + } + + return utils.strdup_new (dirname (const_cast(info.dli_fname))); +} +#endif + inline void MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader, @@ -1498,6 +1598,29 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl utils.set_world_accessable (counters_path); } + void *api_dso_handle = nullptr; +#if defined (WINDOWS) || defined (APPLE_OS_X) + const char *my_location = get_my_location (); + if (my_location != nullptr) { + simple_pointer_guard dso_path (utils.path_combine (my_location, API_DSO_NAME)); + log_info (LOG_DEFAULT, "Attempting to load %s", dso_path.get ()); + api_dso_handle = dlopen (dso_path.get (), RTLD_NOW); +#if defined (APPLE_OS_X) + delete[] my_location; +#else + free (static_cast(const_cast(my_location))); // JI allocates with `calloc` +#endif + } + + if (api_dso_handle == nullptr) { + log_info (LOG_DEFAULT, "Attempting to load %s with \"bare\" dlopen", API_DSO_NAME); + api_dso_handle = dlopen (API_DSO_NAME, RTLD_NOW); + } +#endif + if (api_dso_handle == nullptr) + api_dso_handle = androidSystem.load_dso_from_any_directories (API_DSO_NAME, RTLD_NOW); + init_internal_api_dso (api_dso_handle); + mono_dl_fallback_register (monodroid_dlopen, monodroid_dlsym, nullptr, nullptr); set_profile_options (); diff --git a/src/monodroid/jni/monodroid-networkinfo.cc b/src/monodroid/jni/monodroid-networkinfo.cc index 9053aae8045..704cf425203 100644 --- a/src/monodroid/jni/monodroid-networkinfo.cc +++ b/src/monodroid/jni/monodroid-networkinfo.cc @@ -126,22 +126,19 @@ _monodroid_get_network_interface_state (const char *ifname, mono_bool *is_up, mo return ret; } -/* !DO NOT REMOVE! Used by Mono BCL (System.Net.NetworkInformation.NetworkInterface) */ -MONO_API mono_bool +mono_bool _monodroid_get_network_interface_up_state (const char *ifname, mono_bool *is_up) { return _monodroid_get_network_interface_state (ifname, is_up, nullptr); } -/* !DO NOT REMOVE! Used by Mono BCL (System.Net.NetworkInformation.NetworkInterface) */ -MONO_API mono_bool +mono_bool _monodroid_get_network_interface_supports_multicast (const char *ifname, mono_bool *supports_multicast) { return _monodroid_get_network_interface_state (ifname, nullptr, supports_multicast); } -/* !DO NOT REMOVE! Used by Mono BCL (System.Net.NetworkInformation.UnixIPInterfaceProperties) */ -MONO_API int +int _monodroid_get_dns_servers (void **dns_servers_array) { if (!dns_servers_array) { @@ -157,7 +154,7 @@ _monodroid_get_dns_servers (void **dns_servers_array) char prop_name[] = "net.dnsX"; for (int i = 0; i < 8; i++) { prop_name [7] = (char)(i + 0x31); - len = static_cast(monodroid_get_system_property (prop_name, &dns)); + len = static_cast(androidSystem.monodroid_get_system_property (prop_name, &dns)); if (len == 0) { dns_servers [i] = nullptr; continue; diff --git a/src/monodroid/jni/util.cc b/src/monodroid/jni/util.cc index 98dc0b0d1e5..8fe1c886b9b 100644 --- a/src/monodroid/jni/util.cc +++ b/src/monodroid/jni/util.cc @@ -311,3 +311,15 @@ Util::get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *nam return reinterpret_cast (make_gref ? osBridge.lref_to_gref (env, field) : field); } + +int +Util::monodroid_getpagesize (void) +{ +#ifndef WINDOWS + return getpagesize (); +#else + SYSTEM_INFO info; + GetSystemInfo (&info); + return info.dwPageSize; +#endif +} diff --git a/src/monodroid/jni/util.hh b/src/monodroid/jni/util.hh index 20077fb239b..80bc187dbf7 100644 --- a/src/monodroid/jni/util.hh +++ b/src/monodroid/jni/util.hh @@ -74,6 +74,7 @@ namespace xamarin::android static constexpr uint32_t ms_in_nsec = 1000000ULL; public: + int monodroid_getpagesize (); void monodroid_store_package_name (const char *name); MonoAssembly *monodroid_load_assembly (MonoDomain *domain, const char *basename); MonoObject *monodroid_runtime_invoke (MonoDomain *domain, MonoMethod *method, void *obj, void **params, MonoObject **exc); diff --git a/src/monodroid/jni/xa-internal-api-impl.hh b/src/monodroid/jni/xa-internal-api-impl.hh new file mode 100644 index 00000000000..7fdae521174 --- /dev/null +++ b/src/monodroid/jni/xa-internal-api-impl.hh @@ -0,0 +1,53 @@ +// Dear Emacs, this is a -*- C++ -*- header +#ifndef __XA_INTERNAL_API_IMPL_HH +#define __XA_INTERNAL_API_IMPL_HH + +#include "xa-internal-api.hh" + +namespace xamarin::android::internal +{ + class MonoAndroidInternalCalls_Impl final : public MonoAndroidInternalCalls + { + public: + virtual mono_bool monodroid_get_network_interface_up_state (const char *ifname, mono_bool *is_up) final override; + virtual mono_bool monodroid_get_network_interface_supports_multicast (const char *ifname, mono_bool *supports_multicast) final override; + virtual int monodroid_get_dns_servers (void **dns_servers_array) final override; + virtual int monodroid_getifaddrs (_monodroid_ifaddrs **ifap) final override; + virtual void monodroid_freeifaddrs (_monodroid_ifaddrs *ifa) final override; + virtual void monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit) final override; + virtual unsigned int monodroid_get_log_categories () final override; + virtual void monodroid_log (LogLevel level, LogCategories category, const char *message) final override; + virtual int monodroid_get_system_property (const char *name, char **value) final override; + virtual int monodroid_max_gref_get () final override; + virtual int monodroid_gref_get () final override; + virtual void monodroid_gref_log (const char *message) final override; + virtual int monodroid_gref_log_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) final override; + virtual void monodroid_gref_log_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) final override; + virtual void monodroid_weak_gref_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) final override; + virtual void monodroid_weak_gref_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) final override; + virtual void monodroid_lref_log_new (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) final override; + virtual void monodroid_lref_log_delete (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) final override; + virtual void monodroid_gc_wait_for_bridge_processing () final override; + virtual int monodroid_get_android_api_level () final override; + virtual void monodroid_clear_gdb_wait () final override; + virtual void* monodroid_get_identity_hash_code (JNIEnv *env, void *v) final override; + virtual void* monodroid_timezone_get_default_id () final override; + virtual void dump_counters (const char *format, va_list args) final override; + virtual int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) final override; + virtual managed_timing_sequence* monodroid_timing_start (const char *message) final override; + virtual void monodroid_timing_stop (managed_timing_sequence *sequence, const char *message) final override; + virtual void monodroid_strfreev (char **str_array) final override; + virtual char** monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) final override; + virtual char* monodroid_strdup_printf (const char *format, va_list args) final override; + virtual char* monodroid_TypeManager_get_java_class_name (jclass klass) final override; + virtual void monodroid_store_package_name (const char *name) final override; + virtual int monodroid_get_namespaced_system_property (const char *name, char **value) final override; + virtual FILE* monodroid_fopen (const char* filename, const char* mode) final override; + virtual int send_uninterrupted (int fd, void *buf, int len) final override; + virtual int recv_uninterrupted (int fd, void *buf, int len) final override; + virtual void set_world_accessable (const char *path) final override; + virtual void create_public_directory (const char *dir) final override; + virtual char* path_combine (const char *path1, const char *path2) final override; + }; +} +#endif // __XA_INTERNAL_API_IMPL_HH diff --git a/src/monodroid/jni/xa-internal-api.cc b/src/monodroid/jni/xa-internal-api.cc new file mode 100644 index 00000000000..d2714535119 --- /dev/null +++ b/src/monodroid/jni/xa-internal-api.cc @@ -0,0 +1,335 @@ +#ifdef WINDOWS +#include +#include +#include +#include +#include +#include +#endif + +#include "globals.hh" +#include "xa-internal-api-impl.hh" + +using namespace xamarin::android; +using namespace xamarin::android::internal; + +void _monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit); +mono_bool _monodroid_get_network_interface_up_state (const char *ifname, mono_bool *is_up); +mono_bool _monodroid_get_network_interface_supports_multicast (const char *ifname, mono_bool *supports_multicast); +int _monodroid_get_dns_servers (void **dns_servers_array); +int _monodroid_getifaddrs (struct _monodroid_ifaddrs **ifap); +void _monodroid_freeifaddrs (struct _monodroid_ifaddrs *ifa); + +mono_bool +MonoAndroidInternalCalls_Impl::monodroid_get_network_interface_up_state (const char *ifname, mono_bool *is_up) +{ +#ifdef WINDOWS + return FALSE; +#else + return ::_monodroid_get_network_interface_up_state (ifname, is_up); +#endif +} + +mono_bool +MonoAndroidInternalCalls_Impl::monodroid_get_network_interface_supports_multicast (const char *ifname, mono_bool *supports_multicast) +{ +#ifdef WINDOWS + return FALSE; +#else + return ::_monodroid_get_network_interface_supports_multicast (ifname, supports_multicast); +#endif +} + +int +MonoAndroidInternalCalls_Impl::monodroid_get_dns_servers (void **dns_servers_array) +{ +#ifdef WINDOWS + return FALSE; +#else + return ::_monodroid_get_dns_servers (dns_servers_array); +#endif +} + +int +MonoAndroidInternalCalls_Impl::monodroid_getifaddrs (struct _monodroid_ifaddrs **ifap) +{ +#ifdef WINDOWS + return -1; +#else + return ::_monodroid_getifaddrs (ifap); +#endif +} + +void +MonoAndroidInternalCalls_Impl::monodroid_freeifaddrs (struct _monodroid_ifaddrs *ifa) +{ +#ifndef WINDOWS + ::_monodroid_freeifaddrs (ifa); +#endif +} + +void +MonoAndroidInternalCalls_Impl::monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit) +{ + ::_monodroid_detect_cpu_and_architecture (built_for_cpu, running_on_cpu, is64bit); +} + +unsigned int +MonoAndroidInternalCalls_Impl::monodroid_get_log_categories () +{ + return log_categories; +} + +void +MonoAndroidInternalCalls_Impl::monodroid_log (LogLevel level, LogCategories category, const char *message) +{ + switch (level) { + case LogLevel::Verbose: + case LogLevel::Debug: + log_debug_nocheck (category, message); + break; + + case LogLevel::Info: + log_info_nocheck (category, message); + break; + + case LogLevel::Warn: + case LogLevel::Silent: // warn is always printed + log_warn (category, message); + break; + + case LogLevel::Error: + log_error (category, message); + break; + + case LogLevel::Fatal: + log_fatal (category, message); + break; + + default: + case LogLevel::Unknown: + case LogLevel::Default: + log_info_nocheck (category, message); + break; + } +} + +int +MonoAndroidInternalCalls_Impl::monodroid_get_system_property (const char *name, char **value) +{ + return androidSystem.monodroid_get_system_property (name, value); +} + +int +MonoAndroidInternalCalls_Impl::monodroid_max_gref_get () +{ + return static_cast(androidSystem.get_max_gref_count ()); +} + +int +MonoAndroidInternalCalls_Impl::monodroid_gref_get () +{ + return osBridge.get_gc_gref_count (); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_gref_log (const char *message) +{ + osBridge._monodroid_gref_log (message); +} + +int +MonoAndroidInternalCalls_Impl::monodroid_gref_log_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) +{ + return osBridge._monodroid_gref_log_new (curHandle, curType, newHandle, newType, threadName, threadId, from, from_writable); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_gref_log_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) +{ + osBridge._monodroid_gref_log_delete (handle, type, threadName, threadId, from, from_writable); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_weak_gref_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) +{ + osBridge._monodroid_weak_gref_new (curHandle, curType, newHandle, newType, threadName, threadId, from, from_writable); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_weak_gref_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) +{ + osBridge._monodroid_weak_gref_delete (handle, type, threadName, threadId, from, from_writable); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_lref_log_new (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) +{ + osBridge._monodroid_lref_log_new (lrefc, handle, type, threadName, threadId, from, from_writable); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_lref_log_delete (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) +{ + osBridge._monodroid_lref_log_delete (lrefc, handle, type, threadName, threadId, from, from_writable); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_gc_wait_for_bridge_processing () +{ + mono_gc_wait_for_bridge_processing (); +} + +int +MonoAndroidInternalCalls_Impl::monodroid_get_android_api_level () +{ + return monodroidRuntime.get_android_api_level (); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_clear_gdb_wait () +{ + monodroidRuntime.set_monodroid_gdb_wait (false); +} + +void* +MonoAndroidInternalCalls_Impl::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); + return (void*) rv; +} + +void* +MonoAndroidInternalCalls_Impl::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); + jstring id = reinterpret_cast (env->CallObjectMethod (d, getID)); + const char *mutf8 = env->GetStringUTFChars (id, nullptr); + char *def_id = strdup (mutf8); + + env->ReleaseStringUTFChars (id, mutf8); + env->DeleteLocalRef (id); + env->DeleteLocalRef (d); + + return def_id; +} + +void +MonoAndroidInternalCalls_Impl::dump_counters (const char *format, va_list args) +{ + monodroidRuntime.dump_counters_v (format, args); +} + +int +MonoAndroidInternalCalls_Impl::monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) +{ + embeddedAssemblies.set_assemblies_prefix (prefix); + return 0; +} + +managed_timing_sequence* +MonoAndroidInternalCalls_Impl::monodroid_timing_start (const char *message) +{ + if (timing == nullptr) + return nullptr; + + managed_timing_sequence *ret = timing->get_available_sequence (); + if (message != nullptr) { + log_info (LOG_TIMING, message); + } + ret->period.mark_start (); + + return ret; +} + +void +MonoAndroidInternalCalls_Impl::monodroid_timing_stop (managed_timing_sequence *sequence, const char *message) +{ + static constexpr const char DEFAULT_MESSAGE[] = "Managed Timing"; + + if (sequence == nullptr) + return; + + sequence->period.mark_end (); + Timing::info (sequence->period, message == nullptr ? DEFAULT_MESSAGE : message); + timing->release_sequence (sequence); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_strfreev (char **str_array) +{ + utils.monodroid_strfreev (str_array); +} + +char** +MonoAndroidInternalCalls_Impl::monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) +{ + return utils.monodroid_strsplit (str, delimiter, max_tokens); +} + +char* +MonoAndroidInternalCalls_Impl::monodroid_strdup_printf (const char *format, va_list args) +{ + return utils.monodroid_strdup_vprintf (format, args); +} + +char* +MonoAndroidInternalCalls_Impl::monodroid_TypeManager_get_java_class_name (jclass klass) +{ + return monodroidRuntime.get_java_class_name_for_TypeManager (klass); +} + +void +MonoAndroidInternalCalls_Impl::monodroid_store_package_name (const char *name) +{ + utils.monodroid_store_package_name (name); +} + +int +MonoAndroidInternalCalls_Impl::monodroid_get_namespaced_system_property (const char *name, char **value) +{ + return static_cast(androidSystem.monodroid_get_system_property (name, value)); +} + +FILE* +MonoAndroidInternalCalls_Impl::monodroid_fopen (const char* filename, const char* mode) +{ + return utils.monodroid_fopen (filename, mode); +} + +int +MonoAndroidInternalCalls_Impl::send_uninterrupted (int fd, void *buf, int len) +{ + if (len < 0) + len = 0; + return utils.send_uninterrupted (fd, buf, static_cast(len)); +} + +int +MonoAndroidInternalCalls_Impl::recv_uninterrupted (int fd, void *buf, int len) +{ + if (len < 0) + len = 0; + return static_cast(utils.recv_uninterrupted (fd, buf, static_cast(len))); +} + +void +MonoAndroidInternalCalls_Impl::set_world_accessable (const char *path) +{ + utils.set_world_accessable (path); +} + +void +MonoAndroidInternalCalls_Impl::create_public_directory (const char *dir) +{ + utils.create_public_directory (dir); +} + +char* +MonoAndroidInternalCalls_Impl::path_combine (const char *path1, const char *path2) +{ + return utils.path_combine (path1, path2); +} diff --git a/src/monodroid/jni/xa-internal-api.hh b/src/monodroid/jni/xa-internal-api.hh new file mode 100644 index 00000000000..7f2c99dcb3f --- /dev/null +++ b/src/monodroid/jni/xa-internal-api.hh @@ -0,0 +1,71 @@ +// Dear Emacs, this is a -*- C++ -*- header +#ifndef __XA_INTERNAL_API_HH +#define __XA_INTERNAL_API_HH + +#include +#include +#include + +#include "monodroid.h" +#include "logger.hh" +#include "timing.hh" +#include "xamarin_getifaddrs.h" + +namespace xamarin::android +{ + class MonoAndroidInternalCalls + { + public: + static constexpr char INIT_FUNCTION_NAME[] = "_monodroid_init_internal_api"; + static constexpr char SHUTDOWN_FUNCTION_NAME[] = "_monodroid_shutdown_internal_api"; + + // To shush compiler warnings + virtual ~MonoAndroidInternalCalls () + {} + + public: + virtual mono_bool monodroid_get_network_interface_up_state (const char *ifname, mono_bool *is_up) = 0; + virtual mono_bool monodroid_get_network_interface_supports_multicast (const char *ifname, mono_bool *supports_multicast) = 0; + virtual int monodroid_get_dns_servers (void **dns_servers_array) = 0; + virtual int monodroid_getifaddrs (_monodroid_ifaddrs **ifap) = 0; + virtual void monodroid_freeifaddrs (_monodroid_ifaddrs *ifa) = 0; + virtual void monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit) = 0; + virtual unsigned int monodroid_get_log_categories () = 0; + virtual void monodroid_log (LogLevel level, LogCategories category, const char *message) = 0; + virtual int monodroid_get_system_property (const char *name, char **value) = 0; + virtual int monodroid_max_gref_get () = 0; + virtual int monodroid_gref_get () = 0; + virtual void monodroid_gref_log (const char *message) = 0; + virtual int monodroid_gref_log_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) = 0; + virtual void monodroid_gref_log_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) = 0; + virtual void monodroid_weak_gref_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) = 0; + virtual void monodroid_weak_gref_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) = 0; + virtual void monodroid_lref_log_new (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) = 0; + virtual void monodroid_lref_log_delete (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) = 0; + virtual void monodroid_gc_wait_for_bridge_processing () = 0; + virtual int monodroid_get_android_api_level () = 0; + virtual void monodroid_clear_gdb_wait () = 0; + virtual void* monodroid_get_identity_hash_code (JNIEnv *env, void *v) = 0; + virtual void* monodroid_timezone_get_default_id () = 0; + virtual void dump_counters (const char *format, va_list args) = 0; + virtual int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) = 0; + virtual managed_timing_sequence* monodroid_timing_start (const char *message) = 0; + virtual void monodroid_timing_stop (managed_timing_sequence *sequence, const char *message) = 0; + virtual void monodroid_strfreev (char **str_array) = 0; + virtual char** monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) = 0; + virtual char* monodroid_strdup_printf (const char *format, va_list args) = 0; + virtual char* monodroid_TypeManager_get_java_class_name (jclass klass) = 0; + virtual void monodroid_store_package_name (const char *name) = 0; + virtual int monodroid_get_namespaced_system_property (const char *name, char **value) = 0; + virtual FILE* monodroid_fopen (const char* filename, const char* mode) = 0; + virtual int send_uninterrupted (int fd, void *buf, int len) = 0; + virtual int recv_uninterrupted (int fd, void *buf, int len) = 0; + virtual void set_world_accessable (const char *path) = 0; + virtual void create_public_directory (const char *dir) = 0; + virtual char* path_combine (const char *path1, const char *path2) = 0; + }; + + typedef bool (*external_api_init_fn) (MonoAndroidInternalCalls *api); + typedef void (*external_api_shutdown_fn) (); +} +#endif // __XA_INTERNAL_API_HH diff --git a/src/monodroid/jni/xamarin_getifaddrs.h b/src/monodroid/jni/xamarin_getifaddrs.h index 940a12b46e6..a916d7a7999 100644 --- a/src/monodroid/jni/xamarin_getifaddrs.h +++ b/src/monodroid/jni/xamarin_getifaddrs.h @@ -1,4 +1,5 @@ #ifndef __XAMARIN_GETIFADDRS_H +#define __XAMARIN_GETIFADDRS_H #include "monodroid.h" From 3bb113205bceccc6976b834b103dbf910179bd7f Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 30 Jul 2020 13:00:01 -0400 Subject: [PATCH 2/7] Fix whitespace --- build-tools/installers/create-installers.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/installers/create-installers.targets b/build-tools/installers/create-installers.targets index 680509fe76e..e5abae9efd3 100644 --- a/build-tools/installers/create-installers.targets +++ b/build-tools/installers/create-installers.targets @@ -335,7 +335,7 @@ <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\lib\host-$(HostOS)\libMonoPosixHelper.$(LibExtension)" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\lib\host-$(HostOS)\libmonosgen-2.0.$(LibExtension)" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\lib\host-$(HostOS)\libxamarin-app.$(LibExtension)" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> - <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\lib\host-$(HostOS)\libxa-internal-api.$(LibExtension)" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> + <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\lib\host-$(HostOS)\libxa-internal-api.$(LibExtension)" Condition=" '$(PackageId)' != 'Microsoft.Android.Sdk' " /> <_MSBuildFilesUnixSign Include="$(MSBuildSrcDir)\libzip.$(LibExtension)" /> <_MSBuildFilesUnix Include="$(MSBuildSrcDir)\proguard\bin\proguard.sh" /> From df747b5774db369b587572e9e3fb360c07645612 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 30 Jul 2020 13:11:25 -0400 Subject: [PATCH 3/7] Add comments to #if --- src/monodroid/jni/util.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/monodroid/jni/util.cc b/src/monodroid/jni/util.cc index 8fe1c886b9b..9ccbbbd392b 100644 --- a/src/monodroid/jni/util.cc +++ b/src/monodroid/jni/util.cc @@ -317,9 +317,9 @@ Util::monodroid_getpagesize (void) { #ifndef WINDOWS return getpagesize (); -#else +#else // defined(WINDOWS) SYSTEM_INFO info; GetSystemInfo (&info); return info.dwPageSize; -#endif +#endif // defined(WINDOWS) } From e7eb434dba27aade862e07d10ac09ab9feaea4c9 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 30 Jul 2020 13:12:52 -0400 Subject: [PATCH 4/7] Add comments to #if --- src/monodroid/jni/xa-internal-api.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/monodroid/jni/xa-internal-api.cc b/src/monodroid/jni/xa-internal-api.cc index d2714535119..f05084a13ea 100644 --- a/src/monodroid/jni/xa-internal-api.cc +++ b/src/monodroid/jni/xa-internal-api.cc @@ -25,9 +25,9 @@ MonoAndroidInternalCalls_Impl::monodroid_get_network_interface_up_state (const c { #ifdef WINDOWS return FALSE; -#else +#else // !defined(WINDOWS) return ::_monodroid_get_network_interface_up_state (ifname, is_up); -#endif +#endif // defined(WINDOWS) } mono_bool @@ -35,9 +35,9 @@ MonoAndroidInternalCalls_Impl::monodroid_get_network_interface_supports_multicas { #ifdef WINDOWS return FALSE; -#else +#else // !defined(WINDOWS) return ::_monodroid_get_network_interface_supports_multicast (ifname, supports_multicast); -#endif +#endif // defined(WINDOWS) } int @@ -45,9 +45,9 @@ MonoAndroidInternalCalls_Impl::monodroid_get_dns_servers (void **dns_servers_arr { #ifdef WINDOWS return FALSE; -#else +#else // !defined(WINDOWS) return ::_monodroid_get_dns_servers (dns_servers_array); -#endif +#endif // defined(WINDOWS) } int @@ -55,9 +55,9 @@ MonoAndroidInternalCalls_Impl::monodroid_getifaddrs (struct _monodroid_ifaddrs * { #ifdef WINDOWS return -1; -#else +#else // !defined(WINDOWS) return ::_monodroid_getifaddrs (ifap); -#endif +#endif // defined(WINDOWS) } void @@ -65,7 +65,7 @@ MonoAndroidInternalCalls_Impl::monodroid_freeifaddrs (struct _monodroid_ifaddrs { #ifndef WINDOWS ::_monodroid_freeifaddrs (ifa); -#endif +#endif // defined(WINDOWS) } void From 4c99c4bf6519a189956f40f0eac9311f9e4aad60 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 30 Jul 2020 13:16:13 -0400 Subject: [PATCH 5/7] Add comments to #if --- src/monodroid/jni/monodroid-glue-internal.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/monodroid/jni/monodroid-glue-internal.hh b/src/monodroid/jni/monodroid-glue-internal.hh index 116f1bfa717..9b92ea55382 100644 --- a/src/monodroid/jni/monodroid-glue-internal.hh +++ b/src/monodroid/jni/monodroid-glue-internal.hh @@ -66,9 +66,9 @@ namespace xamarin::android::internal static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (dll); #elif defined (APPLE_OS_X) static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (dylib); -#else +#else // !defined(WINDOWS) && !defined(APPLE_OS_X) static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (so); -#endif +#endif // defined(WINDOWS) public: static constexpr int XA_LOG_COUNTERS = MONO_COUNTER_JIT | MONO_COUNTER_METADATA | MONO_COUNTER_GC | MONO_COUNTER_GENERICS | MONO_COUNTER_INTERP; @@ -140,7 +140,7 @@ namespace xamarin::android::internal int convert_dl_flags (int flags); #if defined (WINDOWS) || defined (APPLE_OS_X) static const char* get_my_location (); -#endif +#endif // defined(WINDOWS) || defined(APPLE_OS_X) static void* monodroid_dlopen (const char *name, int flags, char **err, void *user_data); static void* monodroid_dlsym (void *handle, const char *name, char **err, void *user_data); static void* monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory, bool need_api_init = false); From 4769c7dae9f6cf17a6541a3f6102354ea142a68d Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 30 Jul 2020 13:19:04 -0400 Subject: [PATCH 6/7] Add comments to #if --- src/monodroid/jni/monodroid-glue.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc index 659b19d832c..a1fbd9ffdc7 100644 --- a/src/monodroid/jni/monodroid-glue.cc +++ b/src/monodroid/jni/monodroid-glue.cc @@ -42,7 +42,7 @@ #if defined (APPLE_OS_X) #include -#endif +#endif // defined(APPLE_OS_X) #ifndef WINDOWS #include @@ -1516,7 +1516,7 @@ MonodroidRuntime::get_my_location () return utils.strdup_new (dirname (const_cast(info.dli_fname))); } -#endif +#endif // defined(WINDOWS) inline void MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, @@ -1607,16 +1607,16 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl api_dso_handle = dlopen (dso_path.get (), RTLD_NOW); #if defined (APPLE_OS_X) delete[] my_location; -#else +#else // !defined(APPLE_OS_X) free (static_cast(const_cast(my_location))); // JI allocates with `calloc` -#endif +#endif // defined(APPLE_OS_X) } if (api_dso_handle == nullptr) { log_info (LOG_DEFAULT, "Attempting to load %s with \"bare\" dlopen", API_DSO_NAME); api_dso_handle = dlopen (API_DSO_NAME, RTLD_NOW); } -#endif +#endif // defined(WINDOWS) || defined(APPLE_OS_X) if (api_dso_handle == nullptr) api_dso_handle = androidSystem.load_dso_from_any_directories (API_DSO_NAME, RTLD_NOW); init_internal_api_dso (api_dso_handle); From 7304d5fe3651803c7b71e94ff18c479df90b83a4 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 30 Jul 2020 13:20:00 -0400 Subject: [PATCH 7/7] Missed one --- src/monodroid/jni/xa-internal-api.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/monodroid/jni/xa-internal-api.cc b/src/monodroid/jni/xa-internal-api.cc index f05084a13ea..0f68a80fb4a 100644 --- a/src/monodroid/jni/xa-internal-api.cc +++ b/src/monodroid/jni/xa-internal-api.cc @@ -5,7 +5,7 @@ #include #include #include -#endif +#endif // defined(WINDOWS) #include "globals.hh" #include "xa-internal-api-impl.hh"