diff --git a/dotnet/targets/Xamarin.Shared.Sdk.props b/dotnet/targets/Xamarin.Shared.Sdk.props
index 38d185fb27fd..3d078f69feec 100644
--- a/dotnet/targets/Xamarin.Shared.Sdk.props
+++ b/dotnet/targets/Xamarin.Shared.Sdk.props
@@ -213,6 +213,23 @@
true
+
+
+ true
+ true
+ macho
+ true
+
+
+
+
+
+
+
+
+ <_BundlerEnvironmentVariables Include="DOTNET_ReadyToRun" Value="0" />
+
+
<_SdkIsSimulator Condition="'$(RuntimeIdentifier)' != '' And '$(_SdkIsSimulator)' == ''">$(RuntimeIdentifier.Contains('simulator'))
diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets
index b997fbac4bf3..890feeb0d8de 100644
--- a/dotnet/targets/Xamarin.Shared.Sdk.targets
+++ b/dotnet/targets/Xamarin.Shared.Sdk.targets
@@ -1246,13 +1246,14 @@
'%(ResolvedFileToPublish.NuGetPackageId)' == '$(_MonoNugetPackageId)'
"
/>
-
-
-
-
-
- <_BundlerEnvironmentVariables Include="DOTNET_Interpreter" Value="%2A%21%2A" />
- <_BundlerEnvironmentVariables Include="DOTNET_ReadyToRun" Value="0" />
+
+ <_MonoLibrary
+ Remove="@(_MonoLibrary)"
+ Condition=" '$(_XamarinRuntime)' == 'CoreCLR' And
+ '$(_PlatformName)' != 'macOS' And
+ '%(Filename)' == 'libclrjit'
+ "
+ />
@@ -2095,6 +2096,19 @@
+
+
+
+
+
+
+ <_Crossgen2Path Condition="'$(Crossgen2Path)' != ''">$(Crossgen2Path)
+ <_Crossgen2Path Condition="'$(Crossgen2Path)' == ''">$([MSBuild]::NormalizePath('$(MSBuildThisFileDirectory)', '..', '..', 'packs', 'Microsoft.NETCore.App.Runtime.$(_PlatformName.ToLowerInvariant())-$(RuntimeIdentifier.Split('-')[1])', '$(BundledNETCoreAppPackageVersion)', 'tools', 'crossgen2'))
+
+ <_TargetArch>$(RuntimeIdentifier.Split('-')[1])
+ <_TargetOS>$(RuntimeIdentifier.Split('-')[0])
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/runtime/.gitignore b/runtime/.gitignore
index 075909938859..cb42427f6eca 100644
--- a/runtime/.gitignore
+++ b/runtime/.gitignore
@@ -12,3 +12,4 @@ bindings-generated.m
*.dylib
*.o
coreclrhost.h
+host_runtime_contract.h
\ No newline at end of file
diff --git a/runtime/Makefile b/runtime/Makefile
index d5348366632c..ca26775c7da1 100644
--- a/runtime/Makefile
+++ b/runtime/Makefile
@@ -35,10 +35,14 @@ IOS_SIMULATOR_ARCHITECTURES+=x86_64
IOS_DEVICE_ARCHITECTURES+=arm64
coreclrhost.h: Makefile
- $(Q_CURL) curl -L --retry 3 --retry-all-errors --fail --output "$@.tmp" https://raw.githubusercontent.com/dotnet/runtime/f1b8d5a4448d072c9d390744777a87921e45bf2f/src/coreclr/hosts/inc/coreclrhost.h
+ $(Q_CURL) curl -L --retry 3 --retry-all-errors --fail --output "$@.tmp" https://raw.githubusercontent.com/dotnet/runtime/main/src/coreclr/hosts/inc/coreclrhost.h
$(Q) mv "$@.tmp" "$@"
-coreclr-bridge.m: coreclrhost.h
+host_runtime_contract.h: Makefile
+ $(Q_CURL) curl -L --retry 3 --retry-all-errors --fail --output "$@.tmp" https://raw.githubusercontent.com/dotnet/runtime/main/src/native/corehost/host_runtime_contract.h
+ $(Q) mv "$@.tmp" "$@"
+
+coreclr-bridge.m: coreclrhost.h host_runtime_contract.h
xamarin/mono-runtime.h: mono-runtime.h.t4 exports.t4
$(Q_GEN) $(TT) $< -o $@
diff --git a/runtime/coreclr-bridge.m b/runtime/coreclr-bridge.m
index 8554e64980c9..2d39b09b4564 100644
--- a/runtime/coreclr-bridge.m
+++ b/runtime/coreclr-bridge.m
@@ -339,7 +339,7 @@
{
struct TrackedObjectInfo *info = (struct TrackedObjectInfo *) ptr;
info->data->flags = (enum NSObjectFlags) (info->data->flags | NSObjectFlagsInFinalizerQueue);
- LOG_CORECLR (stderr, "%s (%p) flags: %i\n", __func__, ptr, (int) info->flags);
+ LOG_CORECLR (stderr, "%s (%p) flags: %i\n", __func__, ptr, (int) info->data->flags);
}
void
@@ -492,6 +492,7 @@
xamarin_bridge_compute_properties (propertyCount, propertyKeys, propertyValues, &combinedPropertyCount, &combinedPropertyKeys, &combinedPropertyValues);
const char *executablePath = [[[[NSBundle mainBundle] executableURL] path] UTF8String];
+
rv = coreclr_initialize (
executablePath,
xamarin_executable_name,
diff --git a/runtime/runtime.m b/runtime/runtime.m
index fc0dedb34290..b7da178c124f 100644
--- a/runtime/runtime.m
+++ b/runtime/runtime.m
@@ -11,6 +11,8 @@
#include
#include
#include
+#include
+#include
#include "product.h"
#include "shared.h"
@@ -22,6 +24,7 @@
#include "xamarin/monovm-bridge.h"
#else
#include "xamarin/coreclr-bridge.h"
+#include "host_runtime_contract.h"
#endif
#if defined (DEBUG)
@@ -2436,10 +2439,99 @@ -(struct NSObjectData*) xamarinGetNSObjectData;
return rv;
}
+#if defined (CORECLR_RUNTIME)
+size_t get_image_size(void* base_address)
+{
+ uint32_t image_count = _dyld_image_count();
+ for (uint32_t i = 0; i < image_count; ++i)
+ {
+ const struct mach_header_64* header = (const struct mach_header_64*)_dyld_get_image_header(i);
+ if ((const void*)header != base_address)
+ continue;
+
+ const struct load_command* cmd = (const struct load_command*)((const char*)header + sizeof(struct mach_header_64));
+
+ size_t image_size = 0;
+ for (uint32_t j = 0; j < header->ncmds; ++j)
+ {
+ if (cmd->cmd == LC_SEGMENT_64)
+ {
+ const struct segment_command_64* seg = (const struct segment_command_64*)cmd;
+ size_t end_addr = (size_t)(seg->vmaddr + seg->vmsize);
+ if (end_addr > image_size)
+ image_size = end_addr;
+ }
+
+ cmd = (const struct load_command*)((const char*)cmd + cmd->cmdsize);
+ }
+
+ return image_size;
+ }
+
+ return 0;
+}
+
+bool get_native_code_data(const struct host_runtime_contract_native_code_context* context, struct host_runtime_contract_native_code_data* data)
+{
+ if (!context || !data || !context->assembly_path || !context->owner_composite_name)
+ return false;
+
+ // Look for the owner composite R2R image in the same directory as the assembly
+ char r2r_path[PATH_MAX];
+ const char *last_slash = strrchr(context->assembly_path, '/');
+ size_t dir_len = last_slash ? (size_t)(last_slash - context->assembly_path) : 0;
+ if (dir_len >= sizeof(r2r_path) - 1)
+ return false;
+
+ strncpy(r2r_path, context->assembly_path, dir_len);
+ int written = snprintf(r2r_path + dir_len, sizeof(r2r_path) - dir_len, "/%s", context->owner_composite_name);
+ if (written <= 0 || (size_t)written >= sizeof(r2r_path) - dir_len)
+ return false;
+
+ void* handle = dlopen(r2r_path, RTLD_LAZY | RTLD_LOCAL);
+ if (handle == NULL) {
+ return false;
+ }
+
+ void* r2r_header = dlsym(handle, "RTR_HEADER");
+ if (r2r_header == NULL)
+ {
+ dlclose(handle);
+ return false;
+ }
+
+ Dl_info info;
+ if (dladdr(r2r_header, &info) == 0)
+ {
+ dlclose(handle);
+ return false;
+ }
+
+ data->size = sizeof(struct host_runtime_contract_native_code_data);
+ data->r2r_header_ptr = r2r_header;
+ data->image_size = get_image_size(info.dli_fbase);
+ data->image_base = info.dli_fbase;
+
+ return true;
+}
+#endif // defined (CORECLR_RUNTIME)
+
void
xamarin_vm_initialize ()
{
+#if defined (CORECLR_RUNTIME)
+ struct host_runtime_contract host_contract = {
+ .size = sizeof(struct host_runtime_contract),
+ .pinvoke_override = &xamarin_pinvoke_override,
+ .get_native_code_data = &get_native_code_data
+ };
+
+ char contract_str[19]; // 0x + 16 hex digits + '\0'
+ snprintf(contract_str, 19, "0x%zx", (size_t)(&host_contract));
+#else
char *pinvokeOverride = xamarin_strdup_printf ("%p", &xamarin_pinvoke_override);
+#endif
+
char *trusted_platform_assemblies = xamarin_compute_trusted_platform_assemblies ();
char *native_dll_search_directories = xamarin_compute_native_dll_search_directories ();
@@ -2447,18 +2539,22 @@ -(struct NSObjectData*) xamarinGetNSObjectData;
// for the _CreateRuntimeConfiguration target in dotnet/targets/Xamarin.Shared.Sdk.targets.
const char *propertyKeys[] = {
"APP_CONTEXT_BASE_DIRECTORY", // path to where the managed assemblies are (usually at least - RID-specific assemblies will be in subfolders)
- "APP_PATHS",
+#if defined (CORECLR_RUNTIME)
+ "HOST_RUNTIME_CONTRACT",
+#else
"PINVOKE_OVERRIDE",
+#endif
"TRUSTED_PLATFORM_ASSEMBLIES",
- "NATIVE_DLL_SEARCH_DIRECTORIES",
"RUNTIME_IDENTIFIER",
};
const char *propertyValues[] = {
xamarin_get_bundle_path (),
- xamarin_get_bundle_path (),
+#if defined (CORECLR_RUNTIME)
+ contract_str,
+#else
pinvokeOverride,
+#endif
trusted_platform_assemblies,
- native_dll_search_directories,
RUNTIMEIDENTIFIER,
};
static_assert (sizeof (propertyKeys) == sizeof (propertyValues), "The number of keys and values must be the same.");
@@ -2466,7 +2562,9 @@ -(struct NSObjectData*) xamarinGetNSObjectData;
int propertyCount = (int) (sizeof (propertyValues) / sizeof (propertyValues [0]));
bool rv = xamarin_bridge_vm_initialize (propertyCount, propertyKeys, propertyValues);
+#if !defined (CORECLR_RUNTIME)
xamarin_free (pinvokeOverride);
+#endif
xamarin_free (trusted_platform_assemblies);
xamarin_free (native_dll_search_directories);
@@ -2502,7 +2600,7 @@ -(struct NSObjectData*) xamarinGetNSObjectData;
return rv;
}
-void*
+const void*
xamarin_pinvoke_override (const char *libraryName, const char *entrypointName)
{
diff --git a/runtime/xamarin/runtime.h b/runtime/xamarin/runtime.h
index 54b8b878f01a..90566324d0e2 100644
--- a/runtime/xamarin/runtime.h
+++ b/runtime/xamarin/runtime.h
@@ -220,7 +220,7 @@ MonoAssembly* xamarin_assembly_preload_hook (MonoAssemblyName *aname, char **ass
void xamarin_handle_bridge_exception (GCHandle gchandle, const char *method);
void xamarin_vm_initialize ();
bool xamarin_bridge_vm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues);
-void* xamarin_pinvoke_override (const char *libraryName, const char *entrypointName);
+const void* xamarin_pinvoke_override (const char *libraryName, const char *entrypointName);
void xamarin_bridge_call_runtime_initialize (struct InitializationOptions* options, GCHandle* exception_gchandle);
void xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle);
MonoMethod * xamarin_bridge_get_mono_method (MonoReflectionMethod *method);