[BTLS]: Add the native BTLS sources.
[mono.git] / mono / metadata / icall.c
index e1af074c4b459028a909b6e5e75165829ebe74a6..27bafb33291f7151a889412b11f11102bf7f4883 100644 (file)
@@ -43,7 +43,9 @@
 #include <mono/metadata/threadpool-ms-io.h>
 #include <mono/metadata/monitor.h>
 #include <mono/metadata/reflection.h>
+#include <mono/metadata/image-internals.h>
 #include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/exception-internals.h>
@@ -83,6 +85,9 @@
 #include <mono/metadata/file-mmap.h>
 #include <mono/metadata/seq-points-data.h>
 #include <mono/metadata/handle.h>
+#include <mono/metadata/w32mutex.h>
+#include <mono/metadata/w32semaphore.h>
+#include <mono/metadata/w32event.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/monobitset.h>
 #include <mono/utils/mono-time.h>
 #include <sys/utsname.h>
 #endif
 
+#if HAVE_BTLS
+#include <btls/btls-ssl.h>
+#include <btls/btls-bio.h>
+#include <btls/btls-error.h>
+#include <btls/btls-key.h>
+#include <btls/btls-pkcs12.h>
+#include <btls/btls-x509-crl.h>
+#include <btls/btls-x509-chain.h>
+#include <btls/btls-x509-lookup.h>
+#include <btls/btls-x509-lookup-mono.h>
+#include <btls/btls-x509-name.h>
+#include <btls/btls-x509-revoked.h>
+#include <btls/btls-x509-store-ctx.h>
+#include <btls/btls-x509-verify-param.h>
+#endif
+
 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
 
 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
 
-TYPED_HANDLE_DECL (MonoReflectionType);
-
 /* Lazy class loading functions */
 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
@@ -983,11 +1002,6 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStac
        /* if we have no info we are optimistic and assume there is enough room */
        if (!stack_addr)
                return TRUE;
-#ifdef HOST_WIN32
-       // FIXME: Windows dynamically extends the stack, so stack_addr might be close
-       // to the current sp
-       return TRUE;
-#endif
        current = (guint8 *)&stack_addr;
        if (current > stack_addr) {
                if ((current - stack_addr) < min_size)
@@ -2638,37 +2652,38 @@ ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
        return ret;
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_RuntimeType_get_Name (MonoReflectionType *type)
+ICALL_EXPORT MonoStringHandle
+ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
 {
-       MonoDomain *domain = mono_domain_get (); 
-       MonoClass *klass = mono_class_from_mono_type (type->type);
+       MonoDomain *domain = mono_domain_get ();
+       MonoType *type = MONO_HANDLE_RAW(reftype)->type; 
+       MonoClass *klass = mono_class_from_mono_type (type);
 
-       if (type->type->byref) {
+       if (type->byref) {
                char *n = g_strdup_printf ("%s&", klass->name);
-               MonoString *res = mono_string_new (domain, n);
+               MonoStringHandle res = mono_string_new_handle (domain, n, error);
 
                g_free (n);
 
                return res;
        } else {
-               return mono_string_new (domain, klass->name);
+               return mono_string_new_handle (domain, klass->name, error);
        }
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_RuntimeType_get_Namespace (MonoReflectionType *type)
+ICALL_EXPORT MonoStringHandle
+ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
 {
        MonoDomain *domain = mono_domain_get (); 
-       MonoClass *klass = mono_class_from_mono_type (type->type);
+       MonoClass *klass = mono_class_from_mono_type_handle (type);
 
        while (klass->nested_in)
                klass = klass->nested_in;
 
        if (klass->name_space [0] == '\0')
-               return NULL;
+               return NULL_HANDLE_STRING;
        else
-               return mono_string_new (domain, klass->name_space);
+               return mono_string_new_handle (domain, klass->name_space, error);
 }
 
 ICALL_EXPORT gint32
@@ -4542,15 +4557,12 @@ ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname,
        return result;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (assembly); 
-       MonoString *res;
-
-       res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
-
-       return res;
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
+       MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
+       return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
 }
 
 ICALL_EXPORT MonoBoolean
@@ -4559,12 +4571,13 @@ ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly
        return assembly->assembly->ref_only;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (assembly); 
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
+       MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
 
-       return mono_string_new (domain, assembly->assembly->image->version);
+       return mono_string_new_handle (domain, assembly->image->version, error);
 }
 
 ICALL_EXPORT MonoReflectionMethod*
@@ -4619,8 +4632,8 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAss
        return result;
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Reflection_Assembly_GetAotId ()
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
 {
        int i;
        guint8 aotid_sum = 0;
@@ -4636,8 +4649,11 @@ ves_icall_System_Reflection_Assembly_GetAotId ()
 
        if (aotid_sum == 0)
                return NULL;
-       
-       return mono_string_new (domain, mono_guid_to_string((guint8*) aotid));
+
+       gchar *guid = mono_guid_to_string((guint8*) aotid);
+       MonoStringHandle res = mono_string_new_handle (domain, guid, error);
+       g_free (guid);
+       return res;
 }
 
 static MonoObject*
@@ -4827,8 +4843,8 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflection
                g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
                file_idx = impl >> MONO_IMPLEMENTATION_BITS;
 
-               module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
-               if (!module)
+               module = mono_image_load_file_for_image_checked (assembly->assembly->image, file_idx, &error);
+               if (mono_error_set_pending_exception (&error) || !module)
                        return NULL;
        }
        else
@@ -5028,7 +5044,9 @@ ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
                        mono_array_setref (res, j, rm);
                }
                else {
-                       MonoImage *m = mono_image_load_file_for_image (image, i + 1);
+                       MonoImage *m = mono_image_load_file_for_image_checked (image, i + 1, &error);
+                       if (mono_error_set_pending_exception (&error))
+                               return NULL;
                        if (!m) {
                                MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
                                mono_set_pending_exception (mono_get_exception_file_not_found2 (NULL, fname));
@@ -5219,7 +5237,7 @@ ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gbool
                return NULL_HANDLE_STRING;
        }
 
-       res = mono_string_new_handle (domain, name);
+       res = mono_string_new_handle (domain, name, error);
        g_free (name);
 
        return res;
@@ -5552,7 +5570,9 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
        /* Append data from all modules in the assembly */
        for (i = 0; i < table->rows; ++i) {
                if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
-                       MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
+                       MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, &error);
+                       if (mono_error_set_pending_exception (&error))
+                               return NULL;
                        if (loaded_image) {
                                MonoArray *ex2;
                                MonoArray *res2;
@@ -5703,13 +5723,14 @@ ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
                mono_image_close (module->image);*/
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (module); 
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
+       MonoImage *image = MONO_HANDLE_RAW (refmodule)->image;
 
-       g_assert (module->image);
-       return mono_string_new (domain, module->image->guid);
+       g_assert (image);
+       return mono_string_new_handle (domain, image->guid, error);
 }
 
 ICALL_EXPORT gpointer
@@ -6549,27 +6570,20 @@ ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
 #endif
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
 {
-       MonoError error;
        const gchar *value;
-       gchar *utf8_name;
 
-       if (name == NULL)
-               return NULL;
+       if (utf8_name == NULL)
+               return NULL_HANDLE_STRING;
 
-       utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
        value = g_getenv (utf8_name);
 
-       g_free (utf8_name);
-
        if (value == 0)
-               return NULL;
+               return NULL_HANDLE_STRING;
        
-       return mono_string_new (mono_domain_get (), value);
+       return mono_string_new_handle (mono_domain_get (), value, error);
 }
 
 /*
@@ -6768,10 +6782,10 @@ ves_icall_System_Environment_Exit (int result)
        exit (result);
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Environment_GetGacPath (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_GetGacPath (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
+       return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
 }
 
 ICALL_EXPORT MonoString*
@@ -6872,10 +6886,10 @@ ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
        return result;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Environment_InternalGetHome (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_InternalGetHome (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), g_get_home_dir ());
+       return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
 }
 
 static const char *encodings [] = {
@@ -6946,7 +6960,7 @@ ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
        
        if (strstr (codepage, "utf_8") != NULL)
                *int_code_page |= 0x10000000;
-       free (codepage);
+       g_free (codepage);
        
        if (want_name && *int_code_page == -1)
                return mono_string_new (mono_domain_get (), cset);
@@ -7125,10 +7139,10 @@ ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClas
        }
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_IO_get_temp_path (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_IO_get_temp_path (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
+       return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
 }
 
 #ifndef PLATFORM_NO_DRIVEINFO
@@ -7246,17 +7260,18 @@ get_bundled_app_config (void)
        return mono_string_new (mono_domain_get (), app_config);
 }
 
-static MonoString *
-get_bundled_machine_config (void)
+/* this is an icall */
+static MonoStringHandle
+get_bundled_machine_config (MonoError *error)
 {
        const gchar *machine_config;
 
        machine_config = mono_get_machine_config ();
 
        if (!machine_config)
-               return NULL;
+               return NULL_HANDLE_STRING;
 
-       return mono_string_new (mono_domain_get (), machine_config);
+       return mono_string_new_handle (mono_domain_get (), machine_config, error);
 }
 
 ICALL_EXPORT MonoString *
@@ -7394,6 +7409,7 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
                klass = klass->generic_class->container_class;
        }
 
+retry:
        if (definition) {
                /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
                for (parent = klass->parent; parent != NULL; parent = parent->parent) {
@@ -7480,14 +7496,38 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
        result = klass->vtable [slot];
        if (result == NULL) {
                /* It is an abstract method */
+               gboolean found = FALSE;
                gpointer iter = NULL;
-               while ((result = mono_class_get_methods (klass, &iter)))
-                       if (result->slot == slot)
+               while ((result = mono_class_get_methods (klass, &iter))) {
+                       if (result->slot == slot) {
+                               found = TRUE;
                                break;
+                       }
+               }
+               /* found might be FALSE if we looked in an abstract class
+                * that doesn't override an abstract method of its
+                * parent: 
+                *   abstract class Base {
+                *     public abstract void Foo ();
+                *   }
+                *   abstract class Derived : Base { }
+                *   class Child : Derived {
+                *     public override void Foo () { }
+                *  }
+                *
+                *  if m was Child.Foo and we ask for the base method,
+                *  then we get here with klass == Derived and found == FALSE
+                */
+               /* but it shouldn't be the case that if we're looking
+                * for the definition and didn't find a result; the
+                * loop above should've taken us as far as we could
+                * go! */
+               g_assert (!(definition && !found));
+               if (!found)
+                       goto retry;
        }
 
-       if (result == NULL)
-               return m;
+       g_assert (result != NULL);
 
        ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
        mono_error_set_pending_exception (&error);
@@ -8053,6 +8093,16 @@ ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint3
        return SetPriorityClass (handle, priorityClass);
 }
 
+ICALL_EXPORT MonoBoolean
+ves_icall_Mono_Btls_Provider_IsSupported (void)
+{
+#if HAVE_BTLS
+       return TRUE;
+#else
+       return FALSE;
+#endif
+}
+
 #ifndef DISABLE_ICALL_TABLES
 
 #define ICALL_TYPE(id,name,first)