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