Merge remote branch 'gvdb/master'
[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 #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 }