Home | History | Annotate | Download | only in gmodule
      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 
     26 static gpointer self_module = GINT_TO_POINTER (1);
     27 
     28 static 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 
     94 static gpointer
     95 _g_module_self (void)
     96 {
     97   return &self_module;
     98 }
     99 
    100 static 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 
    111 static 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 
    139 static 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