Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2003-12-07 22:20:10 +0300
committerTon Roosendaal <ton@blender.org>2003-12-07 22:20:10 +0300
commita6ed4d2d86725c85bb906a4569ebdcfbb0712f4c (patch)
treebd227b789aa05a7a2132ab94e6a6ec45f962eb1a /source/blender/blenlib/intern/dynlib.c
parent3ae81a528505783858de036ea629a5fcf206da49 (diff)
- Solution for fixing plugins, which now runs without -ldl at OSX 10.2/3
Code from Peter O'Gorman <ogorman@users.sourceforge.net which has been credited in the source. Basically the dlopen() and dlerror() calls have been recreated wrapping the standard OSX methods. Names used are osxdlopen() and osxdlerror(). So no naming conflict will occur.
Diffstat (limited to 'source/blender/blenlib/intern/dynlib.c')
-rw-r--r--source/blender/blenlib/intern/dynlib.c205
1 files changed, 202 insertions, 3 deletions
diff --git a/source/blender/blenlib/intern/dynlib.c b/source/blender/blenlib/intern/dynlib.c
index 77a01f310a6..d2e8f80757b 100644
--- a/source/blender/blenlib/intern/dynlib.c
+++ b/source/blender/blenlib/intern/dynlib.c
@@ -23,9 +23,11 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
+ * The Original Code is: all of this file, with exception of below:
*
- * Contributor(s): none yet.
+ * Contributor(s): Peter O'Gorman
+ * The functions osxdlopen() and osxerror()
+ * are Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -102,7 +104,203 @@ void PIL_dynlib_close(PILdynlib *lib) {
free(lib);
}
-#else /* Unix & MacOS X */
+#else
+#ifdef __APPLE__ /* MacOS X */
+
+#include <mach-o/dyld.h>
+#include <dlfcn.h>
+#include <stdarg.h>
+
+#define ERR_STR_LEN 256
+
+struct PILdynlib {
+ void *handle;
+};
+
+char *osxerror(int setget, const char *str, ...)
+{
+ static char errstr[ERR_STR_LEN];
+ static int err_filled = 0;
+ char *retval;
+ NSLinkEditErrors ler;
+ int lerno;
+ const char *dylderrstr;
+ const char *file;
+ va_list arg;
+ if (setget <= 0)
+ {
+ va_start(arg, str);
+ strncpy(errstr, "dlsimple: ", ERR_STR_LEN);
+ vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
+ va_end(arg);
+ /* We prefer to use the dyld error string if setget is 0 */
+ if (setget == 0) {
+ NSLinkEditError(&ler, &lerno, &file, &dylderrstr);
+ printf("dyld: %s\n",dylderrstr);
+ if (dylderrstr && strlen(dylderrstr))
+ strncpy(errstr,dylderrstr,ERR_STR_LEN);
+ }
+ err_filled = 1;
+ retval = NULL;
+ }
+ else
+ {
+ if (!err_filled)
+ retval = NULL;
+ else
+ retval = errstr;
+ err_filled = 0;
+ }
+ return retval;
+}
+
+void *osxdlopen(const char *path, int mode)
+{
+ void *module = 0;
+ NSObjectFileImage ofi = 0;
+ NSObjectFileImageReturnCode ofirc;
+ static int (*make_private_module_public) (NSModule module) = 0;
+ unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE;
+
+ /* If we got no path, the app wants the global namespace, use -1 as the marker
+ in this case */
+ if (!path)
+ return (void *)-1;
+
+ /* Create the object file image, works for things linked with the -bundle arg to ld */
+ ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
+ switch (ofirc)
+ {
+ case NSObjectFileImageSuccess:
+ /* It was okay, so use NSLinkModule to link in the image */
+ if (!(mode & RTLD_LAZY)) flags += NSLINKMODULE_OPTION_BINDNOW;
+ module = NSLinkModule(ofi, path,flags);
+ /* Don't forget to destroy the object file image, unless you like leaks */
+ NSDestroyObjectFileImage(ofi);
+ /* If the mode was global, then change the module, this avoids
+ multiply defined symbol errors to first load private then make
+ global. Silly, isn't it. */
+ if ((mode & RTLD_GLOBAL))
+ {
+ if (!make_private_module_public)
+ {
+ _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",
+ (unsigned long *)&make_private_module_public);
+ }
+ make_private_module_public(module);
+ }
+ break;
+ case NSObjectFileImageInappropriateFile:
+ /* It may have been a dynamic library rather than a bundle, try to load it */
+ module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
+ break;
+ case NSObjectFileImageFailure:
+ osxerror(0,"Object file setup failure : \"%s\"", path);
+ return 0;
+ case NSObjectFileImageArch:
+ osxerror(0,"No object for this architecture : \"%s\"", path);
+ return 0;
+ case NSObjectFileImageFormat:
+ osxerror(0,"Bad object file format : \"%s\"", path);
+ return 0;
+ case NSObjectFileImageAccess:
+ osxerror(0,"Can't read object file : \"%s\"", path);
+ return 0;
+ }
+ if (!module)
+ osxerror(0, "Can not open \"%s\"", path);
+ return module;
+}
+
+PILdynlib *PIL_dynlib_open(char *name) {
+ void *handle= osxdlopen(name, RTLD_LAZY);
+
+ if (handle) {
+ PILdynlib *lib= malloc(sizeof(*lib));
+ lib->handle= handle;
+
+ return lib;
+ } else {
+ return NULL;
+ }
+}
+
+void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname)
+{
+ int sym_len = strlen(symname);
+ void *value = NULL;
+ char *malloc_sym = NULL;
+ NSSymbol *nssym = 0;
+ malloc_sym = malloc(sym_len + 2);
+ if (malloc_sym)
+ {
+ sprintf(malloc_sym, "_%s", symname);
+ /* If the lib->handle is -1, if is the app global context */
+ if (lib->handle == (void *)-1)
+ {
+ /* Global context, use NSLookupAndBindSymbol */
+ if (NSIsSymbolNameDefined(malloc_sym))
+ {
+ nssym = NSLookupAndBindSymbol(malloc_sym);
+ }
+ }
+ /* Now see if the lib->handle is a struch mach_header* or not, use NSLookupSymbol in image
+ for libraries, and NSLookupSymbolInModule for bundles */
+ else
+ {
+ /* Check for both possible magic numbers depending on x86/ppc byte order */
+ if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
+ (((struct mach_header *)lib->handle)->magic == MH_CIGAM))
+ {
+ if (NSIsSymbolNameDefinedInImage((struct mach_header *)lib->handle, malloc_sym))
+ {
+ nssym = NSLookupSymbolInImage((struct mach_header *)lib->handle,
+ malloc_sym,
+ NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
+ | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
+ }
+
+ }
+ else
+ {
+ nssym = NSLookupSymbolInModule(lib->handle, malloc_sym);
+ }
+ }
+ if (!nssym)
+ {
+ osxerror(0, "symname \"%s\" Not found", symname);
+ }
+ value = NSAddressOfSymbol(nssym);
+ free(malloc_sym);
+ }
+ else
+ {
+ osxerror(-1, "Unable to allocate memory");
+ }
+ return value;
+}
+
+char *PIL_dynlib_get_error_as_string(PILdynlib* lib)
+{
+ return osxerror(1, (char *)NULL);
+}
+
+void PIL_dynlib_close(PILdynlib *lib)
+{
+ if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
+ (((struct mach_header *)lib->handle)->magic == MH_CIGAM))
+ {
+ osxerror(-1, "Can't remove dynamic libraries on darwin");
+ }
+ if (!NSUnLinkModule(lib->handle, 0))
+ {
+ osxerror(0, "unable to unlink module %s", NSNameOfModule(lib->handle));
+ }
+
+ free(lib);
+}
+
+#else /* Unix */
#include <dlfcn.h>
@@ -138,3 +336,4 @@ void PIL_dynlib_close(PILdynlib *lib) {
}
#endif
+#endif