21.4.14 "Reasonable Discussion".
[chise/xemacs-chise.git.1] / src / sysdll.c
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
26 #include <stdlib.h>
27 #include "lisp.h"
28 #include "sysdll.h"
29
30 /* This whole file is conditional upon HAVE_SHLIB */
31 #ifdef HAVE_SHLIB
32
33 /* Thankfully, most systems follow the ELFish dlopen() method.
34 */
35
36 #if defined(HAVE_DLOPEN)
37 #include <dlfcn.h>
38
39 #ifndef RTLD_LAZY
40 # define RTLD_LAZY 1
41 #endif /* RTLD_LAZY isn't defined under FreeBSD - ick */
42
43 #ifndef RTLD_NOW
44 # define RTLD_NOW 2
45 #endif
46
47 int
48 dll_init (const char *arg)
49 {
50   return 0;
51 }
52
53
54 dll_handle
55 dll_open (const char *fname)
56 {
57   return (dll_handle) dlopen (fname, RTLD_NOW);
58 }
59
60 int
61 dll_close (dll_handle h)
62 {
63   return dlclose ((void *) h);
64 }
65
66 dll_func
67 dll_function (dll_handle h, const char *n)
68 {
69 #ifdef DLSYM_NEEDS_UNDERSCORE
70   char *buf = alloca_array (char, strlen (n) + 2);
71   *buf = '_';
72   strcpy (buf + 1, n);
73   n = buf;
74 #endif
75   return (dll_func) dlsym ((void *) h, n);
76 }
77
78 dll_var
79 dll_variable (dll_handle h, const char *n)
80 {
81 #ifdef DLSYM_NEEDS_UNDERSCORE
82   char *buf = alloca_array (char, strlen (n) + 2);
83   *buf = '_';
84   strcpy (buf + 1, n);
85   n = buf;
86 #endif
87   return (dll_var)dlsym ((void *)h, n);
88 }
89
90 const char *
91 dll_error (dll_handle h)
92 {
93 #if defined(HAVE_DLERROR) || defined(dlerror)
94   return (const char *) dlerror ();
95 #elif defined(HAVE__DLERROR)
96   return (const char *) _dlerror();
97 #else
98   return "Shared library error";
99 #endif
100 }
101
102 #elif defined(HAVE_SHL_LOAD)
103 /* This is the HP/UX version */
104 #include <dl.h>
105 int
106 dll_init (const char *arg)
107 {
108   return 0;
109 }
110
111 dll_handle
112 dll_open (const char *fname)
113 {
114   /* shl_load will hang hard if passed a NULL fname. */
115   if (fname == NULL) return NULL;
116
117   return (dll_handle) shl_load (fname, BIND_DEFERRED,0L);
118 }
119
120 int
121 dll_close (dll_handle h)
122 {
123   return shl_unload ((shl_t) h);
124 }
125
126 dll_func
127 dll_function (dll_handle h, const char *n)
128 {
129   long handle = 0L;
130
131   if (shl_findsym ((shl_t *) &h, n, TYPE_PROCEDURE, &handle))
132     return NULL;
133
134   return (dll_func) handle;
135 }
136
137 dll_var
138 dll_variable (dll_handle h, const char *n)
139 {
140   long handle = 0L;
141
142   if (shl_findsym ((shl_t *) &h, n, TYPE_DATA, &handle))
143     return NULL;
144
145   return (dll_var) handle;
146 }
147
148 const char *
149 dll_error (dll_handle h)
150 {
151   /* #### WTF?!  Shouldn't this at least attempt to get strerror or
152      something?  --hniksic */
153   return "Generic shared library error";
154 }
155
156 #elif defined(HAVE_DLD_INIT)
157 #include <dld.h>
158 int
159 dll_init (const char *arg)
160 {
161   char *real_exe = dld_find_executable (arg);
162   int rc;
163
164   rc = dld_init (real_exe);
165   if (rc)
166     {
167       dld_perror (exe);
168       return -1;
169     }
170   return 0;
171 }
172
173 dll_handle
174 dll_open (const char *fname)
175 {
176   rc = dld_link (fname);
177   if (rc)
178     return NULL;
179
180   return (dll_handle) 1;
181 }
182
183 int
184 dll_close (dll_handle h)
185 {
186   /* *sigh* DLD is pretty lame and doesn't return a handle that you can use
187   ** later on to free the file - you have to remember the filename and
188   ** use that as the unlinker.  We should eventually keep a linked list
189   ** of loaded modules and then use the node pointer as the unique id
190   ** for the shared library.  Wheeee.  But not now.
191   */
192   return 1;
193 }
194
195 DLL_FUNC
196 dll_function (dll_handle h, const char *n)
197 {
198   return dld_get_func (n);
199 }
200
201 DLL_FUNC
202 dll_variable (dll_handle h, const char *n)
203 {
204   return dld_get_symbol (n);
205 }
206 #elif defined (WIN32_NATIVE)
207
208 #define WIN32_LEAN_AND_MEAN
209 #include <windows.h>
210 #undef WIN32_LEAN_AND_MEAN
211
212 int
213 dll_init (const char *arg)
214 {
215   return 0;
216 }
217
218 dll_handle
219 dll_open (const char *fname)
220 {
221   return (dll_handle) LoadLibrary (fname);
222 }
223
224 int
225 dll_close (dll_handle h)
226 {
227   return FreeLibrary (h);
228 }
229
230 dll_func
231 dll_function (dll_handle h, const char *n)
232 {
233   return (dll_func) GetProcAddress (h, n);
234 }
235
236 dll_func
237 dll_variable (dll_handle h, const char *n)
238 {
239   return (dll_func) GetProcAddress (h, n);
240 }
241
242 const char *
243 dll_error (dll_handle h)
244 {
245   return "Windows DLL Error";
246 }
247 #elif defined(HAVE_DYLD) 
248
249 /* 
250    This section supports MacOSX dynamic libraries. Dynamically
251    loadable libraries must be compiled as bundles, not dynamiclibs. 
252 */
253
254 #include <mach-o/dyld.h>
255
256 int
257 dll_init (const char *arg)
258 {
259   return 0;
260 }
261
262 dll_handle
263 dll_open (const char *fname)
264 {
265   NSObjectFileImage file;
266   NSObjectFileImageReturnCode ret = 
267     NSCreateObjectFileImageFromFile(fname, &file);
268   if (ret != NSObjectFileImageSuccess) {
269     return NULL;
270   }
271   return (dll_handle)NSLinkModule(file, fname, 
272                                   NSLINKMODULE_OPTION_BINDNOW |
273                                   NSLINKMODULE_OPTION_PRIVATE |
274                                   NSLINKMODULE_OPTION_RETURN_ON_ERROR);
275 }
276
277 int
278 dll_close (dll_handle h)
279 {
280   return NSUnLinkModule((NSModule)h, NSUNLINKMODULE_OPTION_NONE);
281 }
282
283 dll_func
284 dll_function (dll_handle h, const char *n)
285 {
286   NSSymbol sym;
287 #ifdef DLSYM_NEEDS_UNDERSCORE
288   char *buf = alloca_array (char, strlen (n) + 2);
289   *buf = '_';
290   strcpy (buf + 1, n);
291   n = buf;
292 #endif
293   sym = NSLookupSymbolInModule((NSModule)h, n);
294   if (sym == 0) return 0;
295   return (dll_func)NSAddressOfSymbol(sym);
296 }
297
298 dll_var
299 dll_variable (dll_handle h, const char *n)
300 {
301   NSSymbol sym;
302 #ifdef DLSYM_NEEDS_UNDERSCORE
303   char *buf = alloca_array (char, strlen (n) + 2);
304   *buf = '_';
305   strcpy (buf + 1, n);
306   n = buf;
307 #endif
308   sym = NSLookupSymbolInModule((NSModule)h, n);
309   if (sym == 0) return 0;
310   return (dll_var)NSAddressOfSymbol(sym);
311 }
312
313 const char *
314 dll_error (dll_handle h)
315 {
316   NSLinkEditErrors c;
317   int errorNumber;
318   const char *fileNameWithError, *errorString;
319   NSLinkEditError(&c, &errorNumber, &fileNameWithError, &errorString);
320   return errorString;
321 }
322
323
324 #else
325 /* Catchall if we don't know about this system's method of dynamic loading */
326 int
327 dll_init (const char *arg)
328 {
329   return -1;
330 }
331
332 dll_handle
333 dll_open (const char *fname)
334 {
335   return NULL;
336 }
337
338 int
339 dll_close (dll_handle h)
340 {
341   return 0;
342 }
343
344 dll_func
345 dll_function (dll_handle h, const char *n)
346 {
347   return NULL;
348 }
349
350 dll_func
351 dll_variable (dll_handle h, const char *n)
352 {
353   return NULL;
354 }
355
356 const char *
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 */