blob: 5088b059d8c8bb1070ced095a8ae3d2c4a1a1c16 [file] [log] [blame]
Guido van Rossum22a1d361999-12-20 21:18:49 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
32/* Support for dynamic loading of extension modules */
33
34#include "Python.h"
35#include "importdl.h"
36
37
38#ifdef WITH_DYLD
39
40#define USE_DYLD
41
42#include <mach-o/dyld.h>
43
44#else /* WITH_DYLD */
45
46#define USE_RLD
47/* Define this to 1 if you want be able to load ObjC modules as well:
48 it switches between two different way of loading modules on the NeXT,
49 one that directly interfaces with the dynamic loader (rld_load(), which
50 does not correctly load ObjC object files), and another that uses the
51 ObjC runtime (objc_loadModules()) to do the job.
52 You'll have to add ``-ObjC'' to the compiler flags if you set this to 1.
53*/
54#define HANDLE_OBJC_MODULES 1
55#if HANDLE_OBJC_MODULES
56#include <objc/Object.h>
57#include <objc/objc-load.h>
58#endif
59
60#include <mach-o/rld.h>
61
62#endif /* WITH_DYLD */
63
64
65const struct filedescr _PyImport_DynLoadFiletab[] = {
66 {".so", "rb", C_EXTENSION},
67 {"module.so", "rb", C_EXTENSION},
68 {0, 0}
69};
70
Guido van Rossum96a8fb71999-12-22 14:09:35 +000071dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000072 const char *pathname, FILE *fp)
73{
74 dl_funcptr p = NULL;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000075 char funcname[258];
76
77 sprintf(funcname, "_init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000078
79#ifdef USE_RLD
80 {
81 NXStream *errorStream;
82 struct mach_header *new_header;
83 const char *filenames[2];
84 long ret;
85 unsigned long ptr;
86
87 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
88 filenames[0] = pathname;
89 filenames[1] = NULL;
90
91#if HANDLE_OBJC_MODULES
92
93/* The following very bogus line of code ensures that
94 objc_msgSend, etc are linked into the binary. Without
95 it, dynamic loading of a module that includes objective-c
96 method calls will fail with "undefined symbol _objc_msgSend()".
97 This remains true even in the presence of the -ObjC flag
98 to the compiler
99*/
100
101 [Object name];
102
103/* objc_loadModules() dynamically loads the object files
104 indicated by the paths in filenames. If there are any
105 errors generated during loading -- typically due to the
106 inability to find particular symbols -- an error message
107 will be written to errorStream.
108 It returns 0 if the module is successfully loaded, 1
109 otherwise.
110*/
111
112 ret = !objc_loadModules(filenames, errorStream,
113 NULL, &new_header, NULL);
114
115#else /* !HANDLE_OBJC_MODULES */
116
117 ret = rld_load(errorStream, &new_header,
118 filenames, NULL);
119
120#endif /* HANDLE_OBJC_MODULES */
121
122 /* extract the error messages for the exception */
123 if(!ret) {
124 char *streamBuf;
125 int len, maxLen;
126
127 NXPutc(errorStream, (char)0);
128
129 NXGetMemoryBuffer(errorStream,
130 &streamBuf, &len, &maxLen);
131 PyErr_SetString(PyExc_ImportError, streamBuf);
132 }
133
134 if(ret && rld_lookup(errorStream, funcname, &ptr))
135 p = (dl_funcptr) ptr;
136
137 NXCloseMemory(errorStream, NX_FREEBUFFER);
138
139 if(!ret)
140 return NULL;
141 }
142#endif /* USE_RLD */
143#ifdef USE_DYLD
144 /* This is also NeXT-specific. However, frameworks (the new style
145 of shared library) and rld() can't be used in the same program;
146 instead, you have to use dyld, which is mostly unimplemented. */
147 {
148 NSObjectFileImageReturnCode rc;
149 NSObjectFileImage image;
150 NSModule newModule;
151 NSSymbol theSym;
152 void *symaddr;
153 const char *errString;
154
155 rc = NSCreateObjectFileImageFromFile(pathname, &image);
156 switch(rc) {
157 default:
158 case NSObjectFileImageFailure:
159 NSObjectFileImageFormat:
160 /* for these a message is printed on stderr by dyld */
161 errString = "Can't create object file image";
162 break;
163 case NSObjectFileImageSuccess:
164 errString = NULL;
165 break;
166 case NSObjectFileImageInappropriateFile:
167 errString = "Inappropriate file type for dynamic loading";
168 break;
169 case NSObjectFileImageArch:
170 errString = "Wrong CPU type in object file";
171 break;
172 NSObjectFileImageAccess:
173 errString = "Can't read object file (no access)";
174 break;
175 }
176 if (errString == NULL) {
177 newModule = NSLinkModule(image, pathname, TRUE);
178 if (!newModule)
179 errString = "Failure linking new module";
180 }
181 if (errString != NULL) {
182 PyErr_SetString(PyExc_ImportError, errString);
183 return NULL;
184 }
185 if (!NSIsSymbolNameDefined(funcname)) {
186 /* UnlinkModule() isn't implimented in current versions, but calling it does no harm */
187 NSUnLinkModule(newModule, FALSE);
188 PyErr_Format(PyExc_ImportError, "Loaded module does not contain symbol %s", funcname);
189 return NULL;
190 }
191 theSym = NSLookupAndBindSymbol(funcname);
192 p = (dl_funcptr)NSAddressOfSymbol(theSym);
193 }
194#endif /* USE_DYLD */
195
196 return p;
197}