blob: bcb9e4bb372f3db0d8d380b044a486b1d50a9ca6 [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
71dl_funcptr _PyImport_GetDynLoadFunc(const char *name, const char *funcname,
72 const char *pathname, FILE *fp)
73{
74 dl_funcptr p = NULL;
75
76#ifdef USE_RLD
77 {
78 NXStream *errorStream;
79 struct mach_header *new_header;
80 const char *filenames[2];
81 long ret;
82 unsigned long ptr;
83
84 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
85 filenames[0] = pathname;
86 filenames[1] = NULL;
87
88#if HANDLE_OBJC_MODULES
89
90/* The following very bogus line of code ensures that
91 objc_msgSend, etc are linked into the binary. Without
92 it, dynamic loading of a module that includes objective-c
93 method calls will fail with "undefined symbol _objc_msgSend()".
94 This remains true even in the presence of the -ObjC flag
95 to the compiler
96*/
97
98 [Object name];
99
100/* objc_loadModules() dynamically loads the object files
101 indicated by the paths in filenames. If there are any
102 errors generated during loading -- typically due to the
103 inability to find particular symbols -- an error message
104 will be written to errorStream.
105 It returns 0 if the module is successfully loaded, 1
106 otherwise.
107*/
108
109 ret = !objc_loadModules(filenames, errorStream,
110 NULL, &new_header, NULL);
111
112#else /* !HANDLE_OBJC_MODULES */
113
114 ret = rld_load(errorStream, &new_header,
115 filenames, NULL);
116
117#endif /* HANDLE_OBJC_MODULES */
118
119 /* extract the error messages for the exception */
120 if(!ret) {
121 char *streamBuf;
122 int len, maxLen;
123
124 NXPutc(errorStream, (char)0);
125
126 NXGetMemoryBuffer(errorStream,
127 &streamBuf, &len, &maxLen);
128 PyErr_SetString(PyExc_ImportError, streamBuf);
129 }
130
131 if(ret && rld_lookup(errorStream, funcname, &ptr))
132 p = (dl_funcptr) ptr;
133
134 NXCloseMemory(errorStream, NX_FREEBUFFER);
135
136 if(!ret)
137 return NULL;
138 }
139#endif /* USE_RLD */
140#ifdef USE_DYLD
141 /* This is also NeXT-specific. However, frameworks (the new style
142 of shared library) and rld() can't be used in the same program;
143 instead, you have to use dyld, which is mostly unimplemented. */
144 {
145 NSObjectFileImageReturnCode rc;
146 NSObjectFileImage image;
147 NSModule newModule;
148 NSSymbol theSym;
149 void *symaddr;
150 const char *errString;
151
152 rc = NSCreateObjectFileImageFromFile(pathname, &image);
153 switch(rc) {
154 default:
155 case NSObjectFileImageFailure:
156 NSObjectFileImageFormat:
157 /* for these a message is printed on stderr by dyld */
158 errString = "Can't create object file image";
159 break;
160 case NSObjectFileImageSuccess:
161 errString = NULL;
162 break;
163 case NSObjectFileImageInappropriateFile:
164 errString = "Inappropriate file type for dynamic loading";
165 break;
166 case NSObjectFileImageArch:
167 errString = "Wrong CPU type in object file";
168 break;
169 NSObjectFileImageAccess:
170 errString = "Can't read object file (no access)";
171 break;
172 }
173 if (errString == NULL) {
174 newModule = NSLinkModule(image, pathname, TRUE);
175 if (!newModule)
176 errString = "Failure linking new module";
177 }
178 if (errString != NULL) {
179 PyErr_SetString(PyExc_ImportError, errString);
180 return NULL;
181 }
182 if (!NSIsSymbolNameDefined(funcname)) {
183 /* UnlinkModule() isn't implimented in current versions, but calling it does no harm */
184 NSUnLinkModule(newModule, FALSE);
185 PyErr_Format(PyExc_ImportError, "Loaded module does not contain symbol %s", funcname);
186 return NULL;
187 }
188 theSym = NSLookupAndBindSymbol(funcname);
189 p = (dl_funcptr)NSAddressOfSymbol(theSym);
190 }
191#endif /* USE_DYLD */
192
193 return p;
194}