Skip to content

Commit

Permalink
[runtime/dotnet] Call coreclr_initialize/monovm_initialize at startup.
Browse files Browse the repository at this point in the history
We need to call coreclr_initialize/monovm_initialize at startup, so do that.
This is a partial implementation, in that we're not setting all the properties
that we should, and also the PINVOKE_OVERRIDE callback is not doing everything
it should either yet.

Ref: xamarin#10504.
  • Loading branch information
rolfbjarne committed Mar 18, 2021
1 parent af5651a commit 65d302a
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 13 deletions.
26 changes: 26 additions & 0 deletions runtime/coreclr-bridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
#include "xamarin/xamarin.h"
#include "xamarin/coreclr-bridge.h"

#include "coreclrhost.h"

unsigned int coreclr_domainId = 0;
void *coreclr_handle = NULL;

void
xamarin_bridge_setup ()
{
Expand All @@ -21,4 +26,25 @@
{
}

bool
xamarin_bridge_vm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues)
{
int rv;

const char *executablePath = [[[[NSBundle mainBundle] executableURL] path] UTF8String];
rv = coreclr_initialize (
executablePath,
xamarin_executable_name,
propertyCount,
propertyKeys,
propertyValues,
&coreclr_handle,
&coreclr_domainId
);

LOG_CORECLR (stderr, "xamarin_vm_initialize (%i, %p, %p): rv: %i domainId: %i handle: %p\n", propertyCount, propertyKeys, propertyValues, rv, coreclr_domainId, coreclr_handle);

return rv == 0;
}

#endif // CORECLR_RUNTIME
40 changes: 40 additions & 0 deletions runtime/exports.t4
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,17 @@

#endregion

#region mini/mono-private-unstable.

new Export ("int", "monovm_initialize",
"int", "propertyCount",
"const char **", "propertyKeys",
"const char **", "propertyValues"
) {
Mode = DotNetMode.OnlyDotNet,
},

#endregion
};
#><#+
class Arg
Expand All @@ -664,19 +675,48 @@
public string Name;
}

enum DotNetMode {
Both = 0,
OnlyDotNet = 1,
OnlyLegacy = 2,
}

class Export
{
public string ReturnType;
public string EntryPoint;
public string AlternativeExpression;
public List<Arg> Arguments;
public bool Optional;
public DotNetMode Mode;

public Export (string returnType, string entryPoint, params string [] arguments)
: this (false, returnType, entryPoint, arguments)
{
}

public string DotNetIf {
get {
switch (Mode) {
case DotNetMode.OnlyLegacy:
return "#if !DOTNET\n";
case DotNetMode.OnlyDotNet:
return "#if DOTNET\n";
}
return string.Empty;
}
}

public string DotNetEndIf {
get {
switch (Mode) {
case DotNetMode.OnlyLegacy:
case DotNetMode.OnlyDotNet:
return "#endif\n";
}
return string.Empty;
}
}

public Export (bool optional, string returnType, string entryPoint, params string [] arguments)
{
Expand Down
11 changes: 6 additions & 5 deletions runtime/mono-runtime.h.t4
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ char *xamarin_get_mono_runtime_build_info (); // returns NULL if libmono couldn'

#ifdef DYNAMIC_MONO_RUNTIME
<# foreach (var export in exports) { #>
#define <#= export.EntryPoint #> <#= export.EntryPoint #>_impl
<# } #>
<#= export.DotNetIf #>#define <#= export.EntryPoint #> <#= export.EntryPoint #>_impl
<#= export.DotNetEndIf #><# } #>
#endif

/* This is copied from mono's header files */
Expand Down Expand Up @@ -305,15 +305,16 @@ void mono_gc_init_finalizer_thread ();

<# foreach (var export in exports) { #>

MONO_API <#= export.ReturnType #>
<#= export.DotNetIf #>MONO_API <#= export.ReturnType #>
<#= export.EntryPoint #> (<#= export.ArgumentSignature #>);
<# } #>
<#= export.DotNetEndIf #><# } #>

<# foreach (var export in exports) {
if (!export.Optional)
continue; #>
bool
<#= export.DotNetIf #>bool
<#= export.EntryPoint #>_exists ();
<#= export.DotNetEndIf #>

<# } #>

Expand Down
16 changes: 8 additions & 8 deletions runtime/mono-runtime.m.t4
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
#include "runtime-internal.h"

<# foreach (var export in exports) { #>
typedef <#= export.ReturnType #> (* <#= export.EntryPoint #>_def) (<#= export.ArgumentSignature #>);
<# } #>
<#= export.DotNetIf #>typedef <#= export.ReturnType #> (* <#= export.EntryPoint #>_def) (<#= export.ArgumentSignature #>);
<#= export.DotNetEndIf #><# } #>

<# foreach (var export in exports) { #>
<#= export.EntryPoint #>_def <#= export.EntryPoint #>_func = NULL;
<# } #>
<#= export.DotNetIf #><#= export.EntryPoint #>_def <#= export.EntryPoint #>_func = NULL;
<#= export.DotNetEndIf #><# } #>

char *
xamarin_get_mono_runtime_build_info ()
Expand Down Expand Up @@ -75,13 +75,13 @@ xamarin_initialize_dynamic_runtime (const char *mono_runtime_prefix)


<# foreach (var export in exports) { #>
<#= export.EntryPoint #>_func = (<#= export.EntryPoint #>_def) dlsym (libmono, "<#= export.EntryPoint #>");
<#= export.DotNetIf #> <#= export.EntryPoint #>_func = (<#= export.EntryPoint #>_def) dlsym (libmono, "<#= export.EntryPoint #>");
<# if (!export.Optional) { #>
if (<#= export.EntryPoint #>_func == NULL) {
fprintf (stderr, "Could not load <#= export.EntryPoint #>\n");
errmsg = "Failed to load the Mono framework.";
}
<# } #>
<#= export.DotNetEndIf #><# } #>

<# } #>
xamarin_dynamic_runtime_initialized = 1;
Expand All @@ -90,7 +90,7 @@ xamarin_initialize_dynamic_runtime (const char *mono_runtime_prefix)
}

<# foreach (var export in exports) { #>
MONO_API <#= export.ReturnType #>
<#= export.DotNetIf #>MONO_API <#= export.ReturnType #>
<#= export.EntryPoint #> (<#= export.ArgumentSignature #>)
{
<# if (export.Optional) { #>
Expand All @@ -104,7 +104,7 @@ MONO_API <#= export.ReturnType #>
<# } #>
return <#= export.EntryPoint #>_func (<#= export.ArgumentNames #>);
}
<# } #>
<#= export.DotNetEndIf #><# } #>

<# foreach (var export in exports) {
if (!export.Optional)
Expand Down
4 changes: 4 additions & 0 deletions runtime/monotouch-main.m
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ - (void) memoryWarning: (NSNotification *) sender

xamarin_bridge_initialize ();

#if DOTNET
xamarin_vm_initialize ();
#endif

xamarin_initialize ();
DEBUG_LAUNCH_TIME_PRINT ("\tmonotouch init time");

Expand Down
23 changes: 23 additions & 0 deletions runtime/monovm-bridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,28 @@
}
#endif // !LEGACY_XAMARIN_MAC

#if DOTNET

bool
xamarin_bridge_vm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues)
{
int rv;

#if TARGET_OS_TV
rv = 0;
// Due to https:/dotnet/runtime/issues/48508, we can't link with the .NET version of libmonosgen-2.0.dylib,
// which means that we can't call monovm_initialize here (libxamarin.dylib fails native linking). Just ignore it for now.
fprintf (stderr, "xamarin_vm_initialize (%i, %p, %p): Ignored due to https:/dotnet/runtime/issues/48508.\n", propertyCount, propertyKeys, propertyValues);
#else

rv = monovm_initialize (propertyCount, propertyKeys, propertyValues);

LOG_MONOVM (stderr, "xamarin_vm_initialize (%i, %p, %p): rv: %i\n", propertyCount, propertyKeys, propertyValues, rv);
#endif

return rv == 0;
}

#endif // DOTNET

#endif // !CORECLR_RUNTIME
37 changes: 37 additions & 0 deletions runtime/runtime.m
Original file line number Diff line number Diff line change
Expand Up @@ -2455,6 +2455,43 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags;
#endif // defined (__i386__) || defined (__x86_64__)
}

#if DOTNET
void
xamarin_vm_initialize ()
{
char *pinvokeOverride = xamarin_strdup_printf ("%p", &xamarin_pinvoke_override);
const char *propertyKeys[] = {
"APP_PATHS",
"PINVOKE_OVERRIDE",
};
const char *propertyValues[] = {
xamarin_get_bundle_path (),
pinvokeOverride,
};
static_assert (sizeof (propertyKeys) == sizeof (propertyValues), "The number of keys and values must be the same.");

int propertyCount = sizeof (propertyValues) / sizeof (propertyValues [0]);
bool rv = xamarin_bridge_vm_initialize (propertyCount, propertyKeys, propertyValues);
xamarin_free (pinvokeOverride);

if (!rv)
xamarin_assertion_message ("Failed to initialize the VM");
}

void*
xamarin_pinvoke_override (const char *libraryName, const char *entrypointName)
{

void* symbol = NULL;

if (!strcmp (libraryName, "__Internal")) {
symbol = dlsym (RTLD_DEFAULT, entrypointName);
}

return symbol;
}
#endif

void
xamarin_printf (const char *format, ...)
{
Expand Down
3 changes: 3 additions & 0 deletions runtime/xamarin/coreclr-bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#ifndef __CORECLR_BRIDGE__
#define __CORECLR_BRIDGE__

//#define LOG_CORECLR(...)
#define LOG_CORECLR(...) fprintf (__VA_ARGS__)

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
3 changes: 3 additions & 0 deletions runtime/xamarin/monovm-bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#ifndef __MONOVM_BRIDGE__
#define __MONOVM_BRIDGE__

//#define LOG_MONOVM(...)
#define LOG_MONOVM(...) fprintf (__VA_ARGS__)

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
3 changes: 3 additions & 0 deletions runtime/xamarin/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ void xamarin_bridge_initialize (); // this is called a bit later, after parsin
unsigned char * xamarin_load_aot_data (MonoAssembly *assembly, int size, gpointer user_data, void **out_handle);
void xamarin_free_aot_data (MonoAssembly *assembly, int size, gpointer user_data, void *handle);
MonoAssembly* xamarin_assembly_preload_hook (MonoAssemblyName *aname, char **assemblies_path, void* user_data);
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);

MonoObject * xamarin_new_nsobject (id self, MonoClass *klass, GCHandle *exception_gchandle);
bool xamarin_has_managed_ref (id self);
Expand Down

0 comments on commit 65d302a

Please sign in to comment.