blob: 9dec4656987b002b6155dfcad042bf4d75696e20 [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[] = {
12 {".so", "rb", C_EXTENSION},
13 {"module.so", "rb", C_EXTENSION},
14 {0, 0}
15};
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| \
32 NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
33#endif
Guido van Rossum96a8fb71999-12-22 14:09:35 +000034dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Jack Jansend4c76bf2002-02-01 16:01:05 +000035 const char *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +000036{
37 dl_funcptr p = NULL;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000038 char funcname[258];
39
Jeremy Hylton518ab1c2001-11-28 20:42:20 +000040 PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000041
Guido van Rossum22a1d361999-12-20 21:18:49 +000042 {
43 NSObjectFileImageReturnCode rc;
44 NSObjectFileImage image;
45 NSModule newModule;
46 NSSymbol theSym;
Guido van Rossum22a1d361999-12-20 21:18:49 +000047 const char *errString;
Jack Jansend4c76bf2002-02-01 16:01:05 +000048 char errBuf[512];
Guido van Rossum22a1d361999-12-20 21:18:49 +000049
Jack Jansend4c76bf2002-02-01 16:01:05 +000050#ifdef USE_DYLD_GLOBAL_NAMESPACE
Jack Jansenabce4162001-08-11 21:54:11 +000051 if (NSIsSymbolNameDefined(funcname)) {
52 theSym = NSLookupAndBindSymbol(funcname);
53 p = (dl_funcptr)NSAddressOfSymbol(theSym);
54 return p;
55 }
Jack Jansend4c76bf2002-02-01 16:01:05 +000056#endif
Guido van Rossum22a1d361999-12-20 21:18:49 +000057 rc = NSCreateObjectFileImageFromFile(pathname, &image);
58 switch(rc) {
Jack Jansend4c76bf2002-02-01 16:01:05 +000059 default:
60 case NSObjectFileImageFailure:
61 case NSObjectFileImageFormat:
62 /* for these a message is printed on stderr by dyld */
Guido van Rossum22a1d361999-12-20 21:18:49 +000063 errString = "Can't create object file image";
64 break;
Jack Jansend4c76bf2002-02-01 16:01:05 +000065 case NSObjectFileImageSuccess:
Guido van Rossum22a1d361999-12-20 21:18:49 +000066 errString = NULL;
67 break;
Jack Jansend4c76bf2002-02-01 16:01:05 +000068 case NSObjectFileImageInappropriateFile:
Guido van Rossum22a1d361999-12-20 21:18:49 +000069 errString = "Inappropriate file type for dynamic loading";
70 break;
Jack Jansend4c76bf2002-02-01 16:01:05 +000071 case NSObjectFileImageArch:
Guido van Rossum22a1d361999-12-20 21:18:49 +000072 errString = "Wrong CPU type in object file";
73 break;
Jack Jansend4c76bf2002-02-01 16:01:05 +000074 case NSObjectFileImageAccess:
Guido van Rossum22a1d361999-12-20 21:18:49 +000075 errString = "Can't read object file (no access)";
76 break;
77 }
78 if (errString == NULL) {
Jack Jansend4c76bf2002-02-01 16:01:05 +000079 newModule = NSLinkModule(image, pathname, LINKOPTIONS);
80 if (newModule == NULL) {
81 int errNo;
82 char *fileName, *moreErrorStr;
83 NSLinkEditErrors c;
84 NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
85 PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
86 fileName, moreErrorStr);
87 errString = errBuf;
88 }
Guido van Rossum22a1d361999-12-20 21:18:49 +000089 }
90 if (errString != NULL) {
91 PyErr_SetString(PyExc_ImportError, errString);
92 return NULL;
93 }
Jack Jansend4c76bf2002-02-01 16:01:05 +000094#ifdef USE_DYLD_GLOBAL_NAMESPACE
Guido van Rossum22a1d361999-12-20 21:18:49 +000095 if (!NSIsSymbolNameDefined(funcname)) {
Thomas Wouters7e474022000-07-16 12:04:32 +000096 /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
Guido van Rossum22a1d361999-12-20 21:18:49 +000097 NSUnLinkModule(newModule, FALSE);
Guido van Rossum5db862d2000-04-10 12:46:51 +000098 PyErr_Format(PyExc_ImportError,
Jack Jansend4c76bf2002-02-01 16:01:05 +000099 "Loaded module does not contain symbol %.200s",
100 funcname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000101 return NULL;
102 }
103 theSym = NSLookupAndBindSymbol(funcname);
Jack Jansend4c76bf2002-02-01 16:01:05 +0000104#else
105 theSym = NSLookupSymbolInModule(newModule, funcname);
106 if ( theSym == NULL ) {
107 NSUnLinkModule(newModule, FALSE);
108 PyErr_Format(PyExc_ImportError,
109 "Loaded module does not contain symbol %.200s",
110 funcname);
111 return NULL;
112 }
113#endif
Guido van Rossum22a1d361999-12-20 21:18:49 +0000114 p = (dl_funcptr)NSAddressOfSymbol(theSym);
Jack Jansend4c76bf2002-02-01 16:01:05 +0000115 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000116
117 return p;
118}