blob: 85c95b41bb55a000123ec3b94d7f0856ce62b0df [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
Brett Cannon2657df42012-05-04 15:20:40 -040011const char *_PyImport_DynLoadFiletab[] = {".so", NULL};
Guido van Rossum22a1d361999-12-20 21:18:49 +000012
Jack Jansend4c76bf2002-02-01 16:01:05 +000013/*
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| \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028 NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
Jack Jansend4c76bf2002-02-01 16:01:05 +000029#endif
Victor Stinner42040fb2011-02-22 23:16:19 +000030dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
31 const char *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +000032{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033 dl_funcptr p = NULL;
34 char funcname[258];
35 NSObjectFileImageReturnCode rc;
36 NSObjectFileImage image;
37 NSModule newModule;
38 NSSymbol theSym;
39 const char *errString;
40 char errBuf[512];
Guido van Rossum96a8fb71999-12-22 14:09:35 +000041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042 PyOS_snprintf(funcname, sizeof(funcname), "_PyInit_%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000043
Jack Jansend4c76bf2002-02-01 16:01:05 +000044#ifdef USE_DYLD_GLOBAL_NAMESPACE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000045 if (NSIsSymbolNameDefined(funcname)) {
46 theSym = NSLookupAndBindSymbol(funcname);
47 p = (dl_funcptr)NSAddressOfSymbol(theSym);
48 return p;
49 }
Jack Jansend4c76bf2002-02-01 16:01:05 +000050#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 rc = NSCreateObjectFileImageFromFile(pathname, &image);
52 switch(rc) {
53 default:
54 case NSObjectFileImageFailure:
55 case NSObjectFileImageFormat:
56 /* for these a message is printed on stderr by dyld */
57 errString = "Can't create object file image";
58 break;
59 case NSObjectFileImageSuccess:
60 errString = NULL;
61 break;
62 case NSObjectFileImageInappropriateFile:
63 errString = "Inappropriate file type for dynamic loading";
64 break;
65 case NSObjectFileImageArch:
66 errString = "Wrong CPU type in object file";
67 break;
68 case NSObjectFileImageAccess:
69 errString = "Can't read object file (no access)";
70 break;
71 }
72 if (errString == NULL) {
73 newModule = NSLinkModule(image, pathname, LINKOPTIONS);
74 if (newModule == NULL) {
75 int errNo;
76 const char *fileName, *moreErrorStr;
77 NSLinkEditErrors c;
78 NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
79 PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
80 fileName, moreErrorStr);
81 errString = errBuf;
82 }
83 }
84 if (errString != NULL) {
85 PyErr_SetString(PyExc_ImportError, errString);
86 return NULL;
87 }
Jack Jansena762f4c2002-02-01 22:24:56 +000088#ifdef USE_DYLD_GLOBAL_NAMESPACE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 if (!NSIsSymbolNameDefined(funcname)) {
90 /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
91 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
92 PyErr_Format(PyExc_ImportError,
93 "Loaded module does not contain symbol %.200s",
94 funcname);
95 return NULL;
96 }
97 theSym = NSLookupAndBindSymbol(funcname);
Jack Jansena762f4c2002-02-01 22:24:56 +000098#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 theSym = NSLookupSymbolInModule(newModule, funcname);
100 if ( theSym == NULL ) {
101 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
102 PyErr_Format(PyExc_ImportError,
103 "Loaded module does not contain symbol %.200s",
104 funcname);
105 return NULL;
106 }
Jack Jansena762f4c2002-02-01 22:24:56 +0000107#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108 p = (dl_funcptr)NSAddressOfSymbol(theSym);
109 return p;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000110}