blob: 5caff8bc9c4e6c1e1a356116067de51445b2a51e [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},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 {0, 0}
Guido van Rossum22a1d361999-12-20 21:18:49 +000014};
15
Jack Jansend4c76bf2002-02-01 16:01:05 +000016/*
17** Python modules are Mach-O MH_BUNDLE files. The best way to load these
18** is each in a private namespace, so you can load, say, a module bar and a
19** module foo.bar. If we load everything in the global namespace the two
20** initbar() symbols will conflict.
21** However, it seems some extension packages depend upon being able to access
22** each others' global symbols. There seems to be no way to eat our cake and
23** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour
24** you get.
25*/
26
27#ifdef USE_DYLD_GLOBAL_NAMESPACE
28#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR
29#else
30#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031 NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
Jack Jansend4c76bf2002-02-01 16:01:05 +000032#endif
Victor Stinner42040fb2011-02-22 23:16:19 +000033dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
34 const char *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +000035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000036 dl_funcptr p = NULL;
37 char funcname[258];
38 NSObjectFileImageReturnCode rc;
39 NSObjectFileImage image;
40 NSModule newModule;
41 NSSymbol theSym;
42 const char *errString;
43 char errBuf[512];
Guido van Rossum96a8fb71999-12-22 14:09:35 +000044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000045 PyOS_snprintf(funcname, sizeof(funcname), "_PyInit_%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000046
Jack Jansend4c76bf2002-02-01 16:01:05 +000047#ifdef USE_DYLD_GLOBAL_NAMESPACE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000048 if (NSIsSymbolNameDefined(funcname)) {
49 theSym = NSLookupAndBindSymbol(funcname);
50 p = (dl_funcptr)NSAddressOfSymbol(theSym);
51 return p;
52 }
Jack Jansend4c76bf2002-02-01 16:01:05 +000053#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000054 rc = NSCreateObjectFileImageFromFile(pathname, &image);
55 switch(rc) {
56 default:
57 case NSObjectFileImageFailure:
58 case NSObjectFileImageFormat:
59 /* for these a message is printed on stderr by dyld */
60 errString = "Can't create object file image";
61 break;
62 case NSObjectFileImageSuccess:
63 errString = NULL;
64 break;
65 case NSObjectFileImageInappropriateFile:
66 errString = "Inappropriate file type for dynamic loading";
67 break;
68 case NSObjectFileImageArch:
69 errString = "Wrong CPU type in object file";
70 break;
71 case NSObjectFileImageAccess:
72 errString = "Can't read object file (no access)";
73 break;
74 }
75 if (errString == NULL) {
76 newModule = NSLinkModule(image, pathname, LINKOPTIONS);
77 if (newModule == NULL) {
78 int errNo;
79 const char *fileName, *moreErrorStr;
80 NSLinkEditErrors c;
81 NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
82 PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
83 fileName, moreErrorStr);
84 errString = errBuf;
85 }
86 }
87 if (errString != NULL) {
88 PyErr_SetString(PyExc_ImportError, errString);
89 return NULL;
90 }
Jack Jansena762f4c2002-02-01 22:24:56 +000091#ifdef USE_DYLD_GLOBAL_NAMESPACE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 if (!NSIsSymbolNameDefined(funcname)) {
93 /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
94 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
95 PyErr_Format(PyExc_ImportError,
96 "Loaded module does not contain symbol %.200s",
97 funcname);
98 return NULL;
99 }
100 theSym = NSLookupAndBindSymbol(funcname);
Jack Jansena762f4c2002-02-01 22:24:56 +0000101#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 theSym = NSLookupSymbolInModule(newModule, funcname);
103 if ( theSym == NULL ) {
104 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
105 PyErr_Format(PyExc_ImportError,
106 "Loaded module does not contain symbol %.200s",
107 funcname);
108 return NULL;
109 }
Jack Jansena762f4c2002-02-01 22:24:56 +0000110#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 p = (dl_funcptr)NSAddressOfSymbol(theSym);
112 return p;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000113}