• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
_g_module_open(const gchar * file_name,gboolean bind_lazy,gboolean bind_local)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
_g_module_self(void)95 _g_module_self (void)
96 {
97   return &self_module;
98 }
99 
100 static void
_g_module_close(gpointer handle,gboolean is_unref)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
_g_module_symbol(gpointer handle,const gchar * symbol_name)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*
_g_module_build_path(const gchar * directory,const gchar * module_name)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