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;
269 * MacOS X dll support is for bundles, not the current executable, so return
270 * NULL is this case. However, dll_function() uses a special hack where a
271 * NULL handle can be used to find executable symbols. This satisfies the
272 * needs of ui-gtk.c but is not a general solution.
277 ret = NSCreateObjectFileImageFromFile(fname, &file);
279 if (ret != NSObjectFileImageSuccess) {
283 return (dll_handle)NSLinkModule(file, fname,
284 NSLINKMODULE_OPTION_BINDNOW |
285 NSLINKMODULE_OPTION_PRIVATE |
286 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
290 dll_close (dll_handle h)
292 return NSUnLinkModule((NSModule)h, NSUNLINKMODULE_OPTION_NONE);
295 /* Given an address, return the mach_header for the image containing it
296 * or zero if the given address is not contained in any loaded images.
298 * Note: image_for_address(), my_find_image() and search_linked_libs() are
299 * based on code from the dlcompat library
300 * (http://www.opendarwin.org/projects/dlcompat).
303 static struct mach_header*
304 image_for_address(void *address)
307 unsigned long count = _dyld_image_count();
308 struct mach_header *mh = 0;
310 for (i = 0; i < count; i++)
312 unsigned long addr = (unsigned long)address -
313 _dyld_get_image_vmaddr_slide(i);
314 mh = _dyld_get_image_header(i);
318 struct load_command *lc =
319 (struct load_command *)((char *)mh + sizeof(struct mach_header));
322 for (j = 0; j < mh->ncmds;
323 j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
325 if (LC_SEGMENT == lc->cmd &&
326 addr >= ((struct segment_command *)lc)->vmaddr &&
328 ((struct segment_command *)lc)->vmaddr +
329 ((struct segment_command *)lc)->vmsize)
343 static const struct mach_header*
344 my_find_image(const char *name)
346 const struct mach_header *mh = (struct mach_header *)
347 NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED |
348 NSADDIMAGE_OPTION_RETURN_ON_ERROR);
352 int count = _dyld_image_count();
355 for (j = 0; j < count; j++)
357 const char *id = _dyld_get_image_name(j);
359 if (!strcmp(id, name))
361 mh = _dyld_get_image_header(j);
371 * dyld adds libraries by first adding the directly dependant libraries in
372 * link order, and then adding the dependencies for those libraries, so we
373 * should do the same... but we don't bother adding the extra dependencies, if
374 * the symbols are neither in the loaded image nor any of it's direct
375 * dependencies, then it probably isn't there.
378 search_linked_libs(const struct mach_header * mh, const char *symbol)
383 struct load_command *lc =
384 (struct load_command *)((char *)mh + sizeof(struct mach_header));
386 for (n = 0; n < mh->ncmds;
387 n++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
389 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
391 struct mach_header *wh;
393 if ((wh = (struct mach_header *)
394 my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset +
397 if (NSIsSymbolNameDefinedInImage(wh, symbol))
400 NSLookupSymbolInImage(wh,
402 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
403 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
414 dll_function (dll_handle h, const char *n)
417 #ifdef DLSYM_NEEDS_UNDERSCORE
418 char *buf = alloca_array (char, strlen (n) + 2);
424 /* NULL means the program image and shared libraries, not bundles. */
428 /* NOTE: This assumes that this function is included in the main program
429 and not in a shared library. */
430 const struct mach_header* my_mh = image_for_address(&dll_function);
432 if (NSIsSymbolNameDefinedInImage(my_mh, n))
435 NSLookupSymbolInImage(my_mh,
437 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
438 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
443 sym = search_linked_libs(my_mh, n);
448 sym = NSLookupSymbolInModule((NSModule)h, n);
451 if (sym == 0) return 0;
452 return (dll_func)NSAddressOfSymbol(sym);
456 dll_variable (dll_handle h, const char *n)
459 #ifdef DLSYM_NEEDS_UNDERSCORE
460 char *buf = alloca_array (char, strlen (n) + 2);
465 sym = NSLookupSymbolInModule((NSModule)h, n);
466 if (sym == 0) return 0;
467 return (dll_var)NSAddressOfSymbol(sym);
471 dll_error (dll_handle h)
475 const char *fileNameWithError, *errorString;
476 NSLinkEditError(&c, &errorNumber, &fileNameWithError, &errorString);
482 /* Catchall if we don't know about this system's method of dynamic loading */
484 dll_init (const char *arg)
490 dll_open (const char *fname)
496 dll_close (dll_handle h)
502 dll_function (dll_handle h, const char *n)
508 dll_variable (dll_handle h, const char *n)
514 dll_error (dll_handle h)
516 return "Shared libraries not implemented on this system";
518 #endif /* System conditionals */
520 #endif /* HAVE_SHLIB */