applied patch from David Schleef <ds@schleef.org> which implements a
[platform/upstream/glib.git] / gmodule / gmodule-dyld.c
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
23 #include <mach-o/dyld.h>
24
25 static gpointer self_module = GINT_TO_POINTER (1);
26
27 static gpointer
28 _g_module_open (const gchar *file_name,
29                 gboolean     bind_lazy,
30                 gboolean     bind_local)
31 {
32   NSObjectFileImage image;
33   NSObjectFileImageReturnCode ret;
34   NSModule module;
35   unsigned long options;
36   char *msg;
37
38   ret = NSCreateObjectFileImageFromFile (file_name, &image);
39   if (ret != NSObjectFileImageSuccess)
40     {
41       switch (ret)
42         {
43         case NSObjectFileImageInappropriateFile:
44         case NSObjectFileImageFormat:
45           msg = g_strdup_printf ("%s is not a loadable module", file_name);
46           break;
47
48         case NSObjectFileImageArch:
49           msg = g_strdup_printf ("%s is not built for this architecture",
50                                  file_name);
51           break;
52
53         case NSObjectFileImageAccess:
54           if (access (file_name, F_OK) == 0)
55             msg = g_strdup_printf ("%s: permission denied", file_name);
56           else
57             msg = g_strdup_printf ("%s: no such file or directory", file_name);
58           break;
59
60         default:
61           msg = g_strdup_printf ("unknown error for %s", file_name);
62           break;
63         }
64
65       g_module_set_error (msg);
66       g_free (msg);
67       return NULL;
68     }
69
70   options = NSLINKMODULE_OPTION_RETURN_ON_ERROR;
71   if (bind_local)
72     options |= NSLINKMODULE_OPTION_PRIVATE;
73   if (!bind_lazy)
74     options |= NSLINKMODULE_OPTION_BINDNOW;
75   module = NSLinkModule (image, file_name, options);
76   NSDestroyObjectFileImage (image);
77   if (!module)
78     {
79       NSLinkEditErrors c;
80       int error_number;
81       const char *file, *error;
82
83       NSLinkEditError (&c, &error_number, &file, &error);
84       msg = g_strdup_printf ("could not link %s: %s", file_name, error);
85       g_module_set_error (msg);
86       g_free (msg);
87       return NULL;
88     }
89
90   return module;
91 }
92
93 static gpointer
94 _g_module_self (void)
95 {
96   return &self_module;
97 }
98
99 static void
100 _g_module_close (gpointer handle,
101                  gboolean is_unref)
102 {
103   if (handle == &self_module)
104     return;
105
106   if (!NSUnLinkModule (handle, 0))
107     g_module_set_error ("could not unlink module");
108 }
109
110 static gpointer
111 _g_module_symbol (gpointer     handle,
112                   const gchar *symbol_name)
113 {
114   NSSymbol sym;
115   char *msg;
116
117   if (handle == &self_module)
118     {
119       if (NSIsSymbolNameDefined (symbol_name))
120         sym = NSLookupAndBindSymbol (symbol_name);
121       else
122         sym = NULL;
123     }
124   else
125     sym = NSLookupSymbolInModule (handle, symbol_name);
126
127   if (!sym)
128     {
129       msg = g_strdup_printf ("no such symbol %s", symbol_name);
130       g_module_set_error (msg);
131       g_free (msg);
132       return NULL;
133     }
134
135   return NSAddressOfSymbol (sym);
136 }
137
138 static gchar*
139 _g_module_build_path (const gchar *directory,
140                       const gchar *module_name)
141 {
142   if (directory && *directory)
143     {
144       if (strncmp (module_name, "lib", 3) == 0)
145         return g_strconcat (directory, "/", module_name, NULL);
146       else
147         return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL);
148     }
149   else if (strncmp (module_name, "lib", 3) == 0)
150     return g_strdup (module_name);
151   else
152     return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL);
153 }