1
2 /* Support for dynamic loading of extension modules on Mac OS X
3 ** All references to "NeXT" are for historical reasons.
4 */
5
6 #include "Python.h"
7 #include "importdl.h"
8
9 #include <mach-o/dyld.h>
10
11 const char *_PyImport_DynLoadFiletab[] = {".so", NULL};
12
13 /*
14 ** Python modules are Mach-O MH_BUNDLE files. The best way to load these
15 ** is each in a private namespace, so you can load, say, a module bar and a
16 ** module foo.bar. If we load everything in the global namespace the two
17 ** initbar() symbols will conflict.
18 ** However, it seems some extension packages depend upon being able to access
19 ** each others' global symbols. There seems to be no way to eat our cake and
20 ** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour
21 ** you get.
22 */
23
24 #ifdef USE_DYLD_GLOBAL_NAMESPACE
25 #define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR
26 #else
27 #define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
28 NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
29 #endif
_PyImport_FindSharedFuncptr(const char * prefix,const char * shortname,const char * pathname,FILE * fp)30 dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix,
31 const char *shortname,
32 const char *pathname, FILE *fp)
33 {
34 dl_funcptr p = NULL;
35 char funcname[258];
36 NSObjectFileImageReturnCode rc;
37 NSObjectFileImage image;
38 NSModule newModule;
39 NSSymbol theSym;
40 const char *errString;
41 char errBuf[512];
42
43 PyOS_snprintf(funcname, sizeof(funcname), "_%.20s_%.200s", prefix, shortname);
44
45 #ifdef USE_DYLD_GLOBAL_NAMESPACE
46 if (NSIsSymbolNameDefined(funcname)) {
47 theSym = NSLookupAndBindSymbol(funcname);
48 p = (dl_funcptr)NSAddressOfSymbol(theSym);
49 return p;
50 }
51 #endif
52 rc = NSCreateObjectFileImageFromFile(pathname, &image);
53 switch(rc) {
54 default:
55 case NSObjectFileImageFailure:
56 case NSObjectFileImageFormat:
57 /* for these a message is printed on stderr by dyld */
58 errString = "Can't create object file image";
59 break;
60 case NSObjectFileImageSuccess:
61 errString = NULL;
62 break;
63 case NSObjectFileImageInappropriateFile:
64 errString = "Inappropriate file type for dynamic loading";
65 break;
66 case NSObjectFileImageArch:
67 errString = "Wrong CPU type in object file";
68 break;
69 case NSObjectFileImageAccess:
70 errString = "Can't read object file (no access)";
71 break;
72 }
73 if (errString == NULL) {
74 newModule = NSLinkModule(image, pathname, LINKOPTIONS);
75 if (newModule == NULL) {
76 int errNo;
77 const char *fileName, *moreErrorStr;
78 NSLinkEditErrors c;
79 NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
80 PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
81 fileName, moreErrorStr);
82 errString = errBuf;
83 }
84 }
85 if (errString != NULL) {
86 PyErr_SetString(PyExc_ImportError, errString);
87 return NULL;
88 }
89 #ifdef USE_DYLD_GLOBAL_NAMESPACE
90 if (!NSIsSymbolNameDefined(funcname)) {
91 /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
92 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
93 PyErr_Format(PyExc_ImportError,
94 "Loaded module does not contain symbol %.200s",
95 funcname);
96 return NULL;
97 }
98 theSym = NSLookupAndBindSymbol(funcname);
99 #else
100 theSym = NSLookupSymbolInModule(newModule, funcname);
101 if ( theSym == NULL ) {
102 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
103 PyErr_Format(PyExc_ImportError,
104 "Loaded module does not contain symbol %.200s",
105 funcname);
106 return NULL;
107 }
108 #endif
109 p = (dl_funcptr)NSAddressOfSymbol(theSym);
110 return p;
111 }
112