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>
5 This file is part of XEmacs.
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
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
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
30 /* This whole file is conditional upon HAVE_SHLIB */
33 /* Thankfully, most systems follow the ELFish dlopen() method.
36 #if defined(HAVE_DLOPEN)
41 #endif /* RTLD_LAZY isn't defined under FreeBSD - ick */
48 dll_init (const char *arg)
55 dll_open (const char *fname)
57 return (dll_handle) dlopen (fname, RTLD_NOW);
61 dll_close (dll_handle h)
63 return dlclose ((void *) h);
67 dll_function (dll_handle h, const char *n)
69 #ifdef DLSYM_NEEDS_UNDERSCORE
70 char *buf = alloca_array (char, strlen (n) + 2);
75 return (dll_func) dlsym ((void *) h, n);
79 dll_variable (dll_handle h, const char *n)
81 #ifdef DLSYM_NEEDS_UNDERSCORE
82 char *buf = alloca_array (char, strlen (n) + 2);
87 return (dll_var)dlsym ((void *)h, n);
91 dll_error (dll_handle h)
93 #if defined(HAVE_DLERROR) || defined(dlerror)
94 return (const char *) dlerror ();
95 #elif defined(HAVE__DLERROR)
96 return (const char *) _dlerror();
98 return "Shared library error";
102 #elif defined(HAVE_SHL_LOAD)
103 /* This is the HP/UX version */
106 dll_init (const char *arg)
112 dll_open (const char *fname)
114 /* shl_load will hang hard if passed a NULL fname. */
115 if (fname == NULL) return NULL;
117 return (dll_handle) shl_load (fname, BIND_DEFERRED,0L);
121 dll_close (dll_handle h)
123 return shl_unload ((shl_t) h);
127 dll_function (dll_handle h, const char *n)
131 if (shl_findsym ((shl_t *) &h, n, TYPE_PROCEDURE, &handle))
134 return (dll_func) handle;
138 dll_variable (dll_handle h, const char *n)
142 if (shl_findsym ((shl_t *) &h, n, TYPE_DATA, &handle))
145 return (dll_var) handle;
149 dll_error (dll_handle h)
151 /* #### WTF?! Shouldn't this at least attempt to get strerror or
152 something? --hniksic */
153 return "Generic shared library error";
156 #elif defined(HAVE_DLD_INIT)
159 dll_init (const char *arg)
161 char *real_exe = dld_find_executable (arg);
164 rc = dld_init (real_exe);
174 dll_open (const char *fname)
176 rc = dld_link (fname);
180 return (dll_handle) 1;
184 dll_close (dll_handle h)
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.
196 dll_function (dll_handle h, const char *n)
198 return dld_get_func (n);
202 dll_variable (dll_handle h, const char *n)
204 return dld_get_symbol (n);
206 #elif defined (WIN32_NATIVE)
208 #define WIN32_LEAN_AND_MEAN
210 #undef WIN32_LEAN_AND_MEAN
213 dll_init (const char *arg)
219 dll_open (const char *fname)
221 return (dll_handle) LoadLibrary (fname);
225 dll_close (dll_handle h)
227 return FreeLibrary (h);
231 dll_function (dll_handle h, const char *n)
233 return (dll_func) GetProcAddress (h, n);
237 dll_variable (dll_handle h, const char *n)
239 return (dll_func) GetProcAddress (h, n);
243 dll_error (dll_handle h)
245 return "Windows DLL Error";
247 #elif defined(HAVE_DYLD)
250 This section supports MacOSX dynamic libraries. Dynamically
251 loadable libraries must be compiled as bundles, not dynamiclibs.
254 #include <mach-o/dyld.h>
257 dll_init (const char *arg)
263 dll_open (const char *fname)
265 NSObjectFileImage file;
266 NSObjectFileImageReturnCode ret =
267 NSCreateObjectFileImageFromFile(fname, &file);
268 if (ret != NSObjectFileImageSuccess) {
271 return (dll_handle)NSLinkModule(file, fname,
272 NSLINKMODULE_OPTION_BINDNOW |
273 NSLINKMODULE_OPTION_PRIVATE |
274 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
278 dll_close (dll_handle h)
280 return NSUnLinkModule((NSModule)h, NSUNLINKMODULE_OPTION_NONE);
283 /* Given an address, return the mach_header for the image containing it
284 * or zero if the given address is not contained in any loaded images.
286 * Note: image_for_address(), my_find_image() and search_linked_libs() are
287 * based on code from the dlcompat library
288 * (http://www.opendarwin.org/projects/dlcompat).
291 static struct mach_header*
292 image_for_address(void *address)
295 unsigned long count = _dyld_image_count();
296 struct mach_header *mh = 0;
298 for (i = 0; i < count; i++)
300 unsigned long addr = (unsigned long)address -
301 _dyld_get_image_vmaddr_slide(i);
302 mh = _dyld_get_image_header(i);
306 struct load_command *lc =
307 (struct load_command *)((char *)mh + sizeof(struct mach_header));
310 for (j = 0; j < mh->ncmds;
311 j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
313 if (LC_SEGMENT == lc->cmd &&
314 addr >= ((struct segment_command *)lc)->vmaddr &&
316 ((struct segment_command *)lc)->vmaddr +
317 ((struct segment_command *)lc)->vmsize)
331 static const struct mach_header*
332 my_find_image(const char *name)
334 const struct mach_header *mh = (struct mach_header *)
335 NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED |
336 NSADDIMAGE_OPTION_RETURN_ON_ERROR);
340 int count = _dyld_image_count();
343 for (j = 0; j < count; j++)
345 const char *id = _dyld_get_image_name(j);
347 if (!strcmp(id, name))
349 mh = _dyld_get_image_header(j);
359 * dyld adds libraries by first adding the directly dependant libraries in
360 * link order, and then adding the dependencies for those libraries, so we
361 * should do the same... but we don't bother adding the extra dependencies, if
362 * the symbols are neither in the loaded image nor any of it's direct
363 * dependencies, then it probably isn't there.
366 search_linked_libs(const struct mach_header * mh, const char *symbol)
371 struct load_command *lc =
372 (struct load_command *)((char *)mh + sizeof(struct mach_header));
374 for (n = 0; n < mh->ncmds;
375 n++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
377 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
379 struct mach_header *wh;
381 if ((wh = (struct mach_header *)
382 my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset +
385 if (NSIsSymbolNameDefinedInImage(wh, symbol))
388 NSLookupSymbolInImage(wh,
390 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
391 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
402 dll_function (dll_handle h, const char *n)
405 #ifdef DLSYM_NEEDS_UNDERSCORE
406 char *buf = alloca_array (char, strlen (n) + 2);
412 /* NULL means the program image and shared libraries, not bundles. */
416 /* NOTE: This assumes that this function is included in the main program
417 and not in a shared library. */
418 const struct mach_header* my_mh = image_for_address(&dll_function);
420 if (NSIsSymbolNameDefinedInImage(my_mh, n))
423 NSLookupSymbolInImage(my_mh,
425 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
426 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
431 sym = search_linked_libs(my_mh, n);
436 sym = NSLookupSymbolInModule((NSModule)h, n);
439 if (sym == 0) return 0;
440 return (dll_func)NSAddressOfSymbol(sym);
444 dll_variable (dll_handle h, const char *n)
447 #ifdef DLSYM_NEEDS_UNDERSCORE
448 char *buf = alloca_array (char, strlen (n) + 2);
453 sym = NSLookupSymbolInModule((NSModule)h, n);
454 if (sym == 0) return 0;
455 return (dll_var)NSAddressOfSymbol(sym);
459 dll_error (dll_handle h)
463 const char *fileNameWithError, *errorString;
464 NSLinkEditError(&c, &errorNumber, &fileNameWithError, &errorString);
470 /* Catchall if we don't know about this system's method of dynamic loading */
472 dll_init (const char *arg)
478 dll_open (const char *fname)
484 dll_close (dll_handle h)
490 dll_function (dll_handle h, const char *n)
496 dll_variable (dll_handle h, const char *n)
502 dll_error (dll_handle h)
504 return "Shared libraries not implemented on this system";
506 #endif /* System conditionals */
508 #endif /* HAVE_SHLIB */