未验证 提交 7d1191e3 编写于 作者: J Johan Lorensson 提交者: GitHub

CoreCLR runtime tests on Mono Windows x64. (#64281)

Fixed and enabled CoreCLR runtime tests running on Mono Windows x64.
上级 c33d6141
......@@ -293,7 +293,7 @@ jobs:
# Generate test wrappers. This is the step that examines issues.targets to exclude tests.
- script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) buildtestwrappersonly $(logRootNameArg)Wrappers $(runtimeFlavorArgs) $(runtimeVariantArg) $(crossgenArg) $(buildConfig) $(archType) $(crossArg) $(priorityArg) $(librariesOverrideArg)
- script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) buildtestwrappersonly $(logRootNameArg)Wrappers $(runtimeFlavorArgs) $(crossgenArg) $(buildConfig) $(archType) $(crossArg) $(priorityArg) $(librariesOverrideArg) $(runtimeVariantArg)
displayName: Generate test wrappers
......
......@@ -940,6 +940,7 @@ jobs:
runtimeFlavor: mono
platforms:
- OSX_x64
- windows_x64
helixQueueGroup: pr
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
jobParameters:
......
......@@ -3,8 +3,8 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<TestRuntime>true</TestRuntime>
<!-- COM tests are currently only supported only in Windows on coreclr -->
<IgnoreForCI Condition="'$(TargetOS)' != 'Windows' or '$(RuntimeFlavor)' != 'CoreCLR'">true</IgnoreForCI>
<!-- COM tests are currently only supported only in Windows -->
<IgnoreForCI Condition="'$(TargetOS)' != 'Windows'">true</IgnoreForCI>
</PropertyGroup>
<ItemGroup>
<Compile Include="System\Runtime\InteropServices\Marshal\MarshalComDisabledTests.cs" />
......
......@@ -6,6 +6,7 @@
namespace System.Runtime.InteropServices.Tests
{
[PlatformSpecific(TestPlatforms.Windows)]
[SkipOnMono("COM Interop not supported on Mono")]
public partial class MarshalComDisabledTests
{
[Fact]
......
......@@ -162,6 +162,11 @@ public int GetHashCode((Type, string) key)
throw new ApplicationException($"Custom marshaler '{type.FullName}' does not implement a static GetInstance method that takes a single string parameter and returns an ICustomMarshaler.");
}
if (getInstanceMethod.ContainsGenericParameters)
{
throw new System.TypeLoadException($"Custom marshaler '{type.FullName}' contains unassigned generic type parameter(s).");
}
Exception? exc;
try
{
......
......@@ -182,6 +182,31 @@ typedef struct {
MonoCCW* ccw;
} MonoCCWInterface;
/*
* COM Callable Wrappers
*
* CCWs may be called on threads that aren't attached to the runtime, they can
* then run managed code or the method implementations may use coop handles.
* Use the macros below to setup the thread state.
*
* For managed methods, the runtime marshaling wrappers handle attaching and
* coop state switching.
*/
#define MONO_CCW_CALL_ENTER do { \
gpointer dummy; \
gpointer orig_domain = mono_threads_attach_coop (mono_domain_get (), &dummy); \
MONO_ENTER_GC_UNSAFE; \
HANDLE_FUNCTION_ENTER (); \
do {} while (0)
#define MONO_CCW_CALL_EXIT \
HANDLE_FUNCTION_RETURN (); \
MONO_EXIT_GC_UNSAFE; \
mono_threads_detach_coop (orig_domain, &dummy); \
} while (0)
/* IUnknown */
static int STDCALL cominterop_ccw_addref (MonoCCWInterface* ccwe);
......@@ -2104,12 +2129,16 @@ cominterop_get_ccw_method (MonoClass *iface, MonoMethod *method, MonoError *erro
cominterop_setup_marshal_context (&m, adjust_method);
m.mb = mb;
m.runtime_marshalling_enabled = TRUE;
mono_marshal_emit_managed_wrapper (mb, sig_adjusted, mspecs, &m, adjust_method, 0);
mono_cominterop_lock ();
wrapper_method = mono_mb_create_method (mb, m.csig, m.csig->param_count + 16);
mono_cominterop_unlock ();
mono_marshal_emit_managed_wrapper (mb, sig_adjusted, mspecs, &m, adjust_method, 0, error);
gpointer ret = mono_compile_method_checked (wrapper_method, error);
gpointer ret = NULL;
if (is_ok (error)) {
mono_cominterop_lock ();
wrapper_method = mono_mb_create_method (mb, m.csig, m.csig->param_count + 16);
mono_cominterop_unlock ();
ret = mono_compile_method_checked (wrapper_method, error);
}
mono_mb_free (mb);
for (param_index = sig_adjusted->param_count; param_index >= 0; param_index--)
......@@ -2612,12 +2641,9 @@ static int STDCALL
cominterop_ccw_addref (MonoCCWInterface* ccwe)
{
int result;
gpointer dummy;
gpointer orig_domain = mono_threads_attach_coop (mono_domain_get (), &dummy);
MONO_ENTER_GC_UNSAFE;
MONO_CCW_CALL_ENTER;
result = cominterop_ccw_addref_impl (ccwe);
MONO_EXIT_GC_UNSAFE;
mono_threads_detach_coop (orig_domain, &dummy);
MONO_CCW_CALL_EXIT;
return result;
}
......@@ -2646,12 +2672,9 @@ static int STDCALL
cominterop_ccw_release (MonoCCWInterface* ccwe)
{
int result;
gpointer dummy;
gpointer orig_domain = mono_threads_attach_coop (mono_domain_get (), &dummy);
MONO_ENTER_GC_UNSAFE;
MONO_CCW_CALL_ENTER;
result = cominterop_ccw_release_impl (ccwe);
MONO_EXIT_GC_UNSAFE;
mono_threads_detach_coop (orig_domain, &dummy);
MONO_CCW_CALL_EXIT;
return result;
}
......@@ -2698,12 +2721,9 @@ static int STDCALL
cominterop_ccw_queryinterface (MonoCCWInterface* ccwe, const guint8* riid, gpointer* ppv)
{
int result;
gpointer dummy;
gpointer orig_domain = mono_threads_attach_coop (mono_domain_get (), &dummy);
MONO_ENTER_GC_UNSAFE;
MONO_CCW_CALL_ENTER;
result = cominterop_ccw_queryinterface_impl (ccwe, riid, ppv);
MONO_EXIT_GC_UNSAFE;
mono_threads_detach_coop (orig_domain, &dummy);
MONO_CCW_CALL_EXIT;
return result;
}
......@@ -2821,12 +2841,9 @@ cominterop_ccw_get_ids_of_names (MonoCCWInterface* ccwe, gpointer riid,
guint32 lcid, gint32 *rgDispId)
{
int result;
gpointer dummy;
gpointer orig_domain = mono_threads_attach_coop (mono_domain_get(), &dummy);
MONO_ENTER_GC_UNSAFE;
MONO_CCW_CALL_ENTER;
result = cominterop_ccw_get_ids_of_names_impl (ccwe, riid, rgszNames, cNames, lcid, rgDispId);
MONO_EXIT_GC_UNSAFE;
mono_threads_detach_coop (orig_domain, &dummy);
MONO_CCW_CALL_EXIT;
return result;
}
......@@ -2936,8 +2953,9 @@ static SafeArrayCreateFunc safe_array_create_ms = NULL;
static gboolean
init_com_provider_ms (void)
{
ERROR_DECL (error);
static gboolean initialized = FALSE;
char *error_msg;
MonoDl *module = NULL;
const char* scope = "liboleaut32.so";
......@@ -2948,78 +2966,90 @@ init_com_provider_ms (void)
return TRUE;
}
module = mono_dl_open(scope, MONO_DL_LAZY, &error_msg);
if (error_msg) {
g_warning ("Error loading COM support library '%s': %s", scope, error_msg);
module = mono_dl_open (scope, MONO_DL_LAZY, error);
if (!module) {
g_warning ("Error loading COM support library '%s': %s", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SysAllocStringLen", (gpointer*)&sys_alloc_string_len_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SysAllocStringLen", scope, error_msg);
sys_alloc_string_len_ms = (SysAllocStringLenFunc)mono_dl_symbol (module, "SysAllocStringLen", error);
if (!sys_alloc_string_len_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SysAllocStringLen", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SysStringLen", (gpointer*)&sys_string_len_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SysStringLen", scope, error_msg);
sys_string_len_ms = (SysStringLenFunc)mono_dl_symbol (module, "SysStringLen", error);
if (!sys_string_len_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SysStringLen", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SysFreeString", (gpointer*)&sys_free_string_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SysFreeString", scope, error_msg);
sys_free_string_ms = (SysFreeStringFunc)mono_dl_symbol (module, "SysFreeString", error);
if (!sys_free_string_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SysFreeString", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SafeArrayGetDim", (gpointer*)&safe_array_get_dim_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayGetDim", scope, error_msg);
safe_array_get_dim_ms = (SafeArrayGetDimFunc)mono_dl_symbol (module, "SafeArrayGetDim", error);
if (!safe_array_get_dim_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayGetDim", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SafeArrayGetLBound", (gpointer*)&safe_array_get_lbound_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayGetLBound", scope, error_msg);
safe_array_get_lbound_ms = (SafeArrayGetLBoundFunc)mono_dl_symbol (module, "SafeArrayGetLBound", error);
if (!safe_array_get_lbound_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayGetLBound", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SafeArrayGetUBound", (gpointer*)&safe_array_get_ubound_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayGetUBound", scope, error_msg);
safe_array_get_ubound_ms = (SafeArrayGetUBoundFunc)mono_dl_symbol (module, "SafeArrayGetUBound", error);
if (!safe_array_get_ubound_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayGetUBound", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SafeArrayPtrOfIndex", (gpointer*)&safe_array_ptr_of_index_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayPtrOfIndex", scope, error_msg);
safe_array_ptr_of_index_ms = (SafeArrayPtrOfIndexFunc)mono_dl_symbol (module, "SafeArrayPtrOfIndex", error);
if (!safe_array_ptr_of_index_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayPtrOfIndex", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SafeArrayDestroy", (gpointer*)&safe_array_destroy_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayDestroy", scope, error_msg);
safe_array_destroy_ms = (SafeArrayDestroyFunc)mono_dl_symbol (module, "SafeArrayDestroy", error);
if (!safe_array_destroy_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayDestroy", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SafeArrayPutElement", (gpointer*)&safe_array_put_element_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayPutElement", scope, error_msg);
safe_array_put_element_ms = (SafeArrayPutElementFunc)mono_dl_symbol (module, "SafeArrayPutElement", error);
if (!safe_array_put_element_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayPutElement", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
error_msg = mono_dl_symbol (module, "SafeArrayCreate", (gpointer*)&safe_array_create_ms);
if (error_msg) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayCreate", scope, error_msg);
safe_array_create_ms = (SafeArrayCreateFunc)mono_dl_symbol (module, "SafeArrayCreate", error);
if (!safe_array_create_ms) {
g_warning ("Error loading entry point '%s' in COM support library '%s': %s", "SafeArrayCreate", scope, mono_error_get_message_without_fields (error));
mono_error_cleanup (error);
g_assert_not_reached ();
return FALSE;
}
......
......@@ -120,13 +120,12 @@ load_component_entrypoint (MonoComponentLibrary *component_lib, const MonoCompon
{
char *component_init = component_init_name (component);
gpointer sym = NULL;
char *error_msg = mono_dl_symbol (component_lib->lib, component_init, &sym);
if (error_msg) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "Component %s library does not have symbol %s: %s", component->name, component_init, error_msg);
g_free (error_msg);
g_free (component_init);
return NULL;
}
ERROR_DECL (symbol_error);
sym = mono_dl_symbol (component_lib->lib, component_init, symbol_error);
if (!sym)
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "Component %s library does not have symbol %s: %s", component->name, component_init, mono_error_get_message_without_fields (symbol_error));
mono_error_cleanup (symbol_error);
g_free (component_init);
return sym;
}
......@@ -161,15 +160,14 @@ try_load (const char* dir, const MonoComponentEntry *component, const char* comp
void *iter = NULL;
while (lib == NULL && (path = mono_dl_build_platform_path (dir, component_base_lib, &iter))) {
char *error_msg = NULL;
lib = mono_dl_open (path, MONO_DL_EAGER | MONO_DL_LOCAL, &error_msg);
if (!lib) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "Component library %s not found at %s: %s", component_base_lib, path, error_msg);
g_free (error_msg);
} else {
ERROR_DECL (load_error);
lib = mono_dl_open (path, MONO_DL_EAGER | MONO_DL_LOCAL, load_error);
if (!lib)
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "Component library %s not found at %s: %s", component_base_lib, path, mono_error_get_message_without_fields (load_error));
else
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "Component library %s found at %s", component_base_lib, path);
}
g_free (path);
mono_error_cleanup (load_error);
}
return lib;
......
......@@ -1973,6 +1973,46 @@ gc_safe_transition_builder_cleanup (GCSafeTransitionBuilder *builder)
#endif
}
static gboolean
emit_native_wrapper_validate_signature (MonoMethodBuilder *mb, MonoMethodSignature* sig, MonoMarshalSpec** mspecs)
{
if (mspecs) {
for (int i = 0; i < sig->param_count; i ++) {
if (mspecs [i + 1] && mspecs [i + 1]->native == MONO_NATIVE_CUSTOM) {
if (!mspecs [i + 1]->data.custom_data.custom_name || strlen (mspecs [i + 1]->data.custom_data.custom_name) == 0) {
mono_mb_emit_exception_full (mb, "System", "TypeLoadException", g_strdup ("Missing ICustomMarshaler type"));
return FALSE;
}
switch (sig->params[i]->type) {
case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_VALUETYPE:
break;
default:
mono_mb_emit_exception_full (mb, "System.Runtime.InteropServices", "MarshalDirectiveException", g_strdup_printf ("custom marshalling of type %x is currently not supported", sig->params[i]->type));
return FALSE;
}
}
else if (sig->params[i]->type == MONO_TYPE_VALUETYPE) {
MonoMarshalType *marshal_type = mono_marshal_load_type_info (mono_class_from_mono_type_internal (sig->params [i]));
for (int field_idx = 0; field_idx < marshal_type->num_fields; ++field_idx) {
if (marshal_type->fields [field_idx].mspec && marshal_type->fields [field_idx].mspec->native == MONO_NATIVE_CUSTOM) {
mono_mb_emit_exception_full (mb, "System", "TypeLoadException", g_strdup ("Value type includes custom marshaled fields"));
return FALSE;
}
}
}
}
}
return TRUE;
}
/**
* emit_native_wrapper_ilgen:
* \param image the image to use for looking up custom marshallers
......@@ -2012,6 +2052,9 @@ emit_native_wrapper_ilgen (MonoImage *image, MonoMethodBuilder *mb, MonoMethodSi
m.sig = sig;
m.piinfo = piinfo;
if (!emit_native_wrapper_validate_signature (mb, sig, mspecs))
return;
if (!skip_gc_trans)
need_gc_safe = gc_safe_transition_builder_init (&gc_safe_transition_builder, mb, func_param);
......@@ -4559,6 +4602,31 @@ emit_marshal_custom_get_instance (MonoMethodBuilder *mb, MonoClass *klass, MonoM
mono_mb_emit_op (mb, CEE_CALL, get_instance);
}
static int
emit_marshal_custom_ilgen_throw_exception (MonoMethodBuilder *mb, const char *exc_nspace, const char *exc_name, const char *msg, MarshalAction action)
{
/* Throw exception and emit compensation code, if neccesary */
switch (action) {
case MARSHAL_ACTION_CONV_IN:
case MARSHAL_ACTION_MANAGED_CONV_IN:
case MARSHAL_ACTION_CONV_RESULT:
case MARSHAL_ACTION_MANAGED_CONV_RESULT:
if ((action == MARSHAL_ACTION_CONV_RESULT) || (action == MARSHAL_ACTION_MANAGED_CONV_RESULT))
mono_mb_emit_byte (mb, CEE_POP);
mono_mb_emit_exception_full (mb, exc_nspace, exc_name, msg);
break;
case MARSHAL_ACTION_PUSH:
mono_mb_emit_byte (mb, CEE_LDNULL);
break;
default:
break;
}
return 0;
}
static int
emit_marshal_custom_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
MonoMarshalSpec *spec,
......@@ -4581,27 +4649,8 @@ emit_marshal_custom_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
if (!ICustomMarshaler) {
MonoClass *klass = mono_class_try_get_icustom_marshaler_class ();
if (!klass) {
char *exception_msg = g_strdup ("Current profile doesn't support ICustomMarshaler");
/* Throw exception and emit compensation code if neccesary */
switch (action) {
case MARSHAL_ACTION_CONV_IN:
case MARSHAL_ACTION_CONV_RESULT:
case MARSHAL_ACTION_MANAGED_CONV_RESULT:
if ((action == MARSHAL_ACTION_CONV_RESULT) || (action == MARSHAL_ACTION_MANAGED_CONV_RESULT))
mono_mb_emit_byte (mb, CEE_POP);
mono_mb_emit_exception_full (mb, "System", "ApplicationException", exception_msg);
break;
case MARSHAL_ACTION_PUSH:
mono_mb_emit_byte (mb, CEE_LDNULL);
break;
default:
break;
}
return 0;
}
if (!klass)
return emit_marshal_custom_ilgen_throw_exception (mb, "System", "ApplicationException", g_strdup ("Current profile doesn't support ICustomMarshaler"), action);
cleanup_native = get_method_nofail (klass, "CleanUpNativeData", 1, 0);
g_assert (cleanup_native);
......@@ -4624,8 +4673,9 @@ emit_marshal_custom_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
else
mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, alc, m->image, error);
g_assert (mtype != NULL);
mono_error_assert_ok (error);
if (!mtype)
return emit_marshal_custom_ilgen_throw_exception (mb, "System", "TypeLoadException", g_strdup ("Failed to load ICustomMarshaler type"), action);
mklass = mono_class_from_mono_type_internal (mtype);
g_assert (mklass != NULL);
......@@ -4691,29 +4741,45 @@ emit_marshal_custom_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
mono_mb_emit_ldloc (mb, conv_arg);
pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
if (m_type_is_byref (t)) {
if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_OUT)) {
mono_mb_emit_ldarg (mb, argnum);
emit_marshal_custom_get_instance (mb, mklass, spec);
mono_mb_emit_byte (mb, CEE_DUP);
mono_mb_emit_ldarg (mb, argnum);
mono_mb_emit_byte (mb, CEE_LDIND_REF);
mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_managed);
mono_mb_emit_ldloc (mb, conv_arg);
mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
mono_mb_emit_byte (mb, CEE_STIND_REF);
} else if (t->attrs & PARAM_ATTRIBUTE_OUT) {
} else if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT)) {
mono_mb_emit_ldarg (mb, argnum);
emit_marshal_custom_get_instance (mb, mklass, spec);
mono_mb_emit_ldloc (mb, conv_arg);
mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
mono_mb_emit_byte (mb, CEE_STIND_REF);
} else if (t->attrs & PARAM_ATTRIBUTE_OUT) {
emit_marshal_custom_get_instance (mb, mklass, spec);
mono_mb_emit_ldloc (mb, conv_arg);
mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
/* We have nowhere to store the result */
mono_mb_emit_byte (mb, CEE_POP);
}
emit_marshal_custom_get_instance (mb, mklass, spec);
// Only call cleanup_native if MARSHAL_ACTION_CONV_IN called marshal_managed_to_native.
if (!(m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT)) &&
!(!m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT) && !(t->attrs & PARAM_ATTRIBUTE_IN))) {
emit_marshal_custom_get_instance (mb, mklass, spec);
mono_mb_emit_ldloc (mb, conv_arg);
mono_mb_emit_ldloc (mb, conv_arg);
mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_native);
mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_native);
}
mono_mb_patch_branch (mb, pos2);
break;
......@@ -4726,31 +4792,38 @@ emit_marshal_custom_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
break;
case MARSHAL_ACTION_CONV_RESULT:
loc1 = mono_mb_add_local (mb, int_type);
mono_mb_emit_stloc (mb, 3);
mono_mb_emit_ldloc (mb, 3);
mono_mb_emit_stloc (mb, loc1);
/* Check for null */
mono_mb_emit_ldloc (mb, 3);
pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
emit_marshal_custom_get_instance (mb, mklass, spec);
mono_mb_emit_byte (mb, CEE_DUP);
mono_mb_emit_ldloc (mb, 3);
mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
mono_mb_emit_stloc (mb, 3);
mono_mb_emit_ldloc (mb, loc1);
mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_native);
mono_mb_patch_branch (mb, pos2);
break;
case MARSHAL_ACTION_MANAGED_CONV_IN:
switch (t->type) {
case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_BOOLEAN:
break;
default:
g_warning ("custom marshalling of type %x is currently not supported", t->type);
g_assert_not_reached ();
break;
}
conv_arg = mono_mb_add_local (mb, object_type);
mono_mb_emit_byte (mb, CEE_LDNULL);
......@@ -4820,11 +4893,12 @@ emit_marshal_custom_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
mono_mb_emit_byte (mb, CEE_STIND_I);
}
/* Call CleanUpManagedData */
emit_marshal_custom_get_instance (mb, mklass, spec);
mono_mb_emit_ldloc (mb, conv_arg);
mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_managed);
// Only call cleanup_managed if MARSHAL_ACTION_MANAGED_CONV_IN called marshal_native_to_managed.
if (!(m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT))) {
emit_marshal_custom_get_instance (mb, mklass, spec);
mono_mb_emit_ldloc (mb, conv_arg);
mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_managed);
}
mono_mb_patch_branch (mb, pos2);
break;
......@@ -6202,8 +6276,48 @@ emit_marshal_variant_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
return conv_arg;
}
static gboolean
emit_managed_wrapper_validate_signature (MonoMethodSignature* sig, MonoMarshalSpec** mspecs, MonoError* error)
{
if (mspecs) {
for (int i = 0; i < sig->param_count; i ++) {
if (mspecs [i + 1] && mspecs [i + 1]->native == MONO_NATIVE_CUSTOM) {
if (!mspecs [i + 1]->data.custom_data.custom_name || strlen (mspecs [i + 1]->data.custom_data.custom_name) == 0) {
mono_error_set_generic_error (error, "System", "TypeLoadException", "Missing ICustomMarshaler type");
return FALSE;
}
switch (sig->params[i]->type) {
case MONO_TYPE_OBJECT:
case MONO_TYPE_CLASS:
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_STRING:
case MONO_TYPE_BOOLEAN:
break;
default:
mono_error_set_generic_error (error, "System.Runtime.InteropServices", "MarshalDirectiveException", "custom marshalling of type %x is currently not supported", sig->params[i]->type);
return FALSE;
}
} else if (sig->params[i]->type == MONO_TYPE_VALUETYPE) {
MonoClass *klass = mono_class_from_mono_type_internal (sig->params [i]);
MonoMarshalType *marshal_type = mono_marshal_load_type_info (klass);
for (int field_idx = 0; field_idx < marshal_type->num_fields; ++field_idx) {
if (marshal_type->fields [field_idx].mspec && marshal_type->fields [field_idx].mspec->native == MONO_NATIVE_CUSTOM) {
mono_error_set_type_load_class (error, klass, "Value type includes custom marshaled fields");
return FALSE;
}
}
}
}
}
return TRUE;
}
static void
emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle)
emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle, MonoError *error)
{
MonoMethodSignature *sig, *csig;
int i, *tmp_locals, orig_domain, attach_cookie;
......@@ -6212,6 +6326,9 @@ emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_s
sig = m->sig;
csig = m->csig;
if (!emit_managed_wrapper_validate_signature (sig, mspecs, error))
return;
MonoType *int_type = mono_get_int_type ();
MonoType *boolean_type = m_class_get_byval_arg (mono_defaults.boolean_class);
/* allocate local 0 (pointer) src_ptr */
......@@ -6278,20 +6395,25 @@ emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_s
tmp_locals = g_newa (int, sig->param_count);
for (i = 0; i < sig->param_count; i ++) {
MonoType *t = sig->params [i];
MonoMarshalSpec *spec = mspecs [i + 1];
switch (t->type) {
case MONO_TYPE_OBJECT:
case MONO_TYPE_CLASS:
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_STRING:
case MONO_TYPE_BOOLEAN:
tmp_locals [i] = mono_emit_marshal (m, i, sig->params [i], mspecs [i + 1], 0, &csig->params [i], MARSHAL_ACTION_MANAGED_CONV_IN);
break;
default:
tmp_locals [i] = 0;
break;
if (spec && spec->native == MONO_NATIVE_CUSTOM) {
tmp_locals [i] = mono_emit_marshal (m, i, t, mspecs [i + 1], 0, &csig->params [i], MARSHAL_ACTION_MANAGED_CONV_IN);
} else {
switch (t->type) {
case MONO_TYPE_OBJECT:
case MONO_TYPE_CLASS:
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_STRING:
case MONO_TYPE_BOOLEAN:
tmp_locals [i] = mono_emit_marshal (m, i, t, mspecs [i + 1], 0, &csig->params [i], MARSHAL_ACTION_MANAGED_CONV_IN);
break;
default:
tmp_locals [i] = 0;
break;
}
}
}
......
......@@ -174,7 +174,7 @@ emit_marshal_variant_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
#ifndef ENABLE_ILGEN
static void
emit_managed_wrapper_noilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle)
emit_managed_wrapper_noilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle, MonoError *error)
{
MonoMethodSignature *sig, *csig;
int i;
......
......@@ -3837,9 +3837,9 @@ mono_marshal_get_native_func_wrapper_indirect (MonoClass *caller_class, MonoMeth
* THIS_LOC is the memory location where the target of the delegate is stored.
*/
void
mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle)
mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle, MonoError *error)
{
get_marshal_cb ()->emit_managed_wrapper (mb, invoke_sig, mspecs, m, method, target_handle);
get_marshal_cb ()->emit_managed_wrapper (mb, invoke_sig, mspecs, m, method, target_handle, error);
}
static gboolean
......@@ -4121,23 +4121,27 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass,
mono_custom_attrs_free (cinfo);
}
mono_marshal_emit_managed_wrapper (mb, invoke_sig, mspecs, &m, method, target_handle);
mono_marshal_emit_managed_wrapper (mb, invoke_sig, mspecs, &m, method, target_handle, error);
if (!target_handle) {
WrapperInfo *info;
res = NULL;
if (is_ok (error)) {
if (!target_handle) {
WrapperInfo *info;
// FIXME: Associate it with the method+delegate_klass pair
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
info->d.native_to_managed.method = method;
info->d.native_to_managed.klass = delegate_klass;
// FIXME: Associate it with the method+delegate_klass pair
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
info->d.native_to_managed.method = method;
info->d.native_to_managed.klass = delegate_klass;
res = mono_mb_create_and_cache_full (cache, method,
mb, csig, sig->param_count + 16,
info, NULL);
} else {
get_marshal_cb ()->mb_set_dynamic (mb);
res = mono_mb_create (mb, csig, sig->param_count + 16, NULL);
res = mono_mb_create_and_cache_full (cache, method,
mb, csig, sig->param_count + 16,
info, NULL);
} else {
get_marshal_cb ()->mb_set_dynamic (mb);
res = mono_mb_create (mb, csig, sig->param_count + 16, NULL);
}
}
mono_mb_free (mb);
for (i = invoke_sig->param_count; i >= 0; i--)
......@@ -4198,7 +4202,8 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type)
/* FIXME: Implement VTFIXUP_TYPE_FROM_UNMANAGED_RETAIN_APPDOMAIN. */
mono_marshal_emit_managed_wrapper (mb, sig, mspecs, &m, method, 0);
mono_marshal_emit_managed_wrapper (mb, sig, mspecs, &m, method, 0, error);
mono_error_assert_ok (error);
get_marshal_cb ()->mb_set_dynamic (mb);
method = mono_mb_create (mb, csig, sig->param_count + 16, NULL);
......@@ -5333,6 +5338,12 @@ mono_struct_delete_old (MonoClass *klass, char *ptr)
info = mono_marshal_load_type_info (klass);
if (info->native_size == 0)
return;
if (m_class_is_blittable (klass))
return;
for (i = 0; i < info->num_fields; i++) {
MonoMarshalConv conv;
MonoType *ftype = info->fields [i].field->type;
......@@ -5349,7 +5360,7 @@ mono_struct_delete_old (MonoClass *klass, char *ptr)
switch (conv) {
case MONO_MARSHAL_CONV_NONE:
if (MONO_TYPE_ISSTRUCT (ftype)) {
mono_struct_delete_old (ftype->data.klass, cpos);
mono_struct_delete_old (mono_class_from_mono_type_internal (ftype), cpos);
continue;
}
break;
......
......@@ -335,7 +335,7 @@ typedef struct {
void (*emit_stelemref) (MonoMethodBuilder *mb);
void (*emit_array_address) (MonoMethodBuilder *mb, int rank, int elem_size);
void (*emit_native_wrapper) (MonoImage *image, MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethodPInvoke *piinfo, MonoMarshalSpec **mspecs, gpointer func, MonoNativeWrapperFlags flags);
void (*emit_managed_wrapper) (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle);
void (*emit_managed_wrapper) (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle, MonoError *error);
void (*emit_runtime_invoke_body) (MonoMethodBuilder *mb, const char **param_names, MonoImage *image, MonoMethod *method, MonoMethodSignature *sig, MonoMethodSignature *callsig, gboolean virtual_, gboolean need_direct_wrapper);
void (*emit_runtime_invoke_dynamic) (MonoMethodBuilder *mb);
void (*emit_delegate_begin_invoke) (MonoMethodBuilder *mb, MonoMethodSignature *sig);
......@@ -677,7 +677,7 @@ void
mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethodPInvoke *piinfo, MonoMarshalSpec **mspecs, gpointer func, MonoNativeWrapperFlags flags);
void
mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle);
mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle, MonoError *error);
GHashTable*
mono_marshal_get_cache (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func);
......
......@@ -6805,6 +6805,8 @@ handle_enum:
else
*conv = MONO_MARSHAL_CONV_STR_BYVALSTR;
return MONO_NATIVE_BYVALTSTR;
case MONO_NATIVE_CUSTOM:
return MONO_NATIVE_CUSTOM;
default:
g_error ("Can not marshal string to native type '%02x': Invalid managed/unmanaged type combination (String fields must be paired with LPStr, LPWStr, BStr or ByValTStr).", mspec->native);
}
......@@ -6819,6 +6821,9 @@ handle_enum:
}
case MONO_TYPE_PTR: return MONO_NATIVE_UINT;
case MONO_TYPE_VALUETYPE: /*FIXME*/
if (mspec && mspec->native == MONO_NATIVE_CUSTOM)
return MONO_NATIVE_CUSTOM;
if (m_class_is_enumtype (type->data.klass)) {
t = mono_class_enum_basetype_internal (type->data.klass)->type;
goto handle_enum;
......@@ -6844,6 +6849,8 @@ handle_enum:
case MONO_NATIVE_LPARRAY:
*conv = MONO_MARSHAL_CONV_ARRAY_LPARRAY;
return MONO_NATIVE_LPARRAY;
case MONO_NATIVE_CUSTOM:
return MONO_NATIVE_CUSTOM;
default:
g_error ("cant marshal array as native type %02x", mspec->native);
}
......
......@@ -324,7 +324,9 @@ exit:
static void
remove_cached_module (gpointer key, gpointer value, gpointer user_data)
{
mono_dl_close((MonoDl*)value);
ERROR_DECL (close_error);
mono_dl_close((MonoDl*)value, close_error);
mono_error_cleanup (close_error);
}
void
......@@ -355,7 +357,7 @@ static gpointer
lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_out);
static gpointer
pinvoke_probe_for_symbol (MonoDl *module, MonoMethodPInvoke *piinfo, const char *import, char **error_msg_out);
pinvoke_probe_for_symbol (MonoDl *module, MonoMethodPInvoke *piinfo, const char *import);
static void
pinvoke_probe_convert_status_for_api (MonoLookupPInvokeStatus *status, const char **exc_class, const char **exc_arg)
......@@ -490,27 +492,39 @@ convert_dllimport_flags (int flags)
}
static MonoDl *
netcore_probe_for_module_variations (const char *mdirname, const char *file_name, int raw_flags)
netcore_probe_for_module_variations (const char *mdirname, const char *file_name, int raw_flags, MonoError *error)
{
void *iter = NULL;
char *full_name = NULL;
MonoDl *module = NULL;
ERROR_DECL (bad_image_error);
while (module == NULL && (full_name = mono_dl_build_path (mdirname, file_name, &iter))) {
char *error_msg = NULL;
module = mono_dl_open_full (full_name, MONO_DL_LAZY, raw_flags, &error_msg);
if (!module) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "DllImport error loading library '%s': '%s'.", full_name, error_msg);
g_free (error_msg);
}
mono_error_cleanup (error);
error_init_reuse (error);
module = mono_dl_open_full (full_name, MONO_DL_LAZY, raw_flags, error);
if (!module)
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "DllImport error loading library '%s': '%s'.", full_name, mono_error_get_message_without_fields (error));
g_free (full_name);
if (!module && !is_ok (error) && mono_error_get_error_code (error) == MONO_ERROR_BAD_IMAGE) {
mono_error_cleanup (bad_image_error);
mono_error_move (bad_image_error, error);
}
}
if (!module && !is_ok (bad_image_error)) {
mono_error_cleanup (error);
mono_error_move (error, bad_image_error);
}
mono_error_cleanup (bad_image_error);
return module;
}
static MonoDl *
netcore_probe_for_module (MonoImage *image, const char *file_name, int flags)
netcore_probe_for_module (MonoImage *image, const char *file_name, int flags, MonoError *error)
{
MonoDl *module = NULL;
int lflags = convert_dllimport_flags (flags);
......@@ -518,27 +532,59 @@ netcore_probe_for_module (MonoImage *image, const char *file_name, int flags)
// TODO: this algorithm doesn't quite match CoreCLR, so respecting DLLIMPORTSEARCHPATH_LEGACY_BEHAVIOR makes little sense
// If the difference becomes a problem, overhaul this algorithm to match theirs exactly
ERROR_DECL (bad_image_error);
// Try without any path additions
module = netcore_probe_for_module_variations (NULL, file_name, lflags);
module = netcore_probe_for_module_variations (NULL, file_name, lflags, error);
if (!module && !is_ok (error) && mono_error_get_error_code (error) == MONO_ERROR_BAD_IMAGE)
mono_error_move (bad_image_error, error);
// Check the NATIVE_DLL_SEARCH_DIRECTORIES
for (int i = 0; i < pinvoke_search_directories_count && module == NULL; ++i)
module = netcore_probe_for_module_variations (pinvoke_search_directories[i], file_name, lflags);
for (int i = 0; i < pinvoke_search_directories_count && module == NULL; ++i) {
mono_error_cleanup (error);
error_init_reuse (error);
module = netcore_probe_for_module_variations (pinvoke_search_directories[i], file_name, lflags, error);
if (!module && !is_ok (error) && mono_error_get_error_code (error) == MONO_ERROR_BAD_IMAGE) {
mono_error_cleanup (bad_image_error);
mono_error_move (bad_image_error, error);
}
}
// Check the assembly directory if the search flag is set and the image exists
if ((flags & DLLIMPORTSEARCHPATH_ASSEMBLY_DIRECTORY) != 0 && image != NULL &&
module == NULL && (image->filename != NULL)) {
mono_error_cleanup (error);
error_init_reuse (error);
char *mdirname = g_path_get_dirname (image->filename);
if (mdirname)
module = netcore_probe_for_module_variations (mdirname, file_name, lflags);
module = netcore_probe_for_module_variations (mdirname, file_name, lflags, error);
g_free (mdirname);
}
// TODO: Pass remaining flags on to LoadLibraryEx on Windows where appropriate, see https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportsearchpath?view=netcore-3.1
if (!module && !is_ok (bad_image_error)) {
mono_error_cleanup (error);
mono_error_move (error, bad_image_error);
}
mono_error_cleanup (bad_image_error);
return module;
}
static MonoDl *
netcore_probe_for_module_nofail (MonoImage *image, const char *file_name, int flags)
{
MonoDl *result = NULL;
ERROR_DECL (error);
result = netcore_probe_for_module (image, file_name, flags, error);
mono_error_cleanup (error);
return result;
}
static MonoDl *
netcore_resolve_with_dll_import_resolver (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, const char *scope, guint32 flags, MonoError *error)
{
......@@ -760,15 +806,16 @@ netcore_check_alc_cache (MonoAssemblyLoadContext *alc, const char *scope)
static MonoDl*
netcore_lookup_self_native_handle()
{
char *error_msg = NULL;
ERROR_DECL (load_error);
if (!internal_module)
internal_module = mono_dl_open_self (&error_msg);
internal_module = mono_dl_open_self (load_error);
if (!internal_module)
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "DllImport error loading library '__Internal': '%s'.", mono_error_get_message_without_fields (load_error));
if (!internal_module) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "DllImport error loading library '__Internal': '%s'.", error_msg);
g_free (error_msg);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "Native library found via __Internal.");
mono_error_cleanup (load_error);
return internal_module;
}
......@@ -838,7 +885,7 @@ netcore_lookup_native_library (MonoAssemblyLoadContext *alc, MonoImage *image, c
goto add_to_alc_cache;
}
module = netcore_probe_for_module (image, scope, flags);
module = netcore_probe_for_module_nofail (image, scope, flags);
if (module) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "Native library found via filesystem probing: '%s'.", scope);
goto add_to_global_cache;
......@@ -956,7 +1003,6 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou
const char *orig_scope = NULL;
const char *new_scope = NULL;
const char *error_scope = NULL;
char *error_msg = NULL;
MonoDl *module = NULL;
gpointer addr = NULL;
......@@ -1068,7 +1114,8 @@ retry_with_libcoreclr:
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT,
"DllImport searching in: '%s' ('%s').", new_scope, module->full_name);
addr = pinvoke_probe_for_symbol (module, piinfo, new_import, &error_msg);
addr = pinvoke_probe_for_symbol (module, piinfo, new_import);
if (!addr) {
#ifndef HOST_WIN32
......@@ -1090,24 +1137,22 @@ exit:
}
g_free ((char *)new_import);
g_free ((char *)new_scope);
g_free (error_msg);
return addr;
}
static gpointer
pinvoke_probe_for_symbol (MonoDl *module, MonoMethodPInvoke *piinfo, const char *import, char **error_msg_out)
pinvoke_probe_for_symbol (MonoDl *module, MonoMethodPInvoke *piinfo, const char *import)
{
char *error_msg = NULL;
gpointer addr = NULL;
g_assert (error_msg_out);
ERROR_DECL (symbol_error);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT,
"Searching for '%s'.", import);
#ifdef HOST_WIN32 // For netcore, name mangling is Windows-exclusive
if (piinfo->piflags & PINVOKE_ATTRIBUTE_NO_MANGLE)
error_msg = mono_dl_symbol (module, import, &addr);
addr = mono_dl_symbol (module, import, symbol_error);
else {
/*
* Search using a variety of mangled names
......@@ -1172,17 +1217,17 @@ pinvoke_probe_for_symbol (MonoDl *module, MonoMethodPInvoke *piinfo, const char
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT,
"Probing '%s'.", mangled_name);
error_msg = mono_dl_symbol (module, mangled_name, &addr);
error_init_reuse (symbol_error);
addr = mono_dl_symbol (module, mangled_name, symbol_error);
if (addr)
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT,
"Found as '%s'.", mangled_name);
else
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT,
"Could not find '%s' due to '%s'.", mangled_name, error_msg);
"Could not find '%s' due to '%s'.", mangled_name, mono_error_get_message_without_fields (symbol_error));
g_free (error_msg);
error_msg = NULL;
mono_error_cleanup (symbol_error);
if (mangled_name != import)
g_free (mangled_name);
......@@ -1191,16 +1236,18 @@ pinvoke_probe_for_symbol (MonoDl *module, MonoMethodPInvoke *piinfo, const char
}
}
#else
error_msg = mono_dl_symbol (module, import, &addr);
addr = mono_dl_symbol (module, import, symbol_error);
mono_error_cleanup (symbol_error);
#endif
*error_msg_out = error_msg;
return addr;
}
void
ves_icall_System_Runtime_InteropServices_NativeLibrary_FreeLib (gpointer lib, MonoError *error)
{
ERROR_DECL (close_error);
MonoDl *module;
guint32 ref_count;
......@@ -1220,14 +1267,22 @@ ves_icall_System_Runtime_InteropServices_NativeLibrary_FreeLib (gpointer lib, Mo
g_hash_table_remove (native_library_module_map, module->handle);
g_hash_table_add (native_library_module_blocklist, module);
mono_dl_close (module);
mono_dl_close (module, close_error);
} else {
MonoDl* raw_module = g_new0(MonoDl, 1);
raw_module->handle = lib;
mono_dl_close (raw_module);
MonoDl *raw_module = (MonoDl *) g_malloc0 (sizeof (MonoDl));
if (raw_module) {
raw_module->handle = lib;
mono_dl_close (raw_module, close_error);
}
}
leave:
if (!is_ok (close_error)) {
mono_error_set_invalid_operation (error, NULL);
mono_error_cleanup (close_error);
}
native_library_unlock ();
}
......@@ -1249,15 +1304,21 @@ ves_icall_System_Runtime_InteropServices_NativeLibrary_GetSymbol (gpointer lib,
module = netcore_handle_lookup (lib);
if (module) {
mono_dl_symbol (module, symbol_name, &symbol);
if (!symbol)
symbol = mono_dl_symbol (module, symbol_name, error);
if (!symbol) {
mono_error_cleanup (error);
error_init_reuse (error);
mono_error_set_generic_error (error, "System", "EntryPointNotFoundException", "%s: %s", module->full_name, symbol_name);
}
} else {
MonoDl raw_module = { { 0 } };
raw_module.handle = lib;
mono_dl_symbol (&raw_module, symbol_name, &symbol);
if (!symbol)
symbol = mono_dl_symbol (&raw_module, symbol_name, error);
if (!symbol) {
mono_error_cleanup (error);
error_init_reuse (error);
mono_error_set_generic_error (error, "System", "EntryPointNotFoundException", "%p: %s", lib, symbol_name);
}
}
native_library_unlock ();
......@@ -1302,9 +1363,18 @@ ves_icall_System_Runtime_InteropServices_NativeLibrary_LoadByName (MonoStringHan
goto_if_nok (error, leave);
// FIXME: implement search flag defaults properly
module = netcore_probe_for_module (image, lib_name, has_search_flag ? search_flag : DLLIMPORTSEARCHPATH_ASSEMBLY_DIRECTORY);
if (!module)
mono_error_set_generic_error (error, "System", "DllNotFoundException", "%s", lib_name);
{
ERROR_DECL (load_error);
module = netcore_probe_for_module (image, lib_name, has_search_flag ? search_flag : DLLIMPORTSEARCHPATH_ASSEMBLY_DIRECTORY, load_error);
if (!module) {
if (mono_error_get_error_code (load_error) == MONO_ERROR_BAD_IMAGE)
mono_error_set_generic_error (error, "System", "BadImageFormatException", "%s", lib_name);
else
mono_error_set_generic_error (error, "System", "DllNotFoundException", "%s", lib_name);
}
mono_error_cleanup (load_error);
}
goto_if_nok (error, leave);
native_library_lock ();
......@@ -1325,7 +1395,6 @@ ves_icall_System_Runtime_InteropServices_NativeLibrary_LoadFromPath (MonoStringH
{
MonoDl *module;
gpointer handle = NULL;
char *error_msg = NULL;
char *lib_path;
ERROR_LOCAL_BEGIN (local_error, error, throw_on_error)
......@@ -1333,12 +1402,20 @@ ves_icall_System_Runtime_InteropServices_NativeLibrary_LoadFromPath (MonoStringH
lib_path = mono_string_handle_to_utf8 (lib_path_handle, error);
goto_if_nok (error, leave);
module = mono_dl_open (lib_path, MONO_DL_LAZY, &error_msg);
ERROR_DECL (load_error);
module = mono_dl_open (lib_path, MONO_DL_LAZY, load_error);
if (!module) {
const char *error_msg = mono_error_get_message_without_fields (load_error);
guint16 error_code = mono_error_get_error_code (load_error);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "DllImport error loading library '%s': '%s'.", lib_path, error_msg);
mono_error_set_generic_error (error, "System", "DllNotFoundException", "'%s': '%s'", lib_path, error_msg);
g_free (error_msg);
if (error_code == MONO_ERROR_BAD_IMAGE)
mono_error_set_generic_error (error, "System", "BadImageFormatException", "'%s': '%s'", lib_path, error_msg);
else
mono_error_set_generic_error (error, "System", "DllNotFoundException", "'%s': '%s'", lib_path, error_msg);
}
mono_error_cleanup (load_error);
goto_if_nok (error, leave);
native_library_lock ();
......@@ -1385,7 +1462,7 @@ void
mono_loader_save_bundled_library (int fd, uint64_t offset, uint64_t size, const char *destfname)
{
MonoDl *lib;
char *file, *buffer, *err, *internal_path;
char *file, *buffer, *internal_path;
if (!bundle_save_library_initialized)
bundle_save_library_initialize ();
......@@ -1393,11 +1470,15 @@ mono_loader_save_bundled_library (int fd, uint64_t offset, uint64_t size, const
buffer = g_str_from_file_region (fd, offset, size);
g_file_set_contents (file, buffer, size, NULL);
lib = mono_dl_open (file, MONO_DL_LAZY, &err);
if (lib == NULL){
fprintf (stderr, "Error loading shared library: %s %s\n", file, err);
ERROR_DECL (load_error);
lib = mono_dl_open (file, MONO_DL_LAZY, load_error);
if (!lib) {
fprintf (stderr, "Error loading shared library: %s %s\n", file, mono_error_get_message_without_fields (load_error));
mono_error_cleanup (load_error);
exit (1);
}
mono_error_assert_ok (load_error);
// Register the name with "." as this is how it will be found when embedded
internal_path = g_build_filename (".", destfname, (const char*)NULL);
mono_loader_register_module (internal_path, lib);
......
......@@ -28,22 +28,28 @@ load_profiler (MonoDl *module, const char *name, const char *desc)
{
g_assert (module);
char *err, *old_name = g_strdup_printf (OLD_INITIALIZER_NAME);
char *old_name = g_strdup_printf (OLD_INITIALIZER_NAME);
MonoProfilerInitializer func;
if (!(err = mono_dl_symbol (module, old_name, (gpointer*) &func))) {
ERROR_DECL (symbol_error);
func = (MonoProfilerInitializer)mono_dl_symbol (module, old_name, symbol_error);
mono_error_cleanup (symbol_error);
if (func) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_PROFILER, "Found old-style startup symbol '%s' for the '%s' profiler; it has not been migrated to the new API.", old_name, name);
g_free (old_name);
return FALSE;
}
g_free (err);
g_free (old_name);
char *new_name = g_strdup_printf (NEW_INITIALIZER_NAME "_%s", name);
if ((err = mono_dl_symbol (module, new_name, (gpointer *) &func))) {
g_free (err);
error_init_reuse (symbol_error);
func = (MonoProfilerInitializer)mono_dl_symbol (module, new_name, symbol_error);
mono_error_cleanup (symbol_error);
if (!func) {
g_free (new_name);
return FALSE;
}
......@@ -58,7 +64,7 @@ load_profiler (MonoDl *module, const char *name, const char *desc)
static gboolean
load_profiler_from_executable (const char *name, const char *desc)
{
char *err;
ERROR_DECL (load_error);
/*
* Some profilers (such as ours) may need to call back into the runtime
......@@ -68,35 +74,37 @@ load_profiler_from_executable (const char *name, const char *desc)
* invoking the dynamic linker which is not async-signal-safe. Passing
* MONO_DL_EAGER will ask the dynamic linker to resolve everything upfront.
*/
MonoDl *module = mono_dl_open (NULL, MONO_DL_EAGER, &err);
MonoDl *module = mono_dl_open (NULL, MONO_DL_EAGER, load_error);
if (!module) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_PROFILER, "Could not open main executable: %s", err);
g_free (err);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_PROFILER, "Could not open main executable: %s", mono_error_get_message_without_fields (load_error));
mono_error_cleanup (load_error);
return FALSE;
}
mono_error_assert_ok (load_error);
return load_profiler (module, name, desc);
}
static gboolean
load_profiler_from_directory (const char *directory, const char *libname, const char *name, const char *desc)
{
char *path, *err;
char *path;
void *iter = NULL;
while ((path = mono_dl_build_path (directory, libname, &iter))) {
MonoDl *module = mono_dl_open (path, MONO_DL_EAGER, &err);
ERROR_DECL (load_error);
MonoDl *module = mono_dl_open (path, MONO_DL_EAGER, load_error);
if (!module) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_PROFILER, "Could not open from directory \"%s\": %s", path, err);
g_free (err);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_PROFILER, "Could not open from directory \"%s\": %s", path, mono_error_get_message_without_fields (load_error));
mono_error_cleanup (load_error);
g_free (path);
continue;
}
mono_error_assert_ok (load_error);
g_free (path);
return load_profiler (module, name, desc);
}
......@@ -106,15 +114,17 @@ load_profiler_from_directory (const char *directory, const char *libname, const
static gboolean
load_profiler_from_installation (const char *libname, const char *name, const char *desc)
{
char *err;
MonoDl *module = mono_dl_open_runtime_lib (libname, MONO_DL_EAGER, &err);
ERROR_DECL (load_error);
MonoDl *module = mono_dl_open_runtime_lib (libname, MONO_DL_EAGER, load_error);
if (!module) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_PROFILER, "Could not open from installation: %s", err);
g_free (err);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_PROFILER, "Could not open from installation: %s", mono_error_get_message_without_fields (load_error));
mono_error_cleanup (load_error);
return FALSE;
}
mono_error_assert_ok (load_error);
return load_profiler (module, name, desc);
}
......
......@@ -1506,10 +1506,9 @@ find_symbol (MonoDl *module, gpointer *globals, const char *name, gpointer *valu
if (symbol != name)
g_free (symbol);
} else {
char *err = mono_dl_symbol (module, name, value);
if (err)
g_free (err);
ERROR_DECL (symbol_error);
*value = mono_dl_symbol (module, name, symbol_error);
mono_error_cleanup (symbol_error);
}
}
......@@ -1963,17 +1962,18 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer
}
found_aot_name = g_strdup (aot_name);
} else {
char *err;
aot_name = g_strdup_printf ("%s%s", assembly->image->name, MONO_SOLIB_EXT);
sofile = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
if (sofile) {
found_aot_name = g_strdup (aot_name);
} else {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "AOT: image '%s' not found: %s", aot_name, err);
g_free (err);
{
ERROR_DECL (load_error);
sofile = mono_dl_open (aot_name, MONO_DL_LAZY, load_error);
if (sofile)
found_aot_name = g_strdup (aot_name);
else
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "AOT: image '%s' not found: %s", aot_name, mono_error_get_message_without_fields (load_error));
mono_error_cleanup (load_error);
}
g_free (aot_name);
if (!sofile) {
GList *l;
......@@ -1983,19 +1983,22 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer
char *basename = g_path_get_basename (assembly->image->name);
aot_name = g_strdup_printf ("%s/%s%s", path, basename, MONO_SOLIB_EXT);
sofile = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
if (sofile) {
ERROR_DECL (load_error);
sofile = mono_dl_open (aot_name, MONO_DL_LAZY, load_error);
if (sofile)
found_aot_name = g_strdup (aot_name);
} else {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "AOT: image '%s' not found: %s", aot_name, err);
g_free (err);
}
else
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "AOT: image '%s' not found: %s", aot_name, mono_error_get_message_without_fields (load_error));
mono_error_cleanup (load_error);
g_free (basename);
g_free (aot_name);
if (sofile)
break;
}
}
if (!sofile) {
// Maybe do these on more platforms ?
#ifndef HOST_WASM
......@@ -2051,8 +2054,11 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer
}
g_free (msg);
g_free (found_aot_name);
if (sofile)
mono_dl_close (sofile);
if (sofile) {
ERROR_DECL (close_error);
mono_dl_close (sofile, close_error);
mono_error_cleanup (close_error);
}
assembly->image->aot_module = NULL;
return;
}
......
......@@ -247,15 +247,19 @@ struct MonoLLVMJIT {
if (namestr == "___bzero") {
return JITSymbol{(uint64_t)(gssize)(void*)bzero, flags};
}
ERROR_DECL (error);
auto namebuf = namestr.c_str ();
auto current = mono_dl_open (NULL, 0, NULL);
auto current = mono_dl_open (NULL, 0, error);
mono_error_cleanup (error);
g_assert (current);
auto name = namebuf[0] == '_' ? namebuf + 1 : namebuf;
void *sym = nullptr;
auto err = mono_dl_symbol (current, name, &sym);
error_init_reuse (error);
sym = mono_dl_symbol (current, name, error);
if (!sym) {
outs () << "R: " << namestr << " " << err << "\n";
outs () << "R: " << namestr << " " << mono_error_get_message_without_fields (error) << "\n";
}
mono_error_cleanup (error);
assert (sym);
return JITSymbol{(uint64_t)(gssize)sym, flags};
};
......
......@@ -74,7 +74,7 @@ mono_dl_get_system_dir (void)
#endif
void *
mono_dl_open_file (const char *file, int flags)
mono_dl_open_file (const char *file, int flags, MonoError *error)
{
#ifdef HOST_ANDROID
/* Bionic doesn't support NULL filenames */
......@@ -108,7 +108,7 @@ mono_dl_open_file (const char *file, int flags)
}
void
mono_dl_close_handle (MonoDl *module)
mono_dl_close_handle (MonoDl *module, MonoError *error)
{
dlclose (module->handle);
}
......
......@@ -77,14 +77,14 @@ mono_dl_convert_flags (int mono_flags, int native_flags)
}
void *
mono_dl_open_file (const char *file, int flags)
mono_dl_open_file (const char *file, int flags, MonoError *error)
{
// Actual dlopen is done in driver.c:wasm_dl_load()
return NULL;
}
void
mono_dl_close_handle (MonoDl *module)
mono_dl_close_handle (MonoDl *module, MonoError *error)
{
}
......
......@@ -14,6 +14,7 @@
#if defined(HOST_WIN32)
#include <mono/utils/mono-dl.h>
#include <mono/utils/mono-error-internals.h>
#include <mono/utils/mono-dl-windows-internals.h>
#include <mono/utils/mono-embed.h>
#include <mono/utils/mono-path.h>
......@@ -46,7 +47,7 @@ mono_dl_get_so_suffixes (void)
}
void*
mono_dl_open_file (const char *file, int flags)
mono_dl_open_file (const char *file, int flags, MonoError *error)
{
gpointer hModule = NULL;
if (file) {
......@@ -73,8 +74,13 @@ mono_dl_open_file (const char *file, int flags)
g_free (file_utf16);
if (!hModule)
if (!hModule) {
if (last_error == ERROR_BAD_EXE_FORMAT || last_error == ERROR_BAD_FORMAT)
mono_error_set_error (error, MONO_ERROR_BAD_IMAGE, NULL);
else
mono_error_set_error (error, MONO_ERROR_FILE_NOT_FOUND, NULL);
SetLastError (last_error);
}
} else {
#if HAVE_API_SUPPORT_WIN32_GET_MODULE_HANDLE
hModule = GetModuleHandleW (NULL);
......@@ -86,10 +92,13 @@ mono_dl_open_file (const char *file, int flags)
}
void
mono_dl_close_handle (MonoDl *module)
mono_dl_close_handle (MonoDl *module, MonoError *error)
{
if (!module->main_module)
FreeLibrary ((HMODULE)module->handle);
if (!module->main_module) {
if (FreeLibrary ((HMODULE)module->handle) == FALSE) {
mono_error_set_invalid_operation (error, NULL);
}
}
}
#if HAVE_API_SUPPORT_WIN32_ENUM_PROCESS_MODULES
......
......@@ -15,6 +15,7 @@
#include "mono/utils/mono-embed.h"
#include "mono/utils/mono-path.h"
#include "mono/utils/mono-threads-api.h"
#include "mono/utils/mono-error-internals.h"
#include <stdlib.h>
#include <stdio.h>
......@@ -173,24 +174,24 @@ fix_libc_name (const char *name)
/**
* mono_dl_open_self:
* \param error_msg pointer for error message on failure
* \param error pointer to MonoError
*
* Returns a handle to the main program, on android x86 it's not possible to
* call dl_open(null), it returns a null handle, so this function returns RTLD_DEFAULT
* handle in this platform.
* \p error points to MonoError where an error will be stored in
* case of failure. The error needs to be cleared when done using it, \c mono_error_cleanup.
* \returns a \c MonoDl pointer on success, NULL on failure.
*/
MonoDl*
mono_dl_open_self (char **error_msg)
mono_dl_open_self (MonoError *error)
{
#if defined(TARGET_ANDROID) && !defined(WIN32)
MonoDl *module;
if (error_msg)
*error_msg = NULL;
module = (MonoDl *) g_malloc (sizeof (MonoDl));
if (!module) {
if (error_msg)
*error_msg = g_strdup ("Out of memory");
mono_error_set_out_of_memory (error, NULL);
return NULL;
}
mono_refcount_init (module, NULL);
......@@ -199,7 +200,7 @@ mono_dl_open_self (char **error_msg)
module->full_name = NULL;
return module;
#else
return mono_dl_open (NULL, MONO_DL_LAZY, error_msg);
return mono_dl_open (NULL, MONO_DL_LAZY, error);
#endif
}
......@@ -207,7 +208,7 @@ mono_dl_open_self (char **error_msg)
* mono_dl_open:
* \param name name of file containing shared module
* \param flags flags
* \param error_msg pointer for error message on failure
* \param error pointer to MonoError
*
* Load the given file \p name as a shared library or dynamically loadable
* module. \p name can be NULL to indicate loading the currently executing
......@@ -215,18 +216,18 @@ mono_dl_open_self (char **error_msg)
* \p flags can have the \c MONO_DL_LOCAL bit set to avoid exporting symbols
* from the module to the shared namespace. The \c MONO_DL_LAZY bit can be set
* to lazily load the symbols instead of resolving everything at load time.
* \p error_msg points to a string where an error message will be stored in
* case of failure. The error must be released with \c g_free.
* \p error points to MonoError where an error will be stored in
* case of failure. The error needs to be cleared when done using it, \c mono_error_cleanup.
* \returns a \c MonoDl pointer on success, NULL on failure.
*/
MonoDl*
mono_dl_open (const char *name, int flags, char **error_msg)
mono_dl_open (const char *name, int flags, MonoError *error)
{
return mono_dl_open_full (name, flags, 0, error_msg);
return mono_dl_open_full (name, flags, 0, error);
}
MonoDl *
mono_dl_open_full (const char *name, int mono_flags, int native_flags, char **error_msg)
mono_dl_open_full (const char *name, int mono_flags, int native_flags, MonoError *error)
{
MonoDl *module;
void *lib;
......@@ -234,21 +235,30 @@ mono_dl_open_full (const char *name, int mono_flags, int native_flags, char **er
int lflags = mono_dl_convert_flags (mono_flags, native_flags);
char *found_name = NULL;
if (error_msg)
*error_msg = NULL;
module = (MonoDl *) g_malloc (sizeof (MonoDl));
if (!module) {
if (error_msg)
*error_msg = g_strdup ("Out of memory");
mono_error_set_out_of_memory (error, NULL);
return NULL;
}
module->main_module = name == NULL? TRUE: FALSE;
name = fix_libc_name (name);
ERROR_DECL (load_error);
// No GC safe transition because this is called early in main.c
lib = mono_dl_open_file (name, lflags);
lib = mono_dl_open_file (name, lflags, load_error);
if (!lib && !is_ok (load_error) && mono_error_get_error_code (load_error) == MONO_ERROR_BAD_IMAGE) {
char *error_msg = mono_dl_current_error_string ();
mono_error_set_error (error, MONO_ERROR_BAD_IMAGE, "%s", error_msg);
g_free (error_msg);
mono_error_cleanup (load_error);
return NULL;
}
mono_error_cleanup (load_error);
if (lib)
found_name = g_strdup (name);
......@@ -256,12 +266,9 @@ mono_dl_open_full (const char *name, int mono_flags, int native_flags, char **er
GSList *node;
for (node = fallback_handlers; node != NULL; node = node->next){
MonoDlFallbackHandler *handler = (MonoDlFallbackHandler *) node->data;
if (error_msg)
*error_msg = NULL;
lib = handler->load_func (name, lflags, error_msg, handler->user_data);
if (error_msg && *error_msg != NULL)
g_free (*error_msg);
char *error_msg = NULL;
lib = handler->load_func (name, lflags, &error_msg, handler->user_data);
g_free (error_msg);
if (lib != NULL){
dl_fallback = handler;
......@@ -278,6 +285,7 @@ mono_dl_open_full (const char *name, int mono_flags, int native_flags, char **er
/* This platform does not support dlopen */
if (name == NULL) {
g_free (module);
mono_error_set_not_supported (error, NULL);
return NULL;
}
......@@ -289,7 +297,10 @@ mono_dl_open_full (const char *name, int mono_flags, int native_flags, char **er
llname = get_dl_name_from_libtool (lname);
g_free (lname);
if (llname) {
lib = mono_dl_open_file (llname, lflags);
error_init_reuse (load_error);
lib = mono_dl_open_file (llname, lflags, load_error);
mono_error_cleanup (load_error);
if (lib)
found_name = g_strdup (llname);
#if defined (_AIX)
......@@ -304,7 +315,9 @@ mono_dl_open_full (const char *name, int mono_flags, int native_flags, char **er
/* try common suffix */
char *llaixname;
llaixname = g_strconcat (llname, "(shr_64.o)", (const char*)NULL);
lib = mono_dl_open_file (llaixname, lflags);
error_init_reuse (load_error);
lib = mono_dl_open_file (llaixname, lflags, load_error);
mono_error_cleanup (load_error);
if (lib)
found_name = g_strdup (llaixname);
/* XXX: try another suffix like (shr.o)? */
......@@ -314,9 +327,9 @@ mono_dl_open_full (const char *name, int mono_flags, int native_flags, char **er
g_free (llname);
}
if (!lib) {
if (error_msg) {
*error_msg = mono_dl_current_error_string ();
}
char *error_msg = mono_dl_current_error_string ();
mono_error_set_error (error, MONO_ERROR_FILE_NOT_FOUND, "%s", error_msg);
g_free (error_msg);
g_free (module);
return NULL;
}
......@@ -332,13 +345,14 @@ mono_dl_open_full (const char *name, int mono_flags, int native_flags, char **er
* mono_dl_symbol:
* \param module a MonoDl pointer
* \param name symbol name
* \param symbol pointer for the result value
* \param error pointer to MonoError
* Load the address of symbol \p name from the given \p module.
* The address is stored in the pointer pointed to by \p symbol.
* \returns NULL on success, an error message on failure
* \p error points to MonoError where an error will be stored in
* case of failure. The error needs to be cleared when done using it, \c mono_error_cleanup.
* \returns address to symbol on success, NULL on failure
*/
char*
mono_dl_symbol (MonoDl *module, const char *name, void **symbol)
void*
mono_dl_symbol (MonoDl *module, const char *name, MonoError *error)
{
void *sym;
char *err = NULL;
......@@ -350,23 +364,28 @@ mono_dl_symbol (MonoDl *module, const char *name, void **symbol)
}
if (sym) {
if (symbol)
*symbol = sym;
return NULL;
mono_error_assert_ok (error);
return sym;
}
if (symbol)
*symbol = NULL;
return (module->dl_fallback != NULL) ? err : mono_dl_current_error_string ();
err = (module->dl_fallback != NULL) ? err : mono_dl_current_error_string ();
mono_error_set_generic_error (error, "System", "EntryPointNotFoundException", "%s", err);
g_free (err);
return NULL;
}
/**
* mono_dl_close:
* \param module a \c MonoDl pointer
* \param error pointer to a MonoError.
* Unload the given module and free the module memory.
* \p error points to a MonoError where an error will be stored in
* case of failure. The error needs to be cleared when done using it, \c mono_error_cleanup.
* \returns \c 0 on success.
*/
void
mono_dl_close (MonoDl *module)
mono_dl_close (MonoDl *module, MonoError *error)
{
MonoDlFallbackHandler *dl_fallback = module->dl_fallback;
......@@ -374,7 +393,7 @@ mono_dl_close (MonoDl *module)
if (dl_fallback->close_func != NULL)
dl_fallback->close_func (module->handle, dl_fallback->user_data);
} else
mono_dl_close_handle (module);
mono_dl_close_handle (module, error);
g_free (module->full_name);
g_free (module);
......@@ -581,16 +600,16 @@ mono_dl_fallback_unregister (MonoDlFallbackHandler *handler)
}
static MonoDl*
try_load (const char *lib_name, char *dir, int flags, char **err)
try_load (const char *lib_name, char *dir, int flags, MonoError *error)
{
gpointer iter;
MonoDl *runtime_lib;
char *path;
iter = NULL;
*err = NULL;
while ((path = mono_dl_build_path (dir, lib_name, &iter))) {
g_free (*err);
runtime_lib = mono_dl_open (path, flags, err);
mono_error_cleanup (error);
error_init_reuse (error);
runtime_lib = mono_dl_open (path, flags, error);
g_free (path);
if (runtime_lib)
return runtime_lib;
......@@ -599,10 +618,9 @@ try_load (const char *lib_name, char *dir, int flags, char **err)
}
MonoDl*
mono_dl_open_runtime_lib (const char* lib_name, int flags, char **error_msg)
mono_dl_open_runtime_lib (const char* lib_name, int flags, MonoError *error)
{
MonoDl *runtime_lib = NULL;
*error_msg = NULL;
char *resolvedname = minipal_getexepath();
......@@ -612,33 +630,42 @@ mono_dl_open_runtime_lib (const char* lib_name, int flags, char **error_msg)
char *baseparent = NULL;
base = g_path_get_dirname (resolvedname);
name = g_strdup_printf ("%s/.libs", base);
runtime_lib = try_load (lib_name, name, flags, error_msg);
runtime_lib = try_load (lib_name, name, flags, error);
g_free (name);
if (!runtime_lib)
baseparent = g_path_get_dirname (base);
if (!runtime_lib) {
mono_error_cleanup (error);
error_init_reuse (error);
name = g_strdup_printf ("%s/lib", baseparent);
runtime_lib = try_load (lib_name, name, flags, error_msg);
runtime_lib = try_load (lib_name, name, flags, error);
g_free (name);
}
#ifdef __MACH__
if (!runtime_lib) {
mono_error_cleanup (error);
error_init_reuse (error);
name = g_strdup_printf ("%s/Libraries", baseparent);
runtime_lib = try_load (lib_name, name, flags, error_msg);
runtime_lib = try_load (lib_name, name, flags, error);
g_free (name);
}
#endif
if (!runtime_lib) {
mono_error_cleanup (error);
error_init_reuse (error);
name = g_strdup_printf ("%s/profiler/.libs", baseparent);
runtime_lib = try_load (lib_name, name, flags, error_msg);
runtime_lib = try_load (lib_name, name, flags, error);
g_free (name);
}
g_free (base);
g_free (resolvedname);
g_free (baseparent);
}
if (!runtime_lib)
runtime_lib = try_load (lib_name, NULL, flags, error_msg);
if (!runtime_lib) {
mono_error_cleanup (error);
error_init_reuse (error);
runtime_lib = try_load (lib_name, NULL, flags, error);
}
return runtime_lib;
}
......@@ -8,6 +8,7 @@
#include "mono/utils/mono-compiler.h"
#include "mono/utils/mono-dl-fallback.h"
#include "mono/utils/refcount.h"
#include "mono/utils/mono-error.h"
#ifdef TARGET_WIN32
#define MONO_SOLIB_EXT ".dll"
......@@ -29,29 +30,29 @@ typedef struct {
} MonoDl;
MONO_EXTERN_C
MonoDl* mono_dl_open (const char *name, int flags, char **error_msg);
MonoDl* mono_dl_open (const char *name, int flags, MonoError *error);
MONO_EXTERN_C
char* mono_dl_symbol (MonoDl *module, const char *name, void **symbol);
void* mono_dl_symbol (MonoDl *module, const char *name, MonoError *error);
MONO_EXTERN_C
void mono_dl_close (MonoDl *module);
void mono_dl_close (MonoDl *module, MonoError *error);
char* mono_dl_build_path (const char *directory, const char *name, void **iter);
char* mono_dl_build_platform_path (const char *directory, const char *name, void **iter);
MonoDl* mono_dl_open_runtime_lib (const char *lib_name, int flags, char **error_msg);
MonoDl* mono_dl_open_runtime_lib (const char *lib_name, int flags, MonoError *error);
MonoDl *
mono_dl_open_self (char **error_msg);
mono_dl_open_self (MonoError *error);
// This converts the MONO_DL_* enum to native flags, combines it with the other flags passed, and resolves some inconsistencies
MonoDl *
mono_dl_open_full (const char *name, int mono_flags, int native_flags, char **error_msg);
mono_dl_open_full (const char *name, int mono_flags, int native_flags, MonoError *error);
//Platform API for mono_dl
const char* mono_dl_get_so_prefix (void);
const char** mono_dl_get_so_suffixes (void);
void* mono_dl_open_file (const char *file, int flags);
void mono_dl_close_handle (MonoDl *module);
void* mono_dl_open_file (const char *file, int flags, MonoError *error);
void mono_dl_close_handle (MonoDl *module, MonoError *error);
void* mono_dl_lookup_symbol (MonoDl *module, const char *name);
int mono_dl_convert_flags (int mono_flags, int native_flags);
char* mono_dl_current_error_string (void);
......
......@@ -160,6 +160,18 @@ do { \
#define mono_error_assert_msg_ok(error, msg) g_assertf (is_ok (error), msg ", due to %s", mono_error_get_message (error))
#define mono_error_assertf_ok(error, fmt, ...) g_assertf (is_ok (error), fmt ", due to %s", __VA_ARGS__, mono_error_get_message (error))
/*
* Returns a pointer to the error message, wihtout fields, empty string if no message is available.
* Caller should NOT release returned pointer, owned by MonoError.
*/
static inline
const char *
mono_error_get_message_without_fields (MonoError *oerror)
{
MonoErrorInternal *error = (MonoErrorInternal*)oerror;
return error->full_message ? error->full_message : "";
}
void
mono_error_dup_strings (MonoError *error, gboolean dup_strings);
......
......@@ -113,7 +113,10 @@ mono_valloc_aligned (size_t length, size_t alignment, int flags, MonoMemAccountT
aligned = mono_aligned_address (mem, length, alignment);
aligned = (char*)VirtualAlloc (aligned, length, MEM_COMMIT, prot);
g_assert (aligned);
if (!aligned) {
VirtualFree (mem, 0, MEM_RELEASE);
return NULL;
}
mono_account_mem (type, (ssize_t)length);
......
......@@ -106,11 +106,19 @@ public static void DoCallTryFinally()
public static void ManualRaiseException()
{
#if WINDOWS
try
if (!TestLibrary.Utilities.IsMonoRuntime)
{
try
{
RaiseException(5, 0, 0, IntPtr.Zero);
}
catch(SEHException ex) { GC.Collect(); s_SEHExceptionCatchCalled++; }
}
else
{
RaiseException(5, 0, 0, IntPtr.Zero);
// SEH exception handling not supported on Mono.
s_SEHExceptionCatchCalled++;
}
catch(SEHException ex) { GC.Collect(); s_SEHExceptionCatchCalled++; }
#else
// TODO: test on Unix when implementing pinvoke inlining
s_SEHExceptionCatchCalled++;
......
......@@ -12,5 +12,6 @@
</ItemGroup>
<ItemGroup>
<CMakeProjectReference Include="../NativeLibraryToLoad/CMakeLists.txt" />
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
</ItemGroup>
</Project>
......@@ -51,8 +51,8 @@ public static int Main(string[] args)
TestUnmanagedCallersOnlyViaUnmanagedCalli();
TestPInvokeMarkedWithUnmanagedCallersOnly();
// Exception handling is only supported on Windows.
if (TestLibrary.Utilities.IsWindows)
// Exception handling is only supported on CoreCLR Windows.
if (TestLibrary.Utilities.IsWindows && !TestLibrary.Utilities.IsMonoRuntime)
{
TestUnmanagedCallersOnlyValid_ThrowException();
TestUnmanagedCallersOnlyViaUnmanagedCalli_ThrowException();
......
......@@ -115,9 +115,9 @@ if /i "%1" == "perfmap" (set __CreatePerfmap=1&set processedArgs=!
if /i "%1" == "Exclude" (set __Exclude=%2&set processedArgs=!processedArgs! %1 %2&shift&shift&goto Arg_Loop)
if /i "%1" == "-priority" (set __Priority=%2&shift&set processedArgs=!processedArgs! %1=%2&shift&goto Arg_Loop)
if /i "%1" == "allTargets" (set "__BuildNeedTargetArg=/p:CLRTestBuildAllTargets=%1"&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "-excludemonofailures" (set __Mono=1&set processedArgs=!processedArgs!&shift&goto Arg_Loop)
if /i "%1" == "-mono" (set __Mono=1&set processedArgs=!processedArgs!&shift&goto Arg_Loop)
if /i "%1" == "mono" (set __Mono=1&set processedArgs=!processedArgs!&shift&goto Arg_Loop)
if /i "%1" == "-excludemonofailures" (set __Mono=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "-mono" (set __Mono=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "mono" (set __Mono=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "--" (set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if [!processedArgs!]==[] (
......
......@@ -2061,6 +2061,175 @@
<ExcludeList Include = "$(XunitTestBinBase)/Interop/DisabledRuntimeMarshalling/**">
<Issue>https://github.com/dotnet/runtime/issues/64127</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/Interop/IJW/FixupCallsHostWhenLoaded/FixupCallsHostWhenLoaded/*">
<Issue>C++/CLI, IJW not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler/*">
<Issue>C++/CLI, IJW not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/Interop/IJW/ManagedCallingNative/ManagedCallingNative/*">
<Issue>C++/CLI, IJW not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/Interop/IJW/NativeCallingManaged/NativeCallingManaged/*">
<Issue>C++/CLI, IJW not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/Interop/IJW/NativeVarargs/NativeVarargsTest/*">
<Issue>C++/CLI, IJW not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/baseservices/typeequivalence/simple/Simple/*">
<Issue>Mono doesn't support type equivalence on types implemented in different assemblies</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/ArrayMarshalling/SafeArray/SafeArrayTest/*">
<Issue>Requires COM support, disabled on all Mono platforms.</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/ExecInDefAppDom/ExecInDefAppDom/*">
<Issue>CLR Runtime Host API not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/MarshalAPI/IUnknown/IUnknownTest/*">
<Issue>Requires COM support, disabled on all Mono platforms</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/MarshalAPI/IUnknown/IUnknownTestInALC/*">
<Issue>Requires COM support, disabled on all Mono platforms</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/Varargs/VarargsTest/*">
<Issue>PInvoke Varargs/ArgIterator marshalling not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/Attributes/LCID/LCIDTest/*">
<Issue>PInvoke LCIDConversionAttribute not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/NativeCallManagedComVisible/Default/DefaultTest/*">
<Issue>Requires COM support, disabled on all Mono platforms</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/NativeCallManagedComVisible/Default/DefaultTestInALC/*">
<Issue>PInvoke object marshalling not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/NativeCallManagedComVisible/AssemblyWithoutComVisible/AssemblyWithoutComVisibleTest/*">
<Issue>PInvoke object marshalling not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/NativeCallManagedComVisible/AssemblyTrue/AssemblyTrueTest/*">
<Issue>PInvoke object marshalling not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/Variant/VariantTest/*">
<Issue>PInvoke object marshalling not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/Variant/VariantTestBuiltInComDisabled/*">
<Issue>PInvoke object marshalling not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/Variant/VariantTestComWrappers/*">
<Issue>Requires COM support, disabled on all Mono platforms</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/IEnumerator/IEnumeratorTest/*">
<Issue>PInvoke IEnumerator/IEnumarable marshalling not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/StructMarshalling/ReversePInvoke/MarshalExpStruct/DelegatePInvoke/DelegatePInvokeTest/*">
<Issue>https://github.com/dotnet/runtime/issues/65695</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/StructMarshalling/ReversePInvoke/MarshalExpStruct/ReversePInvokeManaged/ReversePInvokeTest/*">
<Issue>https://github.com/dotnet/runtime/issues/65695</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/WinRT/WinRT/*">
<Issue>WinRT not supported on Mono</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/GitHub_22583/GitHub_22583/*">
<Issue>Mono doesn't support type equivalence on types implemented in different assemblies</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/CustomMarshalers/CustomMarshalersTest/*">
<Issue>Requires COM support, disabled on all Mono platforms</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/opt/Tailcall/TailcallVerifyWithPrefix/*">
<Issue>Fails on Windows Mono, test doesn't execute on none Windows platforms</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/BestFitMapping/Assembly_False_True/Assembly_False_True/*">
<Issue>Mono doesn't support interop BestFitMapping and ThrowOnUnmappableChar attributes</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/BestFitMapping/Assembly_True_True/Assembly_True_True/*">
<Issue>Mono doesn't support interop BestFitMapping and ThrowOnUnmappableChar attributes</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/BestFitMapping/Assembly_Default/Assembly_Default/*">
<Issue>Mono doesn't support interop BestFitMapping and ThrowOnUnmappableChar attributes</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/BestFitMapping/Assembly_False_False/Assembly_False_False/*">
<Issue>Mono doesn't support interop BestFitMapping and ThrowOnUnmappableChar attributes</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/PInvoke/BestFitMapping/Assembly_True_False/Assembly_True_False/*">
<Issue>Mono doesn't support interop BestFitMapping and ThrowOnUnmappableChar attributes</Issue>
</ExcludeList>
</ItemGroup>
<!-- Known failures for mono runtime on Windows -->
<ItemGroup Condition="'$(RuntimeFlavor)' == 'mono' and '$(TargetsWindows)' == 'true'" >
<ExcludeList Include = "$(XunitTestBinBase)/GC/Scenarios/Dynamo/dynamo/*">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/StringMarshalling/VBByRefStr/VBByRefStrTest/*">
<Issue>https://github.com/dotnet/runtime/issues/65698</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/callconv/PlatformDefaultMemberFunction/PlatformDefaultMemberFunctionTest/*">
<Issue>https://github.com/dotnet/runtime/issues/50440</Issue>
</ExcludeList>
<ExcludeList Include="$(XUnitTestBinBase)/JIT/Directed/callconv/CdeclMemberFunction/CdeclMemberFunctionTest/*">
<Issue>https://github.com/dotnet/runtime/issues/50440</Issue>
</ExcludeList>
<ExcludeList Include="$(XUnitTestBinBase)/JIT/Directed/callconv/StdCallMemberFunction/StdCallMemberFunctionTest/*">
<Issue>https://github.com/dotnet/runtime/issues/50440</Issue>
</ExcludeList>
<ExcludeList Include="$(XUnitTestBinBase)/JIT/Directed/callconv/ThisCall/ThisCallTest/*">
<Issue>https://github.com/dotnet/runtime/issues/50440</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/arglist/vararg_TargetWindows/*">
<Issue>https://github.com/dotnet/runtime/issues/10478</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/pinvoke/calli_excep/*">
<Issue>Mono doesn't support SEH exceptions in Mono Windows runtime exception handler (AddVectoredExceptionHandler)</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i37/*">
<Issue>https://github.com/dotnet/runtime/issues/65702</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i57/*">
<Issue>https://github.com/dotnet/runtime/issues/65702</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i67/*">
<Issue>https://github.com/dotnet/runtime/issues/65702</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i77/*">
<Issue>https://github.com/dotnet/runtime/issues/65702</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i87/*">
<Issue>https://github.com/dotnet/runtime/issues/65702</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/Methodical/eh/finallyexec/loopinfinally_do/*">
<Issue>https://github.com/dotnet/runtime/issues/65704</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/Methodical/eh/finallyexec/loopinfinally_ro/*">
<Issue>https://github.com/dotnet/runtime/issues/65704</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/GC/Regressions/v2.0-beta1/149926/149926/*">
<Issue>Triggers OOM issue on CI, pass on local test run</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/baseservices/TieredCompilation/BasicTest_DefaultMode_R2r/*">
<Issue>missing assembly</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/baseservices/TieredCompilation/BasicTest_QuickJitForLoopsOff_R2r/*">
<Issue>missing assembly</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/baseservices/TieredCompilation/BasicTest_QuickJitForLoopsOn_R2r/*">
<Issue>missing assembly</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/baseservices/TieredCompilation/BasicTest_QuickJitOff_R2r/*">
<Issue>missing assembly</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/baseservices/TieredCompilation/BasicTest_QuickJitOn_R2r/*">
<Issue>missing assembly</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)Interop/MonoAPI/MonoMono/PInvokeDetach/*">
<Issue>https://github.com/dotnet/runtime/issues/67047</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)Interop/MonoAPI/MonoMono/Thunks/*">
<Issue>https://github.com/dotnet/runtime/issues/67047</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)Interop/MonoAPI/MonoMono/InstallEHCallback/*">
<Issue>https://github.com/dotnet/runtime/issues/67047</Issue>
</ExcludeList>
</ItemGroup>
<!-- Known failures for mono runtime on *all* architectures/operating systems in interpreter runtime mode -->
......@@ -3779,9 +3948,6 @@
<ExcludeList Include = "$(XunitTestBinBase)/GC/Scenarios/Dynamo/dynamo/*">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/baseservices/TieredCompilation/BasicTest_DefaultMode_R2r/*">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/baseservices/TieredCompilation/BasicTest_DefaultMode_R2r/*">
<Issue>missing assembly</Issue>
</ExcludeList>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册