[utils] Cleanup the dynamic loading code and split the platform specific code into...
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 27 Jan 2015 22:58:19 +0000 (17:58 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 27 Jan 2015 22:59:33 +0000 (17:59 -0500)
This makes the actual code much simpler to read and work with as we can clearly see what's done on each
target.

mono/utils/Makefile.am
mono/utils/mono-dl-darwin.c [new file with mode: 0644]
mono/utils/mono-dl-posix.c [new file with mode: 0644]
mono/utils/mono-dl-windows.c [new file with mode: 0644]
mono/utils/mono-dl.c
mono/utils/mono-dl.h

index 20d89c5ea7ccff41a8fdb9c074d15d08366bfca1..286ef7dae2178f7b4d7b6d0a4dae8b6786ff1e96 100644 (file)
@@ -22,6 +22,9 @@ monoutils_sources = \
        mono-counters.c         \
        mono-compiler.h         \
        mono-dl.c               \
+       mono-dl-windows.c       \
+       mono-dl-darwin.c        \
+       mono-dl-posix.c         \
        mono-dl.h               \
        mono-internal-hash.c    \
        mono-internal-hash.h    \
diff --git a/mono/utils/mono-dl-darwin.c b/mono/utils/mono-dl-darwin.c
new file mode 100644 (file)
index 0000000..b1cd30f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * mono-dl.c: Interface to the dynamic linker
+ *
+ * Author:
+ *    Mono Team (http://www.mono-project.com)
+ *
+ * Copyright 2001-2004 Ximian, Inc.
+ * Copyright 2004-2009 Novell, Inc.
+ */
+#include <config.h>
+
+#if defined (TARGET_MACH)
+
+#include "mono/utils/mono-dl.h"
+#include "mono/utils/mono-embed.h"
+#include "mono/utils/mono-path.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <glib.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <mach-o/dyld.h>
+
+const char *
+mono_dl_get_so_prefix (void)
+{
+       return "lib";
+}
+const char **
+mono_dl_get_so_suffixes (void)
+{
+       static const char *suffixes[] = {
+               ".dylib",
+               ".so",
+               ".bundle",
+               "",
+       };
+       return suffixes;
+}
+
+int
+mono_dl_get_executable_path (char *buf, int buflen)
+{
+       uint32_t bsize = buflen;
+       if (_NSGetExecutablePath (buf, &bsize) == 0)
+               return strlen (buf);
+       return -1;
+}
+
+#endif
diff --git a/mono/utils/mono-dl-posix.c b/mono/utils/mono-dl-posix.c
new file mode 100644 (file)
index 0000000..d6da89d
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * mono-dl.c: Interface to the dynamic linker
+ *
+ * Author:
+ *    Mono Team (http://www.mono-project.com)
+ *
+ * Copyright 2001-2004 Ximian, Inc.
+ * Copyright 2004-2009 Novell, Inc.
+ */
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if defined(_POSIX_VERSION)
+
+#include "mono/utils/mono-dl.h"
+#include "mono/utils/mono-embed.h"
+#include "mono/utils/mono-path.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <glib.h>
+#include <dlfcn.h>
+
+#if !defined (TARGET_MACH)
+const char *
+mono_dl_get_so_prefix (void)
+{
+       return "lib";
+}
+const char **
+mono_dl_get_so_suffixes (void)
+{
+       static const char *suffixes[] = {
+               ".so",
+               "",
+       };
+       return suffixes;
+}
+
+int
+mono_dl_get_executable_path (char *buf, int buflen)
+{
+       return readlink ("/proc/self/exe", buf, buflen - 1;
+}
+#endif
+
+void *
+mono_dl_open_file (const char *file, int flags)
+{
+#ifdef PLATFORM_ANDROID
+       /* Bionic doesn't support NULL filenames */
+       if (!name)
+               return NULL;
+#endif
+       return dlopen (file, flags);
+}
+
+void
+mono_dl_close_handle (MonoDl *module)
+{
+       dlclose (module->handle);
+}
+
+void*
+mono_dl_lookup_symbol (MonoDl *module, const char *name)
+{
+       return dlsym (module->handle, name);
+}
+
+int
+mono_dl_convert_flags (int flags)
+{
+       int lflags = flags & MONO_DL_LOCAL? 0: RTLD_GLOBAL;
+
+       if (flags & MONO_DL_LAZY)
+               lflags |= RTLD_LAZY;
+       else
+               lflags |= RTLD_NOW;
+       return lflags;
+}
+
+char*
+mono_dl_current_error_string (void)
+{
+       return g_strdup (dlerror ());
+}
+
+#endif
diff --git a/mono/utils/mono-dl-windows.c b/mono/utils/mono-dl-windows.c
new file mode 100644 (file)
index 0000000..5dabce4
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * mono-dl.c: Interface to the dynamic linker
+ *
+ * Author:
+ *    Mono Team (http://www.mono-project.com)
+ *
+ * Copyright 2001-2004 Ximian, Inc.
+ * Copyright 2004-2009 Novell, Inc.
+ */
+#include <config.h>
+
+#if defined(HOST_WIN32)
+
+#include "mono/utils/mono-dl.h"
+#include "mono/utils/mono-embed.h"
+#include "mono/utils/mono-path.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <glib.h>
+
+#include <windows.h>
+#include <psapi.h>
+
+
+const char*
+mono_dl_get_so_prefix (void)
+{
+       return "";
+}
+
+const char**
+mono_dl_get_so_suffixes (void)
+{
+       static const char *suffixes[] = {
+               ".dll",
+               "",
+       };
+       return suffixes;
+}
+
+void*
+mono_dl_open_file (const char *file, int flags)
+{
+       gpointer hModule = NULL;
+       if (file) {
+               gunichar2* file_utf16 = g_utf8_to_utf16 (file, strlen (file), NULL, NULL, NULL);
+               guint last_sem = SetErrorMode (SEM_FAILCRITICALERRORS);
+               guint32 last_error = 0;
+
+               hModule = LoadLibrary (file_utf16);
+               if (!hModule)
+                       last_error = GetLastError ();
+
+               SetErrorMode (last_sem);
+               g_free (file_utf16);
+
+               if (!hModule)
+                       SetLastError (last_error);
+       } else {
+               hModule = GetModuleHandle (NULL);
+       }
+       return hModule;
+}
+
+void
+mono_dl_close_handle (MonoDl *module)
+{
+       if (!module->main_module)
+               FreeLibrary (module->handle);
+}
+
+void*
+mono_dl_lookup_symbol (MonoDl *module, const char *symbol_name)
+{
+       HMODULE *modules;
+       DWORD buffer_size = sizeof (HMODULE) * 1024;
+       DWORD needed, i;
+       gpointer proc = NULL;
+
+       /* get the symbol directly from the specified module */
+       if (!module->main_module)
+               return GetProcAddress (module->handle, symbol_name);
+
+       /* get the symbol from the main module */
+       proc = GetProcAddress (module->handle, symbol_name);
+       if (proc != NULL)
+               return proc;
+
+       /* get the symbol from the loaded DLLs */
+       modules = (HMODULE *) g_malloc (buffer_size);
+       if (modules == NULL)
+               return NULL;
+
+       if (!EnumProcessModules (GetCurrentProcess (), modules,
+                                buffer_size, &needed)) {
+               g_free (modules);
+               return NULL;
+       }
+
+       /* check whether the supplied buffer was too small, realloc, retry */
+       if (needed > buffer_size) {
+               g_free (modules);
+
+               buffer_size = needed;
+               modules = (HMODULE *) g_malloc (buffer_size);
+
+               if (modules == NULL)
+                       return NULL;
+
+               if (!EnumProcessModules (GetCurrentProcess (), modules,
+                                        buffer_size, &needed)) {
+                       g_free (modules);
+                       return NULL;
+               }
+       }
+
+       for (i = 0; i < needed / sizeof (HANDLE); i++) {
+               proc = GetProcAddress (modules [i], symbol_name);
+               if (proc != NULL) {
+                       g_free (modules);
+                       return proc;
+               }
+       }
+
+       g_free (modules);
+       return NULL;
+}
+
+int
+mono_dl_convert_flags (int flags)
+{
+       return 0;
+}
+
+char*
+mono_dl_current_error_string (void)
+{
+       char* ret = NULL;
+       wchar_t* buf = NULL;
+       DWORD code = GetLastError ();
+
+       if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+               code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL))
+       {
+               ret = g_utf16_to_utf8 (buf, wcslen(buf), NULL, NULL, NULL);
+               LocalFree (buf);
+       } else {
+               g_assert_not_reached ();
+       }
+       return ret;
+}
+
+int
+mono_dl_get_executable_path (char *buf, int buflen)
+{
+       return -1; //TODO
+}
+
+#endif
index c13c68a042151e52ee55c6082426189fd35270fe..64b939961744fad2e62189cc57ca1e64b28817a4 100644 (file)
 #include <string.h>
 #include <glib.h>
 
-#ifdef TARGET_WIN32
-#define SOPREFIX ""
-static const char suffixes [][5] = {
-       ".dll"
-};
-#elif defined(__APPLE__)
-#define SOPREFIX "lib"
-static const char suffixes [][8] = {
-       ".dylib",
-       ".so",
-       ".bundle"
-};
-#else
-#define SOPREFIX "lib"
-static const char suffixes [][4] = {
-       ".so"
-};
-#endif
-
-#ifdef TARGET_WIN32
-
-#include <windows.h>
-#include <psapi.h>
-
-#define SO_HANDLE_TYPE HMODULE
-#define LL_SO_OPEN(file,flags) w32_load_module ((file), (flags))
-#define LL_SO_CLOSE(module) do { if (!(module)->main_module) FreeLibrary ((module)->handle); } while (0)
-#define LL_SO_SYMBOL(module, name) w32_find_symbol ((module), (name))
-#define LL_SO_TRFLAGS(flags) 0
-#define LL_SO_ERROR() w32_dlerror ()
-
-#elif defined (HAVE_DL_LOADER)
-
-#include <dlfcn.h>
-#include <unistd.h>
-
-#ifdef __MACH__
-#include <mach-o/dyld.h>
-#endif
-
-
-#ifndef RTLD_LAZY
-#define RTLD_LAZY       1
-#endif  /* RTLD_LAZY */
-
-#define SO_HANDLE_TYPE void*
-#define LL_SO_OPEN(file,flags) dlopen ((file), (flags))
-#define LL_SO_CLOSE(module) dlclose ((module)->handle)
-#define LL_SO_SYMBOL(module, name) dlsym ((module)->handle, (name))
-#define LL_SO_TRFLAGS(flags) convert_flags ((flags))
-#define LL_SO_ERROR() g_strdup (dlerror ())
-
-static int
-convert_flags (int flags)
-{
-       int lflags = flags & MONO_DL_LOCAL? 0: RTLD_GLOBAL;
-
-       if (flags & MONO_DL_LAZY)
-               lflags |= RTLD_LAZY;
-       else
-               lflags |= RTLD_NOW;
-       return lflags;
-}
-
-#else
-/* no dynamic loader supported */
-#define SO_HANDLE_TYPE void*
-#define LL_SO_OPEN(file,flags) NULL
-#define LL_SO_CLOSE(module) 
-#define LL_SO_SYMBOL(module, name) NULL
-#define LL_SO_TRFLAGS(flags) (flags)
-#define LL_SO_ERROR() g_strdup ("No support for dynamic loader")
-
-#endif
-
-static GSList *fallback_handlers;
-
 struct MonoDlFallbackHandler {
        MonoDlFallbackLoad load_func;
        MonoDlFallbackSymbol symbol_func;
        MonoDlFallbackClose close_func;
        void *user_data;
 };
-       
-struct _MonoDl {
-       SO_HANDLE_TYPE handle;
-       int main_module;
-
-       /* If not NULL, use the methods in MonoDlFallbackHandler instead of the LL_* methods */
-       MonoDlFallbackHandler *dl_fallback;
-};
-
-#ifdef TARGET_WIN32
-
-static char*
-w32_dlerror (void)
-{
-       char* ret = NULL;
-       wchar_t* buf = NULL;
-       DWORD code = GetLastError ();
 
-       if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
-               code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL))
-       {
-               ret = g_utf16_to_utf8 (buf, wcslen(buf), NULL, NULL, NULL);
-               LocalFree (buf);
-       } else {
-               g_assert_not_reached ();
-       }
-       return ret;
-}
-
-static gpointer
-w32_find_symbol (MonoDl *module, const gchar *symbol_name)
-{
-       HMODULE *modules;
-       DWORD buffer_size = sizeof (HMODULE) * 1024;
-       DWORD needed, i;
-       gpointer proc = NULL;
-
-       /* get the symbol directly from the specified module */
-       if (!module->main_module)
-               return GetProcAddress (module->handle, symbol_name);
-
-       /* get the symbol from the main module */
-       proc = GetProcAddress (module->handle, symbol_name);
-       if (proc != NULL)
-               return proc;
-
-       /* get the symbol from the loaded DLLs */
-       modules = (HMODULE *) g_malloc (buffer_size);
-       if (modules == NULL)
-               return NULL;
-
-       if (!EnumProcessModules (GetCurrentProcess (), modules,
-                                buffer_size, &needed)) {
-               g_free (modules);
-               return NULL;
-       }
-
-       /* check whether the supplied buffer was too small, realloc, retry */
-       if (needed > buffer_size) {
-               g_free (modules);
-
-               buffer_size = needed;
-               modules = (HMODULE *) g_malloc (buffer_size);
-
-               if (modules == NULL)
-                       return NULL;
-
-               if (!EnumProcessModules (GetCurrentProcess (), modules,
-                                        buffer_size, &needed)) {
-                       g_free (modules);
-                       return NULL;
-               }
-       }
-
-       for (i = 0; i < needed / sizeof (HANDLE); i++) {
-               proc = GetProcAddress (modules [i], symbol_name);
-               if (proc != NULL) {
-                       g_free (modules);
-                       return proc;
-               }
-       }
-
-       g_free (modules);
-       return NULL;
-}
-
-
-static gpointer
-w32_load_module (const char* file, int flags)
-{
-       gpointer hModule = NULL;
-       if (file) {
-               gunichar2* file_utf16 = g_utf8_to_utf16 (file, strlen (file), NULL, NULL, NULL);
-               guint last_sem = SetErrorMode (SEM_FAILCRITICALERRORS);
-               guint32 last_error = 0;
-
-               hModule = LoadLibrary (file_utf16);
-               if (!hModule)
-                       last_error = GetLastError ();
-
-               SetErrorMode (last_sem);
-               g_free (file_utf16);
-
-               if (!hModule)
-                       SetLastError (last_error);
-       } else {
-               hModule = GetModuleHandle (NULL);
-       }
-       return hModule;
-}
-#endif
+static GSList *fallback_handlers;
 
 /*
  * read a value string from line with any of the following formats:
@@ -320,7 +134,7 @@ mono_dl_open (const char *name, int flags, char **error_msg)
        MonoDl *module;
        void *lib;
        MonoDlFallbackHandler *dl_fallback = NULL;
-       int lflags = LL_SO_TRFLAGS (flags);
+       int lflags = mono_dl_convert_flags (flags);
 
        if (error_msg)
                *error_msg = NULL;
@@ -333,15 +147,8 @@ mono_dl_open (const char *name, int flags, char **error_msg)
        }
        module->main_module = name == NULL? TRUE: FALSE;
 
-#ifdef PLATFORM_ANDROID
-       /* Bionic doesn't support NULL filenames */
-       if (!name)
-               lib = NULL;
-       else
-               lib = LL_SO_OPEN (name, lflags);
-#else
-       lib = LL_SO_OPEN (name, lflags);
-#endif
+       lib = mono_dl_open_file (name, lflags);
+
        if (!lib) {
                GSList *node;
                for (node = fallback_handlers; node != NULL; node = node->next){
@@ -378,12 +185,12 @@ mono_dl_open (const char *name, int flags, char **error_msg)
                llname = get_dl_name_from_libtool (lname);
                g_free (lname);
                if (llname) {
-                       lib = LL_SO_OPEN (llname, lflags);
+                       lib = mono_dl_open_file (llname, lflags);
                        g_free (llname);
                }
                if (!lib) {
                        if (error_msg) {
-                               *error_msg = LL_SO_ERROR ();
+                               *error_msg = mono_dl_current_error_string ();
                        }
                        free (module);
                        return NULL;
@@ -419,11 +226,11 @@ mono_dl_symbol (MonoDl *module, const char *name, void **symbol)
                        char *usname = malloc (strlen (name) + 2);
                        *usname = '_';
                        strcpy (usname + 1, name);
-                       sym = LL_SO_SYMBOL (module, usname);
+                       sym = mono_dl_lookup_symbol (module, usname);
                        free (usname);
                }
 #else
-               sym = LL_SO_SYMBOL (module, name);
+               sym = mono_dl_lookup_symbol (module, name);
 #endif
        }
 
@@ -434,7 +241,7 @@ mono_dl_symbol (MonoDl *module, const char *name, void **symbol)
        }
        if (symbol)
                *symbol = NULL;
-       return (module->dl_fallback != NULL) ? err :  LL_SO_ERROR ();
+       return (module->dl_fallback != NULL) ? err :  mono_dl_current_error_string ();
 }
 
 /**
@@ -454,7 +261,7 @@ mono_dl_close (MonoDl *module)
                if (dl_fallback->close_func != NULL)
                        dl_fallback->close_func (module->handle, dl_fallback->user_data);
        } else
-               LL_SO_CLOSE (module);
+               mono_dl_close_handle (module);
        
        free (module);
 }
@@ -504,16 +311,16 @@ mono_dl_build_path (const char *directory, const char *name, void **iter)
                suffixlen = 0;
        } else {
                idx--;
-               if (idx >= G_N_ELEMENTS (suffixes))
+               if (mono_dl_get_so_suffixes () [idx] == '\0')
                        return NULL;
                first_call = FALSE;
-               suffix = suffixes [idx];
+               suffix = mono_dl_get_so_suffixes () [idx];
                suffixlen = strlen (suffix);
        }
 
-       prlen = strlen (SOPREFIX);
-       if (prlen && strncmp (name, SOPREFIX, prlen) != 0)
-               prefix = SOPREFIX;
+       prlen = strlen (mono_dl_get_so_prefix ());
+       if (prlen && strncmp (name, mono_dl_get_so_prefix (), prlen) != 0)
+               prefix = mono_dl_get_so_prefix ();
        else
                prefix = "";
 
@@ -563,9 +370,6 @@ mono_dl_fallback_unregister (MonoDlFallbackHandler *handler)
        g_free (handler);
 }
 
-
-#if defined (HAVE_DL_LOADER)
-
 static MonoDl*
 try_load (const char *lib_name, char *dir, int flags, char **err)
 {
@@ -590,17 +394,10 @@ mono_dl_open_runtime_lib (const char* lib_name, int flags, char **error_msg)
        MonoDl *runtime_lib = NULL;
        char buf [4096];
        int binl;
-       binl = readlink ("/proc/self/exe", buf, sizeof (buf)-1);
        *error_msg = NULL;
 
-#ifdef __MACH__
-       if (binl == -1) {
-               uint32_t bsize = sizeof (buf);
-               if (_NSGetExecutablePath (buf, &bsize) == 0) {
-                       binl = strlen (buf);
-               }
-       }
-#endif
+       binl = mono_dl_get_executable_path (buf, sizeof (buf));
+
        if (binl != -1) {
                char *base;
                char *resolvedname, *name;
@@ -632,13 +429,3 @@ mono_dl_open_runtime_lib (const char* lib_name, int flags, char **error_msg)
 
        return runtime_lib;
 }
-
-#else
-
-MonoDl*
-mono_dl_open_runtime_lib (const char* lib_name, int flags, char **error_msg)
-{
-       return NULL;
-}
-
-#endif
index 205916b6d4bb34f1f67dc8d78b16dc03475f5822..4b972ef62f0a4cfcbabfbd6965945a4cfaa0c6fd 100644 (file)
 #define MONO_SOLIB_EXT ".so"
 #endif
 
-typedef struct _MonoDl MonoDl;
+typedef struct {
+       void *handle;
+       int main_module;
+
+       /* If not NULL, use the methods in MonoDlFallbackHandler instead of the LL_* methods */
+       MonoDlFallbackHandler *dl_fallback;
+} MonoDl;
+
 
 MonoDl*     mono_dl_open       (const char *name, int flags, char **error_msg) MONO_LLVM_INTERNAL;
 char*       mono_dl_symbol     (MonoDl *module, const char *name, void **symbol) MONO_LLVM_INTERNAL;
@@ -26,5 +33,16 @@ char*       mono_dl_build_path (const char *directory, const char *name, void **
 
 MonoDl*     mono_dl_open_runtime_lib (const char *lib_name, int flags, char **error_msg) MONO_INTERNAL;
 
+
+//Platform API for mono_dl
+const char* mono_dl_get_so_prefix (void) MONO_INTERNAL;
+const char** mono_dl_get_so_suffixes (void) MONO_INTERNAL;
+void* mono_dl_open_file (const char *file, int flags) MONO_INTERNAL;
+void mono_dl_close_handle (MonoDl *module) MONO_INTERNAL;
+void* mono_dl_lookup_symbol (MonoDl *module, const char *name) MONO_INTERNAL;
+int mono_dl_convert_flags (int flags) MONO_INTERNAL;
+char* mono_dl_current_error_string (void) MONO_INTERNAL;
+int mono_dl_get_executable_path (char *buf, int buflen) MONO_INTERNAL;
+
 #endif /* __MONO_UTILS_DL_H__ */