428
|
1 /* sysdll.c --- system dependent support for dynamic linked libraries
|
|
2 Copyright (C) 1998 Free Software Foundation, Inc.
|
|
3 Author: William Perry <wmperry@aventail.com>
|
|
4
|
|
5 This file is part of XEmacs.
|
|
6
|
|
7 XEmacs is free software; you can redistribute it and/or modify it
|
|
8 under the terms of the GNU General Public License as published by the
|
|
9 Free Software Foundation; either version 2, or (at your option) any
|
|
10 later version.
|
|
11
|
|
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
|
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
15 for more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with XEmacs; see the file COPYING. If not, write to the Free
|
|
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
20 02111-1307, USA. */
|
|
21
|
|
22 #ifdef HAVE_CONFIG_H
|
|
23 #include <config.h>
|
|
24 #endif
|
|
25
|
430
|
26 #include <stdlib.h>
|
1272
|
27 #include "lisp.h"
|
428
|
28 #include "sysdll.h"
|
|
29
|
1383
|
30 #ifdef DLSYM_NEEDS_UNDERSCORE
|
|
31 #define MAYBE_PREPEND_UNDERSCORE(n) do { \
|
|
32 char *buf = alloca_array (char, strlen (n) + 2); \
|
|
33 *buf = '_'; \
|
|
34 strcpy (buf + 1, n); \
|
|
35 n = buf; \
|
|
36 } while (0)
|
|
37 #else
|
|
38 #define MAYBE_PREPEND_UNDERSCORE(n)
|
|
39 #endif
|
|
40
|
428
|
41 /* This whole file is conditional upon HAVE_SHLIB */
|
|
42 #ifdef HAVE_SHLIB
|
|
43
|
|
44 /* Thankfully, most systems follow the ELFish dlopen() method.
|
|
45 */
|
452
|
46 #if defined(HAVE_DLOPEN)
|
428
|
47 #include <dlfcn.h>
|
|
48
|
|
49 #ifndef RTLD_LAZY
|
1383
|
50 # ifdef DL_LAZY
|
|
51 # define RTLD_LAZY DL_LAZY
|
|
52 # else
|
|
53 # define RTLD_LAZY 1
|
|
54 # endif
|
428
|
55 #endif /* RTLD_LAZY isn't defined under FreeBSD - ick */
|
|
56
|
863
|
57 #ifndef RTLD_NOW
|
1383
|
58 # ifdef DL_NOW
|
|
59 # define RTLD_NOW DL_NOW
|
|
60 # else
|
|
61 # define RTLD_NOW 2
|
|
62 # endif
|
863
|
63 #endif
|
|
64
|
428
|
65 int
|
442
|
66 dll_init (const char *arg)
|
428
|
67 {
|
|
68 return 0;
|
|
69 }
|
|
70
|
|
71 dll_handle
|
442
|
72 dll_open (const char *fname)
|
428
|
73 {
|
880
|
74 return (dll_handle) dlopen (fname, RTLD_NOW);
|
428
|
75 }
|
|
76
|
|
77 int
|
|
78 dll_close (dll_handle h)
|
|
79 {
|
442
|
80 return dlclose ((void *) h);
|
428
|
81 }
|
|
82
|
|
83 dll_func
|
442
|
84 dll_function (dll_handle h, const char *n)
|
428
|
85 {
|
1383
|
86 MAYBE_PREPEND_UNDERSCORE (n);
|
442
|
87 return (dll_func) dlsym ((void *) h, n);
|
428
|
88 }
|
|
89
|
|
90 dll_var
|
442
|
91 dll_variable (dll_handle h, const char *n)
|
428
|
92 {
|
1383
|
93 MAYBE_PREPEND_UNDERSCORE (n);
|
428
|
94 return (dll_var)dlsym ((void *)h, n);
|
|
95 }
|
|
96
|
442
|
97 const char *
|
428
|
98 dll_error (dll_handle h)
|
|
99 {
|
|
100 #if defined(HAVE_DLERROR) || defined(dlerror)
|
442
|
101 return (const char *) dlerror ();
|
428
|
102 #elif defined(HAVE__DLERROR)
|
442
|
103 return (const char *) _dlerror();
|
428
|
104 #else
|
|
105 return "Shared library error";
|
|
106 #endif
|
|
107 }
|
|
108
|
|
109 #elif defined(HAVE_SHL_LOAD)
|
|
110 /* This is the HP/UX version */
|
|
111 #include <dl.h>
|
|
112 int
|
442
|
113 dll_init (const char *arg)
|
428
|
114 {
|
|
115 return 0;
|
|
116 }
|
|
117
|
|
118 dll_handle
|
442
|
119 dll_open (const char *fname)
|
428
|
120 {
|
442
|
121 /* shl_load will hang hard if passed a NULL fname. */
|
|
122 if (fname == NULL) return NULL;
|
428
|
123
|
1383
|
124 return (dll_handle) shl_load (fname, BIND_DEFERRED, 0L);
|
428
|
125 }
|
|
126
|
|
127 int
|
|
128 dll_close (dll_handle h)
|
|
129 {
|
442
|
130 return shl_unload ((shl_t) h);
|
428
|
131 }
|
|
132
|
|
133 dll_func
|
442
|
134 dll_function (dll_handle h, const char *n)
|
428
|
135 {
|
|
136 long handle = 0L;
|
|
137
|
442
|
138 if (shl_findsym ((shl_t *) &h, n, TYPE_PROCEDURE, &handle))
|
428
|
139 return NULL;
|
|
140
|
442
|
141 return (dll_func) handle;
|
428
|
142 }
|
|
143
|
|
144 dll_var
|
442
|
145 dll_variable (dll_handle h, const char *n)
|
428
|
146 {
|
|
147 long handle = 0L;
|
|
148
|
442
|
149 if (shl_findsym ((shl_t *) &h, n, TYPE_DATA, &handle))
|
428
|
150 return NULL;
|
|
151
|
442
|
152 return (dll_var) handle;
|
428
|
153 }
|
|
154
|
442
|
155 const char *
|
428
|
156 dll_error (dll_handle h)
|
|
157 {
|
|
158 /* #### WTF?! Shouldn't this at least attempt to get strerror or
|
|
159 something? --hniksic */
|
|
160 return "Generic shared library error";
|
|
161 }
|
|
162
|
1596
|
163 #elif defined(HAVE_DLD_INIT)
|
428
|
164 #include <dld.h>
|
|
165 int
|
442
|
166 dll_init (const char *arg)
|
428
|
167 {
|
|
168 char *real_exe = dld_find_executable (arg);
|
|
169 int rc;
|
|
170
|
|
171 rc = dld_init (real_exe);
|
|
172 if (rc)
|
|
173 {
|
|
174 dld_perror (exe);
|
|
175 return -1;
|
|
176 }
|
|
177 return 0;
|
|
178 }
|
|
179
|
|
180 dll_handle
|
442
|
181 dll_open (const char *fname)
|
428
|
182 {
|
|
183 rc = dld_link (fname);
|
|
184 if (rc)
|
|
185 return NULL;
|
|
186
|
442
|
187 return (dll_handle) 1;
|
428
|
188 }
|
|
189
|
|
190 int
|
|
191 dll_close (dll_handle h)
|
|
192 {
|
|
193 /* *sigh* DLD is pretty lame and doesn't return a handle that you can use
|
|
194 ** later on to free the file - you have to remember the filename and
|
|
195 ** use that as the unlinker. We should eventually keep a linked list
|
|
196 ** of loaded modules and then use the node pointer as the unique id
|
|
197 ** for the shared library. Wheeee. But not now.
|
|
198 */
|
|
199 return 1;
|
|
200 }
|
|
201
|
|
202 DLL_FUNC
|
442
|
203 dll_function (dll_handle h, const char *n)
|
428
|
204 {
|
442
|
205 return dld_get_func (n);
|
428
|
206 }
|
|
207
|
|
208 DLL_FUNC
|
442
|
209 dll_variable (dll_handle h, const char *n)
|
428
|
210 {
|
442
|
211 return dld_get_symbol (n);
|
428
|
212 }
|
1632
|
213 #elif defined (WIN32_NATIVE) || defined (CYGWIN)
|
442
|
214
|
1632
|
215 #include "syswindows.h"
|
|
216 #include "sysfile.h"
|
442
|
217
|
428
|
218 int
|
442
|
219 dll_init (const char *arg)
|
428
|
220 {
|
|
221 return 0;
|
|
222 }
|
|
223
|
|
224 dll_handle
|
442
|
225 dll_open (const char *fname)
|
428
|
226 {
|
1632
|
227 Ibyte *winfname, *unifname;
|
|
228 LOCAL_TO_WIN32_FILE_FORMAT ((char *) fname, winfname);
|
|
229 C_STRING_TO_TSTR (winfname, unifname);
|
|
230 return (dll_handle) qxeLoadLibrary (unifname);
|
428
|
231 }
|
|
232
|
|
233 int
|
|
234 dll_close (dll_handle h)
|
|
235 {
|
|
236 return FreeLibrary (h);
|
|
237 }
|
|
238
|
|
239 dll_func
|
442
|
240 dll_function (dll_handle h, const char *n)
|
428
|
241 {
|
442
|
242 return (dll_func) GetProcAddress (h, n);
|
428
|
243 }
|
|
244
|
|
245 dll_func
|
442
|
246 dll_variable (dll_handle h, const char *n)
|
428
|
247 {
|
442
|
248 return (dll_func) GetProcAddress (h, n);
|
428
|
249 }
|
|
250
|
442
|
251 const char *
|
428
|
252 dll_error (dll_handle h)
|
|
253 {
|
1632
|
254 /* Since nobody frees the returned string, I have to make this ugly hack. */
|
|
255 static char err[32] = "Windows DLL Error ";
|
|
256 snprintf (&err[18], 14, "%lu", GetLastError ());
|
|
257 return err;
|
428
|
258 }
|
1383
|
259 #elif defined(HAVE_DYLD)
|
|
260 /* This section supports MacOSX dynamic libraries. Dynamically
|
|
261 loadable libraries must be compiled as bundles, not dynamiclibs.
|
|
262 */
|
|
263
|
|
264 #include <mach-o/dyld.h>
|
|
265
|
|
266 int
|
|
267 dll_init (const char *arg)
|
|
268 {
|
|
269 return 0;
|
|
270 }
|
|
271
|
|
272 dll_handle
|
|
273 dll_open (const char *fname)
|
|
274 {
|
|
275 NSObjectFileImage file;
|
1418
|
276 NSModule out;
|
1383
|
277 NSObjectFileImageReturnCode ret =
|
|
278 NSCreateObjectFileImageFromFile(fname, &file);
|
|
279 if (ret != NSObjectFileImageSuccess) {
|
|
280 return NULL;
|
|
281 }
|
1418
|
282 out = NSLinkModule(file, fname,
|
|
283 NSLINKMODULE_OPTION_BINDNOW |
|
|
284 NSLINKMODULE_OPTION_PRIVATE |
|
|
285 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
|
1383
|
286 return (dll_handle)out;
|
|
287 }
|
|
288
|
|
289 int
|
|
290 dll_close (dll_handle h)
|
|
291 {
|
|
292 return NSUnLinkModule((NSModule)h, NSUNLINKMODULE_OPTION_NONE);
|
|
293 }
|
|
294
|
|
295 dll_func
|
|
296 dll_function (dll_handle h, const char *n)
|
|
297 {
|
|
298 NSSymbol sym;
|
|
299 MAYBE_PREPEND_UNDERSCORE (n);
|
|
300 sym = NSLookupSymbolInModule((NSModule)h, n);
|
|
301 if (sym == 0) return 0;
|
|
302 return (dll_func)NSAddressOfSymbol(sym);
|
|
303 }
|
|
304
|
|
305 dll_var
|
|
306 dll_variable (dll_handle h, const char *n)
|
|
307 {
|
|
308 NSSymbol sym;
|
|
309 MAYBE_PREPEND_UNDERSCORE (n);
|
|
310 sym = NSLookupSymbolInModule((NSModule)h, n);
|
|
311 if (sym == 0) return 0;
|
|
312 return (dll_var)NSAddressOfSymbol(sym);
|
|
313 }
|
|
314
|
|
315 const char *
|
|
316 dll_error (dll_handle h)
|
|
317 {
|
|
318 NSLinkEditErrors c;
|
|
319 int errorNumber;
|
|
320 const char *fileNameWithError, *errorString;
|
|
321 NSLinkEditError(&c, &errorNumber, &fileNameWithError, &errorString);
|
|
322 return errorString;
|
|
323 }
|
428
|
324 #else
|
|
325 /* Catchall if we don't know about this systems method of dynamic loading */
|
|
326 int
|
442
|
327 dll_init (const char *arg)
|
428
|
328 {
|
|
329 return -1;
|
|
330 }
|
|
331
|
|
332 dll_handle
|
442
|
333 dll_open (const char *fname)
|
428
|
334 {
|
|
335 return NULL;
|
|
336 }
|
|
337
|
|
338 int
|
|
339 dll_close (dll_handle h)
|
|
340 {
|
|
341 return 0;
|
|
342 }
|
|
343
|
|
344 dll_func
|
442
|
345 dll_function (dll_handle h, const char *n)
|
428
|
346 {
|
|
347 return NULL;
|
|
348 }
|
|
349
|
|
350 dll_func
|
442
|
351 dll_variable (dll_handle h, const char *n)
|
428
|
352 {
|
|
353 return NULL;
|
|
354 }
|
|
355
|
442
|
356 const char *
|
428
|
357 dll_error (dll_handle h)
|
|
358 {
|
|
359 return "Shared libraries not implemented on this system";
|
|
360 }
|
|
361 #endif /* System conditionals */
|
|
362
|
|
363 #endif /* HAVE_SHLIB */
|