blob: cabf9b96637c7769f056e5096e394e6b6261b52f [file] [log] [blame]
Guido van Rossum22a1d361999-12-20 21:18:49 +00001
Jack Jansend4c76bf2002-02-01 16:01:05 +00002/* Support for dynamic loading of extension modules on Mac OS X
3** All references to "NeXT" are for historical reasons.
4*/
Guido van Rossum22a1d361999-12-20 21:18:49 +00005
6#include "Python.h"
7#include "importdl.h"
8
Guido van Rossum22a1d361999-12-20 21:18:49 +00009#include <mach-o/dyld.h>
10
Guido van Rossum22a1d361999-12-20 21:18:49 +000011const struct filedescr _PyImport_DynLoadFiletab[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000012 {".so", "rb", C_EXTENSION},
13 {"module.so", "rb", C_EXTENSION},
14 {0, 0}
Guido van Rossum22a1d361999-12-20 21:18:49 +000015};
16
Jack Jansend4c76bf2002-02-01 16:01:05 +000017/*
18** Python modules are Mach-O MH_BUNDLE files. The best way to load these
19** is each in a private namespace, so you can load, say, a module bar and a
20** module foo.bar. If we load everything in the global namespace the two
21** initbar() symbols will conflict.
22** However, it seems some extension packages depend upon being able to access
23** each others' global symbols. There seems to be no way to eat our cake and
24** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour
25** you get.
26*/
27
28#ifdef USE_DYLD_GLOBAL_NAMESPACE
29#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR
30#else
31#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000032 NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
Jack Jansend4c76bf2002-02-01 16:01:05 +000033#endif
Guido van Rossum96a8fb71999-12-22 14:09:35 +000034dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000035 const char *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +000036{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 dl_funcptr p = NULL;
38 char funcname[258];
39 NSObjectFileImageReturnCode rc;
40 NSObjectFileImage image;
41 NSModule newModule;
42 NSSymbol theSym;
43 const char *errString;
44 char errBuf[512];
Guido van Rossum96a8fb71999-12-22 14:09:35 +000045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000046 PyOS_snprintf(funcname, sizeof(funcname), "_PyInit_%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000047
Jack Jansend4c76bf2002-02-01 16:01:05 +000048#ifdef USE_DYLD_GLOBAL_NAMESPACE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049 if (NSIsSymbolNameDefined(funcname)) {
50 theSym = NSLookupAndBindSymbol(funcname);
51 p = (dl_funcptr)NSAddressOfSymbol(theSym);
52 return p;
53 }
Jack Jansend4c76bf2002-02-01 16:01:05 +000054#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000055 rc = NSCreateObjectFileImageFromFile(pathname, &image);
56 switch(rc) {
57 default:
58 case NSObjectFileImageFailure:
59 case NSObjectFileImageFormat:
60 /* for these a message is printed on stderr by dyld */
61 errString = "Can't create object file image";
62 break;
63 case NSObjectFileImageSuccess:
64 errString = NULL;
65 break;
66 case NSObjectFileImageInappropriateFile:
67 errString = "Inappropriate file type for dynamic loading";
68 break;
69 case NSObjectFileImageArch:
70 errString = "Wrong CPU type in object file";
71 break;
72 case NSObjectFileImageAccess:
73 errString = "Can't read object file (no access)";
74 break;
75 }
76 if (errString == NULL) {
77 newModule = NSLinkModule(image, pathname, LINKOPTIONS);
78 if (newModule == NULL) {
79 int errNo;
80 const char *fileName, *moreErrorStr;
81 NSLinkEditErrors c;
82 NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
83 PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
84 fileName, moreErrorStr);
85 errString = errBuf;
86 }
87 }
88 if (errString != NULL) {
89 PyErr_SetString(PyExc_ImportError, errString);
90 return NULL;
91 }
Jack Jansena762f4c2002-02-01 22:24:56 +000092#ifdef USE_DYLD_GLOBAL_NAMESPACE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 if (!NSIsSymbolNameDefined(funcname)) {
94 /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
95 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
96 PyErr_Format(PyExc_ImportError,
97 "Loaded module does not contain symbol %.200s",
98 funcname);
99 return NULL;
100 }
101 theSym = NSLookupAndBindSymbol(funcname);
Jack Jansena762f4c2002-02-01 22:24:56 +0000102#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 theSym = NSLookupSymbolInModule(newModule, funcname);
104 if ( theSym == NULL ) {
105 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
106 PyErr_Format(PyExc_ImportError,
107 "Loaded module does not contain symbol %.200s",
108 funcname);
109 return NULL;
110 }
Jack Jansena762f4c2002-02-01 22:24:56 +0000111#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 p = (dl_funcptr)NSAddressOfSymbol(theSym);
113 return p;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000114}