From dcc12071be28c8cedae44787af69fd7d123eb2e0 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Fri, 14 Jun 2019 10:11:07 +0200 Subject: [PATCH] Stop using dlopen/dlsym to load Mono symbols Since the dawn of time `Xamarin.Android` (nee `MonoAndroid`) used `dlopen/dlsym` to load Mono runtime symbols that were required for the managed applications to work on Android. This was done due to the fact that there had been no way to reliably load shared libraries referenced by the XA runtime in earlier versions of Android. However, thanks to the recent switch to API level 16 as our lowest supported level, we are now able to simply preload the shared libraries we depend on and, thus, allow the system linker to resolve all the symbols when loading `libmonodroid.so`. This, in turn, means we can now directly link `libmonosgen-2.0` on all target platforms (including all of the supported host operating systems) and, what's also very important, include Mono headers directly in our source. This makes sure we don't divert in definitions of various macros and functions that we use accross our runtime and that we continue to work with any version of Mono shipped in the Mono SDK archives. This commit removes all traces of the `DylibMono` class and it also renames all the C++ header files to have the `.hh` extension, to mirror the `.cc` source file convention and cleary mark the C++ headers as such, as opposed to the handful of C headers (`.h`) we have in our tree. --- Configuration.props | 1 - .../installers/create-installers.targets | 1 + build-tools/scripts/PrepareWindows.targets | 1 + .../xaprepare/Application/RuntimeFileType.cs | 1 + .../xaprepare/Application/Utilities.cs | 2 +- .../ConfigAndData/Configurables.MacOS.cs | 4 + .../ConfigAndData/Configurables.Unix.cs | 3 + .../xaprepare/ConfigAndData/Configurables.cs | 3 + .../xaprepare/ConfigAndData/Runtimes.Code.cs | 250 +++++ .../xaprepare/ConfigAndData/Runtimes.cs | 540 ++++++----- .../Scenarios/Scenario_Standard.MacOS.cs | 16 + .../Scenarios/Scenario_Standard.Unix.cs | 4 + .../Step_ChangeLibMonoSgenDylibID.MacOS.cs | 49 + .../xaprepare/Steps/Step_CreateBundle.Unix.cs | 44 + .../xaprepare/xaprepare/xaprepare.csproj | 3 + .../Xamarin.Android.Common.targets | 2 + src/java-runtime/java-runtime.targets | 6 +- .../java/mono/android/DebugRuntime.java | 8 + .../java/mono/android/MonoPackageManager.java | 38 +- .../java/mono/android/debug/BuildConfig.java | 5 + .../mono/android/release/BuildConfig.java | 5 + src/monodroid/CMakeLists.txt | 82 +- src/monodroid/jni/android-system.cc | 263 +----- .../{android-system.h => android-system.hh} | 100 +- src/monodroid/jni/basic-android-system.cc | 79 ++ src/monodroid/jni/basic-android-system.hh | 109 +++ src/monodroid/jni/basic-utilities.cc | 373 ++++++++ .../jni/{util.h => basic-utilities.hh} | 201 +--- .../jni/{cppcompat.h => cppcompat.hh} | 20 + src/monodroid/jni/cpu-arch-detect.cc | 2 +- src/monodroid/jni/{cpu-arch.h => cpu-arch.hh} | 0 src/monodroid/jni/debug-app-helper.cc | 346 +++++++ src/monodroid/jni/debug-app-helper.hh | 17 + src/monodroid/jni/debug-constants.cc | 2 +- src/monodroid/jni/debug.cc | 6 +- src/monodroid/jni/{debug.h => debug.hh} | 0 src/monodroid/jni/dylib-mono.cc | 883 ------------------ src/monodroid/jni/dylib-mono.h | 706 -------------- src/monodroid/jni/embedded-assemblies.cc | 30 +- ...ed-assemblies.h => embedded-assemblies.hh} | 3 +- src/monodroid/jni/globals.cc | 3 +- src/monodroid/jni/{globals.h => globals.hh} | 12 +- .../jni/{jni-wrappers.h => jni-wrappers.hh} | 0 src/monodroid/jni/logger.cc | 16 +- src/monodroid/jni/{logger.h => logger.hh} | 0 src/monodroid/jni/mkbundle-api.h | 2 +- ...-internal.h => monodroid-glue-internal.hh} | 5 +- src/monodroid/jni/monodroid-glue.cc | 317 +++---- src/monodroid/jni/monodroid-glue.h | 3 +- src/monodroid/jni/monodroid-networkinfo.cc | 5 +- src/monodroid/jni/monodroid.h | 33 +- src/monodroid/jni/osbridge.cc | 87 +- src/monodroid/jni/{osbridge.h => osbridge.hh} | 2 +- src/monodroid/jni/shared-constants.cc | 3 + src/monodroid/jni/shared-constants.hh | 33 + src/monodroid/jni/timezones.cc | 39 +- src/monodroid/jni/util.cc | 446 +-------- src/monodroid/jni/util.hh | 144 +++ src/monodroid/jni/xamarin_getifaddrs.cc | 4 +- src/monodroid/monodroid.props | 2 +- .../EmbeddedDSOs/EmbeddedDSO-UnitTests/run.sh | 2 +- 61 files changed, 2259 insertions(+), 3107 deletions(-) create mode 100644 build-tools/xaprepare/xaprepare/ConfigAndData/Runtimes.Code.cs create mode 100644 build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.MacOS.cs create mode 100644 build-tools/xaprepare/xaprepare/Steps/Step_ChangeLibMonoSgenDylibID.MacOS.cs create mode 100644 src/java-runtime/java/mono/android/DebugRuntime.java create mode 100644 src/java-runtime/java/mono/android/debug/BuildConfig.java create mode 100644 src/java-runtime/java/mono/android/release/BuildConfig.java rename src/monodroid/jni/{android-system.h => android-system.hh} (55%) create mode 100644 src/monodroid/jni/basic-android-system.cc create mode 100644 src/monodroid/jni/basic-android-system.hh create mode 100644 src/monodroid/jni/basic-utilities.cc rename src/monodroid/jni/{util.h => basic-utilities.hh} (61%) rename src/monodroid/jni/{cppcompat.h => cppcompat.hh} (67%) rename src/monodroid/jni/{cpu-arch.h => cpu-arch.hh} (100%) create mode 100644 src/monodroid/jni/debug-app-helper.cc create mode 100644 src/monodroid/jni/debug-app-helper.hh rename src/monodroid/jni/{debug.h => debug.hh} (100%) delete mode 100644 src/monodroid/jni/dylib-mono.cc delete mode 100644 src/monodroid/jni/dylib-mono.h rename src/monodroid/jni/{embedded-assemblies.h => embedded-assemblies.hh} (99%) rename src/monodroid/jni/{globals.h => globals.hh} (65%) rename src/monodroid/jni/{jni-wrappers.h => jni-wrappers.hh} (100%) rename src/monodroid/jni/{logger.h => logger.hh} (100%) rename src/monodroid/jni/{monodroid-glue-internal.h => monodroid-glue-internal.hh} (83%) rename src/monodroid/jni/{osbridge.h => osbridge.hh} (99%) create mode 100644 src/monodroid/jni/shared-constants.cc create mode 100644 src/monodroid/jni/shared-constants.hh create mode 100644 src/monodroid/jni/util.hh diff --git a/Configuration.props b/Configuration.props index 42d4438d29c..092658754b4 100644 --- a/Configuration.props +++ b/Configuration.props @@ -56,7 +56,6 @@ -j$(HostCpuCount) mono --debug=casts - 5 $(USERPROFILE) v1.0 $(HOME)\android-archives diff --git a/build-tools/installers/create-installers.targets b/build-tools/installers/create-installers.targets index 4599f5b22ea..67f4d1d1c18 100644 --- a/build-tools/installers/create-installers.targets +++ b/build-tools/installers/create-installers.targets @@ -73,6 +73,7 @@ <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libMonoPosixHelper.so')" /> <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libmonosgen-2.0.so')" /> <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libsqlite3_xamarin.so')" /> + <_MSBuildFiles Include="@(AndroidSupportedTargetJitAbi->'$(MSBuildSrcDir)\lib\%(Identity)\libxamarin-debug-app-helper.so')" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\libZipSharp.dll" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\libZipSharp.dll.config" Condition=" '$(HostOS)' != 'Windows' " /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Mono.Posix.NETStandard.dll" /> diff --git a/build-tools/scripts/PrepareWindows.targets b/build-tools/scripts/PrepareWindows.targets index 84591ffcb2a..e589d0ccdbc 100644 --- a/build-tools/scripts/PrepareWindows.targets +++ b/build-tools/scripts/PrepareWindows.targets @@ -7,6 +7,7 @@ <_XAPrepareStandardArgs Condition=" '$(RunningOnCI)' == 'true' ">--no-emoji --run-mode=CI -a -v:d <_XAPrepareStandardArgs Condition=" '$(XA_FORCE_COMPONENT_REFRESH)' == 'true' ">$(_XAPrepareStandardArgs) -refresh <_XAPrepareBundleArgs Condition=" '$(BundleRootPath)' != '' ">--bundle-path="$(BundleRootPath)" + <_XAPrepareBundleArgs Condition=" '$(RunMode)' == 'CI' ">$(_XAPrepareBundleArgs) -v:d diff --git a/build-tools/xaprepare/xaprepare/Application/RuntimeFileType.cs b/build-tools/xaprepare/xaprepare/Application/RuntimeFileType.cs index 82b1f63b08d..70e0e9cde58 100644 --- a/build-tools/xaprepare/xaprepare/Application/RuntimeFileType.cs +++ b/build-tools/xaprepare/xaprepare/Application/RuntimeFileType.cs @@ -5,5 +5,6 @@ enum RuntimeFileType Other, Binary, StrippableBinary, + SdkHeader, } } diff --git a/build-tools/xaprepare/xaprepare/Application/Utilities.cs b/build-tools/xaprepare/xaprepare/Application/Utilities.cs index abdd6a5dd48..97d988e77ac 100644 --- a/build-tools/xaprepare/xaprepare/Application/Utilities.cs +++ b/build-tools/xaprepare/xaprepare/Application/Utilities.cs @@ -654,7 +654,7 @@ public static void DeleteDirectoryWithRetry (string directoryPath, bool recursiv return; } catch (IOException e) { ex = e; - } catch (UnauthorizedAccessException e) { + } catch (UnauthorizedAccessException e) { ex = e; tryResetFilePermissions = true; } diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.MacOS.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.MacOS.cs index ee73304840e..3ca233f04d0 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.MacOS.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.MacOS.cs @@ -18,8 +18,12 @@ partial class Defaults partial class Paths { + const string LibMonoSgenBaseName = "libmonosgen-2.0"; + public const string MonoCrossRuntimeInstallPath = "Darwin"; public const string NdkToolchainOSTag = "darwin-x86_64"; + public static readonly string UnstrippedLibMonoSgenName = $"{LibMonoSgenBaseName}.d{Defaults.NativeLibraryExtension}"; + public static readonly string StrippedLibMonoSgenName = $"{LibMonoSgenBaseName}{Defaults.NativeLibraryExtension}"; } } } diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Unix.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Unix.cs index 499eb8d5919..1d1896c9fb4 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Unix.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Unix.cs @@ -21,8 +21,11 @@ partial class Paths public static string BCLTestsSourceDir => GetCachedPath (ref bclTestsSourceDir, () => Path.Combine (MonoProfileDir, "tests")); public static string BCLAssembliesSourceDir => MonoProfileDir; + public static string HostRuntimeDir => GetCachedPath (ref hostRuntimeDir, () => Path.Combine (XAInstallPrefix, "xbuild", "Xamarin", "Android", "lib", $"host-{ctx.OS.Type}")); public static readonly string MonoRuntimeHostMingwNativeLibraryPrefix = Path.Combine ("..", "bin"); + + static string hostRuntimeDir; } } } diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs index 51125b727c2..aff66c1bd81 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs @@ -267,6 +267,7 @@ public static partial class Paths public static readonly string ExternalXamarinAndroidToolsSln = Path.Combine (ExternalDir, "xamarin-android-tools", "Xamarin.Android.Tools.sln"); public static readonly string MxeSourceDir = Path.Combine (ExternalDir, "mxe"); public static readonly string MonoSDKSRelativeOutputDir = Path.Combine ("sdks", "out"); + public static readonly string MonoSDKRelativeIncludeSourceDir = Path.Combine ("include", "mono-2.0", "mono"); public static readonly string RuntimeInstallRelativeLibDir = "lib"; public static readonly string PackageImageDependenciesTemplate = Path.Combine (BuildToolsScriptsDir, "prepare-image-dependencies.sh.in"); public static readonly string PackageImageDependenciesOutput = Path.Combine (BuildPaths.XamarinAndroidSourceRoot, "prepare-image-dependencies.sh"); @@ -278,6 +279,7 @@ public static partial class Paths public static string MonoSDKSOutputDir => GetCachedPath (ref monoSDKsOutputDir, () => Path.Combine (MonoSourceFullPath, MonoSDKSRelativeOutputDir)); public static string MonoProfileDir => GetCachedPath (ref monoProfileDir, () => Path.Combine (MonoSDKSOutputDir, "android-bcl", "monodroid")); public static string MonoProfileToolsDir => GetCachedPath (ref monoProfileToolsDir, () => Path.Combine (MonoSDKSOutputDir, "android-bcl", "monodroid_tools")); + public static string MonoSDKIncludeDestinationDir => GetCachedPath (ref monoSDKSIncludeDestDir, () => Path.Combine (OutputIncludeDir, "mono-2.0", "mono")); public static string BCLFacadeAssembliesSourceDir => GetCachedPath (ref bclFacadeAssembliesSourceDir, () => Path.Combine (BCLAssembliesSourceDir, "Facades")); public static string BCLHostAssembliesSourceDir => BCLAssembliesSourceDir; @@ -419,6 +421,7 @@ static string GetCachedPath (ref string variable, Func creator) static string externalJavaInteropDir; static string monoSdksTpnPath; static string monoSdksTpnExternalPath; + static string monoSDKSIncludeDestDir; } } } diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Runtimes.Code.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Runtimes.Code.cs new file mode 100644 index 00000000000..c312ae27b8d --- /dev/null +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Runtimes.Code.cs @@ -0,0 +1,250 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Xamarin.Android.Prepare +{ + partial class Runtimes + { + static Context ctx => Context.Instance; + + static string GetMonoUtilitySourcePath (string utilityName) + { + return Path.Combine (Configurables.Paths.MonoProfileToolsDir, utilityName); + } + + static string GetLlvmOutputSourcePath (Runtime runtime) + { + var llvmRuntime = EnsureRuntimeType (runtime, "LLVM"); + return Path.Combine (GetLlvmInputDir (runtime), "bin"); + } + + static string GetLlvmOutputDestinationPath (Runtime runtime) + { + var llvmRuntime = EnsureRuntimeType (runtime, "LLVM"); + return llvmRuntime.InstallPath; + } + + static string GetMonoPosixHelperOutputSourcePath (Runtime runtime) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputMonoPosixHelperFilename}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetMonoPosixHelperOutputDestinationPath (Runtime runtime, bool debug) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputMonoPosixHelperFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetMonoBtlsOutputSourcePath (Runtime runtime) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputMonoBtlsFilename}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetMonoBtlsOutputDestinationPath (Runtime runtime, bool debug) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputMonoBtlsFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetAotProfilerOutputSourcePath (Runtime runtime) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputAotProfilerFilename}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetAotProfilerOutputDestinationPath (Runtime runtime, bool debug) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputAotProfilerFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetProfilerOutputSourcePath (Runtime runtime) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputProfilerFilename}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetProfilerOutputDestinationPath (Runtime runtime, bool debug) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputProfilerFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetCrossRuntimeOutputSourcePath (Runtime runtime) + { + var crossRuntime = EnsureRuntimeType (runtime, "cross compilation"); + return Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), "bin", $"{crossRuntime.ExePrefix}mono-sgen{crossRuntime.ExeSuffix}"); + } + + static string GetCrossRuntimeOutputDestinationPath (Runtime runtime, bool debug) + { + var crossRuntime = EnsureRuntimeType (runtime, "cross compilation"); + string runtimeName = $"{crossRuntime.CrossMonoName}{GetDebugInfix (debug)}{crossRuntime.ExeSuffix}"; + if (String.IsNullOrEmpty (crossRuntime.InstallPath)) + return runtimeName; + + return Path.Combine (crossRuntime.InstallPath, runtimeName); + } + + static string GetRuntimeOutputSourcePath (Runtime runtime) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputRuntimeFilename}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetRuntimeOutputDestinationPath (Runtime runtime, bool debug) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputRuntimeFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetMonoNativeOutputSourcePath (Runtime runtime) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + if (IsAbi (runtime, AbiNames.HostJit.Darwin)) + return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"libmono-native-compat{monoRuntime.NativeLibraryExtension}"); + + return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"libmono-native{monoRuntime.NativeLibraryExtension}"); + } + + static string GetMonoNativeOutputDestinationPath (Runtime runtime, bool debug) + { + var monoRuntime = EnsureRuntimeType (runtime, "Mono"); + return Path.Combine (GetRuntimeOutputDir (runtime), $"libmono-native{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); + } + + static string GetDebugInfix (bool debug) + { + return debug ? Configurables.Defaults.DebugBinaryInfix : String.Empty; + } + + static bool IsHostOrTargetRuntime (Runtime runtime) + { + return IsRuntimeType (runtime) || IsRuntimeType (runtime); + } + + static T EnsureRuntimeType (Runtime runtime, string typeName) where T: Runtime + { + var ret = runtime.As (); + if (ret == null) + throw new InvalidOperationException ($"Runtime {runtime.Name} is not a {typeName} runtime"); + + return ret; + } + + static bool IsRuntimeType (Runtime runtime) where T: Runtime + { + return runtime.As() != null; + } + + static bool IsWindowsRuntime (Runtime runtime) + { + return String.Compare (runtime.ExeSuffix, Configurables.Defaults.WindowsExecutableSuffix, StringComparison.Ordinal) == 0; + } + + static bool IsAbi (Runtime runtime, string abiName, params string[] furtherAbiNames) + { + if (ExpectedAbi (abiName)) + return true; + + if (furtherAbiNames == null) + return false; + + foreach (string a in furtherAbiNames) { + if (ExpectedAbi (a)) + return true; + } + + return false; + + bool ExpectedAbi (string abi) + { + if (String.IsNullOrEmpty (abi)) + return false; + + return String.Compare (abi, runtime.Name ?? String.Empty, StringComparison.Ordinal) == 0; + } + } + + static string GetLlvmInputDir (Runtime runtime) + { + return GetLlvmInputRootDir (runtime); + } + + static string GetLlvmInputRootDir (Runtime runtime) + { + return Path.Combine (Configurables.Paths.MonoSDKSRelativeOutputDir, $"llvm-{runtime.PrefixedName}"); + } + + static string GetAndroidInputLibDir (Runtime runtime) + { + return Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), "lib"); + } + + static string GetRuntimeOutputDir (Runtime runtime) + { + return Path.Combine (Configurables.Paths.RuntimeInstallRelativeLibDir, runtime.PrefixedName); + } + + static bool IsLlvmRuntimeEnabled (Context ctx, string llvmAbi) + { + bool enabled = false; + bool windows = ctx.IsLlvmWindowsAbi (llvmAbi); + bool is64Bit = ctx.Is64BitLlvmAbi (llvmAbi); + + HashSet targets; + if (windows) + targets = is64Bit ? AbiNames.All64BitWindowsAotAbis : AbiNames.All32BitWindowsAotAbis; + else + targets = is64Bit ? AbiNames.All64BitHostAotAbis : AbiNames.All32BitHostAotAbis; + + foreach (string target in targets) { + if (Context.Instance.IsTargetAotAbiEnabled (target)) { + enabled = true; + break; + } + } + + return enabled && (!is64Bit || Context.Instance.OS.Is64Bit); + } + + public Runtimes () + { + Context c = ctx; + foreach (Runtime runtime in Items) { + runtime.Init (c); + } + + DesignerHostBclFilesToInstall = new List (); + DesignerWindowsBclFilesToInstall = new List (); + + PopulateDesignerBclFiles (DesignerHostBclFilesToInstall, DesignerWindowsBclFilesToInstall); + } + + List BclToDesigner (BclFileTarget ignoreForTarget) + { + return BclFilesToInstall.Where (bf => ShouldIncludeDesignerBcl (bf)).Select (bf => new BclFile (bf.Name, bf.Type, excludeDebugSymbols: true, version: bf.Version, target: ignoreForTarget)).ToList (); + + bool ShouldIncludeDesignerBcl (BclFile bf) + { + if (DesignerIgnoreFiles == null || !DesignerIgnoreFiles.TryGetValue (bf.Name, out (BclFileType Type, BclFileTarget Target) bft)) { + return true; + } + + if (bf.Type != bft.Type || bft.Target != ignoreForTarget) + return true; + + Log.Instance.DebugLine ($"BCL file {bf.Name} will NOT be included in the installed Designer BCL files ({ignoreForTarget})"); + return false; + } + } + + partial void PopulateDesignerBclFiles (List designerHostBclFilesToInstall, List designerWindowsBclFilesToInstall); + + List bundleItems; + } +} diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Runtimes.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Runtimes.cs index 097dc8e25c6..14df9009b1f 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/Runtimes.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Runtimes.cs @@ -7,8 +7,6 @@ namespace Xamarin.Android.Prepare { partial class Runtimes { - static Context ctx => Context.Instance; - public readonly List Items = new List { new MonoJitRuntime ( abiName: AbiNames.TargetJit.AndroidArmV7a, @@ -392,11 +390,291 @@ partial class Runtimes /// public readonly List RuntimeFilesToInstall = new List { new RuntimeFile ( - sourceCreator: (Runtime runtime) => Path.Combine (GetAndroidInputRootDir (runtime), "share", "mono-2.0", "mono", "eglib", "eglib-config.h"), - destinationCreator:(Runtime runtime) => Path.Combine (Configurables.Paths.OutputIncludeDir, runtime.PrefixedName, "eglib", "eglib-config.h"), + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), "share", "mono-2.0", "mono", "eglib", "eglib-config.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.OutputIncludeDir, runtime.PrefixedName, "eglib", "eglib-config.h"), shouldSkip: (Runtime runtime) => !IsHostOrTargetRuntime (runtime) ), + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "cil", "opcode.def"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "cil", "opcode.def"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "jit", "jit.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "jit", "jit.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "appdomain.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "appdomain.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "assembly.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "assembly.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "attrdefs.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "attrdefs.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "blob.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "blob.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "class.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "class.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "debug-helpers.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "debug-helpers.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "debug-mono-symfile.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "debug-mono-symfile.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "environment.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "environment.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "exception.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "exception.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "image.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "image.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "loader.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "loader.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "metadata.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "metadata.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "mono-config.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "mono-config.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "mono-debug.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "mono-debug.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "mono-gc.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "mono-gc.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "object-forward.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "object-forward.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "object.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "object.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "opcodes.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "opcodes.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "profiler-events.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "profiler-events.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "profiler.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "profiler.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "reflection.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "reflection.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "row-indexes.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "row-indexes.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "sgen-bridge.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "sgen-bridge.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "threads.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "threads.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "tokentype.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "tokentype.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "metadata", "verify.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "metadata", "verify.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "utils", "mono-counters.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "utils", "mono-counters.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "utils", "mono-dl-fallback.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "utils", "mono-dl-fallback.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "utils", "mono-error.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "utils", "mono-error.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "utils", "mono-forward.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "utils", "mono-forward.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "utils", "mono-jemalloc.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "utils", "mono-jemalloc.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "utils", "mono-logger.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "utils", "mono-logger.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir, "utils", "mono-publib.h"), + destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoSDKIncludeDestinationDir, "utils", "mono-publib.h"), + strip: false, + shared: true, + type: RuntimeFileType.SdkHeader + ), + new RuntimeFile ( sourceCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.MonoProfileDir, "Consts.cs"), destinationCreator: (Runtime runtime) => Path.Combine (Configurables.Paths.OutputIncludeDir, "Consts.cs"), @@ -436,7 +714,14 @@ partial class Runtimes shared: true ), - // Stripped runtime + new RuntimeFile ( + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), "lib", "libmonosgen-2.0.dll.a"), + destinationCreator: (Runtime runtime) => Path.Combine (GetRuntimeOutputDir (runtime), "libmonosgen-2.0.dll.a"), + shouldSkip: (Runtime runtime) => !IsAbi (runtime, AbiNames.HostJit.Win32, AbiNames.HostJit.Win64), + strip: false + ), + + // Stripped runtime new RuntimeFile ( sourceCreator: (Runtime runtime) => GetRuntimeOutputSourcePath (runtime), destinationCreator: (Runtime runtime) => GetRuntimeOutputDestinationPath (runtime, debug: false), @@ -489,7 +774,7 @@ partial class Runtimes // Unstripped host mono binary new RuntimeFile ( - sourceCreator: (Runtime runtime) => Path.Combine (GetAndroidInputRootDir (runtime), "bin", "mono"), + sourceCreator: (Runtime runtime) => Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), "bin", "mono"), destinationCreator: (Runtime runtime) => Path.Combine (runtime.Name, "mono"), shouldSkip: (Runtime runtime) => !IsRuntimeType (runtime) || IsAbi (runtime, AbiNames.HostJit.Win32, AbiNames.HostJit.Win64), type: RuntimeFileType.StrippableBinary, @@ -644,248 +929,5 @@ public List BundleItems { Configurables.Paths.InstallBCLFrameworkDir, Configurables.Paths.OutputIncludeDir, }; - - static string GetMonoUtilitySourcePath (string utilityName) - { - return Path.Combine (Configurables.Paths.MonoProfileToolsDir, utilityName); - } - - static string GetLlvmOutputSourcePath (Runtime runtime) - { - var llvmRuntime = EnsureRuntimeType (runtime, "LLVM"); - return Path.Combine (GetLlvmInputDir (runtime), "bin"); - } - - static string GetLlvmOutputDestinationPath (Runtime runtime) - { - var llvmRuntime = EnsureRuntimeType (runtime, "LLVM"); - return llvmRuntime.InstallPath; - } - - static string GetMonoPosixHelperOutputSourcePath (Runtime runtime) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputMonoPosixHelperFilename}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetMonoPosixHelperOutputDestinationPath (Runtime runtime, bool debug) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputMonoPosixHelperFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetMonoBtlsOutputSourcePath (Runtime runtime) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputMonoBtlsFilename}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetMonoBtlsOutputDestinationPath (Runtime runtime, bool debug) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputMonoBtlsFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetAotProfilerOutputSourcePath (Runtime runtime) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputAotProfilerFilename}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetAotProfilerOutputDestinationPath (Runtime runtime, bool debug) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputAotProfilerFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetProfilerOutputSourcePath (Runtime runtime) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputProfilerFilename}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetProfilerOutputDestinationPath (Runtime runtime, bool debug) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputProfilerFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetCrossRuntimeOutputSourcePath (Runtime runtime) - { - var crossRuntime = EnsureRuntimeType (runtime, "cross compilation"); - return Path.Combine (GetAndroidInputRootDir (runtime), "bin", $"{crossRuntime.ExePrefix}mono-sgen{crossRuntime.ExeSuffix}"); - } - - static string GetCrossRuntimeOutputDestinationPath (Runtime runtime, bool debug) - { - var crossRuntime = EnsureRuntimeType (runtime, "cross compilation"); - string runtimeName = $"{crossRuntime.CrossMonoName}{GetDebugInfix (debug)}{crossRuntime.ExeSuffix}"; - if (String.IsNullOrEmpty (crossRuntime.InstallPath)) - return runtimeName; - - return Path.Combine (crossRuntime.InstallPath, runtimeName); - } - - static string GetRuntimeOutputSourcePath (Runtime runtime) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputRuntimeFilename}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetRuntimeOutputDestinationPath (Runtime runtime, bool debug) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputRuntimeFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetMonoNativeOutputSourcePath (Runtime runtime) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - if (IsAbi (runtime, AbiNames.HostJit.Darwin)) - return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"libmono-native-compat{monoRuntime.NativeLibraryExtension}"); - - return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"libmono-native{monoRuntime.NativeLibraryExtension}"); - } - - static string GetMonoNativeOutputDestinationPath (Runtime runtime, bool debug) - { - var monoRuntime = EnsureRuntimeType (runtime, "Mono"); - return Path.Combine (GetRuntimeOutputDir (runtime), $"libmono-native{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}"); - } - - static string GetDebugInfix (bool debug) - { - return debug ? Configurables.Defaults.DebugBinaryInfix : String.Empty; - } - - static bool IsHostOrTargetRuntime (Runtime runtime) - { - return IsRuntimeType (runtime) || IsRuntimeType (runtime); - } - - static T EnsureRuntimeType (Runtime runtime, string typeName) where T: Runtime - { - var ret = runtime.As (); - if (ret == null) - throw new InvalidOperationException ($"Runtime {runtime.Name} is not a {typeName} runtime"); - - return ret; - } - - static bool IsRuntimeType (Runtime runtime) where T: Runtime - { - return runtime.As() != null; - } - - static bool IsWindowsRuntime (Runtime runtime) - { - return String.Compare (runtime.ExeSuffix, Configurables.Defaults.WindowsExecutableSuffix, StringComparison.Ordinal) == 0; - } - - static bool IsAbi (Runtime runtime, string abiName, params string[] furtherAbiNames) - { - if (ExpectedAbi (abiName)) - return true; - - if (furtherAbiNames == null) - return false; - - foreach (string a in furtherAbiNames) { - if (ExpectedAbi (a)) - return true; - } - - return false; - - bool ExpectedAbi (string abi) - { - if (String.IsNullOrEmpty (abi)) - return false; - - return String.Compare (abi, runtime.Name ?? String.Empty, StringComparison.Ordinal) == 0; - } - } - - static string GetLlvmInputDir (Runtime runtime) - { - return GetLlvmInputRootDir (runtime); - } - - static string GetLlvmInputRootDir (Runtime runtime) - { - return Path.Combine (Configurables.Paths.MonoSDKSRelativeOutputDir, $"llvm-{runtime.PrefixedName}"); - } - - static string GetAndroidInputLibDir (Runtime runtime) - { - return Path.Combine (GetAndroidInputRootDir (runtime), "lib"); - } - - static string GetAndroidInputRootDir (Runtime runtime) - { - return Path.Combine (Configurables.Paths.MonoSDKSRelativeOutputDir, $"android-{runtime.PrefixedName}-{Configurables.Defaults.MonoSdksConfiguration}"); - } - - static string GetRuntimeOutputDir (Runtime runtime) - { - return Path.Combine (Configurables.Paths.RuntimeInstallRelativeLibDir, runtime.PrefixedName); - } - - static bool IsLlvmRuntimeEnabled (Context ctx, string llvmAbi) - { - bool enabled = false; - bool windows = ctx.IsLlvmWindowsAbi (llvmAbi); - bool is64Bit = ctx.Is64BitLlvmAbi (llvmAbi); - - HashSet targets; - if (windows) - targets = is64Bit ? AbiNames.All64BitWindowsAotAbis : AbiNames.All32BitWindowsAotAbis; - else - targets = is64Bit ? AbiNames.All64BitHostAotAbis : AbiNames.All32BitHostAotAbis; - - foreach (string target in targets) { - if (Context.Instance.IsTargetAotAbiEnabled (target)) { - enabled = true; - break; - } - } - - return enabled && (!is64Bit || Context.Instance.OS.Is64Bit); - } - - public Runtimes () - { - Context c = ctx; - foreach (Runtime runtime in Items) { - runtime.Init (c); - } - - DesignerHostBclFilesToInstall = new List (); - DesignerWindowsBclFilesToInstall = new List (); - - PopulateDesignerBclFiles (DesignerHostBclFilesToInstall, DesignerWindowsBclFilesToInstall); - } - - partial void PopulateDesignerBclFiles (List designerHostBclFilesToInstall, List designerWindowsBclFilesToInstall); - - List BclToDesigner (BclFileTarget ignoreForTarget) - { - return BclFilesToInstall.Where (bf => ShouldIncludeDesignerBcl (bf)).Select (bf => new BclFile (bf.Name, bf.Type, excludeDebugSymbols: true, version: bf.Version, target: ignoreForTarget)).ToList (); - - bool ShouldIncludeDesignerBcl (BclFile bf) - { - if (DesignerIgnoreFiles == null || !DesignerIgnoreFiles.TryGetValue (bf.Name, out (BclFileType Type, BclFileTarget Target) bft)) { - return true; - } - - if (bf.Type != bft.Type || bft.Target != ignoreForTarget) - return true; - - Log.Instance.DebugLine ($"BCL file {bf.Name} will NOT be included in the installed Designer BCL files ({ignoreForTarget})"); - return false; - } - } - - List bundleItems; } } diff --git a/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.MacOS.cs b/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.MacOS.cs new file mode 100644 index 00000000000..f6a3f215721 --- /dev/null +++ b/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.MacOS.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace Xamarin.Android.Prepare +{ + partial class Scenario_Standard + { + partial void AddRequiredMacOSSteps (bool beforeBundle) + { + if (beforeBundle) + return; + + Steps.Add (new Step_ChangeLibMonoSgenDylibID ()); + } + } +} diff --git a/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.Unix.cs b/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.Unix.cs index fcdb2a0feaf..ef37e0da0c6 100644 --- a/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.Unix.cs +++ b/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.Unix.cs @@ -7,6 +7,8 @@ partial class Scenario_Standard { partial void AddRequiredOSSpecificSteps (bool beforeBundle) { + AddRequiredMacOSSteps (beforeBundle); + if (!beforeBundle) { // It has to go after the bundle step because bundle unpacking or creation *always* cleans its // destination directory and this is where we download the GAS binaries. They are not part of the bundle @@ -24,5 +26,7 @@ partial void AddRequiredOSSpecificSteps (bool beforeBundle) Log.DebugLine ("Windows JIT ABis DISABLED, SKIPPING MinGW dependencies build step"); } } + + partial void AddRequiredMacOSSteps (bool beforeBundle); } } diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_ChangeLibMonoSgenDylibID.MacOS.cs b/build-tools/xaprepare/xaprepare/Steps/Step_ChangeLibMonoSgenDylibID.MacOS.cs new file mode 100644 index 00000000000..c17d406aeb9 --- /dev/null +++ b/build-tools/xaprepare/xaprepare/Steps/Step_ChangeLibMonoSgenDylibID.MacOS.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace Xamarin.Android.Prepare +{ + class Step_ChangeLibMonoSgenDylibID : Step + { + public Step_ChangeLibMonoSgenDylibID () + : base ("Changing Mono dynamic library ID") + {} + + protected override async Task Execute (Context context) + { + string xcrun = context.OS.Which ("xcrun"); + + var libs = new string[] { + Path.Combine (Configurables.Paths.HostRuntimeDir, Configurables.Paths.UnstrippedLibMonoSgenName), + Path.Combine (Configurables.Paths.HostRuntimeDir, Configurables.Paths.StrippedLibMonoSgenName), + }; + + bool result = true; + Log.StatusLine ("Changing id for:"); + foreach (string libPath in libs) { + if (!Utilities.FileExists (libPath)) { + Log.StatusLine (" not found", ConsoleColor.Magenta); + continue; + } + + if (!ChangeID (libPath)) { + Log.StatusLine (" failed", ConsoleColor.Magenta); + result = false; + } + } + + return result; + + bool ChangeID (string path) + { + Log.DebugLine ($"Changing dylib id for {path}"); + Log.StatusLine ($" {context.Characters.Bullet} {Utilities.GetRelativePath (BuildPaths.XamarinAndroidSourceRoot, path)}"); + var runner = new ProcessRunner (xcrun, "install_name_tool", "-id", "@loader_path/libmonosgen-2.0.dylib", path); + return runner.Run (); + } + } + } +} diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_CreateBundle.Unix.cs b/build-tools/xaprepare/xaprepare/Steps/Step_CreateBundle.Unix.cs index 0f74fe60087..d8285eb5f47 100644 --- a/build-tools/xaprepare/xaprepare/Steps/Step_CreateBundle.Unix.cs +++ b/build-tools/xaprepare/xaprepare/Steps/Step_CreateBundle.Unix.cs @@ -32,6 +32,7 @@ protected override async Task Execute (Context context) throw new InvalidOperationException ($"Unsupported compression type: {cf.Description}"); } + EnsureAllSDKHeadersAreIncluded (context, allRuntimes); List items = allRuntimes.BundleItems.Where (item => item.ShouldInclude == null || item.ShouldInclude (context)).Select ( item => { string relPath = Utilities.GetRelativePath (binRoot, item.SourcePath); @@ -48,5 +49,48 @@ protected override async Task Execute (Context context) return true; } + + void EnsureAllSDKHeadersAreIncluded (Context context, Runtimes allRuntimes) + { + string topDirTail = Configurables.Paths.MonoSDKRelativeIncludeSourceDir; + if (!topDirTail.EndsWith (Path.DirectorySeparatorChar.ToString (), StringComparison.Ordinal)) + topDirTail += Path.DirectorySeparatorChar; + + // Find first enabled runtime - all headers are the same across all runtimes, so we don't care + // where they come from. + Runtime runtime = MonoRuntimesHelpers.GetEnabledRuntimes (allRuntimes, enableLogging: false)?.FirstOrDefault (); + if (runtime == null) { + Log.WarningLine ("No enabled runtimes (?!)"); + return; + } + + string runtimeIncludeDirRoot = Path.Combine (Configurables.Paths.MonoSourceFullPath, MonoRuntimesHelpers.GetRootDir (runtime), Configurables.Paths.MonoSDKRelativeIncludeSourceDir); + IEnumerable sourceIncludes = Directory.EnumerateFiles (runtimeIncludeDirRoot, "*", SearchOption.AllDirectories); + var destinationIncludes = new List (); + + foreach (RuntimeFile rf in allRuntimes.RuntimeFilesToInstall.Where (rf => rf.Type == RuntimeFileType.SdkHeader)) { + destinationIncludes.Add (Path.Combine (Configurables.Paths.MonoSourceFullPath, rf.Source (runtime))); + } + + bool haveDifference = false; + haveDifference &= ReportDifference (sourceIncludes.Except (destinationIncludes).ToList (), "runtime", "bundle"); + haveDifference &= ReportDifference (destinationIncludes.Except (sourceIncludes).ToList (), "bundle", "runtime"); + + if (haveDifference) + throw new InvalidOperationException ("Differences found between the Mono SDK header files shipped in Mono archive and included in Xamarin.Android bundle"); + + bool ReportDifference (List diff, string foundIn, string notFoundIn) + { + if (diff.Count == 0) + return false; + + Log.ErrorLine ($"There are files found in the {foundIn} but not in the {notFoundIn}:"); + foreach (string f in diff) { + Log.ErrorLine ($" {context.Characters.Bullet} {Utilities.GetRelativePath (runtimeIncludeDirRoot, f)}"); + } + Log.ErrorLine (); + return true; + } + } } } diff --git a/build-tools/xaprepare/xaprepare/xaprepare.csproj b/build-tools/xaprepare/xaprepare/xaprepare.csproj index 3d5627cc81c..bed0b1c9450 100644 --- a/build-tools/xaprepare/xaprepare/xaprepare.csproj +++ b/build-tools/xaprepare/xaprepare/xaprepare.csproj @@ -125,6 +125,7 @@ + @@ -236,6 +237,8 @@ + + diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 10bb11589ab..09d6d3b908f 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -2806,6 +2806,8 @@ 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/java-runtime/java-runtime.targets b/src/java-runtime/java-runtime.targets index c756e383362..799126b600e 100644 --- a/src/java-runtime/java-runtime.targets +++ b/src/java-runtime/java-runtime.targets @@ -7,17 +7,17 @@ $(OutputPath)java_runtime.dex $(IntermediateOutputPath)release $(IntermediateOutputPath)release.txt - java\mono\android\debug\MultiDexLoader.java;java\mono\android\MonkeyPatcher.java;java\mono\android\ResourcePatcher.java;java\mono\android\Seppuku.java + java\mono\android\debug\MultiDexLoader.java;java\mono\android\MonkeyPatcher.java;java\mono\android\ResourcePatcher.java;java\mono\android\Seppuku.java;java\mono\android\debug\BuildConfig.java <_RuntimeOutput Include="$(OutputPath)java_runtime_fastdev.jar"> $(OutputPath)java_runtime_fastdev.jar $(OutputPath)java_runtime_fastdev.dex $(IntermediateOutputPath)fastdev $(IntermediateOutputPath)fastdev.txt - java\mono\android\release\MultiDexLoader.java + java\mono\android\release\MultiDexLoader.java;java\mono\android\release\BuildConfig.java - diff --git a/src/java-runtime/java/mono/android/DebugRuntime.java b/src/java-runtime/java/mono/android/DebugRuntime.java new file mode 100644 index 00000000000..212b3916c9f --- /dev/null +++ b/src/java-runtime/java/mono/android/DebugRuntime.java @@ -0,0 +1,8 @@ +package mono.android; + +public class DebugRuntime { + private DebugRuntime () + {} + + public static native void init (String[] apks, String runtimeLibDir, String[] appDirs, String[] externalStorageDirs, int androidApiLevel, boolean embeddedDSOsEnabled); +} diff --git a/src/java-runtime/java/mono/android/MonoPackageManager.java b/src/java-runtime/java/mono/android/MonoPackageManager.java index 148ff23e79f..1ac3c9987d8 100644 --- a/src/java-runtime/java/mono/android/MonoPackageManager.java +++ b/src/java-runtime/java/mono/android/MonoPackageManager.java @@ -12,6 +12,8 @@ import android.content.res.AssetManager; import android.util.Log; import mono.android.Runtime; +import mono.android.DebugRuntime; +import mono.android.BuildConfig; public class MonoPackageManager { @@ -49,36 +51,47 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack external0, "../legacy/Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath (); boolean embeddedDSOsEnabled = (runtimePackage.flags & FLAG_EXTRACT_NATIVE_LIBS) == 0; + String runtimeDir = getNativeLibraryPath (runtimePackage); + String[] appDirs = new String[] {filesDir, cacheDir, dataDir}; + String[] externalStorageDirs = new String[] {externalDir, externalLegacyDir}; + // // Preload DSOs libmonodroid.so depends on so that the dynamic // linker can resolve them when loading monodroid. This is not // needed in the latest Android versions but is required in at least // API 16 and since there's no inherent negative effect of doing it, // we can do it unconditionally. + // + // We need to use our own `BuildConfig` class to detect debug builds here because, + // it seems, ApplicationInfo.flags information is not reliable - in the debug builds + // (with `android:debuggable=true` present on the `` element in the + // manifest) using shared runtime, the `runtimePackage.flags` field does NOT have + // the FLAGS_DEBUGGABLE (0x00000002) set and thus we'd revert to the `else` clause + // below, leading to an error locating the Mono runtime + // + if (BuildConfig.Debug) { + System.loadLibrary ("xamarin-debug-app-helper"); + DebugRuntime.init (apks, runtimeDir, appDirs, externalStorageDirs, android.os.Build.VERSION.SDK_INT, embeddedDSOsEnabled); + } else { + System.loadLibrary("monosgen-2.0"); + } System.loadLibrary("xamarin-app"); System.loadLibrary("monodroid"); Runtime.initInternal ( language, apks, - getNativeLibraryPath (runtimePackage), - new String[]{ - filesDir, - cacheDir, - dataDir, - }, + runtimeDir, + appDirs, loader, - new String[] { - externalDir, - externalLegacyDir - }, + externalStorageDirs, MonoPackageManager_Resources.Assemblies, android.os.Build.VERSION.SDK_INT, embeddedDSOsEnabled ); - + mono.android.app.ApplicationRegistration.registerApplications (); - + initialized = true; } } @@ -116,4 +129,3 @@ public static String getApiPackageName () return MonoPackageManager_Resources.ApiPackageName; } } - diff --git a/src/java-runtime/java/mono/android/debug/BuildConfig.java b/src/java-runtime/java/mono/android/debug/BuildConfig.java new file mode 100644 index 00000000000..198c2d10df9 --- /dev/null +++ b/src/java-runtime/java/mono/android/debug/BuildConfig.java @@ -0,0 +1,5 @@ +package mono.android; + +public class BuildConfig { + public static boolean Debug = true; +} diff --git a/src/java-runtime/java/mono/android/release/BuildConfig.java b/src/java-runtime/java/mono/android/release/BuildConfig.java new file mode 100644 index 00000000000..e709a143496 --- /dev/null +++ b/src/java-runtime/java/mono/android/release/BuildConfig.java @@ -0,0 +1,5 @@ +package mono.android; + +public class BuildConfig { + public static boolean Debug = false; +} diff --git a/src/monodroid/CMakeLists.txt b/src/monodroid/CMakeLists.txt index 67997fa4157..14afee336b8 100644 --- a/src/monodroid/CMakeLists.txt +++ b/src/monodroid/CMakeLists.txt @@ -23,16 +23,31 @@ include("../../build-tools/cmake/xa_macros.cmake") set(JAVA_INTEROP_SRC_PATH "../../external/Java.Interop/src/java-interop") string(REPLACE "\\" "/" TOP_DIR ${CMAKE_SOURCE_DIR}) -if(NOT DEFINED SGEN_BRIDGE_VERSION) - message(FATAL_ERROR "Please set the SGEN_BRIDGE_VERSION variable on command line (-DSGEN_BRIDGE_VERSION=VERSION)") -endif() - if(NOT DEFINED MONO_PATH) message(FATAL_ERROR "Please set the MONO_PATH variable on command line (-DMONO_PATH=PATH)") else() string(REPLACE "\\" "/" MONO_PATH ${MONO_PATH}) endif() +if(NOT DEFINED CONFIGURATION) + message(FATAL_ERROR "Please set the CONFIGURATION variable on command line (-DCONFIGURATION=name)") +endif() + +if(NOT DEFINED CMAKE_BUILD_TYPE) + message(FATAL_ERROR "Please set the CMAKE_BUILD_TYPE variable on command line (-DCMAKE_BUILD_TYPE=name)") +endif() + +set(BIN_DIRS ${CMAKE_BUILD_TYPE} ${CONFIGURATION}) +foreach(bdir ${BIN_DIRS}) + set(BIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/${bdir}") + if(EXISTS ${BIN_DIR}) + message(STATUS "BIN_DIR exists") + set(DEFAULT_BIN_DIR "${BIN_DIR}") + break() + endif() +endforeach(bdir) +set(XA_LIB_TOP_DIR "${DEFAULT_BIN_DIR}/lib/xamarin.android/xbuild/Xamarin/Android/lib") + if(NOT ANDROID) if (NOT DEFINED JDK_INCLUDE) message(FATAL_ERROR "Please set the JDK_INCLUDE variable on command line (-DJDK_INCLUDE)") @@ -120,6 +135,8 @@ if(ENABLE_NDK) # This is missing from the current NDK releases headers (that includes NDK r19b2) add_definitions("-D__ANDROID_API_Q__=29") endif() + + link_directories("${XA_LIB_TOP_DIR}/${ANDROID_ABI}") else() # MinGW needs it for {v,a}sprintf add_definitions("-D_GNU_SOURCE") @@ -146,7 +163,7 @@ else() if(WIN32 OR MINGW) message(STATUS "Win32 or MinGW") set(EXTRA_COMPILER_FLAGS "${EXTRA_COMPILER_FLAGS} -DWINDOWS -DNTDDI_VERSION=NTDDI_VISTA -D_WIN32_WINNT=_WIN32_WINNT_VISTA -fomit-frame-pointer") - set(EXTRA_LINKER_FLAGS "${EXTRA_LINKER_FLAGS} -ldl -lmman -static -pthread -dynamic -lwsock32 -lshlwapi -lpsapi") + set(EXTRA_LINKER_FLAGS "${EXTRA_LINKER_FLAGS} -ldl -lmman -static -pthread -dynamic -lmincore -lmswsock -lwsock32 -lshlwapi -lpsapi -lwinmm") if (MINGW_TARGET_32) set(ANDROID_ABI "host-mxe-Win32") @@ -163,16 +180,16 @@ else() include_directories("/usr/local/opt/mingw-zlib/usr/x86_64-w64-mingw32/include") endif() endif() + + link_directories("${XA_LIB_TOP_DIR}/${ANDROID_ABI}") endif() if(DEFINED HOST_BUILD_NAME) - include_directories("../../bin/${CMAKE_BUILD_TYPE}/include/${HOST_BUILD_NAME}") - include_directories("../../bin/${CMAKE_BUILD_TYPE}/include/${HOST_BUILD_NAME}/eglib") - - if (DEFINED CONFIGURATION) - include_directories("../../bin/${CONFIGURATION}/include/${HOST_BUILD_NAME}") - include_directories("../../bin/${CONFIGURATION}/include/${HOST_BUILD_NAME}/eglib") - endif() + link_directories("${XA_LIB_TOP_DIR}/${HOST_BUILD_NAME}") + include_directories("${DEFAULT_BIN_DIR}/include/${HOST_BUILD_NAME}") + include_directories("${DEFAULT_BIN_DIR}/include/${HOST_BUILD_NAME}/eglib") + include_directories("../../bin/${CONFIGURATION}/include/${HOST_BUILD_NAME}") + include_directories("../../bin/${CONFIGURATION}/include/${HOST_BUILD_NAME}/eglib") endif() endif() @@ -186,22 +203,19 @@ endif() add_definitions("-DHAVE_CONFIG_H") add_definitions("-D_REENTRANT") -add_definitions("-DXAMARIN_ANDROID_DYLIB_MONO") add_definitions("-DJI_DLL_EXPORT") add_definitions("-DMONO_DLL_EXPORT") -add_definitions("-DSGEN_BRIDGE_VERSION=${SGEN_BRIDGE_VERSION}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_COMPILER_FLAGS} ${EXTRA_C_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_COMPILER_FLAGS} ${EXTRA_CXX_FLAGS}") +include_directories("${DEFAULT_BIN_DIR}/include/mono-2.0") include_directories("jni") -include_directories("../../bin/${CMAKE_BUILD_TYPE}/include") -include_directories("../../bin/${CMAKE_BUILD_TYPE}/include/${ANDROID_ABI}/eglib") -if (DEFINED CONFIGURATION) - # This is to allow "release" builds with Debug build type and vice versa - include_directories("../../bin/${CONFIGURATION}/include") - include_directories("../../bin/${CONFIGURATION}/include/${ANDROID_ABI}/eglib") -endif() +include_directories("${DEFAULT_BIN_DIR}/include") +include_directories("${DEFAULT_BIN_DIR}/include/${ANDROID_ABI}/eglib") +# This is to allow "release" builds with Debug build type and vice versa +include_directories("../../bin/${CONFIGURATION}/include") +include_directories("../../bin/${CONFIGURATION}/include/${ANDROID_ABI}/eglib") include_directories("${MONO_PATH}/mono/eglib") include_directories("jni/zip") include_directories("${JAVA_INTEROP_SRC_PATH}") @@ -218,15 +232,17 @@ set(MONODROID_SOURCES ${MONODROID_SOURCES} ${SOURCES_DIR}/new_delete.cc ${SOURCES_DIR}/android-system.cc + ${SOURCES_DIR}/basic-android-system.cc + ${SOURCES_DIR}/basic-utilities.cc ${SOURCES_DIR}/cpu-arch-detect.cc ${SOURCES_DIR}/debug-constants.cc - ${SOURCES_DIR}/dylib-mono.cc ${SOURCES_DIR}/embedded-assemblies.cc ${SOURCES_DIR}/globals.cc ${SOURCES_DIR}/jni.c ${SOURCES_DIR}/logger.cc ${SOURCES_DIR}/monodroid-glue.cc ${SOURCES_DIR}/osbridge.cc + ${SOURCES_DIR}/shared-constants.cc ${SOURCES_DIR}/timezones.cc ${SOURCES_DIR}/util.cc ${SOURCES_DIR}/zip/ioapi.c @@ -248,6 +264,18 @@ endif() set(XAMARIN_APP_STUB_SOURCES ${SOURCES_DIR}/application_dso_stub.cc) add_library(xamarin-app SHARED ${XAMARIN_APP_STUB_SOURCES}) +if(NOT WIN32 AND NOT MINGW) + set(XAMARIN_DEBUG_APP_HELPER_SOURCES + ${SOURCES_DIR}/basic-android-system.cc + ${SOURCES_DIR}/basic-utilities.cc + ${SOURCES_DIR}/cpu-arch-detect.cc + ${SOURCES_DIR}/debug-app-helper.cc + ${SOURCES_DIR}/new_delete.cc + ${SOURCES_DIR}/shared-constants.cc + ) + add_library(xamarin-debug-app-helper SHARED ${XAMARIN_DEBUG_APP_HELPER_SOURCES}) +endif() + set(SOURCES_FRAGMENT_FILE "sources.projitems") file(WRITE ${SOURCES_FRAGMENT_FILE} "\n\ \n\ @@ -272,15 +300,21 @@ if(APPLE) endif() if(MINGW_ZLIB_LIBRARY_PATH) - set(LINK_LIBS "${MINGW_ZLIB_LIBRARY_PATH} ${EXTRA_LINKER_FLAGS}") + set(LINK_LIBS "-lmonosgen-2.0.dll ${MINGW_ZLIB_LIBRARY_PATH} ${EXTRA_LINKER_FLAGS}") else() - set(LINK_LIBS "-lz ${EXTRA_LINKER_FLAGS}") + set(LINK_LIBS "-lmonosgen-2.0 -lz ${EXTRA_LINKER_FLAGS}") endif() +set(DEBUG_HELPER_LINK_LIBS "-ldl") if(ENABLE_NDK) set(LINK_LIBS "${LINK_LIBS} -llog") + set(DEBUG_HELPER_LINK_LIBS "${DEBUG_HELPER_LINK_LIBS} -llog") elseif(NOT ANDROID) set(LINK_LIBS "-pthread ${LINK_LIBS} -ldl") endif() target_link_libraries(${MONO_ANDROID_LIB} ${LINK_LIBS} xamarin-app) + +if(NOT WIN32 AND NOT MINGW) + target_link_libraries(xamarin-debug-app-helper ${DEBUG_HELPER_LINK_LIBS}) +endif() diff --git a/src/monodroid/jni/android-system.cc b/src/monodroid/jni/android-system.cc index aa18e802ed7..c698f8d063e 100644 --- a/src/monodroid/jni/android-system.cc +++ b/src/monodroid/jni/android-system.cc @@ -21,11 +21,11 @@ #endif #include "unzip.h" -#include "globals.h" -#include "android-system.h" +#include "globals.hh" +#include "android-system.hh" #include "monodroid.h" -#include "monodroid-glue-internal.h" -#include "jni-wrappers.h" +#include "monodroid-glue-internal.hh" +#include "jni-wrappers.hh" #include "xamarin-app.h" #if defined (DEBUG) || !defined (ANDROID) @@ -47,33 +47,11 @@ BundledProperty *AndroidSystem::bundled_properties = nullptr; constexpr char AndroidSystem::OVERRIDE_ENVIRONMENT_FILE_NAME[]; #endif // DEBUG || !ANDROID -char* AndroidSystem::override_dirs [MAX_OVERRIDES]; -const char **AndroidSystem::app_lib_directories; -size_t AndroidSystem::app_lib_directories_size = 0; -#if WINDOWS -static const char *SYSTEM_LIB_PATH; -#else -constexpr char AndroidSystem::SYSTEM_LIB_PATH[]; -#endif -constexpr char AndroidSystem::MONO_SGEN_SO[]; -constexpr char AndroidSystem::MONO_SGEN_ARCH_SO[]; - #if defined (WINDOWS) std::mutex AndroidSystem::readdir_mutex; char *AndroidSystem::libmonoandroid_directory_path = nullptr; #endif -// Values correspond to the CPU_KIND_* macros -const char* AndroidSystem::android_abi_names[CPU_KIND_X86_64+1] = { - "unknown", - [CPU_KIND_ARM] = "armeabi-v7a", - [CPU_KIND_ARM64] = "arm64-v8a", - [CPU_KIND_MIPS] = "mips", - [CPU_KIND_X86] = "x86", - [CPU_KIND_X86_64] = "x86_64", -}; -#define ANDROID_ABI_NAMES_SIZE (sizeof(android_abi_names) / sizeof (android_abi_names[0])) - #if !defined (ANDROID) static constexpr uint32_t PROP_NAME_MAX = 32; static constexpr uint32_t PROP_VALUE_MAX = 92; @@ -382,163 +360,6 @@ AndroidSystem::create_update_dir (char *override_dir) log_warn (LOG_DEFAULT, "Creating public update directory: `%s`", override_dir); } -#define TRY_LIBMONOSGEN(dir) \ - if (dir) { \ - libmonoso = utils.path_combine (dir, MONO_SGEN_SO); \ - log_warn (LOG_DEFAULT, "Trying to load sgen from: %s", libmonoso); \ - if (utils.file_exists (libmonoso)) \ - return libmonoso; \ - delete[] libmonoso; \ - } - -#ifndef RELEASE -void -AndroidSystem::copy_native_libraries_to_internal_location () -{ - for (size_t i = 0; i < MAX_OVERRIDES; ++i) { - monodroid_dir_t *dir; - monodroid_dirent_t *e; - - char *dir_path = utils.path_combine (override_dirs [i], "lib"); - log_warn (LOG_DEFAULT, "checking directory: `%s`", dir_path); - - if (dir_path == nullptr || !utils.directory_exists (dir_path)) { - log_warn (LOG_DEFAULT, "directory does not exist: `%s`", dir_path); - delete[] dir_path; - continue; - } - - if ((dir = utils.monodroid_opendir (dir_path)) == nullptr) { - log_warn (LOG_DEFAULT, "could not open directory: `%s`", dir_path); - delete[] dir_path; - continue; - } - - while ((e = readdir (dir)) != nullptr) { - log_warn (LOG_DEFAULT, "checking file: `%s`", e->d_name); - if (utils.monodroid_dirent_hasextension (e, ".so")) { -#if WINDOWS - char *file_name = utils.utf16_to_utf8 (e->d_name); -#else /* def WINDOWS */ - char *file_name = e->d_name; -#endif /* ndef WINDOWS */ - copy_file_to_internal_location (primary_override_dir, dir_path, file_name); -#if WINDOWS - free (file_name); -#endif /* def WINDOWS */ - } - } - utils.monodroid_closedir (dir); - delete[] dir_path; - } -} -#endif - -inline bool AndroidSystem::try_load_libmonosgen (const char *dir, char*& libmonoso) -{ - if (dir == nullptr || *dir == '\0') - return false; - - libmonoso = utils.path_combine (dir, MONO_SGEN_SO); - log_warn (LOG_DEFAULT, "Trying to load sgen from: %s", libmonoso); - if (utils.file_exists (libmonoso)) - return true; - delete[] libmonoso; - libmonoso = nullptr; - - return false; -} - -char* -AndroidSystem::get_libmonosgen_path () -{ - char *libmonoso; - bool embedded_dso_mode_enabled = is_embedded_dso_mode_enabled (); - -#ifndef RELEASE - // Android 5 includes some restrictions on loading dynamic libraries via dlopen() from - // external storage locations so we need to file copy the shared object to an internal - // storage location before loading it. - copy_native_libraries_to_internal_location (); - - if (!embedded_dso_mode_enabled) { - for (size_t i = 0; i < MAX_OVERRIDES; ++i) { - if (try_load_libmonosgen (override_dirs [i], libmonoso)) { - return libmonoso; - } - } - } -#endif - if (!embedded_dso_mode_enabled) { - for (size_t i = 0; i < app_lib_directories_size; i++) { - if (try_load_libmonosgen (app_lib_directories [i], libmonoso)) { - return libmonoso; - } - } - } - - if (runtime_libdir != nullptr) { - libmonoso = utils.path_combine (runtime_libdir, MONO_SGEN_ARCH_SO); - } else - libmonoso = nullptr; - - if (libmonoso != nullptr && utils.file_exists (libmonoso)) { - char* links_dir = utils.path_combine (primary_override_dir, "links"); - char* link = utils.path_combine (links_dir, MONO_SGEN_SO); - if (!utils.directory_exists (links_dir)) { - if (!utils.directory_exists (primary_override_dir)) - utils.create_public_directory (primary_override_dir); - utils.create_public_directory (links_dir); - } - delete[] links_dir; - if (!utils.file_exists (link)) { - int result = symlink (libmonoso, link); - if (result != 0 && errno == EEXIST) { - log_warn (LOG_DEFAULT, "symlink exists, recreating: %s -> %s", link, libmonoso); - unlink (link); - result = symlink (libmonoso, link); - } - if (result != 0) - log_warn (LOG_DEFAULT, "symlink failed with errno=%i %s", errno, strerror (errno)); - } - delete[] libmonoso; - libmonoso = link; - } - - log_warn (LOG_DEFAULT, "Trying to load sgen from: %s", libmonoso); - if (libmonoso != nullptr && utils.file_exists (libmonoso)) - return libmonoso; - delete[] libmonoso; - -#ifdef WINDOWS - if (try_load_libmonosgen (get_libmonoandroid_directory_path (), libmonoso)) - return libmonoso; -#endif - - if (try_load_libmonosgen (SYSTEM_LIB_PATH, libmonoso)) - return libmonoso; - log_fatal (LOG_DEFAULT, "Cannot find '%s'. Looked in the following locations:", MONO_SGEN_SO); - -#ifndef RELEASE - if (!embedded_dso_mode_enabled) { - for (size_t i = 0; i < MAX_OVERRIDES; ++i) { - if (override_dirs [i] == nullptr) - continue; - log_fatal (LOG_DEFAULT, " %s", override_dirs [i]); - } - } -#endif - for (size_t i = 0; i < app_lib_directories_size; i++) { - log_fatal (LOG_DEFAULT, " %s", app_lib_directories [i]); - } - - log_fatal (LOG_DEFAULT, "Do you have a shared runtime build of your app with AndroidManifest.xml android:minSdkVersion < 10 while running on a 64-bit Android 5.0 target? This combination is not supported."); - log_fatal (LOG_DEFAULT, "Please either set android:minSdkVersion >= 10 or use a build without the shared runtime (like default Release configuration)."); - exit (FATAL_EXIT_CANNOT_FIND_LIBMONOSGEN); - - return libmonoso; -} - char* AndroidSystem::get_full_dso_path (const char *base_dir, const char *dso_path, bool *needs_free) { @@ -731,48 +552,6 @@ AndroidSystem::get_max_gref_count_from_system (void) return max; } -#ifdef ANDROID -void -AndroidSystem::copy_file_to_internal_location (char *to_dir, char *from_dir, char *file) -{ - char *from_file = utils.path_combine (from_dir, file); - char *to_file = nullptr; - - do { - if (!from_file || !utils.file_exists (from_file)) - break; - - log_warn (LOG_DEFAULT, "Copying file `%s` from external location `%s` to internal location `%s`", - file, from_dir, to_dir); - - to_file = utils.path_combine (to_dir, file); - if (!to_file) - break; - - int r = unlink (to_file); - if (r < 0 && errno != ENOENT) { - log_warn (LOG_DEFAULT, "Unable to delete file `%s`: %s", to_file, strerror (errno)); - break; - } - - if (!utils.file_copy (to_file, from_file)) { - log_warn (LOG_DEFAULT, "Copy failed from `%s` to `%s`: %s", from_file, to_file, strerror (errno)); - break; - } - - utils.set_user_executable (to_file); - } while (0); - - delete[] from_file; - delete[] to_file; -} -#else /* !defined (ANDROID) */ -void -AndroidSystem::copy_file_to_internal_location (char *to_dir, char *from_dir, char* file) -{ -} -#endif /* defined (ANDROID) */ - long AndroidSystem::get_gref_gc_threshold () { @@ -915,11 +694,11 @@ AndroidSystem::setup_environment () break; default: - aotMode = MonoAotMode::MONO_AOT_MODE_UNKNOWN; + aotMode = MonoAotMode::MONO_AOT_MODE_LAST; break; } - if (aotMode != MonoAotMode::MONO_AOT_MODE_UNKNOWN) + if (aotMode == MonoAotMode::MONO_AOT_MODE_LAST) log_info (LOG_DEFAULT, "Mono AOT mode: %s", mono_aot_mode_name); else log_warn (LOG_DEFAULT, "Unknown Mono AOT mode: %s", mono_aot_mode_name); @@ -962,17 +741,6 @@ AndroidSystem::setup_environment () #endif } -void -AndroidSystem::for_each_apk (JNIEnv *env, jstring_array_wrapper &runtimeApks, void (AndroidSystem::*handler) (const char *apk, size_t index, size_t apk_count, void *user_data), void *user_data) -{ - size_t apksLength = runtimeApks.get_length (); - for (size_t i = 0; i < apksLength; ++i) { - jstring_wrapper &e = runtimeApks [i]; - - (this->*handler) (e.get_cstr (), i, apksLength, user_data); - } -} - void AndroidSystem::setup_process_args_apk (const char *apk, size_t index, size_t apk_count, void *user_data) { @@ -980,28 +748,13 @@ AndroidSystem::setup_process_args_apk (const char *apk, size_t index, size_t apk return; char *args[1] = { (char*) apk }; - monoFunctions.runtime_set_main_args (1, args); + mono_runtime_set_main_args (1, args); } void AndroidSystem::setup_process_args (JNIEnv *env, jstring_array_wrapper &runtimeApks) { - for_each_apk (env, runtimeApks, &AndroidSystem::setup_process_args_apk, nullptr); -} - -void -AndroidSystem::add_apk_libdir (const char *apk, size_t index, size_t apk_count, void *user_data) -{ - assert (user_data != nullptr); - assert (index >= 0 && index < app_lib_directories_size); - app_lib_directories [index] = monodroid_strdup_printf ("%s!/lib/%s", apk, (const char*)user_data); -} - -void -AndroidSystem::setup_apk_directories (JNIEnv *env, unsigned short running_on_cpu, jstring_array_wrapper &runtimeApks) -{ - // Man, the cast is ugly... - for_each_apk (env, runtimeApks, &AndroidSystem::add_apk_libdir, const_cast (static_cast (android_abi_names [running_on_cpu]))); + for_each_apk (env, runtimeApks, static_cast (&AndroidSystem::setup_process_args_apk), nullptr); } monodroid_dirent_t* diff --git a/src/monodroid/jni/android-system.h b/src/monodroid/jni/android-system.hh similarity index 55% rename from src/monodroid/jni/android-system.h rename to src/monodroid/jni/android-system.hh index 8b9cd9b5068..94a80c4381c 100644 --- a/src/monodroid/jni/android-system.h +++ b/src/monodroid/jni/android-system.hh @@ -7,11 +7,13 @@ #include #include -#include "dylib-mono.h" -#include "util.h" -#include "cpu-arch.h" -#include "cppcompat.h" +#include "util.hh" +#include "cppcompat.hh" #include "xamarin-app.h" +#include "shared-constants.hh" +#include "basic-android-system.hh" + +#include namespace xamarin { namespace android { class jstring_wrapper; @@ -24,7 +26,7 @@ namespace xamarin { namespace android { namespace internal struct BundledProperty; #endif - class AndroidSystem + class AndroidSystem : public BasicAndroidSystem { private: #if defined (DEBUG) || !defined (ANDROID) @@ -32,95 +34,26 @@ namespace xamarin { namespace android { namespace internal static constexpr uint32_t OVERRIDE_ENVIRONMENT_FILE_HEADER_SIZE = 22; static BundledProperty *bundled_properties; #endif - static const char* android_abi_names[CPU_KIND_X86_64+1]; #if defined (WINDOWS) static std::mutex readdir_mutex; static char *libmonoandroid_directory_path; #endif -// _WIN32 is defined with _WIN64 so _WIN64 must be checked first. -#if __SIZEOF_POINTER__ == 8 || defined (_WIN64) -#define __BITNESS__ "64bit" -#elif __SIZEOF_POINTER__ == 4 || defined (_WIN32) -#define __BITNESS__ "32bit" -#else -#error Unknown pointer size for this platform -#endif - - public: -#ifdef ANDROID64 - static constexpr char SYSTEM_LIB_PATH[] = "/system/lib64"; -#elif ANDROID - static constexpr char SYSTEM_LIB_PATH[] = "/system/lib"; -#elif LINUX_FLATPAK - static constexpr char SYSTEM_LIB_PATH[] = "/app/lib/mono"; -#elif LINUX - static constexpr char SYSTEM_LIB_PATH[] = "/usr/lib"; -#elif APPLE_OS_X - static constexpr char SYSTEM_LIB_PATH[] = "/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/xamarin.android/xbuild/Xamarin/Android/lib/host-Darwin"; -#elif WINDOWS - static const char *SYSTEM_LIB_PATH; -#else - static constexpr char SYSTEM_LIB_PATH[] = ""; -#endif - -#if ANDROID || LINUX - static constexpr char MONO_SGEN_SO[] = "libmonosgen-2.0.so"; - static constexpr char MONO_SGEN_ARCH_SO[] = "libmonosgen-" __BITNESS__ "-2.0.so"; -#elif APPLE_OS_X - static constexpr char MONO_SGEN_SO[] = "libmonosgen-2.0.dylib"; - static constexpr char MONO_SGEN_ARCH_SO[] = "libmonosgen-" __BITNESS__ "-2.0.dylib"; -#elif WINDOWS - static constexpr char MONO_SGEN_SO[] = "libmonosgen-2.0.dll"; - static constexpr char MONO_SGEN_ARCH_SO[] = "libmonosgen-" __BITNESS__ "-2.0.dll"; -#else - static constexpr char MONO_SGEN_SO[] = "monosgen-2.0"; - static constexpr char MONO_SGEN_ARCH_SO[] = "monosgen-" __BITNESS__ "-2.0"; -#endif - - public: -#ifdef RELEASE - static constexpr size_t MAX_OVERRIDES = 1; -#else - static constexpr size_t MAX_OVERRIDES = 3; -#endif - static char* override_dirs [MAX_OVERRIDES]; - static const char **app_lib_directories; - static size_t app_lib_directories_size; - public: void setup_environment (); void setup_process_args (JNIEnv *env, jstring_array_wrapper &runtimeApks); + void create_update_dir (char *override_dir); int monodroid_get_system_property (const char *name, char **value); size_t monodroid_get_system_property_from_overrides (const char *name, char ** value); size_t monodroid_read_file_into_memory (const char *path, char **value); - void create_update_dir (char *override_dir); - char* get_libmonosgen_path (); char* get_bundled_app (JNIEnv *env, jstring dir); int count_override_assemblies (); long get_gref_gc_threshold (); - void setup_apk_directories (JNIEnv *env, unsigned short running_on_cpu, jstring_array_wrapper &runtimeApks); void* load_dso (const char *path, int dl_flags, bool skip_exists_check); void* load_dso_from_any_directories (const char *name, int dl_flags); char* get_full_dso_path_on_disk (const char *dso_name, bool *needs_free); monodroid_dirent_t* readdir (monodroid_dir_t *dir); - const char* get_override_dir (size_t index) const - { - if (index >= MAX_OVERRIDES) - return nullptr; - - return override_dirs [index]; - } - - void set_override_dir (uint32_t index, const char* dir) - { - if (index >= MAX_OVERRIDES) - return; - - override_dirs [index] = const_cast (dir); - } - long get_max_gref_count () const { return max_gref_count; @@ -149,16 +82,6 @@ namespace xamarin { namespace android { namespace internal return application_config.uses_mono_aot; } - bool is_embedded_dso_mode_enabled () const - { - return embedded_dso_mode_enabled; - } - - void set_embedded_dso_mode_enabled (bool yesno) - { - embedded_dso_mode_enabled = yesno; - } - MonoAotMode get_mono_aot_mode () const { return aotMode; @@ -178,16 +101,12 @@ namespace xamarin { namespace android { namespace internal #if defined (DEBUG) || !defined (ANDROID) size_t _monodroid_get_system_property_from_file (const char *path, char **value); #endif - void copy_native_libraries_to_internal_location (); - void copy_file_to_internal_location (char *to_dir, char *from_dir, char *file); - void add_apk_libdir (const char *apk, size_t index, size_t apk_count, void *user_data); - void for_each_apk (JNIEnv *env, jstring_array_wrapper &runtimeApks, void (AndroidSystem::*handler) (const char *apk, size_t index, size_t apk_count, void *user_data), void *user_data); char* get_full_dso_path (const char *base_dir, const char *dso_path, bool *needs_free); void* load_dso_from_specified_dirs (const char **directories, size_t num_entries, const char *dso_name, int dl_flags); void* load_dso_from_app_lib_dirs (const char *name, int dl_flags); void* load_dso_from_override_dirs (const char *name, int dl_flags); char* get_existing_dso_path_on_disk (const char *base_dir, const char *dso_name, bool *needs_free); - bool try_load_libmonosgen (const char *dir, char*& libmonoso); + #if defined (WINDOWS) struct _wdirent* readdir_windows (_WDIR *dirp); char* get_libmonoandroid_directory_path (); @@ -201,7 +120,6 @@ namespace xamarin { namespace android { namespace internal private: long max_gref_count = 0; MonoAotMode aotMode = MonoAotMode::MONO_AOT_MODE_NONE; - bool embedded_dso_mode_enabled = false; }; }}} #endif // !__ANDROID_SYSTEM_H diff --git a/src/monodroid/jni/basic-android-system.cc b/src/monodroid/jni/basic-android-system.cc new file mode 100644 index 00000000000..253faf647d5 --- /dev/null +++ b/src/monodroid/jni/basic-android-system.cc @@ -0,0 +1,79 @@ +#include + +#include "basic-android-system.hh" +#include "globals.hh" + +using namespace xamarin::android; +using namespace xamarin::android::internal; + +char* BasicAndroidSystem::override_dirs [MAX_OVERRIDES]; +const char **BasicAndroidSystem::app_lib_directories; +size_t BasicAndroidSystem::app_lib_directories_size = 0; +#if WINDOWS +static const char *SYSTEM_LIB_PATH; +#else +constexpr char BasicAndroidSystem::SYSTEM_LIB_PATH[]; +#endif + +// Values correspond to the CPU_KIND_* macros +const char* BasicAndroidSystem::android_abi_names[CPU_KIND_X86_64+1] = { + "unknown", + [CPU_KIND_ARM] = "armeabi-v7a", + [CPU_KIND_ARM64] = "arm64-v8a", + [CPU_KIND_MIPS] = "mips", + [CPU_KIND_X86] = "x86", + [CPU_KIND_X86_64] = "x86_64", +}; +#define ANDROID_ABI_NAMES_SIZE (sizeof(android_abi_names) / sizeof (android_abi_names[0])) + +void +BasicAndroidSystem::setup_app_library_directories (JNIEnv *env, jstring_array_wrapper& runtimeApks, jstring_array_wrapper& appDirs, int androidApiLevel) +{ + if (androidApiLevel < 23 || !is_embedded_dso_mode_enabled ()) { + log_info (LOG_DEFAULT, "Setting up for DSO lookup in app data directories"); + BasicAndroidSystem::app_lib_directories_size = 1; + BasicAndroidSystem::app_lib_directories = (const char**) xcalloc (BasicAndroidSystem::app_lib_directories_size, sizeof(char*)); + BasicAndroidSystem::app_lib_directories [0] = strdup (appDirs[2].get_cstr ()); + } else { + log_info (LOG_DEFAULT, "Setting up for DSO lookup directly in the APK"); + BasicAndroidSystem::app_lib_directories_size = runtimeApks.get_length (); + BasicAndroidSystem::app_lib_directories = (const char**) xcalloc (BasicAndroidSystem::app_lib_directories_size, sizeof(char*)); + + unsigned short built_for_cpu = 0, running_on_cpu = 0; + unsigned char is64bit = 0; + _monodroid_detect_cpu_and_architecture (&built_for_cpu, &running_on_cpu, &is64bit); + setup_apk_directories (env, running_on_cpu, runtimeApks); + } +} + +void +BasicAndroidSystem::for_each_apk (JNIEnv *env, jstring_array_wrapper &runtimeApks, ForEachApkHandler handler, void *user_data) +{ + size_t apksLength = runtimeApks.get_length (); + for (size_t i = 0; i < apksLength; ++i) { + jstring_wrapper &e = runtimeApks [i]; + + (this->*handler) (e.get_cstr (), i, apksLength, user_data); + } +} + +void +BasicAndroidSystem::add_apk_libdir (const char *apk, size_t index, size_t apk_count, void *user_data) +{ + assert (user_data != nullptr); + assert (index >= 0 && index < app_lib_directories_size); + app_lib_directories [index] = utils.monodroid_strdup_printf ("%s!/lib/%s", apk, (const char*)user_data); +} + +void +BasicAndroidSystem::setup_apk_directories (JNIEnv *env, unsigned short running_on_cpu, jstring_array_wrapper &runtimeApks) +{ + // Man, the cast is ugly... + for_each_apk (env, runtimeApks, &BasicAndroidSystem::add_apk_libdir, const_cast (static_cast (android_abi_names [running_on_cpu]))); +} + +char* +BasicAndroidSystem::determine_primary_override_dir (JNIEnv *env, jstring_wrapper &home) +{ + return utils.path_combine (home.get_cstr (), ".__override__"); +} diff --git a/src/monodroid/jni/basic-android-system.hh b/src/monodroid/jni/basic-android-system.hh new file mode 100644 index 00000000000..3d6b1a5530a --- /dev/null +++ b/src/monodroid/jni/basic-android-system.hh @@ -0,0 +1,109 @@ +#ifndef __BASIC_ANDROID_SYSTEM_HH +#define __BASIC_ANDROID_SYSTEM_HH + +#include +#include + +#include "cpu-arch.hh" +#include "jni-wrappers.hh" + +namespace xamarin::android::internal +{ + class BasicAndroidSystem + { + protected: + using ForEachApkHandler = void (BasicAndroidSystem::*) (const char *apk, size_t index, size_t apk_count, void *user_data); + + private: + static const char* android_abi_names[CPU_KIND_X86_64+1]; + + public: +#ifdef ANDROID64 + static constexpr char SYSTEM_LIB_PATH[] = "/system/lib64"; +#elif ANDROID + static constexpr char SYSTEM_LIB_PATH[] = "/system/lib"; +#elif LINUX_FLATPAK + static constexpr char SYSTEM_LIB_PATH[] = "/app/lib/mono"; +#elif LINUX + static constexpr char SYSTEM_LIB_PATH[] = "/usr/lib"; +#elif APPLE_OS_X + static constexpr char SYSTEM_LIB_PATH[] = "/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/xamarin.android/xbuild/Xamarin/Android/lib/host-Darwin"; +#elif WINDOWS + static const char *SYSTEM_LIB_PATH; +#else + static constexpr char SYSTEM_LIB_PATH[] = ""; +#endif + +#ifdef RELEASE + static constexpr size_t MAX_OVERRIDES = 1; +#else + static constexpr size_t MAX_OVERRIDES = 3; +#endif + static char* override_dirs [MAX_OVERRIDES]; + static const char **app_lib_directories; + static size_t app_lib_directories_size; + + public: + void setup_app_library_directories (JNIEnv *env, jstring_array_wrapper& runtimeApks, jstring_array_wrapper& appDirs, int androidApiLevel); + void setup_apk_directories (JNIEnv *env, unsigned short running_on_cpu, jstring_array_wrapper &runtimeApks); + + const char* get_override_dir (size_t index) const + { + if (index >= MAX_OVERRIDES) + return nullptr; + + return override_dirs [index]; + } + + void set_override_dir (uint32_t index, const char* dir) + { + if (index >= MAX_OVERRIDES) + return; + + override_dirs [index] = const_cast (dir); + } + + bool is_embedded_dso_mode_enabled () const + { + return embedded_dso_mode_enabled; + } + + void set_embedded_dso_mode_enabled (bool yesno) + { + embedded_dso_mode_enabled = yesno; + } + + char *get_runtime_libdir () const + { + return runtime_libdir; + } + + void set_runtime_libdir (char *dir) + { + runtime_libdir = dir; + } + + char *get_primary_override_dir () const + { + return primary_override_dir; + } + + void set_primary_override_dir (JNIEnv *env, jstring_wrapper& home) + { + primary_override_dir = determine_primary_override_dir (env, home); + } + + protected: + void add_apk_libdir (const char *apk, size_t index, size_t apk_count, void *user_data); + void for_each_apk (JNIEnv *env, jstring_array_wrapper &runtimeApks, ForEachApkHandler handler, void *user_data); + + private: + char* determine_primary_override_dir (JNIEnv *env, jstring_wrapper &home); + + private: + bool embedded_dso_mode_enabled = false; + char *runtime_libdir = nullptr; + char *primary_override_dir = nullptr; + }; +} +#endif // !__BASIC_ANDROID_SYSTEM_HH diff --git a/src/monodroid/jni/basic-utilities.cc b/src/monodroid/jni/basic-utilities.cc new file mode 100644 index 00000000000..5aa59e07af5 --- /dev/null +++ b/src/monodroid/jni/basic-utilities.cc @@ -0,0 +1,373 @@ +#include +#include + +#ifdef WINDOWS +#include +#include +#endif + +#include "basic-utilities.hh" +#include "logger.hh" + +using namespace xamarin::android; + +int +BasicUtilities::ends_with (const char *str, const char *end) +{ + char *p; + + p = const_cast (strstr (str, end)); + + return p != nullptr && p [strlen (end)] == 0; +} + +char* +BasicUtilities::path_combine (const char *path1, const char *path2) +{ + // Don't let erroneous nullptr parameters situation propagate + assert (path1 != nullptr || path2 != nullptr); + + if (path1 == nullptr) + return strdup_new (path2); + if (path2 == nullptr) + return strdup_new (path1); + + size_t len = add_with_overflow_check (__FILE__, __LINE__, strlen (path1), strlen (path2) + 2); + char *ret = new char [len]; + *ret = '\0'; + + strcat (ret, path1); + strcat (ret, MONODROID_PATH_SEPARATOR); + strcat (ret, path2); + + return ret; +} + +void +BasicUtilities::create_public_directory (const char *dir) +{ +#ifndef WINDOWS + mode_t m = umask (0); + mkdir (dir, 0777); + umask (m); +#else + wchar_t *buffer = utf8_to_utf16 (dir); + _wmkdir (buffer); + free (buffer); +#endif +} + +int +BasicUtilities::create_directory (const char *pathname, mode_t mode) +{ + if (mode <= 0) + mode = DEFAULT_DIRECTORY_MODE; + + if (!pathname || *pathname == '\0') { + errno = EINVAL; + return -1; + } +#ifdef WINDOWS + int oldumask; +#else + mode_t oldumask; +#endif + oldumask = umask (022); + char *path = strdup_new (pathname); + int rv, ret = 0; + for (char *d = path; *d; ++d) { + if (*d != '/') + continue; + *d = 0; + if (*path) { + rv = make_directory (path, mode); + if (rv == -1 && errno != EEXIST) { + ret = -1; + break; + } + } + *d = '/'; + } + delete[] path; + if (ret == 0) + ret = make_directory (pathname, mode); + umask (oldumask); + + return ret; +} + +void +BasicUtilities::set_world_accessable (const char *path) +{ +#ifdef ANDROID + int r; + do + r = chmod (path, 0664); + while (r == -1 && errno == EINTR); + + if (r == -1) + log_error (LOG_DEFAULT, "chmod(\"%s\", 0664) failed: %s", path, strerror (errno)); +#endif +} + +void +BasicUtilities::set_user_executable (const char *path) +{ +#ifdef ANDROID + int r; + do { + r = chmod (path, S_IRUSR | S_IWUSR | S_IXUSR); + } while (r == -1 && errno == EINTR); + + if (r == -1) + log_error (LOG_DEFAULT, "chmod(\"%s\") failed: %s", path, strerror (errno)); +#endif +} + +bool +BasicUtilities::file_exists (const char *file) +{ + monodroid_stat_t s; + if (monodroid_stat (file, &s) == 0 && (s.st_mode & S_IFMT) == S_IFREG) + return true; + return false; +} + +bool +BasicUtilities::directory_exists (const char *directory) +{ + monodroid_stat_t s; + if (monodroid_stat (directory, &s) == 0 && (s.st_mode & S_IFMT) == S_IFDIR) + return true; + return false; +} + +bool +BasicUtilities::file_copy (const char *to, const char *from) +{ + char buffer[BUFSIZ]; + size_t n; + int saved_errno; + + FILE *f1 = monodroid_fopen (from, "r"); + FILE *f2 = monodroid_fopen (to, "w+"); + + while ((n = fread (buffer, sizeof(char), sizeof(buffer), f1)) > 0) { + if (fwrite (buffer, sizeof(char), n, f2) != n) { + saved_errno = errno; + fclose (f1); + fclose (f2); + errno = saved_errno; + + return false; + } + } + + fclose (f1); + fclose (f2); + return true; +} + +bool +BasicUtilities::is_path_rooted (const char *path) +{ + if (path == nullptr) + return false; +#ifdef WINDOWS + LPCWSTR wpath = utf8_to_utf16 (path); + bool ret = !PathIsRelativeW (wpath); + free (const_cast (reinterpret_cast (wpath))); + return ret; +#else + return path [0] == MONODROID_PATH_SEPARATOR_CHAR; +#endif +} + +FILE * +BasicUtilities::monodroid_fopen (const char *filename, const char *mode) +{ +#ifndef WINDOWS + /* On Unix, both path and system calls are all assumed + * to be UTF-8 compliant. + */ + return fopen (filename, mode); +#else + // Convert the path and mode to a UTF-16 and then use the wide variant of fopen + wchar_t *wpath = utf8_to_utf16 (filename); + wchar_t *wmode = utf8_to_utf16 (mode); + + FILE* file = _wfopen (wpath, wmode); + free (wpath); + free (wmode); + + return file; +#endif // ndef WINDOWS +} + +int +BasicUtilities::monodroid_stat (const char *path, monodroid_stat_t *s) +{ + int result; + +#ifndef WINDOWS + result = stat (path, s); +#else + wchar_t *wpath = utf8_to_utf16 (path); + result = _wstat (wpath, s); + free (wpath); +#endif + + return result; +} + +monodroid_dir_t* +BasicUtilities::monodroid_opendir (const char *filename) +{ +#ifndef WINDOWS + return opendir (filename); +#else + wchar_t *wfilename = utf8_to_utf16 (filename); + monodroid_dir_t *result = _wopendir (wfilename); + free (wfilename); + return result; +#endif +} + +int +BasicUtilities::monodroid_closedir (monodroid_dir_t *dirp) +{ +#ifndef WINDOWS + return closedir (dirp); +#else + return _wclosedir (dirp); +#endif +} + +int +BasicUtilities::monodroid_dirent_hasextension (monodroid_dirent_t *e, const char *extension) +{ +#ifndef WINDOWS + return ends_with (e->d_name, extension); +#else + char *mb_dname = utf16_to_utf8 (e->d_name); + int result = ends_with (mb_dname, extension); + free (mb_dname); + return result; +#endif +} + +void +BasicUtilities::monodroid_strfreev (char **str_array) +{ + char **orig = str_array; + if (str_array == nullptr) + return; + while (*str_array != nullptr){ + free (*str_array); + str_array++; + } + free (orig); +} + +char ** +BasicUtilities::monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) +{ + const char *c; + char *token, **vector; + size_t size = 1; + + if (strncmp (str, delimiter, strlen (delimiter)) == 0) { + vector = (char **)xmalloc (2 * sizeof(vector)); + vector[0] = strdup (""); + size++; + str += strlen (delimiter); + } else { + vector = nullptr; + } + + while (*str && !(max_tokens > 0 && size >= max_tokens)) { + c = str; + if (strncmp (str, delimiter, strlen (delimiter)) == 0) { + token = strdup (""); + str += strlen (delimiter); + } else { + while (*str && strncmp (str, delimiter, strlen (delimiter)) != 0) { + str++; + } + + if (*str) { + size_t toklen = static_cast((str - c)); + size_t alloc_size = add_with_overflow_check (__FILE__, __LINE__, toklen, 1); + token = new char [alloc_size]; + strncpy (token, c, toklen); + token [toklen] = '\0'; + + /* Need to leave a trailing empty + * token if the delimiter is the last + * part of the string + */ + if (strcmp (str, delimiter) != 0) { + str += strlen (delimiter); + } + } else { + token = strdup (c); + } + } + + add_to_vector (&vector, size, token); + size++; + } + + if (*str) { + if (strcmp (str, delimiter) == 0) + add_to_vector (&vector, size, strdup ("")); + else { + /* Add the rest of the string as the last element */ + add_to_vector (&vector, size, strdup (str)); + } + size++; + } + + if (vector == nullptr) { + vector = (char **) xmalloc (2 * sizeof (vector)); + vector [0] = nullptr; + } else if (size > 0) { + vector[size - 1] = nullptr; + } + + return vector; +} + +char * +BasicUtilities::monodroid_strdup_printf (const char *format, ...) +{ + va_list args; + + va_start (args, format); + char *ret = monodroid_strdup_vprintf (format, args); + va_end (args); + + return ret; +} + +char* +BasicUtilities::monodroid_strdup_vprintf (const char *format, va_list vargs) +{ + char *ret = nullptr; + int n = vasprintf (&ret, format, vargs); + + return n == -1 ? nullptr : ret; +} + +void +BasicUtilities::add_to_vector (char ***vector, size_t size, char *token) +{ + if (*vector == nullptr) { + *vector = (char **)static_cast(xmalloc (size * sizeof(*vector))); + } else { + size_t alloc_size = multiply_with_overflow_check (__FILE__, __LINE__, sizeof(*vector), size + 1); + *vector = static_cast(xrealloc (*vector, alloc_size)); + } + + (*vector)[size - 1] = token; +} diff --git a/src/monodroid/jni/util.h b/src/monodroid/jni/basic-utilities.hh similarity index 61% rename from src/monodroid/jni/util.h rename to src/monodroid/jni/basic-utilities.hh index 5e048c9641a..3bac0359aaa 100644 --- a/src/monodroid/jni/util.h +++ b/src/monodroid/jni/basic-utilities.hh @@ -1,21 +1,29 @@ -// This is a -*- C++ -*- header -#ifndef __MONODROID_UTIL_H__ -#define __MONODROID_UTIL_H__ +#ifndef __BASIC_UTILITIES_HH +#define __BASIC_UTILITIES_HH -#ifndef TRUE -#ifdef __cplusplus -constexpr int TRUE = 1; -#else -#define TRUE 1 -#endif // __cplusplus -#endif +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include -#ifndef FALSE -#ifdef __cplusplus -constexpr int FALSE = 0; +#include "java-interop-util.h" + +#if __cplusplus >= 201703L +#define UNUSED_ARG [[maybe_unused]] #else -#define FALSE 0 -#endif // __cplusplus +#if defined (__GNUC__) +#define UNUSED_ARG __attribute__((__unused__)) +#else +#define UNUSED_ARG +#endif #endif #if WINDOWS @@ -26,23 +34,6 @@ constexpr int FALSE = 0; #define MONODROID_PATH_SEPARATOR_CHAR '/' #endif -#include -#include -#ifdef HAVE_BSD_STRING_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -#include "monodroid.h" -#include "dylib-mono.h" -#include "jni-wrappers.h" - #if WINDOWS typedef struct _stat monodroid_stat_t; #define monodroid_dir_t _WDIR @@ -53,89 +44,16 @@ typedef struct stat monodroid_stat_t; typedef struct dirent monodroid_dirent_t; #endif -#include "java-interop-util.h" -#include "logger.h" - #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 - MONO_API void monodroid_strfreev (char **str_array); - MONO_API char **monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens); - MONO_API char *monodroid_strdup_printf (const char *format, ...); - MONO_API void monodroid_store_package_name (const char *name); - MONO_API int monodroid_get_namespaced_system_property (const char *name, char **value); - MONO_API FILE *monodroid_fopen (const char* filename, const char* mode); - - MONO_API int send_uninterrupted (int fd, void *buf, int len); - MONO_API int recv_uninterrupted (int fd, void *buf, int len); - MONO_API void set_world_accessable (const char *path); - MONO_API void create_public_directory (const char *dir); - MONO_API char *path_combine (const char *path1, const char *path2); -#ifdef __cplusplus -} - -namespace xamarin { namespace android +namespace xamarin::android { - struct timing_point - { - time_t sec; - uint64_t ns; - - void mark (); - }; - - struct timing_period - { - timing_point start; - timing_point end; - - void mark_start () - { - start.mark (); - } - - void mark_end () - { - end.mark (); - } - }; - - struct timing_diff - { - static constexpr uint32_t ms_in_nsec = 1000000ULL; - - time_t sec; - uint32_t ms; - uint32_t ns; - - timing_diff (const timing_period &period); - }; - #define ADD_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) utils.add_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) #define MULTIPLY_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) utils.multiply_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) - class Util + class BasicUtilities { -#if defined (ANDROID) || defined (LINUX) - using timestruct = timespec; -#else - using timestruct = timeval; -#endif - static constexpr uint32_t ms_in_nsec = 1000000ULL; - public: FILE *monodroid_fopen (const char* filename, const char* mode); int monodroid_stat (const char *path, monodroid_stat_t *s); @@ -146,17 +64,8 @@ namespace xamarin { namespace android char **monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens); char *monodroid_strdup_printf (const char *format, ...); char *monodroid_strdup_vprintf (const char *format, va_list vargs); - void monodroid_store_package_name (const char *name); - size_t monodroid_get_namespaced_system_property (const char *name, char **value); - MonoAssembly *monodroid_load_assembly (MonoDomain *domain, const char *basename); - MonoObject *monodroid_runtime_invoke (MonoDomain *domain, MonoMethod *method, void *obj, void **params, MonoObject **exc); - MonoClass *monodroid_get_class_from_name (MonoDomain *domain, const char* assembly, const char *_namespace, const char *type); - MonoDomain *monodroid_create_appdomain (MonoDomain *parent_domain, const char *friendly_name, int shadow_copy, const char *shadow_directories); - MonoClass *monodroid_get_class_from_image (MonoDomain *domain, MonoImage* image, const char *_namespace, const char *type); int ends_with (const char *str, const char *end); char* path_combine(const char *path1, const char *path2); - int send_uninterrupted (int fd, void *buf, size_t len); - ssize_t recv_uninterrupted (int fd, void *buf, size_t len); void create_public_directory (const char *dir); int create_directory (const char *pathname, mode_t mode); void set_world_accessable (const char *path); @@ -164,9 +73,23 @@ namespace xamarin { namespace android bool file_exists (const char *file); bool directory_exists (const char *directory); bool file_copy (const char *to, const char *from); - jclass get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *name, bool make_gref = false); - char *strdup_new (const char* s) + void *xmalloc (size_t size) + { + return ::xmalloc (size); + } + + void *xrealloc (void *ptr, size_t size) + { + return ::xrealloc (ptr, size); + } + + void *xcalloc (size_t nmemb, size_t size) + { + return ::xcalloc (nmemb, size); + } + + char *strdup_new (const char* s) { assert (s != nullptr); @@ -210,26 +133,6 @@ namespace xamarin { namespace android #endif // !def WINDOWS bool is_path_rooted (const char *path); - void *xmalloc (size_t size) - { - return ::xmalloc (size); - } - - void *xrealloc (void *ptr, size_t size) - { - return ::xrealloc (ptr, size); - } - - void *xcalloc (size_t nmemb, size_t size) - { - return ::xcalloc (nmemb, size); - } - - bool should_log (LogCategories category) const - { - return (log_categories & category) != 0; - } - template inline Ret add_with_overflow_check (const char *file, uint32_t line, P1 a, P2 b) const { @@ -268,20 +171,9 @@ namespace xamarin { namespace android return ret; } - private: - //char *monodroid_strdup_printf (const char *format, va_list vargs); - void add_to_vector (char ***vector, size_t size, char *token); - void monodroid_property_set (MonoDomain *domain, MonoProperty *property, void *obj, void **params, MonoObject **exc); - -#if WINDOWS - void package_hash_to_hex (uint32_t hash); -#else - template - void package_hash_to_hex (IdxType idx); - - template - void package_hash_to_hex (uint32_t hash, IdxType idx, Indices... indices); + protected: +#if !defined (WINDOWS) template void concatenate_strings_into (UNUSED_ARG size_t len, UNUSED_ARG char *dest) {} @@ -315,8 +207,7 @@ namespace xamarin { namespace android } private: - char package_property_suffix[9]; + void add_to_vector (char ***vector, size_t size, char *token); }; -} } -#endif // __cplusplus -#endif /* __MONODROID_UTIL_H__ */ +} +#endif // !__BASIC_UTILITIES_HH diff --git a/src/monodroid/jni/cppcompat.h b/src/monodroid/jni/cppcompat.hh similarity index 67% rename from src/monodroid/jni/cppcompat.h rename to src/monodroid/jni/cppcompat.hh index c7a4c863876..e3539d4cbfc 100644 --- a/src/monodroid/jni/cppcompat.h +++ b/src/monodroid/jni/cppcompat.hh @@ -4,6 +4,21 @@ #include +#undef HAVE_WORKING_MUTEX + +// On desktop builds we can include the actual C++ standard library files which declare type traits +// as well as the `lock_guard` and `mutex` classes. However, some versions of MinGW, even though +// they have the required files, do not declare `mutex` because the `gthreads` feature is not +// enabled. Thus the complicated `#if` below. +#if !defined (ANDROID) && (!defined (WINDOWS) || (defined (WINDOWS) && defined (_GLIBCXX_HAS_GTHREADS))) +#define HAVE_WORKING_MUTEX 1 +#endif + +#if !defined (ANDROID) +#include +#include // Also declares `lock_guard` even if it doesn't declare `mutex` +#endif + // Since Android doesn't currently have any standard C++ library // and we don't want to use any implementation of it shipped in // source form with the NDK (for space reasons), this header will @@ -14,6 +29,7 @@ // we can remove this file. namespace std { +#if defined (ANDROID) template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; @@ -48,7 +64,9 @@ namespace std private: mutex_type &_mutex; }; +#endif // !def ANDROID +#if !defined (HAVE_WORKING_MUTEX) class mutex { public: @@ -67,5 +85,7 @@ namespace std private: pthread_mutex_t _pmutex = PTHREAD_MUTEX_INITIALIZER; }; +#endif // !def HAVE_WORKING_MUTEX } + #endif diff --git a/src/monodroid/jni/cpu-arch-detect.cc b/src/monodroid/jni/cpu-arch-detect.cc index 09de456b3e0..08c5e955810 100644 --- a/src/monodroid/jni/cpu-arch-detect.cc +++ b/src/monodroid/jni/cpu-arch-detect.cc @@ -10,7 +10,7 @@ #include #endif -#include "cpu-arch.h" +#include "cpu-arch.hh" #if __ANDROID__ #define BUF_SIZE 512 diff --git a/src/monodroid/jni/cpu-arch.h b/src/monodroid/jni/cpu-arch.hh similarity index 100% rename from src/monodroid/jni/cpu-arch.h rename to src/monodroid/jni/cpu-arch.hh diff --git a/src/monodroid/jni/debug-app-helper.cc b/src/monodroid/jni/debug-app-helper.cc new file mode 100644 index 00000000000..eb5cd9c9c3f --- /dev/null +++ b/src/monodroid/jni/debug-app-helper.cc @@ -0,0 +1,346 @@ +#include + +#include +#include +#include +#include +#include +#include +#ifdef ANDROID +#include +#endif + +#include "basic-android-system.hh" +#include "basic-utilities.hh" +#include "debug-app-helper.hh" +#include "shared-constants.hh" +#include "jni-wrappers.hh" + +using namespace xamarin::android; +using namespace xamarin::android::internal; + +#undef DO_LOG +#undef log_info + +void log_info (LogCategories category, const char *format, ...); +void log_warn (LogCategories category, const char *format, ...); +void log_error (LogCategories category, const char *format, ...); +void log_fatal (LogCategories category, const char *format, ...); + +static void copy_file_to_internal_location (char *to_dir, char *from_dir, char *file); +static void copy_native_libraries_to_internal_location (); +static bool try_load_libmonosgen (const char *dir, char*& libmonoso); +static char* get_libmonosgen_path (); + +bool maybe_load_library (const char *path); + +#define DO_LOG(_level_,_tag_,_format_,_args_) \ + va_start ((_args_), (_format_)); \ + __android_log_vprint ((_level_), (_tag_), (_format_), (_args_)); \ + va_end ((_args_)); + +#ifndef ANDROID +#define ANDROID_LOG_INFO 1 +#define ANDROID_LOG_WARN 2 +#define ANDROID_LOG_ERROR 3 +#define ANDROID_LOG_FATAL 4 + +static void +__android_log_vprint (int prio, const char* tag, const char* fmt, va_list ap) +{ + printf ("%d [%s] ", prio, tag); + vprintf (fmt, ap); + putchar ('\n'); + fflush (stdout); +} +#endif + +static constexpr char TAG[] = "debug-app-helper"; + +unsigned int log_categories = LOG_DEFAULT; +BasicUtilities utils; +BasicAndroidSystem androidSystem; + +JNIEXPORT jint JNICALL +JNI_OnLoad (JavaVM *vm, void *reserved) +{ + return JNI_VERSION_1_6; +} + +JNIEXPORT void JNICALL +Java_mono_android_DebugRuntime_init (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, + jstring runtimeNativeLibDir, jobjectArray appDirs, + jobjectArray externalStorageDirs, jint androidApiLevel, + jboolean embeddedDSOsEnabled) +{ + androidSystem.set_embedded_dso_mode_enabled ((bool) embeddedDSOsEnabled); + + jstring_array_wrapper applicationDirs (env, appDirs); + jstring_array_wrapper runtimeApks (env, runtimeApksJava); + + androidSystem.set_primary_override_dir (env, applicationDirs [0]); + androidSystem.set_override_dir (0, androidSystem.get_primary_override_dir ()); + androidSystem.setup_app_library_directories (env, runtimeApks, applicationDirs, androidApiLevel); + + if (runtimeNativeLibDir != nullptr) { + jstring_wrapper jstr (env, runtimeNativeLibDir); + androidSystem.set_runtime_libdir (utils.strdup_new (jstr.get_cstr ())); + log_warn (LOG_DEFAULT, "Using runtime path: %s", androidSystem.get_runtime_libdir ()); + } + + char *monosgen_path = get_libmonosgen_path (); + void *monosgen = dlopen (monosgen_path, RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE); + if (monosgen == nullptr) { + log_fatal (LOG_DEFAULT, "Failed to dlopen Mono runtime from %s: %s", monosgen_path, dlerror ()); + exit (FATAL_EXIT_CANNOT_FIND_LIBMONOSGEN); + } +} + +bool +maybe_load_library (const char *path) +{ + struct stat sbuf; + + if (stat (path, &sbuf) != 0) + return false; + + if (dlopen (path, RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE) != nullptr) { + log_info (LOG_DEFAULT, "Mono runtime loaded from %s", path); + return true; + } + + return false; +} + +#ifdef ANDROID +static void +copy_file_to_internal_location (char *to_dir, char *from_dir, char *file) +{ + char *from_file = utils.path_combine (from_dir, file); + char *to_file = nullptr; + + do { + if (!from_file || !utils.file_exists (from_file)) + break; + + log_warn (LOG_DEFAULT, "Copying file `%s` from external location `%s` to internal location `%s`", + file, from_dir, to_dir); + + to_file = utils.path_combine (to_dir, file); + if (!to_file) + break; + + int r = unlink (to_file); + if (r < 0 && errno != ENOENT) { + log_warn (LOG_DEFAULT, "Unable to delete file `%s`: %s", to_file, strerror (errno)); + break; + } + + if (!utils.file_copy (to_file, from_file)) { + log_warn (LOG_DEFAULT, "Copy failed from `%s` to `%s`: %s", from_file, to_file, strerror (errno)); + break; + } + + utils.set_user_executable (to_file); + } while (0); + + delete[] from_file; + delete[] to_file; +} +#else /* !defined (ANDROID) */ +static void +copy_file_to_internal_location (char *to_dir, char *from_dir, char* file) +{ +} +#endif /* defined (ANDROID) */ + +#ifndef RELEASE +static void +copy_native_libraries_to_internal_location () +{ + for (size_t i = 0; i < BasicAndroidSystem::MAX_OVERRIDES; ++i) { + monodroid_dir_t *dir; + monodroid_dirent_t *e; + + char *dir_path = utils.path_combine (BasicAndroidSystem::override_dirs [i], "lib"); + log_warn (LOG_DEFAULT, "checking directory: `%s`", dir_path); + + if (dir_path == nullptr || !utils.directory_exists (dir_path)) { + log_warn (LOG_DEFAULT, "directory does not exist: `%s`", dir_path); + delete[] dir_path; + continue; + } + + if ((dir = utils.monodroid_opendir (dir_path)) == nullptr) { + log_warn (LOG_DEFAULT, "could not open directory: `%s`", dir_path); + delete[] dir_path; + continue; + } + + while ((e = readdir (dir)) != nullptr) { + log_warn (LOG_DEFAULT, "checking file: `%s`", e->d_name); + if (utils.monodroid_dirent_hasextension (e, ".so")) { +#if WINDOWS + char *file_name = utils.utf16_to_utf8 (e->d_name); +#else /* def WINDOWS */ + char *file_name = e->d_name; +#endif /* ndef WINDOWS */ + copy_file_to_internal_location (androidSystem.get_primary_override_dir (), dir_path, file_name); +#if WINDOWS + free (file_name); +#endif /* def WINDOWS */ + } + } + utils.monodroid_closedir (dir); + delete[] dir_path; + } +} +#endif + +static inline bool +runtime_exists (const char *dir, char*& libmonoso) +{ + if (dir == nullptr || *dir == '\0') + return false; + + libmonoso = utils.path_combine (dir, SharedConstants::MONO_SGEN_SO); + log_warn (LOG_DEFAULT, "Checking whether Mono runtime exists at: %s", libmonoso); + if (utils.file_exists (libmonoso)) { + log_info (LOG_DEFAULT, "Mono runtime found at: %s", libmonoso); + return true; + } + delete[] libmonoso; + libmonoso = nullptr; + + return false; +} + +static char* +get_libmonosgen_path () +{ + char *libmonoso; + bool embedded_dso_mode_enabled = androidSystem.is_embedded_dso_mode_enabled (); + +#ifndef RELEASE + // Android 5 includes some restrictions on loading dynamic libraries via dlopen() from + // external storage locations so we need to file copy the shared object to an internal + // storage location before loading it. + copy_native_libraries_to_internal_location (); + + if (!embedded_dso_mode_enabled) { + for (size_t i = 0; i < BasicAndroidSystem::MAX_OVERRIDES; ++i) { + if (runtime_exists (BasicAndroidSystem::override_dirs [i], libmonoso)) { + return libmonoso; + } + } + } +#endif + if (!embedded_dso_mode_enabled) { + for (size_t i = 0; i < BasicAndroidSystem::app_lib_directories_size; i++) { + if (runtime_exists (BasicAndroidSystem::app_lib_directories [i], libmonoso)) { + return libmonoso; + } + } + } + + if (androidSystem.get_runtime_libdir () != nullptr) { + libmonoso = utils.path_combine (androidSystem.get_runtime_libdir (), SharedConstants::MONO_SGEN_ARCH_SO); + } else + libmonoso = nullptr; + + if (libmonoso != nullptr && utils.file_exists (libmonoso)) { + char* links_dir = utils.path_combine (androidSystem.get_primary_override_dir (), "links"); + char* link = utils.path_combine (links_dir, SharedConstants::MONO_SGEN_SO); + if (!utils.directory_exists (links_dir)) { + if (!utils.directory_exists (androidSystem.get_primary_override_dir ())) + utils.create_public_directory (androidSystem.get_primary_override_dir ()); + utils.create_public_directory (links_dir); + } + delete[] links_dir; + if (!utils.file_exists (link)) { + int result = symlink (libmonoso, link); + if (result != 0 && errno == EEXIST) { + log_warn (LOG_DEFAULT, "symlink exists, recreating: %s -> %s", link, libmonoso); + unlink (link); + result = symlink (libmonoso, link); + } + if (result != 0) + log_warn (LOG_DEFAULT, "symlink failed with errno=%i %s", errno, strerror (errno)); + } + delete[] libmonoso; + libmonoso = link; + } + + log_warn (LOG_DEFAULT, "Trying to load sgen from: %s", libmonoso != nullptr ? libmonoso : ""); + if (libmonoso != nullptr && utils.file_exists (libmonoso)) + return libmonoso; + delete[] libmonoso; + +#ifdef WINDOWS + if (runtime_exists (get_libmonoandroid_directory_path (), libmonoso)) + return libmonoso; +#endif + + if (runtime_exists (BasicAndroidSystem::SYSTEM_LIB_PATH, libmonoso)) + return libmonoso; + log_fatal (LOG_DEFAULT, "Cannot find '%s'. Looked in the following locations:", SharedConstants::MONO_SGEN_SO); + +#ifndef RELEASE + if (!embedded_dso_mode_enabled) { + for (size_t i = 0; i < BasicAndroidSystem::MAX_OVERRIDES; ++i) { + if (BasicAndroidSystem::override_dirs [i] == nullptr) + continue; + log_fatal (LOG_DEFAULT, " %s", BasicAndroidSystem::override_dirs [i]); + } + } +#endif + for (size_t i = 0; i < BasicAndroidSystem::app_lib_directories_size; i++) { + log_fatal (LOG_DEFAULT, " %s", BasicAndroidSystem::app_lib_directories [i]); + } + + log_fatal (LOG_DEFAULT, "Do you have a shared runtime build of your app with AndroidManifest.xml android:minSdkVersion < 10 while running on a 64-bit Android 5.0 target? This combination is not supported."); + log_fatal (LOG_DEFAULT, "Please either set android:minSdkVersion >= 10 or use a build without the shared runtime (like default Release configuration)."); + exit (FATAL_EXIT_CANNOT_FIND_LIBMONOSGEN); + + return libmonoso; +} + +void +log_info (LogCategories category, const char *format, ...) +{ + va_list args; + + DO_LOG (ANDROID_LOG_INFO, TAG, format, args); +} + +void +log_info_nocheck (LogCategories category, const char *format, ...) +{ + va_list args; + + if ((log_categories & category) == 0) + return; + + DO_LOG (ANDROID_LOG_INFO, TAG, format, args); +} + +void log_error (LogCategories category, const char* format, ...) +{ + va_list args; + + DO_LOG (ANDROID_LOG_ERROR, TAG, format, args); +} + +void log_fatal (LogCategories category, const char* format, ...) +{ + va_list args; + + DO_LOG (ANDROID_LOG_FATAL, TAG, format, args); +} + +void log_warn (LogCategories category, const char* format, ...) +{ + va_list args; + + DO_LOG (ANDROID_LOG_WARN, TAG, format, args); +} diff --git a/src/monodroid/jni/debug-app-helper.hh b/src/monodroid/jni/debug-app-helper.hh new file mode 100644 index 00000000000..235cdc7cf9d --- /dev/null +++ b/src/monodroid/jni/debug-app-helper.hh @@ -0,0 +1,17 @@ +#include +/* Header for class mono_android_DebugRuntime */ + +#ifndef _Included_mono_android_DebugRuntime +#define _Included_mono_android_DebugRuntime +#ifdef __cplusplus +extern "C" { +#endif + /* + * Class: mono_android_DebugRuntime + * Method: init + * Signature: ([Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String);[Ljava/lang/String);Ljava/lang/String;IZ)V + */ + JNIEXPORT void JNICALL Java_mono_android_DebugRuntime_init + (JNIEnv *, jclass, jobjectArray, jstring, jobjectArray, jobjectArray, jint, jboolean); +} +#endif // _Included_mono_android_DebugRuntime diff --git a/src/monodroid/jni/debug-constants.cc b/src/monodroid/jni/debug-constants.cc index d3bc16a196f..879e4c46d60 100644 --- a/src/monodroid/jni/debug-constants.cc +++ b/src/monodroid/jni/debug-constants.cc @@ -1,4 +1,4 @@ -#include "debug.h" +#include "debug.hh" using namespace xamarin::android; diff --git a/src/monodroid/jni/debug.cc b/src/monodroid/jni/debug.cc index 0ead77a0179..fd62c89fbd3 100644 --- a/src/monodroid/jni/debug.cc +++ b/src/monodroid/jni/debug.cc @@ -30,9 +30,9 @@ #include "java-interop-util.h" #include "monodroid.h" -#include "debug.h" -#include "util.h" -#include "globals.h" +#include "debug.hh" +#include "util.hh" +#include "globals.hh" // // The communication between xs and the app works as follows: diff --git a/src/monodroid/jni/debug.h b/src/monodroid/jni/debug.hh similarity index 100% rename from src/monodroid/jni/debug.h rename to src/monodroid/jni/debug.hh diff --git a/src/monodroid/jni/dylib-mono.cc b/src/monodroid/jni/dylib-mono.cc deleted file mode 100644 index f5927a405c0..00000000000 --- a/src/monodroid/jni/dylib-mono.cc +++ /dev/null @@ -1,883 +0,0 @@ -#include -#include -#include -#include -#include -#ifdef WINDOWS -#include -#endif - -#include "monodroid.h" -#include "dylib-mono.h" -#include "util.h" -#include "globals.h" - -using namespace xamarin::android; - -/* - 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 -*/ -int monodroid_dylib_mono_init (DylibMono *mono_imports, const char *libmono_path) -{ - if (mono_imports == nullptr) - return FALSE; - - /* - * We need to use RTLD_GLOBAL so that libmono-profiler-log.so can resolve - * symbols against the Mono library we're loading. - */ - - void* handle = libmono_path ? androidSystem.load_dso (libmono_path, RTLD_LAZY | RTLD_GLOBAL, FALSE) : dlopen (libmono_path, RTLD_LAZY | RTLD_GLOBAL); - - return monoFunctions.init (handle); -} - -bool DylibMono::init (void *libmono_handle) -{ - if (initialized) - return true; - - if (libmono_handle == nullptr) - return false; - - dl_handle = libmono_handle; - version = sizeof (*this); - - log_info (LOG_DEFAULT, "Loading Mono symbols..."); - - bool symbols_missing = false; - -#define LOAD_SYMBOL_CAST(symbol, cast_type) \ - symbol = reinterpret_cast (dlsym (dl_handle, #symbol)); \ - if (symbol == nullptr) { \ - log_error (LOG_DEFAULT, "Failed to load Mono symbol: %s", #symbol); \ - symbols_missing = true; \ - } - -#define LOAD_SYMBOL(symbol) LOAD_SYMBOL_CAST(symbol, monodroid_ ##symbol ##_fptr) -#define LOAD_SYMBOL_NO_PREFIX(symbol) LOAD_SYMBOL_CAST(symbol, symbol ##_fptr) - - timing_period total_time; - if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) { - total_time.mark_start (); - } - - LOAD_SYMBOL(mono_add_internal_call) - LOAD_SYMBOL(mono_assembly_get_image) - LOAD_SYMBOL(mono_assembly_load_from_full) - LOAD_SYMBOL(mono_assembly_load_full) - LOAD_SYMBOL(mono_assembly_loaded) - LOAD_SYMBOL(mono_assembly_name_free) - LOAD_SYMBOL(mono_assembly_name_get_culture) - LOAD_SYMBOL(mono_assembly_name_get_name) - LOAD_SYMBOL(mono_assembly_name_new) - LOAD_SYMBOL(mono_assembly_open_full) - LOAD_SYMBOL(mono_check_corlib_version) - LOAD_SYMBOL(mono_class_from_mono_type) - LOAD_SYMBOL(mono_class_from_name) - LOAD_SYMBOL(mono_class_get_fields) - LOAD_SYMBOL(mono_class_get_field_from_name) - LOAD_SYMBOL(mono_class_get_method_from_name) - LOAD_SYMBOL(mono_class_get_name) - LOAD_SYMBOL(mono_class_get_namespace) - LOAD_SYMBOL(mono_class_get_property_from_name) - LOAD_SYMBOL(mono_class_is_subclass_of) - LOAD_SYMBOL(mono_class_vtable) - LOAD_SYMBOL(mono_config_for_assembly) - LOAD_SYMBOL(mono_config_parse_memory) - LOAD_SYMBOL(mono_counters_dump) - LOAD_SYMBOL(mono_counters_enable) - LOAD_SYMBOL(mono_debug_init) - LOAD_SYMBOL(mono_debug_open_image_from_memory) - LOAD_SYMBOL(mono_dl_fallback_register) - LOAD_SYMBOL(mono_domain_assembly_open) - LOAD_SYMBOL(mono_domain_create_appdomain) - LOAD_SYMBOL(mono_domain_foreach) - LOAD_SYMBOL(mono_domain_from_appdomain) - LOAD_SYMBOL(mono_domain_get) - LOAD_SYMBOL(mono_domain_get_id) - LOAD_SYMBOL(mono_domain_get_by_id) - LOAD_SYMBOL(mono_domain_set) - LOAD_SYMBOL(mono_domain_unload) - LOAD_SYMBOL(mono_field_get_type) - LOAD_SYMBOL(mono_field_get_value) - LOAD_SYMBOL(mono_field_set_value) - LOAD_SYMBOL(mono_field_static_set_value) - LOAD_SYMBOL_CAST(mono_get_root_domain, monodroid_mono_domain_get_fptr) - LOAD_SYMBOL(mono_gc_register_bridge_callbacks) - LOAD_SYMBOL(mono_gc_wait_for_bridge_processing) - LOAD_SYMBOL(mono_image_open_from_data_with_name) - LOAD_SYMBOL(mono_install_assembly_preload_hook) - LOAD_SYMBOL(mono_install_assembly_refonly_preload_hook) - LOAD_SYMBOL(mono_jit_init_version) - LOAD_SYMBOL(mono_jit_parse_options) - LOAD_SYMBOL(mono_jit_set_trace_options) - LOAD_SYMBOL_CAST(mono_jit_thread_attach, monodroid_mono_jit_thread_attach) - LOAD_SYMBOL_CAST(mono_jit_set_aot_mode, monodroid_mono_jit_set_aot_mode_fptr) - LOAD_SYMBOL(mono_jit_cleanup) - LOAD_SYMBOL(mono_method_full_name) - LOAD_SYMBOL(mono_object_get_class) - LOAD_SYMBOL(mono_object_new) - LOAD_SYMBOL(mono_object_unbox) - LOAD_SYMBOL(mono_profiler_install) - LOAD_SYMBOL(mono_profiler_install_jit_end) - LOAD_SYMBOL(mono_profiler_set_events) - LOAD_SYMBOL(mono_property_set_value) - LOAD_SYMBOL(mono_register_bundled_assemblies) - LOAD_SYMBOL(mono_register_config_for_assembly) - LOAD_SYMBOL(mono_register_machine_config) - LOAD_SYMBOL(mono_register_symfile_for_assembly) - LOAD_SYMBOL(mono_runtime_invoke) - LOAD_SYMBOL(mono_runtime_set_main_args) - LOAD_SYMBOL(mono_set_crash_chaining) - LOAD_SYMBOL(mono_set_defaults) - LOAD_SYMBOL(mono_set_signal_chaining) - LOAD_SYMBOL(mono_string_new) - LOAD_SYMBOL(mono_thread_attach) - LOAD_SYMBOL(mono_thread_create) - LOAD_SYMBOL(mono_thread_current) - LOAD_SYMBOL_CAST(mono_use_llvm, int*) - LOAD_SYMBOL_NO_PREFIX(mono_aot_register_module) - LOAD_SYMBOL(mono_profiler_create) - LOAD_SYMBOL(mono_profiler_set_jit_begin_callback) - LOAD_SYMBOL(mono_profiler_set_jit_done_callback) - LOAD_SYMBOL(mono_profiler_set_jit_failed_callback) - LOAD_SYMBOL(mono_profiler_set_thread_started_callback) - LOAD_SYMBOL(mono_profiler_set_thread_stopped_callback) - LOAD_SYMBOL(mono_add_internal_call_with_flags) - - if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) { - total_time.mark_end (); - - timing_diff diff (total_time); - log_info_nocheck (LOG_TIMING, "DylibMono.init: end, total time; elapsed: %lis:%lu::%lu", diff.sec, diff.ms, diff.ns); - } - - if (symbols_missing) { - log_fatal (LOG_DEFAULT, "Failed to load some Mono symbols, aborting..."); - exit (FATAL_EXIT_MONO_MISSING_SYMBOLS); - } - - initialized = true; - return true; -} - -void -DylibMono::close () -{ - if (dl_handle != nullptr) - dlclose (dl_handle); -} - -void -DylibMono::config_parse_memory (const char *buffer) -{ - if (mono_config_parse_memory == nullptr) - return; - mono_config_parse_memory (buffer); -} - -void -DylibMono::add_internal_call (const char *name, const void *method) -{ - if (mono_add_internal_call == nullptr) - return; - - mono_add_internal_call (name, method); -} - -MonoImage* -DylibMono::assembly_get_image (void *arg0) -{ - if (mono_assembly_get_image == nullptr) - return nullptr; - - return mono_assembly_get_image (arg0); -} - -MonoAssembly* -DylibMono::assembly_load_from_full (MonoImage *image, const char *fname, MonoImageOpenStatus *status, bool refonly) -{ - if (mono_assembly_load_from_full == nullptr) - return nullptr; - - return mono_assembly_load_from_full (image, fname, status, refonly ? TRUE : FALSE); -} - -MonoAssembly* -DylibMono::assembly_load_full (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus* status, bool refonly) -{ - if (mono_assembly_load_full == nullptr) - return nullptr; - - return mono_assembly_load_full (aname, basedir, status, refonly ? TRUE : FALSE); -} - -MonoAssembly* -DylibMono::assembly_loaded (MonoAssemblyName *aname) -{ - if (mono_assembly_loaded == nullptr) - return nullptr; - - return mono_assembly_loaded (aname); -} - -const char* -DylibMono::assembly_name_get_culture (MonoAssemblyName *aname) -{ - if (mono_assembly_name_get_culture == nullptr) - return nullptr; - - return mono_assembly_name_get_culture (aname); -} - -const char* -DylibMono::assembly_name_get_name (MonoAssemblyName *aname) -{ - if (mono_assembly_name_get_name == nullptr) - return nullptr; - - return mono_assembly_name_get_name (aname); -} - -MonoAssemblyName* -DylibMono::assembly_name_new (const char *name) -{ - if (mono_assembly_name_new == nullptr) - return nullptr; - - return mono_assembly_name_new (name); -} - -void -DylibMono::assembly_name_free (MonoAssemblyName *aname) -{ - if (mono_assembly_name_free == nullptr) - return; - - mono_assembly_name_free (aname); -} - -MonoAssembly* -DylibMono::assembly_open_full (const char *filename, MonoImageOpenStatus *status, bool refonly) -{ - if (mono_assembly_open_full == nullptr) - return nullptr; - - return mono_assembly_open_full (filename, status, refonly ? TRUE : FALSE); -} - -char* -DylibMono::check_corlib_version () -{ - if (mono_check_corlib_version == nullptr) - return nullptr; - - return mono_check_corlib_version (); -} - -MonoClass* -DylibMono::class_from_mono_type (void *arg0) -{ - if (mono_class_from_mono_type == nullptr) - return nullptr; - - return mono_class_from_mono_type (arg0); -} - -MonoClass* -DylibMono::class_from_name (MonoImage *image, const char *name_space, const char *name) -{ - if (mono_class_from_name == nullptr) - return nullptr; - - return mono_class_from_name (image, name_space, name); -} - -const char* -DylibMono::class_get_name (MonoClass *arg0) -{ - if (mono_class_get_name == nullptr) - return nullptr; - - return mono_class_get_name (arg0); -} - -const char* -DylibMono::class_get_namespace (MonoClass *arg0) -{ - if (mono_class_get_namespace == nullptr) - return nullptr; - - return mono_class_get_namespace (arg0); -} - -bool -DylibMono::class_is_subclass_of (MonoClass *klass, MonoClass *klassc, bool use_interfaces) -{ - if (mono_class_is_subclass_of == nullptr) - return false; - - return mono_class_is_subclass_of (klass, klassc, use_interfaces ? TRUE : FALSE) ? true : false; -} - -MonoClassField* -DylibMono::class_get_field_from_name (MonoClass *arg0, char *arg1) -{ - if (mono_class_get_field_from_name == nullptr) - return nullptr; - - return mono_class_get_field_from_name (arg0, arg1); -} - -MonoClassField* -DylibMono::class_get_fields (MonoClass *arg0, void **arg1) -{ - if (mono_class_get_fields == nullptr) - return nullptr; - - return mono_class_get_fields (arg0, arg1); -} - -MonoMethod* -DylibMono::class_get_method_from_name (MonoClass *arg0, const char *arg1, int arg2) -{ - if (mono_class_get_method_from_name == nullptr) - return nullptr; - - return mono_class_get_method_from_name (arg0, arg1, arg2); -} - -MonoProperty* -DylibMono::class_get_property_from_name (MonoClass *klass, const char *name) -{ - if (mono_class_get_property_from_name == nullptr) - return nullptr; - - return mono_class_get_property_from_name (klass, name); -} - -MonoVTable* -DylibMono::class_vtable (MonoDomain *domain, MonoClass *klass) -{ - if (mono_class_vtable == nullptr) - return nullptr; - - return mono_class_vtable (domain, klass); -} - -void -DylibMono::config_for_assembly (MonoImage *assembly) -{ - if (mono_config_for_assembly == nullptr) - return; - - mono_config_for_assembly (assembly); -} - -void -DylibMono::counters_dump (int section_mask, FILE* outfile) -{ - if (mono_counters_dump == nullptr) - return; - - mono_counters_dump (section_mask, outfile); -} - -void -DylibMono::counters_enable (int arg0) -{ - if (mono_counters_enable == nullptr) - return; - - mono_counters_enable (arg0); -} - -void -DylibMono::debug_init (int format) -{ - if (mono_debug_init == nullptr) - return; - - mono_debug_init (format); -} - -void -DylibMono::debug_open_image_from_memory (MonoImage *image, const mono_byte *raw_contents, int size) -{ - if (mono_debug_open_image_from_memory == nullptr) - return; - - mono_debug_open_image_from_memory (image, raw_contents, size); -} - -MonoDlFallbackHandler* -DylibMono::dl_fallback_register (MonoDlFallbackLoad load_func, MonoDlFallbackSymbol symbol_func, MonoDlFallbackClose close_func, void *user_data) -{ - if (mono_dl_fallback_register == nullptr) - return nullptr; - - return mono_dl_fallback_register (load_func, symbol_func, close_func, user_data); -} - -MonoAssembly* -DylibMono::domain_assembly_open (MonoDomain *arg0, const char *arg1) -{ - if (mono_domain_assembly_open == nullptr) - return nullptr; - - return mono_domain_assembly_open (arg0, arg1); -} - -MonoDomain* -DylibMono::domain_create_appdomain (char *friendly_name, char *config_file) -{ - if (mono_domain_create_appdomain == nullptr) - return nullptr; - - return mono_domain_create_appdomain (friendly_name, config_file); -} - -void -DylibMono::domain_foreach (MonoDomainFunc func, void *user_data) -{ - if (mono_domain_foreach == nullptr) - return; - - mono_domain_foreach (func, user_data); -} - -MonoDomain* -DylibMono::domain_from_appdomain (MonoObject *appdomain) -{ - if (mono_domain_from_appdomain == nullptr) - return nullptr; - - return mono_domain_from_appdomain (appdomain); -} - -MonoDomain* -DylibMono::domain_get () -{ - if (mono_domain_get == nullptr) - return nullptr; - - return mono_domain_get (); -} - -MonoDomain* -DylibMono::domain_get_by_id (int ID) -{ - if (mono_domain_get_by_id == nullptr) - return nullptr; - - return mono_domain_get_by_id (ID); -} - -int -DylibMono::domain_get_id (MonoDomain *domain) -{ - if (mono_domain_get_id == nullptr) - return -1; - - return mono_domain_get_id (domain); -} - -bool -DylibMono::domain_set (MonoDomain *domain, bool force) -{ - if (mono_domain_set == nullptr) - return false; - - return mono_domain_set (domain, force ? TRUE : FALSE) ? true : false; -} - -void -DylibMono::domain_unload (MonoDomain *domain) -{ - if (mono_domain_unload == nullptr) - return; - - mono_domain_unload (domain); -} - -MonoType* -DylibMono::field_get_type (MonoClassField *arg0) -{ - if (mono_field_get_type == nullptr) - return nullptr; - - return mono_field_get_type (arg0); -} - -void -DylibMono::field_get_value (MonoObject *arg0, MonoClassField *arg1, void *arg2) -{ - if (mono_field_get_value == nullptr) - return; - - mono_field_get_value (arg0, arg1, arg2); -} - -void -DylibMono::field_set_value (MonoObject *arg0, MonoClassField *arg1, void *arg2) -{ - if (mono_field_set_value == nullptr) - return; - - mono_field_set_value (arg0, arg1, arg2); -} - -void -DylibMono::field_static_set_value (MonoVTable *vtable, MonoClassField *field, void *value) -{ - if (mono_field_static_set_value == nullptr) - return; - - mono_field_static_set_value (vtable, field, value); -} - -void -DylibMono::gc_register_bridge_callbacks (void *callback) -{ - if (mono_gc_register_bridge_callbacks == nullptr) - return; - - mono_gc_register_bridge_callbacks (callback); -} - -void -DylibMono::gc_wait_for_bridge_processing (void) -{ - if (mono_gc_wait_for_bridge_processing == nullptr) - return; - - mono_gc_wait_for_bridge_processing (); -} - -MonoImage* -DylibMono::image_open_from_data_with_name (char *data, uint32_t data_len, bool need_copy, MonoImageOpenStatus *status, bool refonly, const char *name) -{ - if (mono_image_open_from_data_with_name == nullptr) - return nullptr; - - return mono_image_open_from_data_with_name (data, data_len, need_copy, status, refonly ? TRUE : FALSE, name); -} - -void -DylibMono::install_assembly_preload_hook (MonoAssemblyPreLoadFunc func, void *user_data) -{ - if (mono_install_assembly_preload_hook == nullptr) - return; - - mono_install_assembly_preload_hook (func, user_data); -} - -MonoDomain* -DylibMono::jit_init_version (char *arg0, char *arg1) -{ - if (mono_jit_init_version == nullptr) - return nullptr; - - return mono_jit_init_version (arg0, arg1); -} - -void -DylibMono::jit_cleanup (MonoDomain *domain) -{ - if (mono_jit_cleanup == nullptr) - return; - - mono_jit_cleanup (domain); -} - -void -DylibMono::jit_parse_options (int argc, char **argv) -{ - if (mono_jit_parse_options == nullptr) - return; - - mono_jit_parse_options (argc, argv); -} - -bool -DylibMono::jit_set_trace_options (const char *options) -{ - if (mono_jit_set_trace_options == nullptr) - return false; - - return mono_jit_set_trace_options (options); -} - -MonoDomain* -DylibMono::jit_thread_attach (MonoDomain *domain) -{ - if (mono_jit_thread_attach == nullptr) - return nullptr; - - return mono_jit_thread_attach (domain); -} - -void -DylibMono::jit_set_aot_mode (MonoAotMode mode) -{ - if (mono_jit_set_aot_mode == nullptr) - return; - - mono_jit_set_aot_mode (mode); -} - -char* -DylibMono::method_full_name (MonoMethod *method, bool signature) -{ - if (mono_method_full_name == nullptr) - return nullptr; - - return mono_method_full_name (method, signature ? TRUE : FALSE); -} - -MonoClass* -DylibMono::object_get_class (MonoObject *obj) -{ - if (mono_object_get_class == nullptr) - return nullptr; - - return mono_object_get_class (obj); -} - -MonoObject* -DylibMono::object_new (MonoDomain *domain, MonoClass *klass) -{ - if (mono_object_new == nullptr) - return nullptr; - - return mono_object_new (domain, klass); -} - -void* -DylibMono::object_unbox (MonoObject *obj) -{ - if (mono_object_unbox == nullptr) - return nullptr; - - return mono_object_unbox (obj); -} - -MonoProfilerHandle -DylibMono::profiler_create () -{ - if (mono_profiler_create == nullptr) - return nullptr; - - return mono_profiler_create (nullptr); -} - -void -DylibMono::profiler_set_thread_started_callback (MonoProfilerHandle handle, MonoThreadStartedEventFunc start_ftn) -{ - if (mono_profiler_set_thread_started_callback == nullptr) - return; - - mono_profiler_set_thread_started_callback (handle, start_ftn); -} - -void -DylibMono::profiler_set_thread_stopped_callback (MonoProfilerHandle handle, MonoThreadStoppedEventFunc end_ftn) -{ - if (mono_profiler_set_thread_stopped_callback == nullptr) - return; - - mono_profiler_set_thread_stopped_callback (handle, end_ftn); -} - -void -DylibMono::profiler_set_jit_begin_callback (MonoProfilerHandle handle, MonoJitBeginEventFunc begin_ftn) -{ - if (mono_profiler_set_jit_begin_callback == nullptr) - return; - - mono_profiler_set_jit_begin_callback (handle, begin_ftn); -} - -void -DylibMono::profiler_set_jit_done_callback (MonoProfilerHandle handle, MonoJitDoneEventFunc done_ftn) -{ - if (mono_profiler_set_jit_done_callback == nullptr) - return; - - mono_profiler_set_jit_done_callback (handle, done_ftn); -} - -void -DylibMono::profiler_set_jit_failed_callback (MonoProfilerHandle handle, MonoJitFailedEventFunc failed_ftn) -{ - if (mono_profiler_set_jit_failed_callback == nullptr) - return; - - mono_profiler_set_jit_failed_callback (handle, failed_ftn); -} - -void -DylibMono::property_set_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc) -{ - if (mono_property_set_value == nullptr) - return; - - mono_property_set_value (prop, obj, params, exc); -} - -void -DylibMono::register_bundled_assemblies (const MonoBundledAssembly **assemblies) -{ - if (mono_register_bundled_assemblies == nullptr) - return; - - mono_register_bundled_assemblies (assemblies); -} - -void -DylibMono::register_config_for_assembly (const char* assembly_name, const char* config_xml) -{ - if (mono_register_config_for_assembly == nullptr) - return; - - mono_register_config_for_assembly (assembly_name, config_xml); -} - -void -DylibMono::register_symfile_for_assembly (const char* assembly_name, const mono_byte *raw_contents, int size) -{ - if (mono_register_symfile_for_assembly == nullptr) - return; - - mono_register_symfile_for_assembly (assembly_name, raw_contents, size); -} - -void -DylibMono::register_machine_config (const char *config) -{ - if (mono_register_machine_config == nullptr) - return; - - mono_register_machine_config (config); -} - -MonoObject* -DylibMono::runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc) -{ - if (mono_runtime_invoke == nullptr) - return nullptr; - - return mono_runtime_invoke (method, obj, params, exc); -} - -void -DylibMono::set_defaults (int arg0, int arg1) -{ - if (mono_set_defaults == nullptr) - return; - - mono_set_defaults (arg0, arg1); -} - -void -DylibMono::set_crash_chaining (bool chain_crashes) -{ - if (mono_set_crash_chaining == nullptr) - return; - - mono_set_crash_chaining (chain_crashes ? TRUE : FALSE); -} - -void -DylibMono::set_signal_chaining (bool chain_signals) -{ - if (mono_set_signal_chaining == nullptr) - return; - - mono_set_signal_chaining (chain_signals ? TRUE : FALSE); -} - -MonoString* -DylibMono::string_new (MonoDomain *domain, const char *text) -{ - if (mono_string_new == nullptr) - return nullptr; - - return mono_string_new (domain, text); -} - -MonoThread* -DylibMono::thread_attach (MonoDomain *domain) -{ - if (mono_thread_attach == nullptr) - return nullptr; - - return mono_thread_attach (domain); -} - -void -DylibMono::thread_create (MonoDomain *domain, void* func, void* arg) -{ - if (mono_thread_create == nullptr) - return; - - mono_thread_create (domain, func, arg); -} - -MonoThread* -DylibMono::thread_current (void) -{ - if (mono_thread_current == nullptr) - return nullptr; - - return mono_thread_current (); -} - -void -DylibMono::gc_disable () -{ - if (mono_gc_disable == nullptr) - return; - - mono_gc_disable (); -} - -void -DylibMono::install_assembly_refonly_preload_hook (MonoAssemblyPreLoadFunc func, void *user_data) -{ - if (mono_install_assembly_refonly_preload_hook == nullptr) - return; - - mono_install_assembly_refonly_preload_hook (func, user_data); -} - -int -DylibMono::runtime_set_main_args (int argc, char* argv[]) -{ - if (mono_runtime_set_main_args == nullptr) - return -1; - - return mono_runtime_set_main_args (argc, argv); -} - -MonoDomain* -DylibMono::get_root_domain () -{ - if (mono_get_root_domain == nullptr) - return nullptr; - - return mono_get_root_domain (); -} - -void -DylibMono::aot_register_module (void *aot_info) -{ - if (mono_aot_register_module == nullptr) - return; - - mono_aot_register_module (aot_info); -} diff --git a/src/monodroid/jni/dylib-mono.h b/src/monodroid/jni/dylib-mono.h deleted file mode 100644 index 3bbb1f7e398..00000000000 --- a/src/monodroid/jni/dylib-mono.h +++ /dev/null @@ -1,706 +0,0 @@ -// This is a -*- c++ -*- header -#ifndef INC_MONODROID_DYLIB_MONO_H -#define INC_MONODROID_DYLIB_MONO_H - -#include -#include - -#include "monodroid.h" - -#ifdef __cplusplus -namespace xamarin { namespace android -{ -#endif // __cplusplus - -enum MonoCounters { - MONO_COUNTER_INT, /* 32 bit int */ - MONO_COUNTER_UINT, /* 32 bit uint */ - MONO_COUNTER_WORD, /* pointer-sized int */ - MONO_COUNTER_LONG, /* 64 bit int */ - MONO_COUNTER_ULONG, /* 64 bit uint */ - MONO_COUNTER_DOUBLE, - MONO_COUNTER_STRING, /* char* */ - MONO_COUNTER_TIME_INTERVAL, /* 64 bits signed int holding usecs. */ - MONO_COUNTER_TYPE_MASK = 0xf, - MONO_COUNTER_CALLBACK = 128, /* ORed with the other values */ - MONO_COUNTER_SECTION_MASK = 0x00ffff00, - /* Sections, bits 8-23 (16 bits) */ - MONO_COUNTER_JIT = 1 << 8, - MONO_COUNTER_GC = 1 << 9, - MONO_COUNTER_METADATA = 1 << 10, - MONO_COUNTER_GENERICS = 1 << 11, - MONO_COUNTER_SECURITY = 1 << 12, - MONO_COUNTER_RUNTIME = 1 << 13, - MONO_COUNTER_SYSTEM = 1 << 14, - MONO_COUNTER_LAST_SECTION, - - /* Unit, bits 24-27 (4 bits) */ - MONO_COUNTER_UNIT_SHIFT = 24, - MONO_COUNTER_UNIT_MASK = 0xFu << MONO_COUNTER_UNIT_SHIFT, - MONO_COUNTER_RAW = 0 << 24, /* Raw value */ - MONO_COUNTER_BYTES = 1 << 24, /* Quantity of bytes. RSS, active heap, etc */ - MONO_COUNTER_TIME = 2 << 24, /* Time interval in 100ns units. Minor pause, JIT compilation*/ - MONO_COUNTER_COUNT = 3 << 24, /* Number of things (threads, queued jobs) or Number of events triggered (Major collections, Compiled methods).*/ - MONO_COUNTER_PERCENTAGE = 4 << 24, /* [0-1] Fraction Percentage of something. Load average. */ - - /* Monotonicity, bits 28-31 (4 bits) */ - MONO_COUNTER_VARIANCE_SHIFT = 28, - MONO_COUNTER_VARIANCE_MASK = 0xFu << MONO_COUNTER_VARIANCE_SHIFT, - MONO_COUNTER_MONOTONIC = 1 << 28, /* This counter value always increase/decreases over time. Reported by --stat. */ - MONO_COUNTER_CONSTANT = 1 << 29, /* Fixed value. Used by configuration data. */ - MONO_COUNTER_VARIABLE = 1 << 30, /* This counter value can be anything on each sampling. Only interesting when sampling. */ -}; - -#ifdef __cplusplus -inline MonoCounters operator | (MonoCounters left, MonoCounters right) -{ - return static_cast (static_cast (left) | static_cast (right)); -} - -inline MonoCounters operator & (MonoCounters left, MonoCounters right) -{ - return static_cast (static_cast (left) & static_cast (right)); -} - -inline MonoCounters& operator |= (MonoCounters& left, MonoCounters right) -{ - return left = left | right; -} -#endif // __cplusplus - -#define XA_LOG_COUNTERS (MONO_COUNTER_JIT | MONO_COUNTER_METADATA | MONO_COUNTER_GC | MONO_COUNTER_GENERICS) - -#define MONO_DEBUG_FORMAT_MONO 1 - -// Mock declarations of all the Mono types used by Mono API declared below. -// DO NOT use `typedef void`! This is a dangerous practice which may lead to hard to discover bugs -// during the runtime. Take for instance this scenario: -// -// void my_code (MonoDomain *domain) { } -// // ... -// MonoDomain *domain = get_domain (); -// my_code (&domain); -// -// The above code will compile without any warning or error from the compilers, since they allow -// silent cast from `void**` to `void*` and MonoDomain IS void! This kind of typedef is very -// confusing since the developer reading code will not know that MonoDomain is void unless they -// think to check it here. -// -// At the same time, we don't care what those types *really* are - a struct is simply a safe way to -// create a unique type and avoid overload resolution, parameter type casting etc errors. -// -#ifndef MonoAssembly - typedef struct _MonoAssembly {} MonoAssembly; -#endif - -#ifndef MonoAssemblyName - typedef struct _MonoAssemblyName {} MonoAssemblyName; -#endif - -#ifndef MonoClass - typedef struct _MonoClass {} MonoClass; -#endif - -#ifndef MonoClassField - typedef struct _MonoClassField {} MonoClassField; -#endif - -#ifndef MonoVTable - typedef struct _MonoVTable {} MonoVTable; -#endif - -#ifndef MonoDomain - typedef struct _MonoDomain {} MonoDomain; -#endif - -#ifndef MonoException - typedef struct _MonoException {} MonoException; -#endif - -#ifndef MonoImage - typedef struct _MonoImage {} MonoImage; -#endif - -#ifndef MonoJitInfo - typedef struct _MonoJitInfo {} MonoJitInfo; -#endif - -#ifndef MonoMethod - typedef struct _MonoMethod {} MonoMethod; -#endif - -#ifndef MonoObject - typedef struct _MonoObject {} MonoObject; -#endif - -#ifndef MonoProfiler - typedef struct _MonoProfiler {} MonoProfiler; -#endif - -#ifndef MonoProfilerHandle - typedef struct _MonoProfilerDesc {} * MonoProfilerHandle; -#endif - -#ifndef MonoProperty - typedef struct _MonoProperty {} MonoProperty; -#endif - -#ifndef MonoString - typedef struct _MonoString {} MonoString; -#endif - -#ifndef MonoThread - typedef struct _MonoThread {} MonoThread; -#endif - -#ifndef MonoType - typedef struct _MonoType {} MonoType; -#endif - -#ifndef MonoDlFallbackHandler - typedef struct _MonoDlFallbackHandler {} MonoDlFallbackHandler; -#endif - -typedef void (*MonoDomainFunc) (MonoDomain *domain, void* user_data); -typedef void (*MonoJitBeginEventFunc) (MonoProfiler *prof, MonoMethod *method); -typedef void (*MonoJitDoneEventFunc) (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo); -typedef void (*MonoJitFailedEventFunc) (MonoProfiler *prof, MonoMethod *method); -typedef void (*MonoThreadStartedEventFunc) (MonoProfiler *prof, uintptr_t tid); -typedef void (*MonoThreadStoppedEventFunc) (MonoProfiler *prof, uintptr_t tid); - -#ifdef __cplusplus -enum class MonoDlKind { -#else -enum MonoDlKind { -#endif // __cplusplus - MONO_DL_LAZY = 1, - MONO_DL_LOCAL = 2, - MONO_DL_MASK = 3 -}; - -#ifdef __cplusplus -enum class MonoImageOpenStatus { -#else -enum MonoImageOpenStatusC { -#endif // __cplusplus - MONO_IMAGE_OK, - MONO_IMAGE_ERROR_ERRNO, - MONO_IMAGE_MISSING_ASSEMBLYREF, - MONO_IMAGE_IMAGE_INVALID -}; - -#ifndef __cplusplus -typedef int MonoImageOpenStatus; -#endif - -#ifdef __cplusplus -enum class MonoProfileFlags { -#else -enum MonoProfileFlags { -#endif // __cplusplus - MONO_PROFILE_NONE = 0, - MONO_PROFILE_APPDOMAIN_EVENTS = 1 << 0, - MONO_PROFILE_ASSEMBLY_EVENTS = 1 << 1, - MONO_PROFILE_MODULE_EVENTS = 1 << 2, - MONO_PROFILE_CLASS_EVENTS = 1 << 3, - MONO_PROFILE_JIT_COMPILATION = 1 << 4, - MONO_PROFILE_INLINING = 1 << 5, - MONO_PROFILE_EXCEPTIONS = 1 << 6, - MONO_PROFILE_ALLOCATIONS = 1 << 7, - MONO_PROFILE_GC = 1 << 8, - MONO_PROFILE_THREADS = 1 << 9, - MONO_PROFILE_REMOTING = 1 << 10, - MONO_PROFILE_TRANSITIONS = 1 << 11, - MONO_PROFILE_ENTER_LEAVE = 1 << 12, - MONO_PROFILE_COVERAGE = 1 << 13, - MONO_PROFILE_INS_COVERAGE = 1 << 14, - MONO_PROFILE_STATISTICAL = 1 << 15, - MONO_PROFILE_METHOD_EVENTS = 1 << 16, - MONO_PROFILE_MONITOR_EVENTS = 1 << 17, - MONO_PROFILE_IOMAP_EVENTS = 1 << 18, /* this should likely be removed, too */ - MONO_PROFILE_GC_MOVES = 1 << 19 -}; -#ifndef __cplusplus -typedef int MonoProfileFlags; -#endif - -#ifdef __cplusplus -inline MonoProfileFlags operator | (MonoProfileFlags left, MonoProfileFlags right) -{ - return static_cast (static_cast (left) | static_cast (right)); -} - -inline MonoProfileFlags operator & (MonoProfileFlags left, MonoProfileFlags right) -{ - return static_cast (static_cast (left) & static_cast (right)); -} - -inline MonoProfileFlags& operator |= (MonoProfileFlags& left, MonoProfileFlags right) -{ - return left = left | right; -} - -enum class MonoProfileResult { -#else -enum MonoProfileResult { -#endif // __cplusplus - MONO_PROFILE_OK, - MONO_PROFILE_FAILED -}; - -struct MonoBundledAssembly { - const char *name; - const unsigned char *data; - const unsigned int size; -}; - -typedef struct MonoBundledAssembly MonoBundledAssembly; - -typedef uint32_t mono_bool; -typedef uint8_t mono_byte; - -#ifndef MONO_ZERO_LEN_ARRAY -#ifdef __GNUC__ -#define MONO_ZERO_LEN_ARRAY 0 -#else -#define MONO_ZERO_LEN_ARRAY 1 -#endif -#endif - -#ifndef SGEN_BRIDGE_VERSION -#error SGEN_BRIDGE_VERSION must be defined! (Use the `$(MonoSgenBridgeVersion)` MSBuild property) -#endif /* ndef SGEN_BRIDGE_VERSION */ - -#if (SGEN_BRIDGE_VERSION < 4) || (SGEN_BRIDGE_VERSION >= 6) -#error Only SGEN_BRIDGE_VERSION/$(MonoSgenBridgeVersion) values of 4 or 5 are supported. -#endif /* SGEN_BRIDGE_VERSION check */ - -#ifdef __cplusplus -enum class MonoGCBridgeObjectKind { -#else -enum MonoGCBridgeObjectKind { -#endif // __cplusplus - /* Instances of this class should be scanned when computing the transitive dependency among bridges. E.g. List*/ - GC_BRIDGE_TRANSPARENT_CLASS, - /* Instances of this class should not be scanned when computing the transitive dependency among bridges. E.g. String*/ - GC_BRIDGE_OPAQUE_CLASS, - /* Instances of this class should be bridged and have their dependency computed. */ - GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS, - /* Instances of this class should be bridged but no dependencies should not be calculated. */ - GC_BRIDGE_OPAQUE_BRIDGE_CLASS, -}; -#ifndef __cplusplus -typedef int MonoGCBridgeObjectKind; -#endif - -struct MonoGCBridgeSCC { - mono_bool is_alive; - int num_objs; - MonoObject *objs [MONO_ZERO_LEN_ARRAY]; -}; -#ifndef __cplusplus -typedef struct MonoGCBridgeSCC MonoGCBridgeSCC; -#endif - -struct MonoGCBridgeXRef { - int src_scc_index; - int dst_scc_index; -}; -#ifndef __cplusplus -typedef struct MonoGCBridgeXRef MonoGCBridgeXRef; -#endif - -struct MonoGCBridgeCallbacks { - int bridge_version; - - // UGLY!!!!!! -#ifdef __cplusplus - MonoGCBridgeObjectKind -#else - int -#endif // __cplusplus - (*bridge_class_kind) (MonoClass *klass); - - mono_bool (*is_bridge_object) (MonoObject *object); - void (*cross_references) (int num_sccs, -#ifdef __cplusplus - MonoGCBridgeSCC **sccs, -#else - int **sccs, -#endif // __cplusplus - int num_xrefs, -#ifdef __cplusplus - MonoGCBridgeXRef *xrefs -#else - int *xrefs -#endif // __cplusplus - ); -}; -#ifndef __cplusplus -typedef struct MonoGCBridgeCallbacks MonoGCBridgeCallbacks; -#endif - -#ifdef __cplusplus -enum class MonoAotMode { -#else -enum MonoAotMode { -#endif // __cplusplus - /* Disables AOT mode */ - MONO_AOT_MODE_NONE, - /* Enables normal AOT mode, equivalent to mono_jit_set_aot_only (false) */ - MONO_AOT_MODE_NORMAL, - /* Enables hyrbid AOT mode, JIT can still be used for wrappers */ - MONO_AOT_MODE_HYBRID, - /* Enables full AOT mode, JIT is disabled and not allowed, - * equivalent to mono_jit_set_aot_only (true) */ - MONO_AOT_MODE_FULL, - - MONO_AOT_MODE_UNKNOWN = 0xBADBAD -}; -#ifndef __cplusplus -typedef int MonoAotMode; -#endif - -#ifdef __cplusplus -/* NOTE: structure members MUST NOT CHANGE ORDER. */ -class DylibMono -{ -#endif /* !__cplusplus */ - // Make sure the typedefs below match exactly their actual Mono counterpart! - - typedef MonoAssembly* (*MonoAssemblyPreLoadFunc) (MonoAssemblyName *aname, char **assemblies_path, void *user_data); - typedef void (*MonoProfileJitResult) (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result); - - typedef void* (*MonoDlFallbackLoad) (const char *name, int flags, char **err, void *user_data); - typedef void* (*MonoDlFallbackSymbol) (void *handle, const char *name, char **err, void *user_data); - typedef void* (*MonoDlFallbackClose) (void *handle, void *user_data); - - typedef void (*monodroid_mono_config_parse_memory_fptr) (const char *buffer); - typedef void (*monodroid_mono_add_internal_call_fptr) (const char *name, const void *method); - typedef void (*monodroid_mono_add_internal_call_with_flags_fptr) (const char *name, const void *method, mono_bool cooperative); - typedef MonoImage* (*monodroid_mono_assembly_get_image_fptr) (void *arg0); - typedef MonoAssembly* (*monodroid_mono_assembly_load_from_full_fptr) (MonoImage *image, const char *fname, MonoImageOpenStatus *status, mono_bool refonly); - typedef MonoAssembly* (*monodroid_mono_assembly_load_full_fptr) (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus* status, mono_bool refonly); - typedef MonoAssembly* (*monodroid_mono_assembly_loaded_fptr) (MonoAssemblyName *aname); - typedef const char* (*monodroid_mono_assembly_name_get_culture_fptr) (MonoAssemblyName *aname); - typedef const char* (*monodroid_mono_assembly_name_get_name_fptr) (MonoAssemblyName *aname); - typedef MonoAssemblyName* (*monodroid_mono_assembly_name_new_fptr) (const char *name); - typedef void (*monodroid_mono_assembly_name_free_fptr) (MonoAssemblyName *aname); - typedef MonoAssembly* (*monodroid_mono_assembly_open_full_fptr) (const char *filename, MonoImageOpenStatus *status, mono_bool refonly); - typedef char* (*monodroid_mono_check_corlib_version_fptr) (); - typedef MonoClass* (*monodroid_mono_class_from_mono_type_fptr) (void *arg0); - typedef MonoClass* (*monodroid_mono_class_from_name_fptr) (MonoImage *image, const char *name_space, const char *name); - typedef const char* (*monodroid_mono_class_get_name_fptr) (MonoClass *arg0); - typedef const char* (*monodroid_mono_class_get_namespace_fptr) (MonoClass *arg0); - typedef mono_bool (*monodroid_mono_class_is_subclass_of_fptr) (MonoClass *klass, MonoClass *klassc, mono_bool use_interfaces); - typedef MonoClassField* (*monodroid_mono_class_get_field_from_name_fptr) (MonoClass *arg0, char *arg1); - typedef MonoClassField* (*monodroid_mono_class_get_fields_fptr) (MonoClass *arg0, void **arg1); - typedef MonoMethod* (*monodroid_mono_class_get_method_from_name_fptr) (MonoClass *arg0, const char *arg1, int arg2); - typedef MonoProperty* (*monodroid_mono_class_get_property_from_name_fptr) (MonoClass *klass, const char *name); - typedef MonoVTable* (*monodroid_mono_class_vtable_fptr) (MonoDomain *domain, MonoClass *klass); - typedef void (*monodroid_mono_config_for_assembly_fptr) (MonoImage *assembly); - typedef void (*monodroid_mono_counters_dump_fptr) (int section_mask, FILE* outfile); - typedef void (*monodroid_mono_counters_enable_fptr) (int arg0); - typedef void (*monodroid_mono_debug_init_fptr) (int format); - typedef void (*monodroid_mono_debug_open_image_from_memory_fptr) (MonoImage *image, const mono_byte *raw_contents, int size); - typedef MonoDlFallbackHandler* (*monodroid_mono_dl_fallback_register_fptr) (MonoDlFallbackLoad load_func, MonoDlFallbackSymbol symbol_func, MonoDlFallbackClose close_func, void *user_data); - typedef MonoAssembly* (*monodroid_mono_domain_assembly_open_fptr) (MonoDomain *arg0, const char *arg1); - typedef MonoDomain* (*monodroid_mono_domain_create_appdomain_fptr) (char *friendly_name, char *config_file); - typedef void (*monodroid_mono_domain_foreach_fptr) (MonoDomainFunc func, void *user_data); - typedef MonoDomain* (*monodroid_mono_domain_from_appdomain_fptr) (MonoObject *appdomain); - typedef MonoDomain* (*monodroid_mono_domain_get_fptr) (); - typedef MonoDomain* (*monodroid_mono_domain_get_by_id_fptr) (int ID); - typedef int (*monodroid_mono_domain_get_id_fptr) (MonoDomain *domain); - typedef mono_bool (*monodroid_mono_domain_set_fptr) (MonoDomain *domain, mono_bool force); - typedef void (*monodroid_mono_domain_unload_fptr) (MonoDomain *domain); - typedef MonoType* (*monodroid_mono_field_get_type_fptr) (MonoClassField *arg0); - typedef void (*monodroid_mono_field_get_value_fptr) (MonoObject *arg0, MonoClassField *arg1, void *arg2); - typedef void (*monodroid_mono_field_set_value_fptr) (MonoObject *arg0, MonoClassField *arg1, void *arg2); - typedef void (*monodroid_mono_field_static_set_value_fptr) (MonoVTable *vtable, MonoClassField *field, void *value); - typedef void (*monodroid_mono_gc_register_bridge_callbacks_fptr) (void *callback); - typedef void (*monodroid_mono_gc_wait_for_bridge_processing_fptr) (void); - typedef MonoImage* (*monodroid_mono_image_open_from_data_with_name_fptr) (char *data, uint32_t data_len, mono_bool need_copy, MonoImageOpenStatus *status, mono_bool refonly, const char *name); - typedef void (*monodroid_mono_install_assembly_preload_hook_fptr) (MonoAssemblyPreLoadFunc func, void *user_data); - typedef MonoDomain* (*monodroid_mono_jit_init_version_fptr) (char *arg0, char *arg1); - typedef void (*monodroid_mono_jit_cleanup_fptr) (MonoDomain *domain); - typedef void (*monodroid_mono_jit_parse_options_fptr) (int argc, char **argv); - typedef mono_bool (*monodroid_mono_jit_set_trace_options_fptr) (const char *options); - typedef MonoDomain* (*monodroid_mono_jit_thread_attach) (MonoDomain *domain); - typedef void (*monodroid_mono_jit_set_aot_mode_fptr) (MonoAotMode mode); - typedef char* (*monodroid_mono_method_full_name_fptr) (MonoMethod *method, mono_bool signature); - typedef MonoClass* (*monodroid_mono_object_get_class_fptr) (MonoObject *obj); - typedef MonoObject* (*monodroid_mono_object_new_fptr) (MonoDomain *domain, MonoClass *klass); - typedef void* (*monodroid_mono_object_unbox_fptr) (MonoObject *obj); - typedef void (*monodroid_mono_profiler_install_fptr) (void *profiler, void *callback); - typedef void (*monodroid_mono_profiler_install_jit_end_fptr) (MonoProfileJitResult end); - typedef void (*monodroid_mono_profiler_install_thread_fptr) (void *start_ftn, void *end_ftn); - typedef void (*monodroid_mono_profiler_set_events_fptr) (MonoProfileFlags events); - typedef void (*monodroid_mono_property_set_value_fptr) (MonoProperty *prop, void *obj, void **params, MonoObject **exc); - typedef void (*monodroid_mono_register_bundled_assemblies_fptr) (const MonoBundledAssembly **assemblies); - typedef void (*monodroid_mono_register_config_for_assembly_fptr) (const char* assembly_name, const char* config_xml); - typedef void (*monodroid_mono_register_symfile_for_assembly_fptr) (const char* assembly_name, const mono_byte *raw_contents, int size); - typedef void (*monodroid_mono_register_machine_config_fptr) (const char *config); - typedef MonoObject* (*monodroid_mono_runtime_invoke_fptr) (MonoMethod *method, void *obj, void **params, MonoObject **exc); - typedef void (*monodroid_mono_set_defaults_fptr)(int arg0, int arg1); - typedef void (*monodroid_mono_set_crash_chaining_fptr)(mono_bool chain_crashes); - typedef void (*monodroid_mono_set_signal_chaining_fptr)(mono_bool chain_signals); - typedef MonoString* (*monodroid_mono_string_new_fptr)(MonoDomain *domain, const char *text); - typedef MonoThread* (*monodroid_mono_thread_attach_fptr) (MonoDomain *domain); - typedef void (*monodroid_mono_thread_create_fptr) (MonoDomain *domain, void* func, void* arg); - typedef MonoThread* (*monodroid_mono_thread_current_fptr) (void); - typedef void (*monodroid_mono_gc_disable_fptr) (void); - typedef void (*monodroid_mono_install_assembly_refonly_preload_hook_fptr) (MonoAssemblyPreLoadFunc func, void *user_data); - typedef int (*monodroid_mono_runtime_set_main_args_fptr) (int argc, char* argv[]); - typedef void (*mono_aot_register_module_fptr) (void* aot_info); - typedef MonoProfilerHandle (*monodroid_mono_profiler_create_fptr) (MonoProfiler* profiler); - typedef void (*monodroid_mono_profiler_set_jit_begin_callback_fptr) (MonoProfilerHandle handle, MonoJitBeginEventFunc begin_ftn); - typedef void (*monodroid_mono_profiler_set_jit_done_callback_fptr) (MonoProfilerHandle handle, MonoJitDoneEventFunc done_ftn); - typedef void (*monodroid_mono_profiler_set_jit_failed_callback_fptr) (MonoProfilerHandle handle, MonoJitFailedEventFunc failed_ftn); - typedef void (*monodroid_mono_profiler_set_thread_started_callback_fptr) (MonoProfilerHandle handle, MonoThreadStartedEventFunc start_ftn); - typedef void (*monodroid_mono_profiler_set_thread_stopped_callback_fptr) (MonoProfilerHandle handle, MonoThreadStoppedEventFunc stopped_ftn); - -#ifdef __cplusplus -private: -#else -struct DylibMono { -#endif /* !__cplusplus */ - void *dl_handle; - int version; - monodroid_mono_assembly_get_image_fptr mono_assembly_get_image; - monodroid_mono_assembly_load_from_full_fptr mono_assembly_load_from_full; - monodroid_mono_assembly_load_full_fptr mono_assembly_load_full; - monodroid_mono_assembly_name_get_culture_fptr mono_assembly_name_get_culture; - monodroid_mono_assembly_name_get_name_fptr mono_assembly_name_get_name; - monodroid_mono_assembly_name_new_fptr mono_assembly_name_new; - monodroid_mono_assembly_name_free_fptr mono_assembly_name_free; - monodroid_mono_assembly_open_full_fptr mono_assembly_open_full; - monodroid_mono_class_from_mono_type_fptr mono_class_from_mono_type; - monodroid_mono_class_from_name_fptr mono_class_from_name; - monodroid_mono_class_get_name_fptr mono_class_get_name; - monodroid_mono_class_get_namespace_fptr mono_class_get_namespace; - monodroid_mono_class_get_field_from_name_fptr mono_class_get_field_from_name; - monodroid_mono_class_get_fields_fptr mono_class_get_fields; - monodroid_mono_class_get_method_from_name_fptr mono_class_get_method_from_name; - monodroid_mono_class_is_subclass_of_fptr mono_class_is_subclass_of; - monodroid_mono_class_vtable_fptr mono_class_vtable; - monodroid_mono_config_parse_memory_fptr mono_config_parse_memory; - monodroid_mono_counters_dump_fptr mono_counters_dump; - monodroid_mono_counters_enable_fptr mono_counters_enable; - monodroid_mono_debug_init_fptr mono_debug_init; - monodroid_mono_debug_open_image_from_memory_fptr mono_debug_open_image_from_memory; - monodroid_mono_domain_assembly_open_fptr mono_domain_assembly_open; - monodroid_mono_dl_fallback_register_fptr mono_dl_fallback_register; - monodroid_mono_field_get_type_fptr mono_field_get_type; - monodroid_mono_field_get_value_fptr mono_field_get_value; - monodroid_mono_field_set_value_fptr mono_field_set_value; - monodroid_mono_field_static_set_value_fptr mono_field_static_set_value; - monodroid_mono_gc_register_bridge_callbacks_fptr mono_gc_register_bridge_callbacks; - monodroid_mono_gc_wait_for_bridge_processing_fptr mono_gc_wait_for_bridge_processing; - monodroid_mono_image_open_from_data_with_name_fptr mono_image_open_from_data_with_name; - monodroid_mono_install_assembly_preload_hook_fptr mono_install_assembly_preload_hook; - monodroid_mono_jit_init_version_fptr mono_jit_init_version; - monodroid_mono_jit_parse_options_fptr mono_jit_parse_options; - monodroid_mono_jit_set_trace_options_fptr mono_jit_set_trace_options; - monodroid_mono_method_full_name_fptr mono_method_full_name; - monodroid_mono_object_get_class_fptr mono_object_get_class; - monodroid_mono_object_unbox_fptr mono_object_unbox; - monodroid_mono_profiler_install_fptr mono_profiler_install; - monodroid_mono_profiler_install_jit_end_fptr mono_profiler_install_jit_end; - monodroid_mono_profiler_install_thread_fptr mono_profiler_install_thread; - monodroid_mono_profiler_set_events_fptr mono_profiler_set_events; - monodroid_mono_register_bundled_assemblies_fptr mono_register_bundled_assemblies; - monodroid_mono_register_config_for_assembly_fptr mono_register_config_for_assembly; - monodroid_mono_register_symfile_for_assembly_fptr mono_register_symfile_for_assembly; - monodroid_mono_register_machine_config_fptr mono_register_machine_config; - monodroid_mono_runtime_invoke_fptr mono_runtime_invoke; - monodroid_mono_set_defaults_fptr mono_set_defaults; - monodroid_mono_set_crash_chaining_fptr mono_set_crash_chaining; - monodroid_mono_set_signal_chaining_fptr mono_set_signal_chaining; - monodroid_mono_thread_attach_fptr mono_thread_attach; - monodroid_mono_gc_disable_fptr mono_gc_disable; - - monodroid_mono_domain_foreach_fptr mono_domain_foreach; - monodroid_mono_thread_create_fptr mono_thread_create; - monodroid_mono_jit_thread_attach mono_jit_thread_attach; - monodroid_mono_install_assembly_refonly_preload_hook_fptr mono_install_assembly_refonly_preload_hook; - monodroid_mono_jit_set_aot_mode_fptr mono_jit_set_aot_mode; - monodroid_mono_runtime_set_main_args_fptr mono_runtime_set_main_args; - int* mono_use_llvm; - - monodroid_mono_jit_cleanup_fptr mono_jit_cleanup; - monodroid_mono_domain_get_id_fptr mono_domain_get_id; - monodroid_mono_domain_get_by_id_fptr mono_domain_get_by_id; - monodroid_mono_domain_set_fptr mono_domain_set; - monodroid_mono_domain_get_fptr mono_domain_get; - monodroid_mono_domain_create_appdomain_fptr mono_domain_create_appdomain; - monodroid_mono_domain_get_fptr mono_get_root_domain; - monodroid_mono_domain_unload_fptr mono_domain_unload; - monodroid_mono_check_corlib_version_fptr mono_check_corlib_version; - - monodroid_mono_add_internal_call_fptr mono_add_internal_call; - monodroid_mono_add_internal_call_with_flags_fptr mono_add_internal_call_with_flags; - monodroid_mono_config_for_assembly_fptr mono_config_for_assembly; - - monodroid_mono_assembly_loaded_fptr mono_assembly_loaded; - - monodroid_mono_object_new_fptr mono_object_new; - monodroid_mono_string_new_fptr mono_string_new; - - monodroid_mono_property_set_value_fptr mono_property_set_value; - monodroid_mono_class_get_property_from_name_fptr mono_class_get_property_from_name; - monodroid_mono_domain_from_appdomain_fptr mono_domain_from_appdomain; - monodroid_mono_thread_current_fptr mono_thread_current; - mono_aot_register_module_fptr mono_aot_register_module; - monodroid_mono_profiler_create_fptr mono_profiler_create; - monodroid_mono_profiler_set_jit_done_callback_fptr mono_profiler_set_jit_done_callback; - monodroid_mono_profiler_set_thread_started_callback_fptr mono_profiler_set_thread_started_callback; - monodroid_mono_profiler_set_thread_stopped_callback_fptr mono_profiler_set_thread_stopped_callback; - monodroid_mono_profiler_set_jit_begin_callback_fptr mono_profiler_set_jit_begin_callback; - monodroid_mono_profiler_set_jit_failed_callback_fptr mono_profiler_set_jit_failed_callback; - -#ifdef __cplusplus - bool initialized; - -public: - explicit DylibMono () = default; - - bool init (void *libmono_path); - void close (); - - void set_use_llvm (bool use_llvm) - { - if (mono_use_llvm != nullptr) - *mono_use_llvm = static_cast (use_llvm); - } - - monodroid_mono_register_bundled_assemblies_fptr get_register_bundled_assemblies_ptr () const - { - return mono_register_bundled_assemblies; - } - - monodroid_mono_register_config_for_assembly_fptr get_register_config_for_assembly_ptr () const - { - return mono_register_config_for_assembly; - } - - monodroid_mono_jit_set_aot_mode_fptr get_jit_set_aot_mode_ptr () const - { - return mono_jit_set_aot_mode; - } - - monodroid_mono_config_parse_memory_fptr get_config_parse_memory_ptr () const - { - return mono_config_parse_memory; - } - - monodroid_mono_register_machine_config_fptr get_register_machine_config_ptr () const - { - return mono_register_machine_config; - } - - mono_aot_register_module_fptr get_aot_register_module_ptr () const - { - return mono_aot_register_module; - } - - void config_parse_memory (const char *buffer); - void add_internal_call (const char *name, const void *method); - MonoImage* assembly_get_image (void *arg0); - MonoAssembly* assembly_load_from_full (MonoImage *image, const char *fname, MonoImageOpenStatus *status, bool refonly); - MonoAssembly* assembly_load_full (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus* status, bool refonly); - MonoAssembly* assembly_loaded (MonoAssemblyName *aname); - const char* assembly_name_get_culture (MonoAssemblyName *aname); - const char* assembly_name_get_name (MonoAssemblyName *aname); - MonoAssemblyName* assembly_name_new (const char *name); - void assembly_name_free (MonoAssemblyName *aname); - MonoAssembly* assembly_open_full (const char *filename, MonoImageOpenStatus *status, bool refonly); - char* check_corlib_version (); - MonoClass* class_from_mono_type (void *arg0); - MonoClass* class_from_name (MonoImage *image, const char *name_space, const char *name); - const char* class_get_name (MonoClass *arg0); - const char* class_get_namespace (MonoClass *arg0); - bool class_is_subclass_of (MonoClass *klass, MonoClass *klassc, bool use_interfaces); - MonoClassField* class_get_field_from_name (MonoClass *arg0, char *arg1); - MonoClassField* class_get_fields (MonoClass *arg0, void **arg1); - MonoMethod* class_get_method_from_name (MonoClass *arg0, const char *arg1, int arg2); - MonoProperty* class_get_property_from_name (MonoClass *klass, const char *name); - MonoVTable* class_vtable (MonoDomain *domain, MonoClass *klass); - void config_for_assembly (MonoImage *assembly); - void counters_dump (int section_mask, FILE* outfile); - void counters_enable (int arg0); - void debug_init (int format); - void debug_open_image_from_memory (MonoImage *image, const mono_byte *raw_contents, int size); - MonoDlFallbackHandler* dl_fallback_register (MonoDlFallbackLoad load_func, MonoDlFallbackSymbol symbol_func, MonoDlFallbackClose close_func, void *user_data); - MonoAssembly* domain_assembly_open (MonoDomain *arg0, const char *arg1); - MonoDomain* domain_create_appdomain (char *friendly_name, char *config_file); - void domain_foreach (MonoDomainFunc func, void *user_data); - MonoDomain* domain_from_appdomain (MonoObject *appdomain); - MonoDomain* domain_get (); - MonoDomain* domain_get_by_id (int ID); - int domain_get_id (MonoDomain *domain); - bool domain_set (MonoDomain *domain, bool force); - void domain_unload (MonoDomain *domain); - MonoType* field_get_type (MonoClassField *arg0); - void field_get_value (MonoObject *arg0, MonoClassField *arg1, void *arg2); - void field_set_value (MonoObject *arg0, MonoClassField *arg1, void *arg2); - void field_static_set_value (MonoVTable *vtable, MonoClassField *field, void *value); - void gc_register_bridge_callbacks (void *callback); - void gc_wait_for_bridge_processing (void); - MonoImage* image_open_from_data_with_name (char *data, uint32_t data_len, bool need_copy, MonoImageOpenStatus *status, bool refonly, const char *name); - void install_assembly_preload_hook (MonoAssemblyPreLoadFunc func, void *user_data); - MonoDomain* jit_init_version (char *arg0, char *arg1); - void jit_cleanup (MonoDomain *domain); - void jit_parse_options (int argc, char **argv); - bool jit_set_trace_options (const char *options); - MonoDomain* jit_thread_attach (MonoDomain *domain); - void jit_set_aot_mode (MonoAotMode mode); - char* method_full_name (MonoMethod *method, bool signature); - MonoClass* object_get_class (MonoObject *obj); - MonoObject* object_new (MonoDomain *domain, MonoClass *klass); - void* object_unbox (MonoObject *obj); - MonoProfilerHandle profiler_create (); - void profiler_set_jit_begin_callback (MonoProfilerHandle handle, MonoJitBeginEventFunc begin_ftn); - void profiler_set_jit_done_callback (MonoProfilerHandle handle, MonoJitDoneEventFunc done_ftn); - void profiler_set_jit_failed_callback (MonoProfilerHandle handle, MonoJitFailedEventFunc failed_ftn); - void profiler_set_thread_started_callback (MonoProfilerHandle handle, MonoThreadStartedEventFunc start_ftn); - void profiler_set_thread_stopped_callback (MonoProfilerHandle handle, MonoThreadStoppedEventFunc end_ftn); - void property_set_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc); - void register_bundled_assemblies (const MonoBundledAssembly **assemblies); - void register_config_for_assembly (const char* assembly_name, const char* config_xml); - void register_symfile_for_assembly (const char* assembly_name, const mono_byte *raw_contents, int size); - void register_machine_config (const char *config); - MonoObject* runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc); - void set_defaults(int arg0, int arg1); - void set_crash_chaining(bool chain_crashes); - void set_signal_chaining(bool chain_signals); - MonoString* string_new(MonoDomain *domain, const char *text); - MonoThread* thread_attach (MonoDomain *domain); - void thread_create (MonoDomain *domain, void* func, void* arg); - MonoThread *thread_current (void); - void gc_disable (void); - void install_assembly_refonly_preload_hook (MonoAssemblyPreLoadFunc func, void *user_data); - int runtime_set_main_args (int argc, char* argv[]); - MonoDomain* get_root_domain (); - void aot_register_module (void *aot_info); - -#endif /* __cplusplus */ -}; -#ifndef __cplusplus -typedef struct DylibMono DylibMono; -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - MONO_API DylibMono* monodroid_dylib_mono_new (const char *libmono_path); - MONO_API void monodroid_dylib_mono_free (DylibMono *mono_imports); - int monodroid_dylib_mono_init (DylibMono *mono_imports, const char *libmono_path); - DylibMono* monodroid_get_dylib (void); - int monodroid_dylib_mono_init_with_handle (DylibMono *mono_imports, void *libmono_handle); -#ifdef __cplusplus -}; - -} } -#endif /* __cplusplus */ - -#endif /* INC_MONODROID_DYLIB_MONO_H */ diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/monodroid/jni/embedded-assemblies.cc index 4718a2713c5..f54b385c0c3 100644 --- a/src/monodroid/jni/embedded-assemblies.cc +++ b/src/monodroid/jni/embedded-assemblies.cc @@ -11,13 +11,16 @@ #include #include +#include +#include +#include + #include "java-interop-util.h" #include "monodroid.h" -#include "dylib-mono.h" -#include "util.h" -#include "embedded-assemblies.h" -#include "globals.h" +#include "util.hh" +#include "embedded-assemblies.hh" +#include "globals.hh" #include "monodroid-glue.h" #include "xamarin-app.h" @@ -64,8 +67,8 @@ void EmbeddedAssemblies::set_assemblies_prefix (const char *prefix) MonoAssembly* EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, bool ref_only) { - const char *culture = monoFunctions.assembly_name_get_culture (aname); - const char *asmname = monoFunctions.assembly_name_get_name (aname); + const char *culture = mono_assembly_name_get_culture (aname); + const char *asmname = mono_assembly_name_get_name (aname); size_t name_len = culture == nullptr ? 0 : strlen (culture) + 1; name_len += sizeof (".exe"); @@ -97,9 +100,9 @@ EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, bool ref_only) const MonoBundledAssembly *e = *p; if (strcmp (e->name, name) == 0 && - (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); + (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); break; } } @@ -127,8 +130,8 @@ EmbeddedAssemblies::open_from_bundles_refonly (MonoAssemblyName *aname, UNUSED_A void EmbeddedAssemblies::install_preload_hooks () { - monoFunctions.install_assembly_preload_hook (open_from_bundles_full, nullptr); - monoFunctions.install_assembly_refonly_preload_hook (open_from_bundles_refonly, nullptr); + mono_install_assembly_preload_hook (open_from_bundles_full, nullptr); + mono_install_assembly_refonly_preload_hook (open_from_bundles_refonly, nullptr); } int @@ -270,6 +273,7 @@ EmbeddedAssemblies::md_mmap_apk_file (int fd, uLong offset, uLong size, const ch uLong offsetSize = size + offsetFromPage; mmap_info.area = mmap (nullptr, offsetSize, PROT_READ, MAP_PRIVATE, fd, static_cast(offsetPage)); + if (mmap_info.area == MAP_FAILED) { log_fatal (LOG_DEFAULT, "Could not `mmap` apk `%s` entry `%s`: %s", apk, filename, strerror (errno)); exit (FATAL_EXIT_CANNOT_FIND_APK); @@ -359,7 +363,7 @@ EmbeddedAssemblies::register_debug_symbols_for_assembly (const char *entry_name, return false; } - monoFunctions.register_symfile_for_assembly (assembly->name, debug_contents, debug_size); + mono_register_symfile_for_assembly (assembly->name, debug_contents, debug_size); return true; } @@ -448,7 +452,7 @@ EmbeddedAssemblies::gather_bundled_assemblies_from_apk (const char* apk, monodro *strrchr (assembly_name, '.') = '\0'; md_mmap_info map_info = md_mmap_apk_file(fd, offset, info.uncompressed_size, cur_entry_name, apk); - monoFunctions.register_config_for_assembly (assembly_name, (const char*)map_info.area); + mono_register_config_for_assembly (assembly_name, (const char*)map_info.area); continue; } diff --git a/src/monodroid/jni/embedded-assemblies.h b/src/monodroid/jni/embedded-assemblies.hh similarity index 99% rename from src/monodroid/jni/embedded-assemblies.h rename to src/monodroid/jni/embedded-assemblies.hh index 53ec06ff83e..d70e7dea09e 100644 --- a/src/monodroid/jni/embedded-assemblies.h +++ b/src/monodroid/jni/embedded-assemblies.hh @@ -3,7 +3,8 @@ #define INC_MONODROID_EMBEDDED_ASSEMBLIES_H #include -#include "dylib-mono.h" +#include + #include "unzip.h" #include "ioapi.h" diff --git a/src/monodroid/jni/globals.cc b/src/monodroid/jni/globals.cc index 9d2f869d3c5..c4cb8285756 100644 --- a/src/monodroid/jni/globals.cc +++ b/src/monodroid/jni/globals.cc @@ -1,9 +1,8 @@ -#include "globals.h" +#include "globals.hh" using namespace xamarin::android; using namespace xamarin::android::internal; -DylibMono monoFunctions; Util utils; AndroidSystem androidSystem; OSBridge osBridge; diff --git a/src/monodroid/jni/globals.h b/src/monodroid/jni/globals.hh similarity index 65% rename from src/monodroid/jni/globals.h rename to src/monodroid/jni/globals.hh index 43acd4b90f6..61176ceddd3 100644 --- a/src/monodroid/jni/globals.h +++ b/src/monodroid/jni/globals.hh @@ -2,14 +2,12 @@ #ifndef __GLOBALS_H #define __GLOBALS_H -#include "dylib-mono.h" -#include "util.h" -#include "debug.h" -#include "embedded-assemblies.h" -#include "monodroid-glue-internal.h" -#include "cppcompat.h" +#include "util.hh" +#include "debug.hh" +#include "embedded-assemblies.hh" +#include "monodroid-glue-internal.hh" +#include "cppcompat.hh" -extern xamarin::android::DylibMono monoFunctions; extern xamarin::android::Util utils; extern xamarin::android::internal::AndroidSystem androidSystem; extern xamarin::android::internal::OSBridge osBridge; diff --git a/src/monodroid/jni/jni-wrappers.h b/src/monodroid/jni/jni-wrappers.hh similarity index 100% rename from src/monodroid/jni/jni-wrappers.h rename to src/monodroid/jni/jni-wrappers.hh diff --git a/src/monodroid/jni/logger.cc b/src/monodroid/jni/logger.cc index d5605d283de..063804185b8 100644 --- a/src/monodroid/jni/logger.cc +++ b/src/monodroid/jni/logger.cc @@ -9,13 +9,13 @@ #include #endif -#include "logger.h" +#include "logger.hh" #include "monodroid.h" #include "monodroid-glue.h" -#include "debug.h" -#include "util.h" -#include "globals.h" +#include "debug.hh" +#include "util.hh" +#include "globals.hh" #define DO_LOG(_level_,_category_,_format_,_args_) \ va_start ((_args_), (_format_)); \ @@ -77,17 +77,17 @@ open_file (LogCategories category, const char *path, const char *override_dir, c } if (!path) { - create_public_directory (override_dir); - p = path_combine (override_dir, filename); + utils.create_public_directory (override_dir); + p = utils.path_combine (override_dir, filename); path = p; } unlink (path); - f = monodroid_fopen (path, "a"); + f = utils.monodroid_fopen (path, "a"); if (f) { - set_world_accessable (path); + utils.set_world_accessable (path); } else { log_warn (category, "Could not open path '%s' for logging: %s", path, strerror (errno)); diff --git a/src/monodroid/jni/logger.h b/src/monodroid/jni/logger.hh similarity index 100% rename from src/monodroid/jni/logger.h rename to src/monodroid/jni/logger.hh diff --git a/src/monodroid/jni/mkbundle-api.h b/src/monodroid/jni/mkbundle-api.h index dc76566e3d7..66ae6a731b9 100644 --- a/src/monodroid/jni/mkbundle-api.h +++ b/src/monodroid/jni/mkbundle-api.h @@ -10,7 +10,7 @@ typedef struct BundleMonoAPI void (*mono_register_bundled_assemblies) (const MonoBundledAssembly **assemblies); void (*mono_register_config_for_assembly) (const char* assembly_name, const char* config_xml); void (*mono_jit_set_aot_mode) (int mode); - void (*mono_aot_register_module) (void* aot_info); + void (*mono_aot_register_module) (void** aot_info); void (*mono_config_parse_memory) (const char *buffer); void (*mono_register_machine_config) (const char *config_xml); } BundleMonoAPI; diff --git a/src/monodroid/jni/monodroid-glue-internal.h b/src/monodroid/jni/monodroid-glue-internal.hh similarity index 83% rename from src/monodroid/jni/monodroid-glue-internal.h rename to src/monodroid/jni/monodroid-glue-internal.hh index cf27decf1fc..7beaeb859a8 100644 --- a/src/monodroid/jni/monodroid-glue-internal.h +++ b/src/monodroid/jni/monodroid-glue-internal.hh @@ -3,9 +3,8 @@ #define __MONODROID_GLUE_INTERNAL_H #include -#include "dylib-mono.h" -#include "android-system.h" -#include "osbridge.h" +#include "android-system.hh" +#include "osbridge.hh" namespace xamarin { namespace android { namespace internal { diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc index beea67ec4c3..09ed494241f 100644 --- a/src/monodroid/jni/monodroid-glue.cc +++ b/src/monodroid/jni/monodroid-glue.cc @@ -18,6 +18,16 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "mono_android_Runtime.h" #if defined (DEBUG) && !defined (WINDOWS) @@ -50,25 +60,26 @@ #include #include "java-interop-util.h" -#include "logger.h" +#include "logger.hh" #include "monodroid.h" -#include "dylib-mono.h" -#include "util.h" -#include "debug.h" -#include "embedded-assemblies.h" +#include "util.hh" +#include "debug.hh" +#include "embedded-assemblies.hh" #include "unzip.h" #include "ioapi.h" #include "monodroid-glue.h" #include "mkbundle-api.h" -#include "monodroid-glue-internal.h" -#include "globals.h" +#include "monodroid-glue-internal.hh" +#include "globals.hh" #include "xamarin-app.h" #ifndef WINDOWS #include "xamarin_getifaddrs.h" #endif +#define XA_LOG_COUNTERS (MONO_COUNTER_JIT | MONO_COUNTER_METADATA | MONO_COUNTER_GC | MONO_COUNTER_GENERICS) + using namespace xamarin::android; using namespace xamarin::android::internal; @@ -89,7 +100,6 @@ static int config_timedout; static struct timeval wait_tv; static struct timespec wait_ts; #endif // def DEBUG -char *xamarin::android::internal::runtime_libdir; static MonoMethod* registerType; /* * If set, monodroid will spin in a loop until the debugger breaks the wait by @@ -113,7 +123,7 @@ monodroid_clear_gdb_wait (void) #ifdef WINDOWS static const char* get_xamarin_android_msbuild_path (void); -const char *AndroidSystem::SYSTEM_LIB_PATH = get_xamarin_android_msbuild_path(); +const char *BasicAndroidSystem::SYSTEM_LIB_PATH = get_xamarin_android_msbuild_path(); #endif /* !DO NOT REMOVE! Used by Mono BCL */ @@ -153,17 +163,6 @@ monodroid_get_system_property (const char *name, char **value) return androidSystem.monodroid_get_system_property (name, value); } -static char* -get_primary_override_dir (JNIEnv *env, jstring_wrapper &home) -{ - return utils.path_combine (home.get_cstr (), ".__override__"); -} - -// TODO: these must be moved to some class -char *xamarin::android::internal::primary_override_dir; -char *xamarin::android::internal::external_override_dir; -char *xamarin::android::internal::external_legacy_override_dir; - /* Set of Windows-specific utility/reimplementation of Unix functions */ #ifdef WINDOWS @@ -381,7 +380,7 @@ log_jit_event (MonoMethod *method, const char *event_name) if (!jit_log) return; - char* name = monoFunctions.method_full_name (method, 1); + char* name = mono_method_full_name (method, 1); timing_diff diff (jit_time); fprintf (jit_log, "JIT method %6s: %s elapsed: %lis:%u::%u\n", event_name, name, diff.sec, diff.ms, diff.ns); @@ -413,8 +412,8 @@ open_from_update_dir (MonoAssemblyName *aname, char **assemblies_path, void *use { MonoAssembly *result = nullptr; int found = 0; - const char *culture = reinterpret_cast (monoFunctions.assembly_name_get_culture (aname)); - const char *name = reinterpret_cast (monoFunctions.assembly_name_get_name (aname)); + const char *culture = reinterpret_cast (mono_assembly_name_get_culture (aname)); + const char *name = reinterpret_cast (mono_assembly_name_get_name (aname)); char *pname; for (uint32_t oi = 0; oi < AndroidSystem::MAX_OVERRIDES; ++oi) @@ -442,7 +441,7 @@ open_from_update_dir (MonoAssemblyName *aname, char **assemblies_path, void *use fullpath = utils.monodroid_strdup_printf (formats [fi], androidSystem.get_override_dir (oi), pname); log_info (LOG_ASSEMBLY, "open_from_update_dir: trying to open assembly: %s\n", fullpath); if (utils.file_exists (fullpath)) - result = monoFunctions.assembly_open_full (fullpath, nullptr, 0); + result = mono_assembly_open_full (fullpath, nullptr, 0); free (fullpath); if (result) { // TODO: register .mdb, .pdb file @@ -750,7 +749,7 @@ set_debug_options (void) return; embeddedAssemblies.set_register_debug_symbols (true); - monoFunctions.debug_init (MONO_DEBUG_FORMAT_MONO); + mono_debug_init (MONO_DEBUG_FORMAT_MONO); } #ifdef ANDROID @@ -883,12 +882,12 @@ mono_runtime_init (char *runtime_args) if (enable_soft_breakpoints ()) { constexpr char soft_breakpoints[] = "--soft-breakpoints"; debug_options[1] = const_cast (soft_breakpoints); - monoFunctions.jit_parse_options (2, debug_options); + mono_jit_parse_options (2, debug_options); } else { - monoFunctions.jit_parse_options (1, debug_options); + mono_jit_parse_options (1, debug_options); } - monoFunctions.debug_init (MONO_DEBUG_FORMAT_MONO); + mono_debug_init (MONO_DEBUG_FORMAT_MONO); } else { set_debug_options (); } @@ -904,14 +903,15 @@ mono_runtime_init (char *runtime_args) delete[] jit_log_path; } - profiler_handle = monoFunctions.profiler_create (); - monoFunctions.profiler_set_thread_started_callback (profiler_handle, thread_start); - monoFunctions.profiler_set_thread_stopped_callback (profiler_handle, thread_end); + profiler_handle = mono_profiler_create (nullptr); + mono_profiler_set_thread_started_callback (profiler_handle, thread_start); + mono_profiler_set_thread_stopped_callback (profiler_handle, thread_end); + if (XA_UNLIKELY (log_methods)) { jit_time.mark_start (); - monoFunctions.profiler_set_jit_begin_callback (profiler_handle, jit_begin); - monoFunctions.profiler_set_jit_done_callback (profiler_handle, jit_done); - monoFunctions.profiler_set_jit_failed_callback (profiler_handle, jit_failed); + mono_profiler_set_jit_begin_callback (profiler_handle, jit_begin); + mono_profiler_set_jit_done_callback (profiler_handle, jit_done); + mono_profiler_set_jit_failed_callback (profiler_handle, jit_failed); } parse_gdb_options (); @@ -937,22 +937,22 @@ mono_runtime_init (char *runtime_args) for (ptr = args; *ptr; ptr++) argc ++; - monoFunctions.jit_parse_options (argc, args); + mono_jit_parse_options (argc, args); } - monoFunctions.set_signal_chaining (1); - monoFunctions.set_crash_chaining (1); + mono_set_signal_chaining (1); + mono_set_crash_chaining (1); osBridge.register_gc_hooks (); if (mono_mkbundle_initialize_mono_api) { BundleMonoAPI bundle_mono_api = { - .mono_register_bundled_assemblies = monoFunctions.get_register_bundled_assemblies_ptr (), - .mono_register_config_for_assembly = monoFunctions.get_register_config_for_assembly_ptr (), - .mono_jit_set_aot_mode = reinterpret_cast(monoFunctions.get_jit_set_aot_mode_ptr ()), - .mono_aot_register_module = monoFunctions.get_aot_register_module_ptr (), - .mono_config_parse_memory = monoFunctions.get_config_parse_memory_ptr (), - .mono_register_machine_config = reinterpret_cast(monoFunctions.get_register_machine_config_ptr ()), + .mono_register_bundled_assemblies = mono_register_bundled_assemblies, + .mono_register_config_for_assembly = mono_register_config_for_assembly, + .mono_jit_set_aot_mode = reinterpret_cast(mono_jit_set_aot_mode), + .mono_aot_register_module = mono_aot_register_module, + .mono_config_parse_memory = mono_config_parse_memory, + .mono_register_machine_config = reinterpret_cast(mono_register_machine_config), }; /* The initialization function copies the struct */ @@ -960,7 +960,7 @@ mono_runtime_init (char *runtime_args) } if (mono_mkbundle_init) - mono_mkbundle_init (monoFunctions.get_register_bundled_assemblies_ptr (), monoFunctions.get_register_config_for_assembly_ptr (), reinterpret_cast(monoFunctions.get_jit_set_aot_mode_ptr ())); + mono_mkbundle_init (mono_register_bundled_assemblies, mono_register_config_for_assembly, reinterpret_cast(mono_jit_set_aot_mode)); /* * Assembly preload hooks are invoked in _reverse_ registration order. @@ -969,7 +969,7 @@ mono_runtime_init (char *runtime_args) */ embeddedAssemblies.install_preload_hooks (); #ifndef RELEASE - monoFunctions.install_assembly_preload_hook (open_from_update_dir, nullptr); + mono_install_assembly_preload_hook (open_from_update_dir, nullptr); #endif } @@ -989,9 +989,9 @@ create_domain (JNIEnv *env, jclass runtimeClass, jstring_array_wrapper &runtimeA } if (is_root_domain) { - domain = monoFunctions.jit_init_version (const_cast ("RootDomain"), const_cast ("mobile")); + domain = mono_jit_init_version (const_cast ("RootDomain"), const_cast ("mobile")); } else { - MonoDomain* root_domain = monoFunctions.get_root_domain (); + MonoDomain* root_domain = mono_get_root_domain (); char *domain_name = utils.monodroid_strdup_printf ("MonoAndroidDomain%d", android_api_level); domain = utils.monodroid_create_appdomain (root_domain, domain_name, /*shadow_copy:*/ 1, /*shadow_directory:*/ androidSystem.get_override_dir (0)); free (domain_name); @@ -1000,7 +1000,7 @@ create_domain (JNIEnv *env, jclass runtimeClass, jstring_array_wrapper &runtimeA if (is_running_on_desktop && is_root_domain) { // Check that our corlib is coherent with the version of Mono we loaded otherwise // tell the IDE that the project likely need to be recompiled. - char* corlib_error_message = monoFunctions.check_corlib_version (); + char* corlib_error_message = const_cast(mono_check_corlib_version ()); if (corlib_error_message == nullptr) { if (!androidSystem.monodroid_get_system_property ("xamarin.studio.fakefaultycorliberrormessage", &corlib_error_message)) { free (corlib_error_message); @@ -1016,9 +1016,9 @@ create_domain (JNIEnv *env, jclass runtimeClass, jstring_array_wrapper &runtimeA // Load a basic environment for the RootDomain if run on desktop so that we can unload // and reload most assemblies including Mono.Android itself - MonoAssemblyName *aname = monoFunctions.assembly_name_new ("System"); - monoFunctions.assembly_load_full (aname, nullptr, nullptr, 0); - monoFunctions.assembly_name_free (aname); + MonoAssemblyName *aname = mono_assembly_name_new ("System"); + mono_assembly_load_full (aname, nullptr, nullptr, 0); + mono_assembly_name_free (aname); } return domain; @@ -1067,7 +1067,7 @@ _monodroid_timezone_get_default_id (void) MONO_API void _monodroid_gc_wait_for_bridge_processing (void) { - monoFunctions.gc_wait_for_bridge_processing (); + mono_gc_wait_for_bridge_processing (); } struct JnienvInitializeArgs { @@ -1111,19 +1111,19 @@ _monodroid_get_display_dpi (float *x_dpi, float *y_dpi) MonoDomain *domain = nullptr; if (!runtime_GetDisplayDPI) { - domain = monoFunctions.get_root_domain (); + domain = mono_get_root_domain (); MonoAssembly *assm = utils.monodroid_load_assembly (domain, "Mono.Android");; MonoImage *image = nullptr; if (assm != nullptr) - image = monoFunctions.assembly_get_image (assm); + image = mono_assembly_get_image (assm); MonoClass *environment = nullptr; if (image != nullptr) environment = utils.monodroid_get_class_from_image (domain, image, "Android.Runtime", "AndroidEnvironment"); if (environment != nullptr) - runtime_GetDisplayDPI = monoFunctions.class_get_method_from_name (environment, "GetDisplayDPI", 2); + runtime_GetDisplayDPI = mono_class_get_method_from_name (environment, "GetDisplayDPI", 2); } if (!runtime_GetDisplayDPI) { @@ -1134,7 +1134,7 @@ _monodroid_get_display_dpi (float *x_dpi, float *y_dpi) args [0] = x_dpi; args [1] = y_dpi; - utils.monodroid_runtime_invoke (domain != nullptr ? domain : monoFunctions.get_root_domain (), runtime_GetDisplayDPI, nullptr, args, &exc); + utils.monodroid_runtime_invoke (domain != nullptr ? domain : mono_get_root_domain (), runtime_GetDisplayDPI, nullptr, args, &exc); if (exc) { *x_dpi = DEFAULT_X_DPI; *y_dpi = DEFAULT_Y_DPI; @@ -1147,10 +1147,10 @@ static void lookup_bridge_info (MonoDomain *domain, MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) { info->klass = utils.monodroid_get_class_from_image (domain, image, type->_namespace, type->_typename); - info->handle = monoFunctions.class_get_field_from_name (info->klass, const_cast ("handle")); - info->handle_type = monoFunctions.class_get_field_from_name (info->klass, const_cast ("handle_type")); - info->refs_added = monoFunctions.class_get_field_from_name (info->klass, const_cast ("refs_added")); - info->weak_handle = monoFunctions.class_get_field_from_name (info->klass, const_cast ("weak_handle")); + info->handle = mono_class_get_field_from_name (info->klass, const_cast ("handle")); + info->handle_type = mono_class_get_field_from_name (info->klass, const_cast ("handle_type")); + info->refs_added = mono_class_get_field_from_name (info->klass, const_cast ("refs_added")); + info->weak_handle = mono_class_get_field_from_name (info->klass, const_cast ("weak_handle")); } static void @@ -1184,7 +1184,7 @@ init_android_runtime (MonoDomain *domain, JNIEnv *env, jclass runtimeClass, jobj init.Class_forName = env->GetStaticMethodID (init.grefClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"); assm = utils.monodroid_load_assembly (domain, "Mono.Android"); - image = monoFunctions.assembly_get_image (assm); + image = mono_assembly_get_image (assm); for (uint32_t i = 0; i < OSBridge::NUM_GC_BRIDGE_TYPES; ++i) { lookup_bridge_info (domain, image, &osBridge.get_java_gc_bridge_type (i), &osBridge.get_java_gc_bridge_info (i)); @@ -1192,7 +1192,7 @@ init_android_runtime (MonoDomain *domain, JNIEnv *env, jclass runtimeClass, jobj // TODO: try looking up the method by its token runtime = utils.monodroid_get_class_from_image (domain, image, "Android.Runtime", "JNIEnv"); - method = monoFunctions.class_get_method_from_name (runtime, "Initialize", 1); + method = mono_class_get_method_from_name (runtime, "Initialize", 1); if (method == 0) { log_fatal (LOG_DEFAULT, "INTERNAL ERROR: Unable to find Android.Runtime.JNIEnv.Initialize!"); @@ -1202,14 +1202,14 @@ init_android_runtime (MonoDomain *domain, JNIEnv *env, jclass runtimeClass, jobj * so always make sure we have the freshest handle to the method. */ if (registerType == 0 || is_running_on_desktop) { - registerType = monoFunctions.class_get_method_from_name (runtime, "RegisterJniNatives", 5); + registerType = mono_class_get_method_from_name (runtime, "RegisterJniNatives", 5); } if (registerType == 0) { log_fatal (LOG_DEFAULT, "INTERNAL ERROR: Unable to find Android.Runtime.JNIEnv.RegisterJniNatives!"); exit (FATAL_EXIT_CANNOT_FIND_JNIENV); } MonoClass *android_runtime_jnienv = runtime; - MonoClassField *bridge_processing_field = monoFunctions.class_get_field_from_name (runtime, const_cast ("BridgeProcessing")); + MonoClassField *bridge_processing_field = mono_class_get_field_from_name (runtime, const_cast ("BridgeProcessing")); if (!android_runtime_jnienv || !bridge_processing_field) { log_fatal (LOG_DEFAULT, "INTERNAL_ERROR: Unable to find Android.Runtime.JNIEnv.BridgeProcessing"); exit (FATAL_EXIT_CANNOT_FIND_JNIENV); @@ -1245,7 +1245,7 @@ static MonoClass* get_android_runtime_class (MonoDomain *domain) { MonoAssembly *assm = utils.monodroid_load_assembly (domain, "Mono.Android"); - MonoImage *image = monoFunctions.assembly_get_image (assm); + MonoImage *image = mono_assembly_get_image (assm); MonoClass *runtime = utils.monodroid_get_class_from_image (domain, image, "Android.Runtime", "JNIEnv"); return runtime; @@ -1255,7 +1255,7 @@ static void shutdown_android_runtime (MonoDomain *domain) { MonoClass *runtime = get_android_runtime_class (domain); - MonoMethod *method = monoFunctions.class_get_method_from_name (runtime, "Exit", 0); + MonoMethod *method = mono_class_get_method_from_name (runtime, "Exit", 0); utils.monodroid_runtime_invoke (domain, method, nullptr, nullptr, nullptr); } @@ -1265,7 +1265,7 @@ propagate_uncaught_exception (MonoDomain *domain, JNIEnv *env, jobject javaThrea { void *args[3]; MonoClass *runtime = get_android_runtime_class (domain); - MonoMethod *method = monoFunctions.class_get_method_from_name (runtime, "PropagateUncaughtException", 3); + MonoMethod *method = mono_class_get_method_from_name (runtime, "PropagateUncaughtException", 3); args[0] = &env; args[1] = &javaThread; @@ -1287,9 +1287,9 @@ setup_gc_logging (void) static int convert_dl_flags (int flags) { - int lflags = flags & static_cast (MonoDlKind::MONO_DL_LOCAL) ? 0: RTLD_GLOBAL; + int lflags = flags & static_cast (MONO_DL_LOCAL) ? 0: RTLD_GLOBAL; - if (flags & static_cast (MonoDlKind::MONO_DL_LAZY)) + if (flags & static_cast (MONO_DL_LAZY)) lflags |= RTLD_LAZY; else lflags |= RTLD_NOW; @@ -1450,7 +1450,7 @@ set_trace_options (void) if (utils.monodroid_get_namespaced_system_property (Debug::DEBUG_MONO_TRACE_PROPERTY, &value) == 0) return; - monoFunctions.jit_set_trace_options (value); + mono_jit_set_trace_options (value); delete[] value; } @@ -1617,7 +1617,7 @@ set_profile_options (JNIEnv *env) unlink (output); log_warn (LOG_DEFAULT, "Initializing profiler with options: %s", value); - monodroid_profiler_load (runtime_libdir, value, output); + monodroid_profiler_load (androidSystem.get_runtime_libdir (), value, output); delete[] value; delete[] output; @@ -1727,12 +1727,12 @@ start_debugging (void) if (enable_soft_breakpoints ()) { constexpr char soft_breakpoints[] = "--soft-breakpoints"; debug_options[1] = const_cast (soft_breakpoints); - monoFunctions.jit_parse_options (2, debug_options); + mono_jit_parse_options (2, debug_options); } else { - monoFunctions.jit_parse_options (1, debug_options); + mono_jit_parse_options (1, debug_options); } - monoFunctions.debug_init (MONO_DEBUG_FORMAT_MONO); + mono_debug_init (MONO_DEBUG_FORMAT_MONO); } static void @@ -1750,7 +1750,7 @@ start_profiling (void) return; log_info (LOG_DEFAULT, "Loading profiler: '%s'", profiler_description); - monodroid_profiler_load (runtime_libdir, profiler_description, nullptr); + monodroid_profiler_load (androidSystem.get_runtime_libdir (), profiler_description, nullptr); } #endif // def DEBUG && !WINDOWS @@ -1798,7 +1798,7 @@ _monodroid_counters_dump (const char *format, ...) fprintf (counters, "\n"); - monoFunctions.counters_dump (static_cast(XA_LOG_COUNTERS), counters); + mono_counters_dump (static_cast(XA_LOG_COUNTERS), counters); } static void @@ -1811,18 +1811,18 @@ load_assembly (MonoDomain *domain, JNIEnv *env, jstring_wrapper &assembly) const char *assm_name = assembly.get_cstr (); MonoAssemblyName *aname; - aname = monoFunctions.assembly_name_new (assm_name); + aname = mono_assembly_name_new (assm_name); - if (domain != monoFunctions.domain_get ()) { - MonoDomain *current = monoFunctions.domain_get (); - monoFunctions.domain_set (domain, FALSE); - monoFunctions.assembly_load_full (aname, NULL, NULL, 0); - monoFunctions.domain_set (current, FALSE); + if (domain != mono_domain_get ()) { + MonoDomain *current = mono_domain_get (); + mono_domain_set (domain, FALSE); + mono_assembly_load_full (aname, NULL, NULL, 0); + mono_domain_set (current, FALSE); } else { - monoFunctions.assembly_load_full (aname, NULL, NULL, 0); + mono_assembly_load_full (aname, NULL, NULL, 0); } - monoFunctions.assembly_name_free (aname); + mono_assembly_name_free (aname); if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) { total_time.mark_end (); @@ -1915,42 +1915,20 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, androidSystem.setup_environment (); - jstr = reinterpret_cast (env->GetObjectArrayElement (appDirs, 1)); - set_environment_variable_for_directory (env, "TMPDIR", jstr); - - jstr = reinterpret_cast (env->GetObjectArrayElement (appDirs, 0)); - set_environment_variable_for_directory (env, "HOME", jstr); - create_xdg_directories_and_environment (env, jstr); - primary_override_dir = get_primary_override_dir (env, jstr); + jstring_array_wrapper applicationDirs (env, appDirs); + jstring_wrapper &home = applicationDirs[0]; + set_environment_variable_for_directory (env, "TMPDIR", applicationDirs[1]); + set_environment_variable_for_directory (env, "HOME", home); + create_xdg_directories_and_environment (env, home); + androidSystem.set_primary_override_dir (env, home); disable_external_signal_handlers (); jstring_array_wrapper runtimeApks (env, runtimeApksJava); - if (android_api_level < 23 || !androidSystem.is_embedded_dso_mode_enabled ()) { - log_info (LOG_DEFAULT, "Setting up for DSO lookup in app data directories"); - jstr = env->GetObjectArrayElement (appDirs, 2); - AndroidSystem::app_lib_directories_size = 1; - AndroidSystem::app_lib_directories = (const char**) xcalloc (AndroidSystem::app_lib_directories_size, sizeof(char*)); - AndroidSystem::app_lib_directories [0] = strdup (jstr.get_cstr ()); - } else { - log_info (LOG_DEFAULT, "Setting up for DSO lookup directly in the APK"); - AndroidSystem::app_lib_directories_size = runtimeApks.get_length (); - AndroidSystem::app_lib_directories = (const char**) xcalloc (AndroidSystem::app_lib_directories_size, sizeof(char*)); + androidSystem.setup_app_library_directories (env, runtimeApks, applicationDirs, apiLevel); - unsigned short built_for_cpu = 0, running_on_cpu = 0; - unsigned char is64bit = 0; - _monodroid_detect_cpu_and_architecture (&built_for_cpu, &running_on_cpu, &is64bit); - androidSystem.setup_apk_directories (env, running_on_cpu, runtimeApks); - } - - jstr = env->GetObjectArrayElement (externalStorageDirs, 0); - external_override_dir = strdup (jstr.get_cstr ()); - - jstr = env->GetObjectArrayElement (externalStorageDirs, 1); - external_legacy_override_dir = strdup (jstr.get_cstr ()); - - init_reference_logging (primary_override_dir); - androidSystem.create_update_dir (primary_override_dir); + init_reference_logging (androidSystem.get_primary_override_dir ()); + androidSystem.create_update_dir (androidSystem.get_primary_override_dir ()); #if DEBUG setup_gc_logging (); @@ -1958,8 +1936,12 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, #endif #ifndef RELEASE - androidSystem.set_override_dir (1, external_override_dir); - androidSystem.set_override_dir (2, external_legacy_override_dir); + jstr = env->GetObjectArrayElement (externalStorageDirs, 0); + androidSystem.set_override_dir (1, utils.strdup_new (jstr.get_cstr ())); + + jstr = env->GetObjectArrayElement (externalStorageDirs, 1); + androidSystem.set_override_dir (2, utils.strdup_new (jstr.get_cstr ())); + for (uint32_t i = 0; i < AndroidSystem::MAX_OVERRIDES; ++i) { const char *p = androidSystem.get_override_dir (i); if (!utils.directory_exists (p)) @@ -1971,32 +1953,15 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, if (runtimeNativeLibDir != nullptr) { jstr = runtimeNativeLibDir; - runtime_libdir = strdup (jstr.get_cstr ()); - log_warn (LOG_DEFAULT, "Using runtime path: %s", runtime_libdir); + androidSystem.set_runtime_libdir (strdup (jstr.get_cstr ())); + log_warn (LOG_DEFAULT, "Using runtime path: %s", androidSystem.get_runtime_libdir ()); } - void *libmonosgen_handle = nullptr; - - /* - * We need to use RTLD_GLOBAL so that libmono-profiler-log.so can resolve - * symbols against the Mono library we're loading. - */ - int sgen_dlopen_flags = RTLD_LAZY | RTLD_GLOBAL; - if (androidSystem.is_embedded_dso_mode_enabled ()) { - libmonosgen_handle = androidSystem.load_dso_from_any_directories (AndroidSystem::MONO_SGEN_SO, sgen_dlopen_flags); - } - - if (libmonosgen_handle == nullptr) - libmonosgen_handle = androidSystem.load_dso (androidSystem.get_libmonosgen_path (), sgen_dlopen_flags, FALSE); - - if (!monoFunctions.init (libmonosgen_handle)) { - log_fatal (LOG_DEFAULT, "shared runtime initialization error: %s", dlerror ()); - exit (FATAL_EXIT_CANNOT_FIND_MONO); - } androidSystem.setup_process_args (env, runtimeApks); if (XA_UNLIKELY (utils.should_log (LOG_TIMING)) && !(log_timing_categories & LOG_TIMING_BARE)) { - monoFunctions.counters_enable (static_cast(XA_LOG_COUNTERS)); + mono_counters_enable (static_cast(XA_LOG_COUNTERS)); + char *counters_path = utils.path_combine (androidSystem.get_override_dir (0), "counters.txt"); log_info_nocheck (LOG_TIMING, "counters path: %s", counters_path); counters = utils.monodroid_fopen (counters_path, "a"); @@ -2004,7 +1969,7 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, delete[] counters_path; } - monoFunctions.dl_fallback_register (monodroid_dlopen, monodroid_dlsym, nullptr, nullptr); + mono_dl_fallback_register (monodroid_dlopen, monodroid_dlsym, nullptr, nullptr); set_profile_options (env); @@ -2033,19 +1998,19 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, } #endif - monoFunctions.config_parse_memory (reinterpret_cast (monodroid_config)); - monoFunctions.register_machine_config (reinterpret_cast (monodroid_machine_config)); + mono_config_parse_memory (reinterpret_cast (monodroid_config)); + mono_register_machine_config (reinterpret_cast (monodroid_machine_config)); log_info (LOG_DEFAULT, "Probing for Mono AOT mode\n"); if (androidSystem.is_mono_aot_enabled ()) { MonoAotMode mode = androidSystem.get_mono_aot_mode (); - if (mode == MonoAotMode::MONO_AOT_MODE_UNKNOWN) + if (mode == MonoAotMode::MONO_AOT_MODE_LAST) mode = MonoAotMode::MONO_AOT_MODE_NONE; if (mode != MonoAotMode::MONO_AOT_MODE_NORMAL && mode != MonoAotMode::MONO_AOT_MODE_NONE) { log_info (LOG_DEFAULT, "Enabling AOT mode in Mono"); - monoFunctions.jit_set_aot_mode (mode); + mono_jit_set_aot_mode (mode); } } @@ -2055,8 +2020,8 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, char *args [1]; args[0] = const_cast ("--llvm"); log_info (LOG_DEFAULT, "Enabling LLVM mode in Mono\n"); - monoFunctions.jit_parse_options (1, args); - monoFunctions.set_use_llvm (true); + mono_jit_parse_options (1, args); + mono_set_use_llvm (true); } char *runtime_args = nullptr; @@ -2086,7 +2051,7 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, // Install our dummy exception handler on Desktop if (is_running_on_desktop) { - monoFunctions.add_internal_call ("System.Diagnostics.Debugger::Mono_UnhandledException_internal(System.Exception)", + mono_add_internal_call ("System.Diagnostics.Debugger::Mono_UnhandledException_internal(System.Exception)", reinterpret_cast (monodroid_Mono_UnhandledException_internal)); } @@ -2106,7 +2071,7 @@ JNICALL Java_mono_android_Runtime_register (JNIEnv *env, jclass klass, jstring m const jchar *managedType_ptr, *methods_ptr; void *args [5]; const char *mt_ptr; - MonoDomain *domain = monoFunctions.domain_get (); + MonoDomain *domain = mono_domain_get (); timing_period total_time; if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) @@ -2124,9 +2089,9 @@ JNICALL Java_mono_android_Runtime_register (JNIEnv *env, jclass klass, jstring m args [3] = &methods_ptr; args [4] = &methods_len; - monoFunctions.jit_thread_attach (domain); + mono_jit_thread_attach (domain); // Refresh current domain as it might have been modified by the above call - domain = monoFunctions.domain_get (); + domain = mono_domain_get (); utils.monodroid_runtime_invoke (domain, registerType, nullptr, args, nullptr); env->ReleaseStringChars (methods, methods_ptr); @@ -2166,14 +2131,14 @@ JNICALL Java_mono_android_Runtime_createNewContext (JNIEnv *env, jclass klass, j { log_info (LOG_DEFAULT, "CREATING NEW CONTEXT"); reinitialize_android_runtime_type_manager (env); - MonoDomain *root_domain = monoFunctions.get_root_domain (); - monoFunctions.jit_thread_attach (root_domain); + MonoDomain *root_domain = mono_get_root_domain (); + mono_jit_thread_attach (root_domain); jstring_array_wrapper runtimeApks (env, runtimeApksJava); jstring_array_wrapper assemblies (env, assembliesJava); MonoDomain *domain = create_and_initialize_domain (env, klass, runtimeApks, assemblies, loader, /*is_root_domain:*/ false); - monoFunctions.domain_set (domain, FALSE); - int domain_id = monoFunctions.domain_get_id (domain); + mono_domain_set (domain, FALSE); + int domain_id = mono_domain_get_id (domain); current_context_id = domain_id; log_info (LOG_DEFAULT, "Created new context with id %d\n", domain_id); return domain_id; @@ -2183,9 +2148,9 @@ JNIEXPORT void JNICALL Java_mono_android_Runtime_switchToContext (JNIEnv *env, jclass klass, jint contextID) { log_info (LOG_DEFAULT, "SWITCHING CONTEXT"); - MonoDomain *domain = monoFunctions.domain_get_by_id ((int)contextID); + MonoDomain *domain = mono_domain_get_by_id ((int)contextID); if (current_context_id != (int)contextID) { - monoFunctions.domain_set (domain, TRUE); + mono_domain_set (domain, TRUE); // Reinitialize TypeManager so that its JNI handle goes into the right domain reinitialize_android_runtime_type_manager (env); } @@ -2195,8 +2160,8 @@ JNICALL Java_mono_android_Runtime_switchToContext (JNIEnv *env, jclass klass, ji JNIEXPORT void JNICALL Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jclass klass, jintArray array) { - MonoDomain *root_domain = monoFunctions.get_root_domain (); - monoFunctions.jit_thread_attach (root_domain); + MonoDomain *root_domain = mono_get_root_domain (); + mono_jit_thread_attach (root_domain); current_context_id = -1; jint *contextIDs = env->GetIntArrayElements (array, nullptr); @@ -2207,7 +2172,7 @@ JNICALL Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jclass klass, ji int i; for (i = 0; i < count; i++) { int domain_id = contextIDs[i]; - MonoDomain *domain = monoFunctions.domain_get_by_id (domain_id); + MonoDomain *domain = mono_domain_get_by_id (domain_id); if (domain == nullptr) continue; @@ -2219,12 +2184,12 @@ JNICALL Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jclass klass, ji for (i = 0; i < count; i++) { int domain_id = contextIDs[i]; - MonoDomain *domain = monoFunctions.domain_get_by_id (domain_id); + MonoDomain *domain = mono_domain_get_by_id (domain_id); if (domain == nullptr) continue; log_info (LOG_DEFAULT, "Unloading domain `%d'", contextIDs[i]); - monoFunctions.domain_unload (domain); + mono_domain_unload (domain); } env->ReleaseIntArrayElements (array, contextIDs, JNI_ABORT); @@ -2237,32 +2202,18 @@ JNICALL Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jclass klass, ji JNIEXPORT void JNICALL Java_mono_android_Runtime_propagateUncaughtException (JNIEnv *env, jclass klass, jobject javaThread, jthrowable javaException) { - MonoDomain *domain = monoFunctions.domain_get (); + MonoDomain *domain = mono_domain_get (); propagate_uncaught_exception (domain, env, javaThread, javaException); } -extern "C" DylibMono* monodroid_dylib_mono_new (const char *libmono_path) +extern "C" void* monodroid_dylib_mono_new (const char *libmono_path) { - DylibMono *imports = new DylibMono (); - if (!imports) - return nullptr; - - void *libmono_handle = androidSystem.load_dso_from_any_directories(libmono_path, RTLD_LAZY | RTLD_GLOBAL); - if (!imports->init (libmono_handle)) { - delete imports; - return nullptr; - } - - return imports; + return nullptr; } -extern "C" void monodroid_dylib_mono_free (DylibMono *mono_imports) +extern "C" void monodroid_dylib_mono_free (void *mono_imports) { - if (!mono_imports) - return; - - mono_imports->close (); - delete mono_imports; + // no-op } /* @@ -2271,16 +2222,16 @@ extern "C" void monodroid_dylib_mono_free (DylibMono *mono_imports) it should also accept libmono_path = nullptr parameter */ -extern "C" int monodroid_dylib_mono_init (DylibMono *mono_imports, const char *libmono_path) +extern "C" int monodroid_dylib_mono_init (void *mono_imports, const char *libmono_path) { if (mono_imports == nullptr) return FALSE; void *libmono_handle = libmono_path ? androidSystem.load_dso_from_any_directories(libmono_path, RTLD_LAZY | RTLD_GLOBAL) : dlopen (libmono_path, RTLD_LAZY | RTLD_GLOBAL);; - return mono_imports->init (libmono_handle) ? TRUE : FALSE; + return TRUE; } -extern "C" DylibMono* monodroid_get_dylib (void) +extern "C" void* monodroid_get_dylib (void) { - return &monoFunctions; + return nullptr; } diff --git a/src/monodroid/jni/monodroid-glue.h b/src/monodroid/jni/monodroid-glue.h index 633c187d1e4..439cb3a7d43 100644 --- a/src/monodroid/jni/monodroid-glue.h +++ b/src/monodroid/jni/monodroid-glue.h @@ -5,7 +5,8 @@ #include #include -#include "dylib-mono.h" +#include +#include #ifdef __cplusplus extern "C" { diff --git a/src/monodroid/jni/monodroid-networkinfo.cc b/src/monodroid/jni/monodroid-networkinfo.cc index 25d9edb2749..b05b1d8bd3c 100644 --- a/src/monodroid/jni/monodroid-networkinfo.cc +++ b/src/monodroid/jni/monodroid-networkinfo.cc @@ -31,8 +31,9 @@ #include "monodroid.h" #include "monodroid-glue.h" -#include "util.h" -#include "globals.h" + +#include "util.hh" +#include "globals.hh" using namespace xamarin::android; diff --git a/src/monodroid/jni/monodroid.h b/src/monodroid/jni/monodroid.h index 5d44a06034f..5f3b7a7f846 100644 --- a/src/monodroid/jni/monodroid.h +++ b/src/monodroid/jni/monodroid.h @@ -1,37 +1,6 @@ #ifndef __MONODROID_H #define __MONODROID_H -/* VS 2010 and later have stdint.h */ -#if defined(_MSC_VER) - - #define MONO_API_EXPORT __declspec(dllexport) - #define MONO_API_IMPORT __declspec(dllimport) - -#else /* defined(_MSC_VER */ - - #define MONO_API_EXPORT __attribute__ ((visibility ("default"))) - #define MONO_API_IMPORT - -#endif /* !defined(_MSC_VER) */ - -#if defined(MONO_DLL_EXPORT) - #define MONO_API_DEF MONO_API_EXPORT -#elif defined(MONO_DLL_IMPORT) - #define MONO_API_DEF MONO_API_IMPORT -#else /* !defined(MONO_DLL_IMPORT) && !defined(MONO_API_IMPORT) */ - #define MONO_API_DEF -#endif /* MONO_DLL_EXPORT... */ - -#ifdef __cplusplus -#define MONO_API extern "C" MONO_API_DEF -#else - -/* Use our own definition, to stay consistent */ -#if defined (MONO_API) -#undef MONO_API -#endif -#define MONO_API MONO_API_DEF - -#endif /* __cplusplus */ +#include #endif /* defined __MONODROID_H */ diff --git a/src/monodroid/jni/osbridge.cc b/src/monodroid/jni/osbridge.cc index dc39a3b76d7..bf6ca1e9534 100644 --- a/src/monodroid/jni/osbridge.cc +++ b/src/monodroid/jni/osbridge.cc @@ -6,6 +6,10 @@ #include #endif +#include +#include +#include + #if defined (WINDOWS) #include #include @@ -15,8 +19,8 @@ #include #endif -#include "globals.h" -#include "osbridge.h" +#include "globals.hh" +#include "osbridge.hh" // These two must stay here until JavaInterop is converted to C++ FILE *gref_log; @@ -110,7 +114,8 @@ OSBridge::get_gc_bridge_index (MonoClass *klass) f++; continue; } - if (klass == k || monoFunctions.class_is_subclass_of (klass, k, 0)) + + if (klass == k || mono_class_is_subclass_of (klass, k, 0)) return static_cast(i); } return f == NUM_GC_BRIDGE_TYPES @@ -137,7 +142,7 @@ OSBridge::get_gc_bridge_info_for_object (MonoObject *object) { if (object == nullptr) return nullptr; - return get_gc_bridge_info_for_class (monoFunctions.object_get_class (object)); + return get_gc_bridge_info_for_class (mono_object_get_class (object)); } jobject @@ -415,7 +420,7 @@ OSBridge::take_global_ref_2_1_compat (JNIEnv *env, MonoObject *obj) if (bridge_info == nullptr) return 0; - monoFunctions.field_get_value (obj, bridge_info->weak_handle, &weak); + mono_field_get_value (obj, bridge_info->weak_handle, &weak); handle = env->CallObjectMethod (weak, weakrefGet); if (gref_log) { fprintf (gref_log, "*try_take_global_2_1 obj=%p -> wref=%p handle=%p\n", obj, weak, handle); @@ -431,10 +436,10 @@ OSBridge::take_global_ref_2_1_compat (JNIEnv *env, MonoObject *obj) _monodroid_weak_gref_delete (weak, get_object_ref_type (env, weak), "finalizer", gettid(), __PRETTY_FUNCTION__, 0); env->DeleteGlobalRef (weak); weak = nullptr; - monoFunctions.field_set_value (obj, bridge_info->weak_handle, &weak); + mono_field_set_value (obj, bridge_info->weak_handle, &weak); - monoFunctions.field_set_value (obj, bridge_info->handle, &handle); - monoFunctions.field_set_value (obj, bridge_info->handle_type, &type); + mono_field_set_value (obj, bridge_info->handle, &handle); + mono_field_set_value (obj, bridge_info->handle_type, &type); return handle != nullptr; } @@ -448,7 +453,7 @@ OSBridge::take_weak_global_ref_2_1_compat (JNIEnv *env, MonoObject *obj) if (bridge_info == nullptr) return 0; - monoFunctions.field_get_value (obj, bridge_info->handle, &handle); + mono_field_get_value (obj, bridge_info->handle, &handle); weaklocal = env->NewObject (weakrefClass, weakrefCtor, handle); weakglobal = env->NewGlobalRef (weaklocal); env->DeleteLocalRef (weaklocal); @@ -462,7 +467,7 @@ OSBridge::take_weak_global_ref_2_1_compat (JNIEnv *env, MonoObject *obj) _monodroid_gref_log_delete (handle, get_object_ref_type (env, handle), "finalizer", gettid (), __PRETTY_FUNCTION__, 0); env->DeleteGlobalRef (handle); - monoFunctions.field_set_value (obj, bridge_info->weak_handle, &weakglobal); + mono_field_set_value (obj, bridge_info->weak_handle, &weakglobal); return 1; } @@ -476,7 +481,7 @@ OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj) if (bridge_info == nullptr) return 0; - monoFunctions.field_get_value (obj, bridge_info->handle, &weak); + mono_field_get_value (obj, bridge_info->handle, &weak); handle = env->NewGlobalRef (weak); if (gref_log) { fprintf (gref_log, "*try_take_global obj=%p -> wref=%p handle=%p\n", obj, weak, handle); @@ -494,10 +499,10 @@ OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj) if (!handle) { void *old_handle = nullptr; - monoFunctions.field_get_value (obj, bridge_info->handle, &old_handle); + mono_field_get_value (obj, bridge_info->handle, &old_handle); } - monoFunctions.field_set_value (obj, bridge_info->handle, &handle); - monoFunctions.field_set_value (obj, bridge_info->handle_type, &type); + mono_field_set_value (obj, bridge_info->handle, &handle); + mono_field_set_value (obj, bridge_info->handle_type, &type); return handle != nullptr; } @@ -511,7 +516,7 @@ OSBridge::take_weak_global_ref_jni (JNIEnv *env, MonoObject *obj) if (bridge_info == nullptr) return 0; - monoFunctions.field_get_value (obj, bridge_info->handle, &handle); + mono_field_get_value (obj, bridge_info->handle, &handle); if (gref_log) { fprintf (gref_log, "*take_weak obj=%p; handle=%p\n", obj, handle); fflush (gref_log); @@ -525,8 +530,8 @@ OSBridge::take_weak_global_ref_jni (JNIEnv *env, MonoObject *obj) _monodroid_gref_log_delete (handle, get_object_ref_type (env, handle), "finalizer", gettid (), "take_weak_global_ref_jni", 0); env->DeleteGlobalRef (handle); - monoFunctions.field_set_value (obj, bridge_info->handle, &weak); - monoFunctions.field_set_value (obj, bridge_info->handle_type, &type); + mono_field_set_value (obj, bridge_info->handle, &weak); + mono_field_set_value (obj, bridge_info->handle_type, &type); return 1; } @@ -540,8 +545,8 @@ OSBridge::gc_bridge_class_kind (MonoClass *klass) i = get_gc_bridge_index (klass); if (i == static_cast (-NUM_GC_BRIDGE_TYPES)) { log_info (LOG_GC, "asked if a class %s.%s is a bridge before we inited java.lang.Object", - monoFunctions.class_get_namespace (klass), - monoFunctions.class_get_name (klass)); + mono_class_get_namespace (klass), + mono_class_get_name (klass)); return MonoGCBridgeObjectKind::GC_BRIDGE_TRANSPARENT_CLASS; } @@ -561,13 +566,13 @@ OSBridge::gc_is_bridge_object (MonoObject *object) if (bridge_info == nullptr) return 0; - monoFunctions.field_get_value (object, bridge_info->handle, &handle); + mono_field_get_value (object, bridge_info->handle, &handle); if (handle == nullptr) { #if DEBUG - MonoClass *mclass = monoFunctions.object_get_class (object); + MonoClass *mclass = mono_object_get_class (object); log_info (LOG_GC, "object of class %s.%s with null handle", - monoFunctions.class_get_namespace (mclass), - monoFunctions.class_get_name (mclass)); + mono_class_get_namespace (mclass), + mono_class_get_name (mclass)); #endif return 0; } @@ -604,7 +609,7 @@ OSBridge::load_reference_target (OSBridge::AddReferenceTarget target, OSBridge:: *bridge_info = get_gc_bridge_info_for_object (target.obj); if (!*bridge_info) return FALSE; - monoFunctions.field_get_value (target.obj, (*bridge_info)->handle, handle); + mono_field_get_value (target.obj, (*bridge_info)->handle, handle); } else { *handle = target.jobj; } @@ -617,10 +622,10 @@ char* OSBridge::describe_target (OSBridge::AddReferenceTarget target) { if (target.is_mono_object) { - MonoClass *klass = monoFunctions.object_get_class (target.obj); + MonoClass *klass = mono_object_get_class (target.obj); return utils.monodroid_strdup_printf ("object of class %s.%s", - monoFunctions.class_get_namespace (klass), - monoFunctions.class_get_name (klass)); + mono_class_get_namespace (klass), + mono_class_get_name (klass)); } else return utils.monodroid_strdup_printf ("", target.jobj); @@ -646,7 +651,7 @@ OSBridge::add_reference (JNIEnv *env, OSBridge::AddReferenceTarget target, OSBri // Java temporaries do not need this because the entire GCUserPeer is discarded. if (success && target.is_mono_object) { int ref_val = 1; - monoFunctions.field_set_value (target.obj, bridge_info->refs_added, &ref_val); + mono_field_set_value (target.obj, bridge_info->refs_added, &ref_val); } #if DEBUG @@ -856,13 +861,13 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri bridge_info = get_gc_bridge_info_for_object (obj); if (bridge_info == nullptr) continue; - monoFunctions.field_get_value (obj, bridge_info->handle, &jref); + mono_field_get_value (obj, bridge_info->handle, &jref); if (jref) { alive++; if (j > 0) assert (sccs [i]->is_alive); sccs [i]->is_alive = 1; - monoFunctions.field_get_value (obj, bridge_info->refs_added, &refs_added); + mono_field_get_value (obj, bridge_info->refs_added, &refs_added); if (refs_added) { java_class = env->GetObjectClass (jref); clear_method_id = env->GetMethodID (java_class, "monodroidClearReferences", "()V"); @@ -872,10 +877,10 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri env->ExceptionClear (); #if DEBUG if (gc_spew_enabled) { - klass = monoFunctions.object_get_class (obj); + klass = mono_object_get_class (obj); log_error (LOG_GC, "Missing monodroidClearReferences method for object of class %s.%s", - monoFunctions.class_get_namespace (klass), - monoFunctions.class_get_name (klass)); + mono_class_get_namespace (klass), + mono_class_get_name (klass)); } #endif } @@ -903,7 +908,7 @@ OSBridge::set_bridge_processing_field (MonodroidBridgeProcessingInfo *list, mono for ( ; list != nullptr; list = list->next) { MonoClassField *bridge_processing_field = list->bridge_processing_field; MonoVTable *jnienv_vtable = list->jnienv_vtable; - monoFunctions.field_static_set_value (jnienv_vtable, bridge_processing_field, &value); + mono_field_static_set_value (jnienv_vtable, bridge_processing_field, &value); } } @@ -924,11 +929,11 @@ OSBridge::gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xre log_info (LOG_GC, "group %d with %d objects", i, sccs [i]->num_objs); for (j = 0; j < sccs [i]->num_objs; ++j) { MonoObject *obj = sccs [i]->objs [j]; - MonoClass *klass = monoFunctions.object_get_class (obj); + MonoClass *klass = mono_object_get_class (obj); log_info (LOG_GC, "\tobj %p [%s::%s]", obj, - monoFunctions.class_get_namespace (klass), - monoFunctions.class_get_name (klass)); + mono_class_get_namespace (klass), + mono_class_get_name (klass)); } } @@ -1033,7 +1038,7 @@ OSBridge::register_gc_hooks (void) bridge_cbs.bridge_class_kind = gc_bridge_class_kind_cb; bridge_cbs.is_bridge_object = gc_is_bridge_object_cb; bridge_cbs.cross_references = gc_cross_references_cb; - monoFunctions.gc_register_bridge_callbacks (&bridge_cbs); + mono_gc_register_bridge_callbacks (&bridge_cbs); } JNIEnv* @@ -1042,7 +1047,7 @@ OSBridge::ensure_jnienv (void) JNIEnv *env; jvm->GetEnv ((void**)&env, JNI_VERSION_1_6); if (env == nullptr) { - monoFunctions.thread_attach (monoFunctions.domain_get ()); + mono_thread_attach (mono_domain_get ()); jvm->GetEnv ((void**)&env, JNI_VERSION_1_6); } return env; @@ -1088,8 +1093,8 @@ OSBridge::add_monodroid_domain (MonoDomain *domain) */ MonoClass *jnienv = utils.monodroid_get_class_from_name (domain, "Mono.Android", "Android.Runtime", "JNIEnv");; node->domain = domain; - node->bridge_processing_field = monoFunctions.class_get_field_from_name (jnienv, const_cast ("BridgeProcessing")); - node->jnienv_vtable = monoFunctions.class_vtable (domain, jnienv); + node->bridge_processing_field = mono_class_get_field_from_name (jnienv, const_cast ("BridgeProcessing")); + node->jnienv_vtable = mono_class_vtable (domain, jnienv); node->next = domains_list; domains_list = node; diff --git a/src/monodroid/jni/osbridge.h b/src/monodroid/jni/osbridge.hh similarity index 99% rename from src/monodroid/jni/osbridge.h rename to src/monodroid/jni/osbridge.hh index ef82970a72f..53ff4223385 100644 --- a/src/monodroid/jni/osbridge.h +++ b/src/monodroid/jni/osbridge.hh @@ -3,7 +3,7 @@ #define __OS_BRIDGE_H #include -#include "dylib-mono.h" +#include namespace xamarin { namespace android { namespace internal { diff --git a/src/monodroid/jni/shared-constants.cc b/src/monodroid/jni/shared-constants.cc new file mode 100644 index 00000000000..050b59a48fe --- /dev/null +++ b/src/monodroid/jni/shared-constants.cc @@ -0,0 +1,3 @@ +#include "shared-constants.hh" + +using namespace xamarin::android::internal; diff --git a/src/monodroid/jni/shared-constants.hh b/src/monodroid/jni/shared-constants.hh new file mode 100644 index 00000000000..9dc32877166 --- /dev/null +++ b/src/monodroid/jni/shared-constants.hh @@ -0,0 +1,33 @@ +#ifndef __SHARED_CONSTANTS_HH +#define __SHARED_CONSTANTS_HH + +namespace xamarin::android::internal +{ +// _WIN32 is defined with _WIN64 so _WIN64 must be checked first. +#if __SIZEOF_POINTER__ == 8 || defined (_WIN64) +#define __BITNESS__ "64bit" +#elif __SIZEOF_POINTER__ == 4 || defined (_WIN32) +#define __BITNESS__ "32bit" +#else +#error Unknown pointer size for this platform +#endif + + class SharedConstants + { + public: +#if ANDROID || LINUX + static constexpr char MONO_SGEN_SO[] = "libmonosgen-2.0.so"; + static constexpr char MONO_SGEN_ARCH_SO[] = "libmonosgen-" __BITNESS__ "-2.0.so"; +#elif APPLE_OS_X + static constexpr char MONO_SGEN_SO[] = "libmonosgen-2.0.dylib"; + static constexpr char MONO_SGEN_ARCH_SO[] = "libmonosgen-" __BITNESS__ "-2.0.dylib"; +#elif WINDOWS + static constexpr char MONO_SGEN_SO[] = "libmonosgen-2.0.dll"; + static constexpr char MONO_SGEN_ARCH_SO[] = "libmonosgen-" __BITNESS__ "-2.0.dll"; +#else + static constexpr char MONO_SGEN_SO[] = "monosgen-2.0"; + static constexpr char MONO_SGEN_ARCH_SO[] = "monosgen-" __BITNESS__ "-2.0"; +#endif + }; +} +#endif // __SHARED_CONSTANTS_HH diff --git a/src/monodroid/jni/timezones.cc b/src/monodroid/jni/timezones.cc index 5fecb717341..9dddad0855b 100644 --- a/src/monodroid/jni/timezones.cc +++ b/src/monodroid/jni/timezones.cc @@ -2,16 +2,21 @@ #include #include +#include +#include +#include +#include +#include + #include "java-interop-util.h" #include "mono_android_Runtime.h" #include "monodroid.h" -#include "dylib-mono.h" -#include "debug.h" -#include "embedded-assemblies.h" -#include "util.h" +#include "debug.hh" +#include "embedded-assemblies.hh" +#include "util.hh" #include "monodroid-glue.h" -#include "globals.h" +#include "globals.hh" using namespace xamarin::android; using namespace xamarin::android::internal; @@ -19,7 +24,7 @@ using namespace xamarin::android::internal; static MonoMethod *AndroidEnvironment_NotifyTimeZoneChanged; static void -init (DylibMono *mono) +init () { MonoAssembly *Mono_Android_dll; MonoImage *Mono_Android_image; @@ -28,10 +33,10 @@ init (DylibMono *mono) if (AndroidEnvironment_NotifyTimeZoneChanged) return; - Mono_Android_dll = utils.monodroid_load_assembly (mono->domain_get (), "Mono.Android"); - Mono_Android_image = mono->assembly_get_image (Mono_Android_dll); - AndroidEnvironment = mono->class_from_name (Mono_Android_image, "Android.Runtime", "AndroidEnvironment"); - AndroidEnvironment_NotifyTimeZoneChanged = mono->class_get_method_from_name (AndroidEnvironment, "NotifyTimeZoneChanged", 0); + Mono_Android_dll = utils.monodroid_load_assembly (mono_domain_get (), "Mono.Android"); + Mono_Android_image = mono_assembly_get_image (Mono_Android_dll); + AndroidEnvironment = mono_class_from_name (Mono_Android_image, "Android.Runtime", "AndroidEnvironment"); + AndroidEnvironment_NotifyTimeZoneChanged = mono_class_get_method_from_name (AndroidEnvironment, "NotifyTimeZoneChanged", 0); if (AndroidEnvironment_NotifyTimeZoneChanged == nullptr) { log_fatal (LOG_DEFAULT, "Unable to find Android.Runtime.AndroidEnvironment.NotifyTimeZoneChanged()!"); @@ -42,9 +47,7 @@ init (DylibMono *mono) static void clear_time_zone_caches_within_domain (void *user_data) { - DylibMono *mono = reinterpret_cast (user_data); - - mono->runtime_invoke ( + mono_runtime_invoke ( AndroidEnvironment_NotifyTimeZoneChanged, /* method */ nullptr, /* obj */ nullptr, /* args */ @@ -55,16 +58,12 @@ clear_time_zone_caches_within_domain (void *user_data) static void clear_time_zone_caches (MonoDomain *domain, void *user_data) { - DylibMono *mono = reinterpret_cast (user_data); - - mono->thread_create (domain, reinterpret_cast (clear_time_zone_caches_within_domain), mono); + mono_thread_create (domain, reinterpret_cast (clear_time_zone_caches_within_domain), user_data); } extern "C" JNIEXPORT void JNICALL Java_mono_android_Runtime_notifyTimeZoneChanged (JNIEnv *env, jclass klass) { - DylibMono *mono = &monoFunctions; - - init (mono); - mono->domain_foreach (clear_time_zone_caches, mono); + init (); + mono_domain_foreach (clear_time_zone_caches, nullptr); } diff --git a/src/monodroid/jni/util.cc b/src/monodroid/jni/util.cc index a297c520a1e..fe597e9a184 100644 --- a/src/monodroid/jni/util.cc +++ b/src/monodroid/jni/util.cc @@ -20,11 +20,14 @@ #include #endif +#include +#include + #include "java-interop-util.h" #include "monodroid.h" -#include "util.h" -#include "globals.h" +#include "util.hh" +#include "globals.hh" #include "monodroid-glue.h" using namespace xamarin::android; @@ -82,154 +85,6 @@ timing_diff::timing_diff (const timing_period &period) ns = static_cast(nsec % ms_in_nsec); } -int -Util::ends_with (const char *str, const char *end) -{ - char *p; - - p = const_cast (strstr (str, end)); - - return p != nullptr && p [strlen (end)] == 0; -} - -char* -Util::path_combine (const char *path1, const char *path2) -{ - // Don't let erroneous nullptr parameters situation propagate - assert (path1 != nullptr || path2 != nullptr); - - if (path1 == nullptr) - return strdup_new (path2); - if (path2 == nullptr) - return strdup_new (path1); - - size_t len = add_with_overflow_check (__FILE__, __LINE__, strlen (path1), strlen (path2) + 2); - char *ret = new char [len]; - *ret = '\0'; - - strcat (ret, path1); - strcat (ret, MONODROID_PATH_SEPARATOR); - strcat (ret, path2); - - return ret; -} - -void -Util::add_to_vector (char ***vector, size_t size, char *token) -{ - if (*vector == nullptr) { - *vector = (char **)static_cast(xmalloc (size * sizeof(*vector))); - } else { - size_t alloc_size = multiply_with_overflow_check (__FILE__, __LINE__, sizeof(*vector), size + 1); - *vector = static_cast(xrealloc (*vector, alloc_size)); - } - - (*vector)[size - 1] = token; -} - -void -Util::monodroid_strfreev (char **str_array) -{ - char **orig = str_array; - if (str_array == nullptr) - return; - while (*str_array != nullptr){ - free (*str_array); - str_array++; - } - free (orig); -} - -char ** -Util::monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) -{ - const char *c; - char *token, **vector; - size_t size = 1; - - if (strncmp (str, delimiter, strlen (delimiter)) == 0) { - vector = (char **)xmalloc (2 * sizeof(vector)); - vector[0] = strdup (""); - size++; - str += strlen (delimiter); - } else { - vector = nullptr; - } - - while (*str && !(max_tokens > 0 && size >= max_tokens)) { - c = str; - if (strncmp (str, delimiter, strlen (delimiter)) == 0) { - token = strdup (""); - str += strlen (delimiter); - } else { - while (*str && strncmp (str, delimiter, strlen (delimiter)) != 0) { - str++; - } - - if (*str) { - size_t toklen = static_cast((str - c)); - size_t alloc_size = add_with_overflow_check (__FILE__, __LINE__, toklen, 1); - token = new char [alloc_size]; - strncpy (token, c, toklen); - token [toklen] = '\0'; - - /* Need to leave a trailing empty - * token if the delimiter is the last - * part of the string - */ - if (strcmp (str, delimiter) != 0) { - str += strlen (delimiter); - } - } else { - token = strdup (c); - } - } - - add_to_vector (&vector, size, token); - size++; - } - - if (*str) { - if (strcmp (str, delimiter) == 0) - add_to_vector (&vector, size, strdup ("")); - else { - /* Add the rest of the string as the last element */ - add_to_vector (&vector, size, strdup (str)); - } - size++; - } - - if (vector == nullptr) { - vector = (char **) xmalloc (2 * sizeof (vector)); - vector [0] = nullptr; - } else if (size > 0) { - vector[size - 1] = nullptr; - } - - return vector; -} - -char * -Util::monodroid_strdup_printf (const char *format, ...) -{ - va_list args; - - va_start (args, format); - char *ret = monodroid_strdup_vprintf (format, args); - va_end (args); - - return ret; -} - -char* -Util::monodroid_strdup_vprintf (const char *format, va_list vargs) -{ - char *ret = nullptr; - int n = vasprintf (&ret, format, vargs); - - return n == -1 ? nullptr : ret; -} - int Util::send_uninterrupted (int fd, void *buf, size_t len) { @@ -269,6 +124,7 @@ Util::recv_uninterrupted (int fd, void *buf, size_t len) do { nbytes = len - total; res = recv (fd, (char *) buf + total, nbytes, flags); + if (res > 0) total += static_cast(res); } while ((res > 0 && total < len) || (res == -1 && errno == EINTR)); @@ -401,18 +257,18 @@ Util::monodroid_load_assembly (MonoDomain *domain, const char *basename) MonoAssemblyName *aname; MonoImageOpenStatus status; - aname = monoFunctions.assembly_name_new (basename); - MonoDomain *current = monoFunctions.domain_get (); + aname = mono_assembly_name_new (basename); + MonoDomain *current = mono_domain_get (); if (domain != current) { - monoFunctions.domain_set (domain, FALSE); - assm = monoFunctions.assembly_load_full (aname, nullptr, &status, 0); - monoFunctions.domain_set (current, FALSE); + mono_domain_set (domain, FALSE); + assm = mono_assembly_load_full (aname, nullptr, &status, 0); + mono_domain_set (current, FALSE); } else { - assm = monoFunctions.assembly_load_full (aname, nullptr, &status, 0); + assm = mono_assembly_load_full (aname, nullptr, &status, 0); } - monoFunctions.assembly_name_free (aname); + mono_assembly_name_free (aname); if (!assm) { log_fatal (LOG_DEFAULT, "Unable to find assembly '%s'.", basename); @@ -424,27 +280,27 @@ Util::monodroid_load_assembly (MonoDomain *domain, const char *basename) MonoObject * Util::monodroid_runtime_invoke (MonoDomain *domain, MonoMethod *method, void *obj, void **params, MonoObject **exc) { - MonoDomain *current = monoFunctions.domain_get (); + MonoDomain *current = mono_domain_get (); if (domain != current) { - monoFunctions.domain_set (domain, FALSE); - MonoObject *r = monoFunctions.runtime_invoke (method, obj, params, exc); - monoFunctions.domain_set (current, FALSE); + mono_domain_set (domain, FALSE); + MonoObject *r = mono_runtime_invoke (method, obj, params, exc); + mono_domain_set (current, FALSE); return r; } else { - return monoFunctions.runtime_invoke (method, obj, params, exc); + return mono_runtime_invoke (method, obj, params, exc); } } void Util::monodroid_property_set (MonoDomain *domain, MonoProperty *property, void *obj, void **params, MonoObject **exc) { - MonoDomain *current = monoFunctions.domain_get (); + MonoDomain *current = mono_domain_get (); if (domain != current) { - monoFunctions.domain_set (domain, FALSE); - monoFunctions.property_set_value (property, obj, params, exc); - monoFunctions.domain_set (current, FALSE); + mono_domain_set (domain, FALSE); + mono_property_set_value (property, obj, params, exc); + mono_domain_set (current, FALSE); } else { - monoFunctions.property_set_value (property, obj, params, exc); + mono_property_set_value (property, obj, params, exc); } } @@ -453,92 +309,25 @@ Util::monodroid_create_appdomain (MonoDomain *parent_domain, const char *friendl { MonoClass *appdomain_setup_klass = monodroid_get_class_from_name (parent_domain, "mscorlib", "System", "AppDomainSetup"); MonoClass *appdomain_klass = monodroid_get_class_from_name (parent_domain, "mscorlib", "System", "AppDomain"); - MonoMethod *create_domain = monoFunctions.class_get_method_from_name (appdomain_klass, "CreateDomain", 3); - MonoProperty *shadow_copy_prop = monoFunctions.class_get_property_from_name (appdomain_setup_klass, "ShadowCopyFiles"); - MonoProperty *shadow_copy_dirs_prop = monoFunctions.class_get_property_from_name (appdomain_setup_klass, "ShadowCopyDirectories"); + MonoMethod *create_domain = mono_class_get_method_from_name (appdomain_klass, "CreateDomain", 3); + MonoProperty *shadow_copy_prop = mono_class_get_property_from_name (appdomain_setup_klass, "ShadowCopyFiles"); + MonoProperty *shadow_copy_dirs_prop = mono_class_get_property_from_name (appdomain_setup_klass, "ShadowCopyDirectories"); - MonoObject *setup = monoFunctions.object_new (parent_domain, appdomain_setup_klass); - MonoString *mono_friendly_name = monoFunctions.string_new (parent_domain, friendly_name); - MonoString *mono_shadow_copy = monoFunctions.string_new (parent_domain, shadow_copy ? "true" : "false"); - MonoString *mono_shadow_copy_dirs = shadow_directories == nullptr ? nullptr : monoFunctions.string_new (parent_domain, shadow_directories); + MonoObject *setup = mono_object_new (parent_domain, appdomain_setup_klass); + MonoString *mono_friendly_name = mono_string_new (parent_domain, friendly_name); + MonoString *mono_shadow_copy = mono_string_new (parent_domain, shadow_copy ? "true" : "false"); + MonoString *mono_shadow_copy_dirs = shadow_directories == nullptr ? nullptr : mono_string_new (parent_domain, shadow_directories); monodroid_property_set (parent_domain, shadow_copy_prop, setup, reinterpret_cast (&mono_shadow_copy), nullptr); if (mono_shadow_copy_dirs != nullptr) monodroid_property_set (parent_domain, shadow_copy_dirs_prop, setup, reinterpret_cast (&mono_shadow_copy_dirs), nullptr); void *args[3] = { mono_friendly_name, nullptr, setup }; - MonoObject *appdomain = monodroid_runtime_invoke (parent_domain, create_domain, nullptr, args, nullptr); + auto appdomain = reinterpret_cast(monodroid_runtime_invoke (parent_domain, create_domain, nullptr, args, nullptr)); if (appdomain == nullptr) return nullptr; - return monoFunctions.domain_from_appdomain (appdomain); -} - -int -Util::create_directory (const char *pathname, mode_t mode) -{ - if (mode <= 0) - mode = DEFAULT_DIRECTORY_MODE; - - if (!pathname || *pathname == '\0') { - errno = EINVAL; - return -1; - } -#ifdef WINDOWS - int oldumask; -#else - mode_t oldumask; -#endif - oldumask = umask (022); - char *path = strdup (pathname); - int rv, ret = 0; - for (char *d = path; *d; ++d) { - if (*d != '/') - continue; - *d = 0; - if (*path) { - rv = make_directory (path, mode); - if (rv == -1 && errno != EEXIST) { - ret = -1; - break; - } - } - *d = '/'; - } - free (path); - if (ret == 0) - ret = make_directory (pathname, mode); - umask (oldumask); - - return ret; -} - -void -Util::set_world_accessable (const char *path) -{ -#ifdef ANDROID - int r; - do - r = chmod (path, 0664); - while (r == -1 && errno == EINTR); - - if (r == -1) - log_error (LOG_DEFAULT, "chmod(\"%s\", 0664) failed: %s", path, strerror (errno)); -#endif -} - -void -Util::set_user_executable (const char *path) -{ -#ifdef ANDROID - int r; - do { - r = chmod (path, S_IRUSR | S_IWUSR | S_IXUSR); - } while (r == -1 && errno == EINTR); - - if (r == -1) - log_error (LOG_DEFAULT, "chmod(\"%s\") failed: %s", path, strerror (errno)); -#endif + return mono_domain_from_appdomain (appdomain); } MonoClass* @@ -547,22 +336,22 @@ Util::monodroid_get_class_from_name (MonoDomain *domain, const char* assembly, c MonoAssembly *assm = nullptr; MonoImage *image = nullptr; MonoClass *result = nullptr; - MonoAssemblyName *aname = monoFunctions.assembly_name_new (assembly); - MonoDomain *current = monoFunctions.domain_get (); + MonoAssemblyName *aname = mono_assembly_name_new (assembly); + MonoDomain *current = mono_domain_get (); if (domain != current) - monoFunctions.domain_set (domain, FALSE); + mono_domain_set (domain, FALSE); - assm = monoFunctions.assembly_loaded (aname); + assm = mono_assembly_loaded (aname); if (assm != nullptr) { - image = monoFunctions.assembly_get_image (assm); - result = monoFunctions.class_from_name (image, _namespace, type); + image = mono_assembly_get_image (assm); + result = mono_class_from_name (image, _namespace, type); } if (domain != current) - monoFunctions.domain_set (current, FALSE); + mono_domain_set (current, FALSE); - monoFunctions.assembly_name_free (aname); + mono_assembly_name_free (aname); return result; } @@ -571,164 +360,17 @@ MonoClass* Util::monodroid_get_class_from_image (MonoDomain *domain, MonoImage *image, const char *_namespace, const char *type) { MonoClass *result = nullptr; - MonoDomain *current = monoFunctions.domain_get (); + MonoDomain *current = mono_domain_get (); if (domain != current) - monoFunctions.domain_set (domain, FALSE); + mono_domain_set (domain, FALSE); - result = monoFunctions.class_from_name (image, _namespace, type); + result = mono_class_from_name (image, _namespace, type); if (domain != current) - monoFunctions.domain_set (current, FALSE); - - return result; -} - -void -Util::create_public_directory (const char *dir) -{ -#ifndef WINDOWS - mode_t m = umask (0); - mkdir (dir, 0777); - umask (m); -#else - wchar_t *buffer = utf8_to_utf16 (dir); - _wmkdir (buffer); - free (buffer); -#endif -} - -FILE * -Util::monodroid_fopen (const char *filename, const char *mode) -{ -#ifndef WINDOWS - /* On Unix, both path and system calls are all assumed - * to be UTF-8 compliant. - */ - return fopen (filename, mode); -#else - // Convert the path and mode to a UTF-16 and then use the wide variant of fopen - wchar_t *wpath = utf8_to_utf16 (filename); - wchar_t *wmode = utf8_to_utf16 (mode); - - FILE* file = _wfopen (wpath, wmode); - free (wpath); - free (wmode); - - return file; -#endif // ndef WINDOWS -} - -int -Util::monodroid_stat (const char *path, monodroid_stat_t *s) -{ - int result; - -#ifndef WINDOWS - result = stat (path, s); -#else - wchar_t *wpath = utf8_to_utf16 (path); - result = _wstat (wpath, s); - free (wpath); -#endif - - return result; -} - -monodroid_dir_t* -Util::monodroid_opendir (const char *filename) -{ -#ifndef WINDOWS - return opendir (filename); -#else - wchar_t *wfilename = utf8_to_utf16 (filename); - monodroid_dir_t *result = _wopendir (wfilename); - free (wfilename); - return result; -#endif -} - -int -Util::monodroid_closedir (monodroid_dir_t *dirp) -{ -#ifndef WINDOWS - return closedir (dirp); -#else - return _wclosedir (dirp); -#endif - -} + mono_domain_set (current, FALSE); -int -Util::monodroid_dirent_hasextension (monodroid_dirent_t *e, const char *extension) -{ -#ifndef WINDOWS - return ends_with (e->d_name, extension); -#else - char *mb_dname = utf16_to_utf8 (e->d_name); - int result = ends_with (mb_dname, extension); - free (mb_dname); return result; -#endif -} - -bool -Util::file_exists (const char *file) -{ - monodroid_stat_t s; - if (monodroid_stat (file, &s) == 0 && (s.st_mode & S_IFMT) == S_IFREG) - return true; - return false; -} - -bool -Util::directory_exists (const char *directory) -{ - monodroid_stat_t s; - if (monodroid_stat (directory, &s) == 0 && (s.st_mode & S_IFMT) == S_IFDIR) - return true; - return false; -} - -bool -Util::file_copy (const char *to, const char *from) -{ - char buffer[BUFSIZ]; - size_t n; - int saved_errno; - - FILE *f1 = utils.monodroid_fopen (from, "r"); - FILE *f2 = utils.monodroid_fopen (to, "w+"); - - while ((n = fread (buffer, sizeof(char), sizeof(buffer), f1)) > 0) { - if (fwrite (buffer, sizeof(char), n, f2) != n) { - saved_errno = errno; - fclose (f1); - fclose (f2); - errno = saved_errno; - - return false; - } - } - - fclose (f1); - fclose (f2); - return true; -} - -bool -Util::is_path_rooted (const char *path) -{ - if (path == nullptr) - return false; -#ifdef WINDOWS - LPCWSTR wpath = utf8_to_utf16 (path); - bool ret = !PathIsRelativeW (wpath); - free (const_cast (reinterpret_cast (wpath))); - return ret; -#else - return path [0] == MONODROID_PATH_SEPARATOR_CHAR; -#endif } jclass diff --git a/src/monodroid/jni/util.hh b/src/monodroid/jni/util.hh new file mode 100644 index 00000000000..5c6b4dbe85c --- /dev/null +++ b/src/monodroid/jni/util.hh @@ -0,0 +1,144 @@ +// This is a -*- C++ -*- header +#ifndef __MONODROID_UTIL_H__ +#define __MONODROID_UTIL_H__ + +#ifndef TRUE +#ifdef __cplusplus +constexpr int TRUE = 1; +#else +#define TRUE 1 +#endif // __cplusplus +#endif + +#ifndef FALSE +#ifdef __cplusplus +constexpr int FALSE = 0; +#else +#define FALSE 0 +#endif // __cplusplus +#endif + +#include +#include +#ifdef HAVE_BSD_STRING_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "monodroid.h" +#include "jni-wrappers.hh" +#ifdef __cplusplus +#include "basic-utilities.hh" +#endif + +#include "java-interop-util.h" +#include "logger.hh" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + MONO_API void monodroid_strfreev (char **str_array); + MONO_API char **monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens); + MONO_API char *monodroid_strdup_printf (const char *format, ...); + MONO_API void monodroid_store_package_name (const char *name); + MONO_API int monodroid_get_namespaced_system_property (const char *name, char **value); + MONO_API FILE *monodroid_fopen (const char* filename, const char* mode); + + MONO_API int send_uninterrupted (int fd, void *buf, int len); + MONO_API int recv_uninterrupted (int fd, void *buf, int len); + MONO_API void set_world_accessable (const char *path); + MONO_API void create_public_directory (const char *dir); + MONO_API char *path_combine (const char *path1, const char *path2); +#ifdef __cplusplus +} + +namespace xamarin { namespace android +{ + struct timing_point + { + time_t sec; + uint64_t ns; + + void mark (); + }; + + struct timing_period + { + timing_point start; + timing_point end; + + void mark_start () + { + start.mark (); + } + + void mark_end () + { + end.mark (); + } + }; + + struct timing_diff + { + static constexpr uint32_t ms_in_nsec = 1000000ULL; + + time_t sec; + uint32_t ms; + uint32_t ns; + + timing_diff (const timing_period &period); + }; + + class Util : public BasicUtilities + { +#if defined (ANDROID) || defined (LINUX) + using timestruct = timespec; +#else + using timestruct = timeval; +#endif + static constexpr uint32_t ms_in_nsec = 1000000ULL; + + public: + void monodroid_store_package_name (const char *name); + size_t monodroid_get_namespaced_system_property (const char *name, char **value); + MonoAssembly *monodroid_load_assembly (MonoDomain *domain, const char *basename); + MonoObject *monodroid_runtime_invoke (MonoDomain *domain, MonoMethod *method, void *obj, void **params, MonoObject **exc); + MonoClass *monodroid_get_class_from_name (MonoDomain *domain, const char* assembly, const char *_namespace, const char *type); + MonoDomain *monodroid_create_appdomain (MonoDomain *parent_domain, const char *friendly_name, int shadow_copy, const char *shadow_directories); + MonoClass *monodroid_get_class_from_image (MonoDomain *domain, MonoImage* image, const char *_namespace, const char *type); + int send_uninterrupted (int fd, void *buf, size_t len); + ssize_t recv_uninterrupted (int fd, void *buf, size_t len); + jclass get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *name, bool make_gref = false); + + bool should_log (LogCategories category) const + { + return (log_categories & category) != 0; + } + + private: + //char *monodroid_strdup_printf (const char *format, va_list vargs); + void monodroid_property_set (MonoDomain *domain, MonoProperty *property, void *obj, void **params, MonoObject **exc); + +#if WINDOWS + void package_hash_to_hex (uint32_t hash); +#else + template + void package_hash_to_hex (IdxType idx); + + template + void package_hash_to_hex (uint32_t hash, IdxType idx, Indices... indices); +#endif + private: + char package_property_suffix[9]; + }; +} } +#endif // __cplusplus +#endif /* __MONODROID_UTIL_H__ */ diff --git a/src/monodroid/jni/xamarin_getifaddrs.cc b/src/monodroid/jni/xamarin_getifaddrs.cc index 84a7c898b95..10aff62e5bd 100644 --- a/src/monodroid/jni/xamarin_getifaddrs.cc +++ b/src/monodroid/jni/xamarin_getifaddrs.cc @@ -31,9 +31,9 @@ #include #endif -#include "logger.h" +#include "logger.hh" -#include "globals.h" +#include "globals.hh" #include "xamarin_getifaddrs.h" /* Some of these aren't defined in android's rtnetlink.h (as of ndk 16). We define values for all of diff --git a/src/monodroid/monodroid.props b/src/monodroid/monodroid.props index f4915965bd6..434b65c07ea 100644 --- a/src/monodroid/monodroid.props +++ b/src/monodroid/monodroid.props @@ -8,7 +8,7 @@ - <_CommonDefines>-DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DJDK_INCLUDE="@(JdkIncludePath->'%(Identity)', ' ')" -DMONO_PATH=$(MonoSourceFullPath) -DSGEN_BRIDGE_VERSION=$(MonoSgenBridgeVersion) + <_CommonDefines>-DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DJDK_INCLUDE="@(JdkIncludePath->'%(Identity)', ' ')" -DMONO_PATH=$(MonoSourceFullPath) <_CmakeCommonHostFlags>$(_CmakeCommonFlags) $(_CommonDefines) -DENABLE_NDK=OFF <_CmakeMxeCommonFlags>$(_CmakeCommonFlags) $(_CommonDefines) -DENABLE_NDK=OFF diff --git a/tests/EmbeddedDSOs/EmbeddedDSO-UnitTests/run.sh b/tests/EmbeddedDSOs/EmbeddedDSO-UnitTests/run.sh index 723b3cc40d9..89cf409dd66 100755 --- a/tests/EmbeddedDSOs/EmbeddedDSO-UnitTests/run.sh +++ b/tests/EmbeddedDSOs/EmbeddedDSO-UnitTests/run.sh @@ -5,4 +5,4 @@ export MSBUILD=msbuild CONFIGURATION=${1:-Debug} msbuild /p:Configuration=${CONFIGURATION} EmbeddedDSO-UnitTests.csproj cd ../../../ -exec mono --debug packages/NUnit.ConsoleRunner.3.9.0/tools/nunit3-console.exe bin/Test${CONFIGURATION}/EmbeddedDSO/EmbeddedDSOUnitTests.dll +exec mono --debug packages/NUnit.ConsoleRunner.3.9.0/tools/nunit3-console.exe bin/Test${CONFIGURATION}/EmbeddedDSOUnitTests.dll