4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file, with exception of below:
28 * Contributor(s): Peter O'Gorman
29 * The functions osxdlopen() and osxerror()
30 * are Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
32 * ***** END GPL/BL DUAL LICENSE BLOCK *****
35 #include "../PIL_dynlib.h"
41 #if !defined(CHAR_MAX)
46 * XXX, should use mallocN so we can see
47 * handle's not being released. fixme zr
58 PILdynlib *PIL_dynlib_open(char *name) {
59 void *handle= LoadLibrary(name);
62 PILdynlib *lib= malloc(sizeof(*lib));
71 void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname) {
72 return GetProcAddress(lib->handle, symname);
75 char *PIL_dynlib_get_error_as_string(PILdynlib* lib) {
78 /* if lib is NULL reset the last error code */
80 SetLastError(ERROR_SUCCESS);
86 static char buf[1024];
88 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
91 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
101 void PIL_dynlib_close(PILdynlib *lib) {
102 FreeLibrary(lib->handle);
108 #ifdef __APPLE__ /* MacOS X */
110 #include <mach-o/dyld.h>
114 #define ERR_STR_LEN 256
120 char *osxerror(int setget, const char *str, ...)
122 static char errstr[ERR_STR_LEN];
123 static int err_filled = 0;
125 NSLinkEditErrors ler;
127 const char *dylderrstr;
133 strncpy(errstr, "dlsimple: ", ERR_STR_LEN);
134 vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
136 /* We prefer to use the dyld error string if setget is 0 */
138 NSLinkEditError(&ler, &lerno, &file, &dylderrstr);
139 printf("dyld: %s\n",dylderrstr);
140 if (dylderrstr && strlen(dylderrstr))
141 strncpy(errstr,dylderrstr,ERR_STR_LEN);
157 void *osxdlopen(const char *path, int mode)
160 NSObjectFileImage ofi = 0;
161 NSObjectFileImageReturnCode ofirc;
162 static int (*make_private_module_public) (NSModule module) = 0;
163 unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE;
165 /* If we got no path, the app wants the global namespace, use -1 as the marker
170 /* Create the object file image, works for things linked with the -bundle arg to ld */
171 ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
174 case NSObjectFileImageSuccess:
175 /* It was okay, so use NSLinkModule to link in the image */
176 if (!(mode & RTLD_LAZY)) flags += NSLINKMODULE_OPTION_BINDNOW;
177 module = NSLinkModule(ofi, path,flags);
178 /* Don't forget to destroy the object file image, unless you like leaks */
179 NSDestroyObjectFileImage(ofi);
180 /* If the mode was global, then change the module, this avoids
181 multiply defined symbol errors to first load private then make
182 global. Silly, isn't it. */
183 if ((mode & RTLD_GLOBAL))
185 if (!make_private_module_public)
187 _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",
188 (unsigned long *)&make_private_module_public);
190 make_private_module_public(module);
193 case NSObjectFileImageInappropriateFile:
194 /* It may have been a dynamic library rather than a bundle, try to load it */
195 module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
197 case NSObjectFileImageFailure:
198 osxerror(0,"Object file setup failure : \"%s\"", path);
200 case NSObjectFileImageArch:
201 osxerror(0,"No object for this architecture : \"%s\"", path);
203 case NSObjectFileImageFormat:
204 osxerror(0,"Bad object file format : \"%s\"", path);
206 case NSObjectFileImageAccess:
207 osxerror(0,"Can't read object file : \"%s\"", path);
211 osxerror(0, "Can not open \"%s\"", path);
215 PILdynlib *PIL_dynlib_open(char *name) {
216 void *handle= osxdlopen(name, RTLD_LAZY);
219 PILdynlib *lib= malloc(sizeof(*lib));
228 void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname)
230 int sym_len = strlen(symname);
232 char *malloc_sym = NULL;
234 malloc_sym = malloc(sym_len + 2);
237 sprintf(malloc_sym, "_%s", symname);
238 /* If the lib->handle is -1, if is the app global context */
239 if (lib->handle == (void *)-1)
241 /* Global context, use NSLookupAndBindSymbol */
242 if (NSIsSymbolNameDefined(malloc_sym))
244 nssym = NSLookupAndBindSymbol(malloc_sym);
247 /* Now see if the lib->handle is a struch mach_header* or not, use NSLookupSymbol in image
248 for libraries, and NSLookupSymbolInModule for bundles */
251 /* Check for both possible magic numbers depending on x86/ppc byte order */
252 if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
253 (((struct mach_header *)lib->handle)->magic == MH_CIGAM))
255 if (NSIsSymbolNameDefinedInImage((struct mach_header *)lib->handle, malloc_sym))
257 nssym = NSLookupSymbolInImage((struct mach_header *)lib->handle,
259 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
260 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
266 nssym = NSLookupSymbolInModule(lib->handle, malloc_sym);
271 osxerror(0, "symname \"%s\" Not found", symname);
273 value = NSAddressOfSymbol(nssym);
278 osxerror(-1, "Unable to allocate memory");
283 char *PIL_dynlib_get_error_as_string(PILdynlib* lib)
285 return osxerror(1, (char *)NULL);
288 void PIL_dynlib_close(PILdynlib *lib)
290 if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
291 (((struct mach_header *)lib->handle)->magic == MH_CIGAM))
293 osxerror(-1, "Can't remove dynamic libraries on darwin");
295 if (!NSUnLinkModule(lib->handle, 0))
297 osxerror(0, "unable to unlink module %s", NSNameOfModule(lib->handle));
311 PILdynlib *PIL_dynlib_open(char *name) {
312 void *handle= dlopen(name, RTLD_LAZY);
315 PILdynlib *lib= malloc(sizeof(*lib));
324 void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname) {
325 return dlsym(lib->handle, symname);
328 char *PIL_dynlib_get_error_as_string(PILdynlib* lib) {
332 void PIL_dynlib_close(PILdynlib *lib) {
333 dlclose(lib->handle);