1/* GMODULE - GLIB wrapper code for dynamic module loading 2 * Copyright (C) 1998, 2000 Tim Janik 3 * 4 * dyld (Darwin) GMODULE implementation 5 * Copyright (C) 2001 Dan Winship 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the 19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 * Boston, MA 02111-1307, USA. 21 */ 22#include "config.h" 23 24#include <mach-o/dyld.h> 25 26static gpointer self_module = GINT_TO_POINTER (1); 27 28static gpointer 29_g_module_open (const gchar *file_name, 30 gboolean bind_lazy, 31 gboolean bind_local) 32{ 33 NSObjectFileImage image; 34 NSObjectFileImageReturnCode ret; 35 NSModule module; 36 unsigned long options; 37 char *msg; 38 39 ret = NSCreateObjectFileImageFromFile (file_name, &image); 40 if (ret != NSObjectFileImageSuccess) 41 { 42 switch (ret) 43 { 44 case NSObjectFileImageInappropriateFile: 45 case NSObjectFileImageFormat: 46 msg = g_strdup_printf ("%s is not a loadable module", file_name); 47 break; 48 49 case NSObjectFileImageArch: 50 msg = g_strdup_printf ("%s is not built for this architecture", 51 file_name); 52 break; 53 54 case NSObjectFileImageAccess: 55 if (access (file_name, F_OK) == 0) 56 msg = g_strdup_printf ("%s: permission denied", file_name); 57 else 58 msg = g_strdup_printf ("%s: no such file or directory", file_name); 59 break; 60 61 default: 62 msg = g_strdup_printf ("unknown error for %s", file_name); 63 break; 64 } 65 66 g_module_set_error (msg); 67 g_free (msg); 68 return NULL; 69 } 70 71 options = NSLINKMODULE_OPTION_RETURN_ON_ERROR; 72 if (bind_local) 73 options |= NSLINKMODULE_OPTION_PRIVATE; 74 if (!bind_lazy) 75 options |= NSLINKMODULE_OPTION_BINDNOW; 76 module = NSLinkModule (image, file_name, options); 77 NSDestroyObjectFileImage (image); 78 if (!module) 79 { 80 NSLinkEditErrors c; 81 int error_number; 82 const char *file, *error; 83 84 NSLinkEditError (&c, &error_number, &file, &error); 85 msg = g_strdup_printf ("could not link %s: %s", file_name, error); 86 g_module_set_error (msg); 87 g_free (msg); 88 return NULL; 89 } 90 91 return module; 92} 93 94static gpointer 95_g_module_self (void) 96{ 97 return &self_module; 98} 99 100static void 101_g_module_close (gpointer handle, 102 gboolean is_unref) 103{ 104 if (handle == &self_module) 105 return; 106 107 if (!NSUnLinkModule (handle, 0)) 108 g_module_set_error ("could not unlink module"); 109} 110 111static gpointer 112_g_module_symbol (gpointer handle, 113 const gchar *symbol_name) 114{ 115 NSSymbol sym; 116 char *msg; 117 118 if (handle == &self_module) 119 { 120 if (NSIsSymbolNameDefined (symbol_name)) 121 sym = NSLookupAndBindSymbol (symbol_name); 122 else 123 sym = NULL; 124 } 125 else 126 sym = NSLookupSymbolInModule (handle, symbol_name); 127 128 if (!sym) 129 { 130 msg = g_strdup_printf ("no such symbol %s", symbol_name); 131 g_module_set_error (msg); 132 g_free (msg); 133 return NULL; 134 } 135 136 return NSAddressOfSymbol (sym); 137} 138 139static gchar* 140_g_module_build_path (const gchar *directory, 141 const gchar *module_name) 142{ 143 if (directory && *directory) 144 { 145 if (strncmp (module_name, "lib", 3) == 0) 146 return g_strconcat (directory, "/", module_name, NULL); 147 else 148 return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL); 149 } 150 else if (strncmp (module_name, "lib", 3) == 0) 151 return g_strdup (module_name); 152 else 153 return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL); 154} 155