symbian-qemu-0.9.1-12/python-2.6.1/Modules/_ctypes/darwin/dlfcn_simple.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2 Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
       
     3 
       
     4 Permission is hereby granted, free of charge, to any person obtaining
       
     5 a copy of this software and associated documentation files (the
       
     6 "Software"), to deal in the Software without restriction, including
       
     7 without limitation the rights to use, copy, modify, merge, publish,
       
     8 distribute, sublicense, and/or sell copies of the Software, and to
       
     9 permit persons to whom the Software is furnished to do so, subject to
       
    10 the following conditions:
       
    11 
       
    12 The above copyright notice and this permission notice shall be
       
    13 included in all copies or substantial portions of the Software.
       
    14 
       
    15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
    16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
    17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
       
    18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
       
    19 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
       
    20 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
       
    21 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
       
    22 */
       
    23 
       
    24 
       
    25 /* Just to prove that it isn't that hard to add Mac calls to your code :)
       
    26    This works with pretty much everything, including kde3 xemacs and the gimp,
       
    27    I'd guess that it'd work in at least 95% of cases, use this as your starting
       
    28    point, rather than the mess that is dlfcn.c, assuming that your code does not
       
    29    require ref counting or symbol lookups in dependent libraries
       
    30 */
       
    31 
       
    32 #include <stdio.h>
       
    33 #include <stdlib.h>
       
    34 #include <string.h>
       
    35 #include <sys/types.h>
       
    36 #include <sys/stat.h>
       
    37 #include <stdarg.h>
       
    38 #include <limits.h>
       
    39 #include <mach-o/dyld.h>
       
    40 #include <AvailabilityMacros.h>
       
    41 #include "dlfcn.h"
       
    42 
       
    43 #ifdef CTYPES_DARWIN_DLFCN
       
    44 
       
    45 #define ERR_STR_LEN 256
       
    46 
       
    47 #ifndef MAC_OS_X_VERSION_10_3
       
    48 #define MAC_OS_X_VERSION_10_3 1030
       
    49 #endif
       
    50 
       
    51 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
       
    52 #define DARWIN_HAS_DLOPEN
       
    53 extern void * dlopen(const char *path, int mode) __attribute__((weak_import));
       
    54 extern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import));
       
    55 extern const char * dlerror(void) __attribute__((weak_import));
       
    56 extern int dlclose(void * handle) __attribute__((weak_import));
       
    57 extern int dladdr(const void *, Dl_info *) __attribute__((weak_import));
       
    58 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */
       
    59 
       
    60 #ifndef DARWIN_HAS_DLOPEN
       
    61 #define dlopen darwin_dlopen
       
    62 #define dlsym darwin_dlsym
       
    63 #define dlerror darwin_dlerror
       
    64 #define dlclose darwin_dlclose
       
    65 #define dladdr darwin_dladdr
       
    66 #endif
       
    67 
       
    68 void * (*ctypes_dlopen)(const char *path, int mode);
       
    69 void * (*ctypes_dlsym)(void * handle, const char *symbol);
       
    70 const char * (*ctypes_dlerror)(void);
       
    71 int (*ctypes_dlclose)(void * handle);
       
    72 int (*ctypes_dladdr)(const void *, Dl_info *);
       
    73 
       
    74 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
       
    75 /* Mac OS X 10.3+ has dlopen, so strip all this dead code to avoid warnings */
       
    76 
       
    77 static void *dlsymIntern(void *handle, const char *symbol);
       
    78 
       
    79 static const char *error(int setget, const char *str, ...);
       
    80 
       
    81 /* Set and get the error string for use by dlerror */
       
    82 static const char *error(int setget, const char *str, ...)
       
    83 {
       
    84 	static char errstr[ERR_STR_LEN];
       
    85 	static int err_filled = 0;
       
    86 	const char *retval;
       
    87 	va_list arg;
       
    88 	if (setget == 0)
       
    89 	{
       
    90 		va_start(arg, str);
       
    91 		strncpy(errstr, "dlcompat: ", ERR_STR_LEN);
       
    92 		vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
       
    93 		va_end(arg);
       
    94 		err_filled = 1;
       
    95 		retval = NULL;
       
    96 	}
       
    97 	else
       
    98 	{
       
    99 		if (!err_filled)
       
   100 			retval = NULL;
       
   101 		else
       
   102 			retval = errstr;
       
   103 		err_filled = 0;
       
   104 	}
       
   105 	return retval;
       
   106 }
       
   107 
       
   108 /* darwin_dlopen */
       
   109 static void *darwin_dlopen(const char *path, int mode)
       
   110 {
       
   111 	void *module = 0;
       
   112 	NSObjectFileImage ofi = 0;
       
   113 	NSObjectFileImageReturnCode ofirc;
       
   114 
       
   115 	/* If we got no path, the app wants the global namespace, use -1 as the marker
       
   116 	   in this case */
       
   117 	if (!path)
       
   118 		return (void *)-1;
       
   119 
       
   120 	/* Create the object file image, works for things linked with the -bundle arg to ld */
       
   121 	ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
       
   122 	switch (ofirc)
       
   123 	{
       
   124 		case NSObjectFileImageSuccess:
       
   125 			/* It was okay, so use NSLinkModule to link in the image */
       
   126 			module = NSLinkModule(ofi, path,
       
   127 								  NSLINKMODULE_OPTION_RETURN_ON_ERROR
       
   128 								  | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE
       
   129 								  | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW);
       
   130 			NSDestroyObjectFileImage(ofi);
       
   131 			break;
       
   132 		case NSObjectFileImageInappropriateFile:
       
   133 			/* It may have been a dynamic library rather than a bundle, try to load it */
       
   134 			module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
       
   135 			break;
       
   136 		default:
       
   137 			/* God knows what we got */
       
   138 			error(0, "Can not open \"%s\"", path);
       
   139 			return 0;
       
   140 	}
       
   141 	if (!module)
       
   142 		error(0, "Can not open \"%s\"", path);
       
   143 	return module;
       
   144 
       
   145 }
       
   146 
       
   147 /* dlsymIntern is used by dlsym to find the symbol */
       
   148 static void *dlsymIntern(void *handle, const char *symbol)
       
   149 {
       
   150 	NSSymbol nssym = 0;
       
   151 	/* If the handle is -1, if is the app global context */
       
   152 	if (handle == (void *)-1)
       
   153 	{
       
   154 		/* Global context, use NSLookupAndBindSymbol */
       
   155 		if (NSIsSymbolNameDefined(symbol))
       
   156 		{
       
   157 			nssym = NSLookupAndBindSymbol(symbol);
       
   158 		}
       
   159 
       
   160 	}
       
   161 	/* Now see if the handle is a struch mach_header* or not, use NSLookupSymbol in image
       
   162 	   for libraries, and NSLookupSymbolInModule for bundles */
       
   163 	else
       
   164 	{
       
   165 		/* Check for both possible magic numbers depending on x86/ppc byte order */
       
   166 		if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
       
   167 			(((struct mach_header *)handle)->magic == MH_CIGAM))
       
   168 		{
       
   169 			if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, symbol))
       
   170 			{
       
   171 				nssym = NSLookupSymbolInImage((struct mach_header *)handle,
       
   172 											  symbol,
       
   173 											  NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
       
   174 											  | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
       
   175 			}
       
   176 
       
   177 		}
       
   178 		else
       
   179 		{
       
   180 			nssym = NSLookupSymbolInModule(handle, symbol);
       
   181 		}
       
   182 	}
       
   183 	if (!nssym)
       
   184 	{
       
   185 		error(0, "Symbol \"%s\" Not found", symbol);
       
   186 		return NULL;
       
   187 	}
       
   188 	return NSAddressOfSymbol(nssym);
       
   189 }
       
   190 
       
   191 static const char *darwin_dlerror(void)
       
   192 {
       
   193 	return error(1, (char *)NULL);
       
   194 }
       
   195 
       
   196 static int darwin_dlclose(void *handle)
       
   197 {
       
   198 	if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
       
   199 		(((struct mach_header *)handle)->magic == MH_CIGAM))
       
   200 	{
       
   201 		error(0, "Can't remove dynamic libraries on darwin");
       
   202 		return 0;
       
   203 	}
       
   204 	if (!NSUnLinkModule(handle, 0))
       
   205 	{
       
   206 		error(0, "unable to unlink module %s", NSNameOfModule(handle));
       
   207 		return 1;
       
   208 	}
       
   209 	return 0;
       
   210 }
       
   211 
       
   212 
       
   213 /* dlsym, prepend the underscore and call dlsymIntern */
       
   214 static void *darwin_dlsym(void *handle, const char *symbol)
       
   215 {
       
   216 	static char undersym[257];	/* Saves calls to malloc(3) */
       
   217 	int sym_len = strlen(symbol);
       
   218 	void *value = NULL;
       
   219 	char *malloc_sym = NULL;
       
   220 
       
   221 	if (sym_len < 256)
       
   222 	{
       
   223 		snprintf(undersym, 256, "_%s", symbol);
       
   224 		value = dlsymIntern(handle, undersym);
       
   225 	}
       
   226 	else
       
   227 	{
       
   228 		malloc_sym = malloc(sym_len + 2);
       
   229 		if (malloc_sym)
       
   230 		{
       
   231 			sprintf(malloc_sym, "_%s", symbol);
       
   232 			value = dlsymIntern(handle, malloc_sym);
       
   233 			free(malloc_sym);
       
   234 		}
       
   235 		else
       
   236 		{
       
   237 			error(0, "Unable to allocate memory");
       
   238 		}
       
   239 	}
       
   240 	return value;
       
   241 }
       
   242 
       
   243 static int darwin_dladdr(const void *handle, Dl_info *info) {
       
   244 	return 0;
       
   245 }
       
   246 #endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
       
   247 
       
   248 #if __GNUC__ < 4
       
   249 #pragma CALL_ON_LOAD ctypes_dlfcn_init
       
   250 #else
       
   251 static void __attribute__ ((constructor)) ctypes_dlfcn_init(void);
       
   252 static
       
   253 #endif
       
   254 void ctypes_dlfcn_init(void) {
       
   255 	if (dlopen != NULL) {
       
   256 		ctypes_dlsym = dlsym;
       
   257 		ctypes_dlopen = dlopen;
       
   258 		ctypes_dlerror = dlerror;
       
   259 		ctypes_dlclose = dlclose;
       
   260 		ctypes_dladdr = dladdr;
       
   261 	} else {
       
   262 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
       
   263 		ctypes_dlsym = darwin_dlsym;
       
   264 		ctypes_dlopen = darwin_dlopen;
       
   265 		ctypes_dlerror = darwin_dlerror;
       
   266 		ctypes_dlclose = darwin_dlclose;
       
   267 		ctypes_dladdr = darwin_dladdr;
       
   268 #endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
       
   269 	}
       
   270 }
       
   271 
       
   272 #endif /* CTYPES_DARWIN_DLFCN */