1 --- a/sim/ucsim/libltdl/ltdl.c
2 +++ b/sim/ucsim/libltdl/ltdl.c
4 /* ltdl.c -- system independent dlopen wrapper
5 - Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
6 - Originally by Thomas Tanner <tanner@ffii.org>
7 - This file is part of GNU Libtool.
9 -This library is free software; you can redistribute it and/or
10 -modify it under the terms of the GNU Lesser General Public
11 -License as published by the Free Software Foundation; either
12 -version 2 of the License, or (at your option) any later version.
14 -As a special exception to the GNU Lesser General Public License,
15 -if you distribute this file as part of a program or library that
16 -is built using GNU libtool, you may include it under the same
17 -distribution terms that you use for the rest of that program.
19 -This library is distributed in the hope that it will be useful,
20 -but WITHOUT ANY WARRANTY; without even the implied warranty of
21 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 -Lesser General Public License for more details.
24 -You should have received a copy of the GNU Lesser General Public
25 -License along with this library; if not, write to the Free Software
26 -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
51 -# include <strings.h>
73 -# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
75 -# define dirent direct
76 -# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
78 -# include <sys/ndir.h>
81 -# include <sys/dir.h>
95 -# define assert(arg) ((void) 0)
101 -# include <dmalloc.h>
107 -/* --- WINDOWS SUPPORT --- */
111 -# define LT_GLOBAL_DATA __declspec(dllexport)
113 -# define LT_GLOBAL_DATA
116 -/* fopen() mode flags for reading a text file */
117 -#undef LT_READTEXT_MODE
119 -# define LT_READTEXT_MODE "rt"
121 -# define LT_READTEXT_MODE "r"
127 -/* --- MANIFEST CONSTANTS --- */
130 -/* Standard libltdl search path environment variable name */
131 -#undef LTDL_SEARCHPATH_VAR
132 -#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
134 -/* Standard libtool archive file extension. */
135 -#undef LTDL_ARCHIVE_EXT
136 -#define LTDL_ARCHIVE_EXT ".la"
138 -/* max. filename length */
139 -#ifndef LT_FILENAME_MAX
140 -# define LT_FILENAME_MAX 1024
143 -/* This is the maximum symbol size that won't require malloc/free */
144 -#undef LT_SYMBOL_LENGTH
145 -#define LT_SYMBOL_LENGTH 128
147 -/* This accounts for the _LTX_ separator */
148 -#undef LT_SYMBOL_OVERHEAD
149 -#define LT_SYMBOL_OVERHEAD 5
154 -/* --- MEMORY HANDLING --- */
157 -/* These are the functions used internally. In addition to making
158 - use of the associated function pointers above, they also perform
160 -static char *lt_estrdup LT_PARAMS((const char *str));
161 -static lt_ptr lt_emalloc LT_PARAMS((size_t size));
162 -static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size));
164 -static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size));
166 -/* These are the pointers that can be changed by the caller: */
167 -LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
168 - = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
169 -LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size))
170 - = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
171 -LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
172 - = (void (*) LT_PARAMS((lt_ptr))) free;
174 -/* The following macros reduce the amount of typing needed to cast
175 - assigned memory. */
178 -#define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
179 -#define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
180 -#define LT_DLFREE(p) \
181 - LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
183 -#define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
184 -#define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
188 -#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
189 -#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
190 -#define LT_DLFREE(p) \
191 - LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
193 -#define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
194 -#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
198 -#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
199 - if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \
203 -/* --- REPLACEMENT FUNCTIONS --- */
207 -#define strdup rpl_strdup
209 -static char *strdup LT_PARAMS((const char *str));
219 - tmp = LT_DLMALLOC (char, 1+ strlen (str));
233 -#define strcmp rpl_strcmp
235 -static int strcmp LT_PARAMS((const char *str1, const char *str2));
249 - for (;*str1 && *str2; ++str1, ++str2)
251 - if (*str1 != *str2)
255 - return (int)(*str1 - *str2);
263 -# define strchr index
265 -# define strchr rpl_strchr
267 -static const char *strchr LT_PARAMS((const char *str, int ch));
276 - for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
279 - return (*p == (char)ch) ? p : 0;
283 -#endif /* !HAVE_STRCHR */
289 -# define strrchr rindex
291 -# define strrchr rpl_strrchr
293 -static const char *strrchr LT_PARAMS((const char *str, int ch));
300 - const char *p, *q = 0;
302 - for (p = str; *p != LT_EOS_CHAR; ++p)
304 - if (*p == (char) ch)
316 -/* NOTE: Neither bcopy nor the memcpy implementation below can
317 - reliably handle copying in overlapping areas of memory. Use
318 - memmove (for which there is a fallback implmentation below)
319 - if you need that behaviour. */
323 -# define memcpy(dest, src, size) bcopy (src, dest, size)
325 -# define memcpy rpl_memcpy
327 -static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
330 -memcpy (dest, src, size)
337 - for (i = 0; i < size; ++i)
345 -# endif /* !HAVE_BCOPY */
346 -#endif /* !HAVE_MEMCPY */
349 -# define memmove rpl_memmove
351 -static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
354 -memmove (dest, src, size)
362 - for (i = 0; i < size; ++i)
366 - else if (dest > src)
367 - for (i = size -1; i >= 0; --i)
375 -#endif /* !HAVE_MEMMOVE */
378 -/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
379 - ``realloc is not entirely portable''
380 - In any case we want to use the allocator supplied by the user without
381 - burdening them with an lt_dlrealloc function pointer to maintain.
382 - Instead implement our own version (with known boundary conditions)
383 - using lt_dlmalloc and lt_dlfree. */
386 -#define realloc rpl_realloc
395 - /* For zero or less bytes, free the original memory */
405 - /* Allow reallocation of a NULL pointer. */
406 - return lt_dlmalloc (size);
410 - /* Allocate a new block, copy and free the old block. */
411 - lt_ptr mem = lt_dlmalloc (size);
415 - memcpy (mem, ptr, size);
419 - /* Note that the contents of PTR are not damaged if there is
420 - insufficient memory to realloc. */
426 -#if ! HAVE_ARGZ_APPEND
427 -# define argz_append rpl_argz_append
429 -static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
430 - const char *buf, size_t buf_len));
433 -argz_append (pargz, pargz_len, buf, buf_len)
443 - assert (pargz_len);
444 - assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
446 - /* If nothing needs to be appended, no more work is required. */
450 - /* Ensure there is enough room to append BUF_LEN. */
451 - argz_len = *pargz_len + buf_len;
452 - argz = LT_DLREALLOC (char, *pargz, argz_len);
456 - /* Copy characters from BUF after terminating '\0' in ARGZ. */
457 - memcpy (argz + *pargz_len, buf, buf_len);
459 - /* Assign new values. */
461 - *pargz_len = argz_len;
465 -#endif /* !HAVE_ARGZ_APPEND */
468 -#if ! HAVE_ARGZ_CREATE_SEP
469 -# define argz_create_sep rpl_argz_create_sep
471 -static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
472 - char **pargz, size_t *pargz_len));
475 -argz_create_sep (str, delim, pargz, pargz_len)
486 - assert (pargz_len);
488 - /* Make a copy of STR, but replacing each occurence of
489 - DELIM with '\0'. */
490 - argz_len = 1+ LT_STRLEN (str);
496 - argz = LT_DLMALLOC (char, argz_len);
500 - for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
504 - /* Ignore leading delimiters, and fold consecutive
505 - delimiters in STR into a single '\0' in ARGZ. */
506 - if ((q > argz) && (q[-1] != LT_EOS_CHAR))
507 - *q++ = LT_EOS_CHAR;
514 - /* Copy terminating LT_EOS_CHAR. */
518 - /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
522 - /* Assign new values. */
524 - *pargz_len = argz_len;
528 -#endif /* !HAVE_ARGZ_CREATE_SEP */
531 -#if ! HAVE_ARGZ_INSERT
532 -# define argz_insert rpl_argz_insert
534 -static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
535 - char *before, const char *entry));
538 -argz_insert (pargz, pargz_len, before, entry)
545 - assert (pargz_len);
546 - assert (entry && *entry);
548 - /* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL,
549 - or BEFORE points into an address within the ARGZ vector. */
550 - assert ((!*pargz && !*pargz_len && !before)
551 - || ((*pargz <= before) && (before < (*pargz + *pargz_len))));
553 - /* No BEFORE address indicates ENTRY should be inserted after the
554 - current last element. */
556 - return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
558 - /* This probably indicates a programmer error, but to preserve
559 - semantics, scan back to the start of an entry if BEFORE points
560 - into the middle of it. */
561 - while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR))
565 - size_t entry_len = 1+ LT_STRLEN (entry);
566 - size_t argz_len = *pargz_len + entry_len;
567 - size_t offset = before - *pargz;
568 - char *argz = LT_DLREALLOC (char, *pargz, argz_len);
573 - /* Make BEFORE point to the equivalent offset in ARGZ that it
574 - used to have in *PARGZ incase realloc() moved the block. */
575 - before = argz + offset;
577 - /* Move the ARGZ entries starting at BEFORE up into the new
578 - space at the end -- making room to copy ENTRY into the
580 - memmove (before + entry_len, before, *pargz_len - offset);
581 - memcpy (before, entry, entry_len);
583 - /* Assign new values. */
585 - *pargz_len = argz_len;
590 -#endif /* !HAVE_ARGZ_INSERT */
593 -#if ! HAVE_ARGZ_NEXT
594 -# define argz_next rpl_argz_next
596 -static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
597 - const char *entry));
600 -argz_next (argz, argz_len, entry)
605 - assert ((argz && argz_len) || (!argz && !argz_len));
609 - /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
610 - within the ARGZ vector. */
611 - assert ((!argz && !argz_len)
612 - || ((argz <= entry) && (entry < (argz + argz_len))));
614 - /* Move to the char immediately after the terminating
616 - entry = 1+ strchr (entry, LT_EOS_CHAR);
618 - /* Return either the new ENTRY, or else NULL if ARGZ is
620 - return (entry >= argz + argz_len) ? 0 : (char *) entry;
624 - /* This should probably be flagged as a programmer error,
625 - since starting an argz_next loop with the iterator set
626 - to ARGZ is safer. To preserve semantics, handle the NULL
627 - case by returning the start of ARGZ (if any). */
634 -#endif /* !HAVE_ARGZ_NEXT */
638 -#if ! HAVE_ARGZ_STRINGIFY
639 -# define argz_stringify rpl_argz_stringify
641 -static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
645 -argz_stringify (argz, argz_len, sep)
650 - assert ((argz && argz_len) || (!argz && !argz_len));
654 - --argz_len; /* don't stringify the terminating EOS */
655 - while (--argz_len > 0)
657 - if (argz[argz_len] == LT_EOS_CHAR)
658 - argz[argz_len] = sep;
662 -#endif /* !HAVE_ARGZ_STRINGIFY */
667 -/* --- TYPE DEFINITIONS -- */
670 -/* This type is used for the array of caller data sets in each handler. */
672 - lt_dlcaller_id key;
679 -/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
682 -/* Extract the diagnostic strings from the error table macro in the same
683 - order as the enumerated indices in ltdl.h. */
685 -static const char *lt_dlerror_strings[] =
687 -#define LT_ERROR(name, diagnostic) (diagnostic),
694 -/* This structure is used for the list of registered loaders. */
695 -struct lt_dlloader {
696 - struct lt_dlloader *next;
697 - const char *loader_name; /* identifying name for each loader */
698 - const char *sym_prefix; /* prefix for symbols */
699 - lt_module_open *module_open;
700 - lt_module_close *module_close;
701 - lt_find_sym *find_sym;
702 - lt_dlloader_exit *dlloader_exit;
703 - lt_user_data dlloader_data;
706 -struct lt_dlhandle_struct {
707 - struct lt_dlhandle_struct *next;
708 - lt_dlloader *loader; /* dlopening interface */
710 - int depcount; /* number of dependencies */
711 - lt_dlhandle *deplibs; /* dependencies */
712 - lt_module module; /* system module handle */
713 - lt_ptr system; /* system specific data */
714 - lt_caller_data *caller_data; /* per caller associated data */
715 - int flags; /* various boolean stats */
718 -/* Various boolean flags can be stored in the flags field of an
719 - lt_dlhandle_struct... */
720 -#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
721 -#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
723 -#define LT_DLRESIDENT_FLAG (0x01 << 0)
724 -/* ...add more flags here... */
726 -#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
729 -#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
731 -static const char objdir[] = LTDL_OBJDIR;
732 -static const char archive_ext[] = LTDL_ARCHIVE_EXT;
733 -#ifdef LTDL_SHLIB_EXT
734 -static const char shlib_ext[] = LTDL_SHLIB_EXT;
736 -#ifdef LTDL_SYSSEARCHPATH
737 -static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
743 -/* --- MUTEX LOCKING --- */
746 -/* Macros to make it easier to run the lock functions only if they have
747 - been registered. The reason for the complicated lock macro is to
748 - ensure that the stored error message from the last error is not
749 - accidentally erased if the current function doesn't generate an
750 - error of its own. */
751 -#define LT_DLMUTEX_LOCK() LT_STMT_START { \
752 - if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
754 -#define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
755 - if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
757 -#define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
758 - if (lt_dlmutex_seterror_func) \
759 - (*lt_dlmutex_seterror_func) (errormsg); \
760 - else lt_dllast_error = (errormsg); } LT_STMT_END
761 -#define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
762 - if (lt_dlmutex_seterror_func) \
763 - (errormsg) = (*lt_dlmutex_geterror_func) (); \
764 - else (errormsg) = lt_dllast_error; } LT_STMT_END
766 -/* The mutex functions stored here are global, and are necessarily the
767 - same for all threads that wish to share access to libltdl. */
768 -static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
769 -static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
770 -static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
771 -static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
772 -static const char *lt_dllast_error = 0;
775 -/* Either set or reset the mutex functions. Either all the arguments must
776 - be valid functions, or else all can be NULL to turn off locking entirely.
777 - The registered functions should be manipulating a static global lock
778 - from the lock() and unlock() callbacks, which needs to be reentrant. */
780 -lt_dlmutex_register (lock, unlock, seterror, geterror)
781 - lt_dlmutex_lock *lock;
782 - lt_dlmutex_unlock *unlock;
783 - lt_dlmutex_seterror *seterror;
784 - lt_dlmutex_geterror *geterror;
786 - lt_dlmutex_unlock *old_unlock = unlock;
789 - /* Lock using the old lock() callback, if any. */
790 - LT_DLMUTEX_LOCK ();
792 - if ((lock && unlock && seterror && geterror)
793 - || !(lock || unlock || seterror || geterror))
795 - lt_dlmutex_lock_func = lock;
796 - lt_dlmutex_unlock_func = unlock;
797 - lt_dlmutex_geterror_func = geterror;
801 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
805 - /* Use the old unlock() callback we saved earlier, if any. Otherwise
806 - record any errors using internal storage. */
810 - /* Return the number of errors encountered during the execution of
818 -/* --- ERROR HANDLING --- */
821 -static const char **user_error_strings = 0;
822 -static int errorcount = LT_ERROR_MAX;
825 -lt_dladderror (diagnostic)
826 - const char *diagnostic;
830 - const char **temp = (const char **) 0;
832 - assert (diagnostic);
834 - LT_DLMUTEX_LOCK ();
836 - errindex = errorcount - LT_ERROR_MAX;
837 - temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
840 - user_error_strings = temp;
841 - user_error_strings[errindex] = diagnostic;
842 - result = errorcount++;
845 - LT_DLMUTEX_UNLOCK ();
851 -lt_dlseterror (errindex)
856 - LT_DLMUTEX_LOCK ();
858 - if (errindex >= errorcount || errindex < 0)
860 - /* Ack! Error setting the error message! */
861 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
864 - else if (errindex < LT_ERROR_MAX)
866 - /* No error setting the error message! */
867 - LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
871 - /* No error setting the error message! */
872 - LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
875 - LT_DLMUTEX_UNLOCK ();
884 - lt_ptr mem = lt_dlmalloc (size);
886 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
891 -lt_erealloc (addr, size)
895 - lt_ptr mem = realloc (addr, size);
897 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
905 - char *copy = strdup (str);
906 - if (LT_STRLEN (str) && !copy)
907 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
914 -/* --- DLOPEN() INTERFACE LOADER --- */
917 -/* The Cygwin dlopen implementation prints a spurious error message to
918 - stderr if its call to LoadLibrary() fails for any reason. We can
919 - mitigate this by not using the Cygwin implementation, and falling
920 - back to our own LoadLibrary() wrapper. */
921 -#if HAVE_LIBDL && !defined(__CYGWIN__)
923 -/* dynamic linking with dlopen/dlsym */
930 -# include <sys/dl.h>
934 -# define LT_GLOBAL RTLD_GLOBAL
937 -# define LT_GLOBAL DL_GLOBAL
939 -#endif /* !RTLD_GLOBAL */
941 -# define LT_GLOBAL 0
942 -#endif /* !LT_GLOBAL */
944 -/* We may have to define LT_LAZY_OR_NOW in the command line if we
945 - find out it does not work in some platform. */
946 -#ifndef LT_LAZY_OR_NOW
948 -# define LT_LAZY_OR_NOW RTLD_LAZY
951 -# define LT_LAZY_OR_NOW DL_LAZY
953 -# endif /* !RTLD_LAZY */
955 -#ifndef LT_LAZY_OR_NOW
957 -# define LT_LAZY_OR_NOW RTLD_NOW
960 -# define LT_LAZY_OR_NOW DL_NOW
962 -# endif /* !RTLD_NOW */
964 -#ifndef LT_LAZY_OR_NOW
965 -# define LT_LAZY_OR_NOW 0
966 -#endif /* !LT_LAZY_OR_NOW */
969 -# define DLERROR(arg) dlerror ()
971 -# define DLERROR(arg) LT_DLSTRERROR (arg)
975 -sys_dl_open (loader_data, filename)
976 - lt_user_data loader_data;
977 - const char *filename;
979 - lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
983 - LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
990 -sys_dl_close (loader_data, module)
991 - lt_user_data loader_data;
996 - if (dlclose (module) != 0)
998 - LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
1006 -sys_dl_sym (loader_data, module, symbol)
1007 - lt_user_data loader_data;
1009 - const char *symbol;
1011 - lt_ptr address = dlsym (module, symbol);
1015 - LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
1021 -static struct lt_user_dlloader sys_dl =
1023 -# ifdef NEED_USCORE
1028 - sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
1031 -#endif /* HAVE_LIBDL */
1035 -/* --- SHL_LOAD() INTERFACE LOADER --- */
1039 -/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1045 -/* some flags are missing on some systems, so we provide
1046 - * harmless defaults.
1049 - * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1050 - * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1053 - * BIND_FIRST - Place the library at the head of the symbol search
1055 - * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1056 - * unsatisfied symbols as fatal. This flag allows
1057 - * binding of unsatisfied code symbols to be deferred
1059 - * [Perl: For certain libraries, like DCE, deferred
1060 - * binding often causes run time problems. Adding
1061 - * BIND_NONFATAL to BIND_IMMEDIATE still allows
1062 - * unresolved references in situations like this.]
1063 - * BIND_NOSTART - Do not call the initializer for the shared library
1064 - * when the library is loaded, nor on a future call to
1066 - * BIND_VERBOSE - Print verbose messages concerning possible
1067 - * unsatisfied symbols.
1069 - * hp9000s700/hp9000s800:
1070 - * BIND_RESTRICTED - Restrict symbols visible by the library to those
1071 - * present at library load time.
1072 - * DYNAMIC_PATH - Allow the loader to dynamically search for the
1073 - * library specified by the path argument.
1076 -#ifndef DYNAMIC_PATH
1077 -# define DYNAMIC_PATH 0
1079 -#ifndef BIND_RESTRICTED
1080 -# define BIND_RESTRICTED 0
1083 -#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1086 -sys_shl_open (loader_data, filename)
1087 - lt_user_data loader_data;
1088 - const char *filename;
1090 - static shl_t self = (shl_t) 0;
1091 - lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1093 - /* Since searching for a symbol against a NULL module handle will also
1094 - look in everything else that was already loaded and exported with
1095 - the -E compiler flag, we always cache a handle saved before any
1096 - modules are loaded. */
1100 - shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1109 - module = shl_load (filename, LT_BIND_FLAGS, 0L);
1113 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1121 -sys_shl_close (loader_data, module)
1122 - lt_user_data loader_data;
1127 - if (module && (shl_unload ((shl_t) (module)) != 0))
1129 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1137 -sys_shl_sym (loader_data, module, symbol)
1138 - lt_user_data loader_data;
1140 - const char *symbol;
1142 - lt_ptr address = 0;
1144 - /* sys_shl_open should never return a NULL module handle */
1145 - if (module == (lt_module) 0)
1147 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1149 - else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
1153 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1160 -static struct lt_user_dlloader sys_shl = {
1161 - 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
1164 -#endif /* HAVE_SHL_LOAD */
1169 -/* --- LOADLIBRARY() INTERFACE LOADER --- */
1173 -/* dynamic linking for Win32 */
1175 -#include <windows.h>
1177 -/* Forward declaration; required to implement handle search below. */
1178 -static lt_dlhandle handles;
1181 -sys_wll_open (loader_data, filename)
1182 - lt_user_data loader_data;
1183 - const char *filename;
1186 - lt_module module = 0;
1187 - const char *errormsg = 0;
1188 - char *searchname = 0;
1190 - char self_name_buf[MAX_PATH];
1194 - /* Get the name of main module */
1195 - *self_name_buf = 0;
1196 - GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
1197 - filename = ext = self_name_buf;
1201 - ext = strrchr (filename, '.');
1206 - /* FILENAME already has an extension. */
1207 - searchname = lt_estrdup (filename);
1211 - /* Append a `.' to stop Windows from adding an
1212 - implicit `.dll' extension. */
1213 - searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
1215 - sprintf (searchname, "%s.", filename);
1222 - char wpath[MAX_PATH];
1223 - cygwin_conv_to_full_win32_path(searchname, wpath);
1224 - module = LoadLibrary(wpath);
1227 - module = LoadLibrary (searchname);
1229 - LT_DLFREE (searchname);
1231 - /* libltdl expects this function to fail if it is unable
1232 - to physically load the library. Sadly, LoadLibrary
1233 - will search the loaded libraries for a match and return
1234 - one of them if the path search load fails.
1236 - We check whether LoadLibrary is returning a handle to
1237 - an already loaded module, and simulate failure if we
1239 - LT_DLMUTEX_LOCK ();
1249 - if (cur->module == module)
1256 - LT_DLMUTEX_UNLOCK ();
1258 - if (cur || !module)
1260 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1268 -sys_wll_close (loader_data, module)
1269 - lt_user_data loader_data;
1274 - if (FreeLibrary(module) == 0)
1276 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1284 -sys_wll_sym (loader_data, module, symbol)
1285 - lt_user_data loader_data;
1287 - const char *symbol;
1289 - lt_ptr address = GetProcAddress (module, symbol);
1293 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1299 -static struct lt_user_dlloader sys_wll = {
1300 - 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1303 -#endif /* __WINDOWS__ */
1305 + Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
1306 + 2007, 2008 Free Software Foundation, Inc.
1307 + Written by Thomas Tanner, 1998
1309 + NOTE: The canonical source of this file is maintained with the
1310 + GNU Libtool package. Report bugs to bug-libtool@gnu.org.
1313 -/* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1318 -/* dynamic linking for BeOS */
1320 -#include <kernel/image.h>
1323 -sys_bedl_open (loader_data, filename)
1324 - lt_user_data loader_data;
1325 - const char *filename;
1327 - image_id image = 0;
1331 - image = load_add_on (filename);
1337 - if (get_next_image_info (0, &cookie, &info) == B_OK)
1338 - image = load_add_on (info.name);
1343 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1347 - return (lt_module) image;
1351 -sys_bedl_close (loader_data, module)
1352 - lt_user_data loader_data;
1357 - if (unload_add_on ((image_id) module) != B_OK)
1359 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1367 -sys_bedl_sym (loader_data, module, symbol)
1368 - lt_user_data loader_data;
1370 - const char *symbol;
1372 - lt_ptr address = 0;
1373 - image_id image = (image_id) module;
1375 - if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1377 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1380 +GNU Libltdl is free software; you can redistribute it and/or
1381 +modify it under the terms of the GNU Lesser General Public
1382 +License as published by the Free Software Foundation; either
1383 +version 2 of the License, or (at your option) any later version.
1387 +As a special exception to the GNU Lesser General Public License,
1388 +if you distribute this file as part of a program or library that
1389 +is built using GNU Libtool, you may include this file under the
1390 +same distribution terms that you use for the rest of that program.
1392 -static struct lt_user_dlloader sys_bedl = {
1393 - 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1395 +GNU Libltdl is distributed in the hope that it will be useful,
1396 +but WITHOUT ANY WARRANTY; without even the implied warranty of
1397 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1398 +GNU Lesser General Public License for more details.
1400 -#endif /* __BEOS__ */
1401 +You should have received a copy of the GNU Lesser General Public
1402 +License along with GNU Libltdl; see the file COPYING.LIB. If not, a
1403 +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html,
1404 +or obtained by writing to the Free Software Foundation, Inc.,
1405 +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1408 +#include "lt__private.h"
1409 +#include "lt_system.h"
1410 +#include "lt_dlloader.h"
1414 -/* --- DLD_LINK() INTERFACE LOADER --- */
1415 +/* --- MANIFEST CONSTANTS --- */
1419 +/* Standard libltdl search path environment variable name */
1420 +#undef LTDL_SEARCHPATH_VAR
1421 +#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
1423 -/* dynamic linking with dld */
1424 +/* Standard libtool archive file extension. */
1425 +#undef LT_ARCHIVE_EXT
1426 +#define LT_ARCHIVE_EXT ".la"
1430 +/* max. filename length */
1431 +#if !defined(LT_FILENAME_MAX)
1432 +# define LT_FILENAME_MAX 1024
1436 -sys_dld_open (loader_data, filename)
1437 - lt_user_data loader_data;
1438 - const char *filename;
1440 - lt_module module = strdup (filename);
1442 - if (dld_link (filename) != 0)
1444 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1445 - LT_DLFREE (module);
1453 -sys_dld_close (loader_data, module)
1454 - lt_user_data loader_data;
1459 - if (dld_unlink_by_file ((char*)(module), 1) != 0)
1461 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1466 - LT_DLFREE (module);
1471 +#if !defined(LT_LIBEXT)
1472 +# define LT_LIBEXT "a"
1476 -sys_dld_sym (loader_data, module, symbol)
1477 - lt_user_data loader_data;
1479 - const char *symbol;
1481 - lt_ptr address = dld_get_func (symbol);
1482 +/* This is the maximum symbol size that won't require malloc/free */
1483 +#undef LT_SYMBOL_LENGTH
1484 +#define LT_SYMBOL_LENGTH 128
1488 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1490 +/* This accounts for the _LTX_ separator */
1491 +#undef LT_SYMBOL_OVERHEAD
1492 +#define LT_SYMBOL_OVERHEAD 5
1496 +/* Various boolean flags can be stored in the flags field of an
1498 +#define LT_DLIS_RESIDENT(handle) ((handle)->info.is_resident)
1499 +#define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal)
1500 +#define LT_DLIS_SYMLOCAL(handle) ((handle)->info.is_symlocal)
1502 -static struct lt_user_dlloader sys_dld = {
1503 - 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1506 -#endif /* HAVE_DLD */
1507 +static const char objdir[] = LT_OBJDIR;
1508 +static const char archive_ext[] = LT_ARCHIVE_EXT;
1509 +static const char libext[] = LT_LIBEXT;
1510 +#if defined(LT_MODULE_EXT)
1511 +static const char shlib_ext[] = LT_MODULE_EXT;
1513 +#if defined(LT_DLSEARCH_PATH)
1514 +static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH;
1520 -/* --- DLPREOPEN() INTERFACE LOADER --- */
1523 -/* emulate dynamic linking using preloaded_symbols */
1525 -typedef struct lt_dlsymlists_t
1527 - struct lt_dlsymlists_t *next;
1528 - const lt_dlsymlist *syms;
1531 -static const lt_dlsymlist *default_preloaded_symbols = 0;
1532 -static lt_dlsymlists_t *preloaded_symbols = 0;
1535 -presym_init (loader_data)
1536 - lt_user_data loader_data;
1540 - LT_DLMUTEX_LOCK ();
1542 - preloaded_symbols = 0;
1543 - if (default_preloaded_symbols)
1545 - errors = lt_dlpreload (default_preloaded_symbols);
1547 +/* --- DYNAMIC MODULE LOADING --- */
1549 - LT_DLMUTEX_UNLOCK ();
1552 +/* The type of a function used at each iteration of foreach_dirinpath(). */
1553 +typedef int foreach_callback_func (char *filename, void *data1,
1555 +/* foreachfile_callback itself calls a function of this type: */
1556 +typedef int file_worker_func (const char *filename, void *data);
1559 +static int foreach_dirinpath (const char *search_path,
1560 + const char *base_name,
1561 + foreach_callback_func *func,
1562 + void *data1, void *data2);
1563 +static int find_file_callback (char *filename, void *data1,
1565 +static int find_handle_callback (char *filename, void *data,
1567 +static int foreachfile_callback (char *filename, void *data1,
1571 +static int canonicalize_path (const char *path, char **pcanonical);
1572 +static int argzize_path (const char *path,
1573 + char **pargz, size_t *pargz_len);
1574 +static FILE *find_file (const char *search_path,
1575 + const char *base_name, char **pdir);
1576 +static lt_dlhandle *find_handle (const char *search_path,
1577 + const char *base_name,
1578 + lt_dlhandle *handle,
1579 + lt_dladvise advise);
1580 +static int find_module (lt_dlhandle *handle, const char *dir,
1581 + const char *libdir, const char *dlname,
1582 + const char *old_name, int installed,
1583 + lt_dladvise advise);
1584 +static int has_library_ext (const char *filename);
1585 +static int load_deplibs (lt_dlhandle handle, char *deplibs);
1586 +static int trim (char **dest, const char *str);
1587 +static int try_dlopen (lt_dlhandle *handle,
1588 + const char *filename, const char *ext,
1589 + lt_dladvise advise);
1590 +static int tryall_dlopen (lt_dlhandle *handle,
1591 + const char *filename,
1592 + lt_dladvise padvise,
1593 + const lt_dlvtable *vtable);
1594 +static int unload_deplibs (lt_dlhandle handle);
1595 +static int lt_argz_insert (char **pargz, size_t *pargz_len,
1596 + char *before, const char *entry);
1597 +static int lt_argz_insertinorder (char **pargz, size_t *pargz_len,
1598 + const char *entry);
1599 +static int lt_argz_insertdir (char **pargz, size_t *pargz_len,
1600 + const char *dirnam, struct dirent *dp);
1601 +static int lt_dlpath_insertdir (char **ppath, char *before,
1603 +static int list_files_by_dir (const char *dirnam,
1604 + char **pargz, size_t *pargz_len);
1605 +static int file_not_found (void);
1607 +#ifdef HAVE_LIBDLLOADER
1608 +static int loader_init_callback (lt_dlhandle handle);
1609 +#endif /* HAVE_LIBDLLOADER */
1611 +static int loader_init (lt_get_vtable *vtable_func,
1612 + lt_user_data data);
1614 +static char *user_search_path= 0;
1615 +static lt_dlhandle handles = 0;
1616 +static int initialized = 0;
1618 +/* Our memory failure callback sets the error message to be passed back
1619 + up to the client, so we must be careful to return from mallocation
1620 + callers if allocation fails (as this callback returns!!). */
1622 +lt__alloc_die_callback (void)
1624 + LT__SETERROR (NO_MEMORY);
1627 +#ifdef HAVE_LIBDLLOADER
1628 +/* This function is called to initialise each preloaded module loader,
1629 + and hook it into the list of loaders to be used when attempting to
1630 + dlopen an application module. */
1632 +loader_init_callback (lt_dlhandle handle)
1634 + lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable");
1635 + return loader_init (vtable_func, 0);
1637 +#endif /* HAVE_LIBDLLOADER */
1640 -presym_free_symlists ()
1641 +loader_init (lt_get_vtable *vtable_func, lt_user_data data)
1643 - lt_dlsymlists_t *lists;
1645 - LT_DLMUTEX_LOCK ();
1646 + const lt_dlvtable *vtable = 0;
1649 - lists = preloaded_symbols;
1653 - lt_dlsymlists_t *tmp = lists;
1655 - lists = lists->next;
1657 + vtable = (*vtable_func) (data);
1659 - preloaded_symbols = 0;
1661 - LT_DLMUTEX_UNLOCK ();
1667 -presym_exit (loader_data)
1668 - lt_user_data loader_data;
1670 - presym_free_symlists ();
1675 -presym_add_symlist (preloaded)
1676 - const lt_dlsymlist *preloaded;
1678 - lt_dlsymlists_t *tmp;
1679 - lt_dlsymlists_t *lists;
1682 - LT_DLMUTEX_LOCK ();
1683 + /* lt_dlloader_add will LT__SETERROR if it fails. */
1684 + errors += lt_dlloader_add (vtable);
1686 - lists = preloaded_symbols;
1689 - if (lists->syms == preloaded)
1693 - lists = lists->next;
1695 + assert (errors || vtable);
1697 - tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
1700 - memset (tmp, 0, sizeof(lt_dlsymlists_t));
1701 - tmp->syms = preloaded;
1702 - tmp->next = preloaded_symbols;
1703 - preloaded_symbols = tmp;
1706 + if ((!errors) && vtable->dlloader_init)
1709 + if ((*vtable->dlloader_init) (vtable->dlloader_data))
1711 + LT__SETERROR (INIT_LOADER);
1717 - LT_DLMUTEX_UNLOCK ();
1722 -presym_open (loader_data, filename)
1723 - lt_user_data loader_data;
1724 - const char *filename;
1726 - lt_dlsymlists_t *lists;
1727 - lt_module module = (lt_module) 0;
1729 - LT_DLMUTEX_LOCK ();
1730 - lists = preloaded_symbols;
1734 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
1738 - /* Can't use NULL as the reflective symbol header, as NULL is
1739 - used to mark the end of the entire symbol list. Self-dlpreopened
1740 - symbols follow this magic number, chosen to be an unlikely
1741 - clash with a real module name. */
1744 - filename = "@PROGRAM@";
1749 - const lt_dlsymlist *syms = lists->syms;
1751 - while (syms->name)
1753 - if (!syms->address && strcmp(syms->name, filename) == 0)
1755 - module = (lt_module) syms;
1761 - lists = lists->next;
1764 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
1767 - LT_DLMUTEX_UNLOCK ();
1772 -presym_close (loader_data, module)
1773 - lt_user_data loader_data;
1776 - /* Just to silence gcc -Wall */
1782 -presym_sym (loader_data, module, symbol)
1783 - lt_user_data loader_data;
1785 - const char *symbol;
1787 - lt_dlsymlist *syms = (lt_dlsymlist*) module;
1790 - while (syms->address)
1792 - if (strcmp(syms->name, symbol) == 0)
1794 - return syms->address;
1800 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1805 -static struct lt_user_dlloader presym = {
1806 - 0, presym_open, presym_close, presym_sym, presym_exit, 0
1813 -/* --- DYNAMIC MODULE LOADING --- */
1816 -/* The type of a function used at each iteration of foreach_dirinpath(). */
1817 -typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
1819 +/* Bootstrap the loader loading with the preopening loader. */
1820 +#define get_vtable preopen_LTX_get_vtable
1821 +#define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
1823 -static int foreach_dirinpath LT_PARAMS((const char *search_path,
1824 - const char *base_name,
1825 - foreach_callback_func *func,
1826 - lt_ptr data1, lt_ptr data2));
1828 -static int find_file_callback LT_PARAMS((char *filename, lt_ptr data,
1830 -static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data,
1832 -static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1,
1836 -static int canonicalize_path LT_PARAMS((const char *path,
1837 - char **pcanonical));
1838 -static int argzize_path LT_PARAMS((const char *path,
1840 - size_t *pargz_len));
1841 -static FILE *find_file LT_PARAMS((const char *search_path,
1842 - const char *base_name,
1844 -static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
1845 - const char *base_name,
1846 - lt_dlhandle *handle));
1847 -static int find_module LT_PARAMS((lt_dlhandle *handle,
1849 - const char *libdir,
1850 - const char *dlname,
1851 - const char *old_name,
1853 -static int free_vars LT_PARAMS((char *dlname, char *oldname,
1854 - char *libdir, char *deplibs));
1855 -static int load_deplibs LT_PARAMS((lt_dlhandle handle,
1857 -static int trim LT_PARAMS((char **dest,
1858 - const char *str));
1859 -static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
1860 - const char *filename));
1861 -static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
1862 - const char *filename));
1863 -static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
1864 -static int lt_argz_insert LT_PARAMS((char **pargz,
1865 - size_t *pargz_len,
1867 - const char *entry));
1868 -static int lt_argz_insertinorder LT_PARAMS((char **pargz,
1869 - size_t *pargz_len,
1870 - const char *entry));
1871 -static int lt_argz_insertdir LT_PARAMS((char **pargz,
1872 - size_t *pargz_len,
1873 - const char *dirnam,
1874 - struct dirent *dp));
1875 -static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
1877 - const char *dir));
1878 -static int list_files_by_dir LT_PARAMS((const char *dirnam,
1880 - size_t *pargz_len));
1881 -static int file_not_found LT_PARAMS((void));
1883 -static char *user_search_path= 0;
1884 -static lt_dlloader *loaders = 0;
1885 -static lt_dlhandle handles = 0;
1886 -static int initialized = 0;
1888 +LT_SCOPE const lt_dlvtable * get_vtable (lt_user_data data);
1890 +#ifdef HAVE_LIBDLLOADER
1891 +extern lt_dlsymlist preloaded_symbols;
1894 /* Initialize libltdl. */
1901 - LT_DLMUTEX_LOCK ();
1904 /* Initialize only at first call. */
1905 if (++initialized == 1)
1908 - user_search_path = 0; /* empty search path */
1910 -#if HAVE_LIBDL && !defined(__CYGWIN__)
1911 - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
1914 - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
1917 - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
1920 - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
1923 - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
1925 - errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
1927 - if (presym_init (presym.dlloader_data))
1929 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
1932 - else if (errors != 0)
1934 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
1939 - LT_DLMUTEX_UNLOCK ();
1945 -lt_dlpreload (preloaded)
1946 - const lt_dlsymlist *preloaded;
1952 - errors = presym_add_symlist (preloaded);
1953 + lt__alloc_die = lt__alloc_die_callback;
1955 + user_search_path = 0; /* empty search path */
1957 + /* First set up the statically loaded preload module loader, so
1958 + we can use it to preopen the other loaders we linked in at
1960 + errors += loader_init (get_vtable, 0);
1962 + /* Now open all the preloaded module loaders, so the application
1963 + can use _them_ to lt_dlopen its own modules. */
1964 +#ifdef HAVE_LIBDLLOADER
1967 + errors += lt_dlpreload (&preloaded_symbols);
1972 + errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback);
1974 +#endif /* HAVE_LIBDLLOADER */
1978 - presym_free_symlists();
1980 - LT_DLMUTEX_LOCK ();
1981 - if (default_preloaded_symbols)
1983 - errors = lt_dlpreload (default_preloaded_symbols);
1985 - LT_DLMUTEX_UNLOCK ();
1987 +#ifdef LT_DEBUG_LOADERS
1988 + lt_dlloader_dump();
1995 -lt_dlpreload_default (preloaded)
1996 - const lt_dlsymlist *preloaded;
1998 - LT_DLMUTEX_LOCK ();
1999 - default_preloaded_symbols = preloaded;
2000 - LT_DLMUTEX_UNLOCK ();
2008 /* shut down libltdl */
2009 - lt_dlloader *loader;
2012 - LT_DLMUTEX_LOCK ();
2014 + lt_dlloader *loader = 0;
2015 + lt_dlhandle handle = handles;
2020 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
2021 + LT__SETERROR (SHUTDOWN);
2025 @@ -1823,171 +269,236 @@
2026 /* shut down only at last call. */
2027 if (--initialized == 0)
2032 while (handles && LT_DLIS_RESIDENT (handles))
2034 - handles = handles->next;
2037 + handles = handles->next;
2040 /* close all modules */
2041 - for (level = 1; handles; ++level)
2043 - lt_dlhandle cur = handles;
2044 - int saw_nonresident = 0;
2048 - lt_dlhandle tmp = cur;
2050 - if (!LT_DLIS_RESIDENT (tmp))
2051 - saw_nonresident = 1;
2052 - if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
2054 - if (lt_dlclose (tmp))
2060 - /* done if only resident modules are left */
2061 - if (!saw_nonresident)
2064 + for (level = 1; handle; ++level)
2066 + lt_dlhandle cur = handles;
2067 + int saw_nonresident = 0;
2071 + lt_dlhandle tmp = cur;
2073 + if (!LT_DLIS_RESIDENT (tmp))
2075 + saw_nonresident = 1;
2076 + if (tmp->info.ref_count <= level)
2078 + if (lt_dlclose (tmp))
2082 + /* Make sure that the handle pointed to by 'cur' still exists.
2083 + lt_dlclose recursively closes dependent libraries which removes
2084 + them from the linked list. One of these might be the one
2085 + pointed to by 'cur'. */
2088 + for (tmp = handles; tmp; tmp = tmp->next)
2097 + /* done if only resident modules are left */
2098 + if (!saw_nonresident)
2102 + /* When removing loaders, we can only find out failure by testing
2103 + the error string, so avoid a spurious one from an earlier
2104 + failed command. */
2106 + LT__SETERRORSTR (0);
2108 /* close all loaders */
2111 - lt_dlloader *next = loader->next;
2112 - lt_user_data data = loader->dlloader_data;
2113 - if (loader->dlloader_exit && loader->dlloader_exit (data))
2118 - LT_DLMEM_REASSIGN (loader, next);
2121 + for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;)
2123 + lt_dlloader *next = (lt_dlloader *) lt_dlloader_next (loader);
2124 + lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader);
2126 + if ((vtable = lt_dlloader_remove ((char *) vtable->name)))
2132 + /* ignore errors due to resident modules */
2134 + LT__GETERROR (err);
2142 + FREE(user_search_path);
2146 - LT_DLMUTEX_UNLOCK ();
2151 +/* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME.
2152 + If the library is not successfully loaded, return non-zero. Otherwise,
2153 + the dlhandle is stored at the address given in PHANDLE. */
2155 -tryall_dlopen (handle, filename)
2156 - lt_dlhandle *handle;
2157 - const char *filename;
2160 - lt_dlloader *loader;
2161 - const char *saved_error;
2163 +tryall_dlopen (lt_dlhandle *phandle, const char *filename,
2164 + lt_dladvise advise, const lt_dlvtable *vtable)
2166 + lt_dlhandle handle = handles;
2167 + const char * saved_error = 0;
2170 - LT_DLMUTEX_GETERROR (saved_error);
2171 - LT_DLMUTEX_LOCK ();
2172 +#ifdef LT_DEBUG_LOADERS
2173 + fprintf (stderr, "tryall_dlopen (%s, %s)\n",
2174 + filename ? filename : "(null)",
2175 + vtable ? vtable->name : "(ALL)");
2180 + LT__GETERROR (saved_error);
2182 /* check whether the module was already opened */
2184 + for (;handle; handle = handle->next)
2186 - /* try to dlopen the program itself? */
2187 - if (!cur->info.filename && !filename)
2192 - if (cur->info.filename && filename
2193 - && strcmp (cur->info.filename, filename) == 0)
2199 + if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */
2200 + || (handle->info.filename && filename
2201 + && streq (handle->info.filename, filename)))
2210 - ++cur->info.ref_count;
2212 + ++handle->info.ref_count;
2213 + *phandle = handle;
2218 + handle = *phandle;
2221 - cur->info.filename = lt_estrdup (filename);
2222 - if (!cur->info.filename)
2227 + /* Comment out the check of file permissions using access.
2228 + This call seems to always return -1 with error EACCES.
2230 + /* We need to catch missing file errors early so that
2231 + file_not_found() can detect what happened.
2232 + if (access (filename, R_OK) != 0)
2234 + LT__SETERROR (FILE_NOT_FOUND);
2239 + handle->info.filename = lt__strdup (filename);
2240 + if (!handle->info.filename)
2248 - cur->info.filename = 0;
2249 + handle->info.filename = 0;
2254 - lt_user_data data = loader->dlloader_data;
2256 + lt_dlloader loader = lt_dlloader_next (0);
2257 + const lt_dlvtable *loader_vtable;
2259 - cur->module = loader->module_open (data, filename);
2263 + loader_vtable = vtable;
2265 + loader_vtable = lt_dlloader_get (loader);
2267 +#ifdef LT_DEBUG_LOADERS
2268 + fprintf (stderr, "Calling %s->module_open (%s)\n",
2269 + (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)",
2270 + filename ? filename : "(null)");
2272 + handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data,
2273 + filename, advise);
2274 +#ifdef LT_DEBUG_LOADERS
2275 + fprintf (stderr, " Result: %s\n",
2276 + handle->module ? "Success" : "Failed");
2279 + if (handle->module != 0)
2283 + handle->info.is_resident = advise->is_resident;
2284 + handle->info.is_symglobal = advise->is_symglobal;
2285 + handle->info.is_symlocal = advise->is_symlocal;
2290 + while (!vtable && (loader = lt_dlloader_next (loader)));
2292 - if (cur->module != 0)
2296 - loader = loader->next;
2298 + /* If VTABLE was given but couldn't open the module, or VTABLE wasn't
2299 + given but we exhausted all loaders without opening the module, bail
2301 + if ((vtable && !handle->module)
2302 + || (!vtable && !loader))
2304 + FREE (handle->info.filename);
2311 - LT_DLFREE (cur->info.filename);
2315 + handle->vtable = loader_vtable;
2318 - cur->loader = loader;
2319 - LT_DLMUTEX_SETERROR (saved_error);
2320 + LT__SETERRORSTR (saved_error);
2323 - LT_DLMUTEX_UNLOCK ();
2330 -tryall_dlopen_module (handle, prefix, dirname, dlname)
2331 - lt_dlhandle *handle;
2332 - const char *prefix;
2333 - const char *dirname;
2334 - const char *dlname;
2337 - char *filename = 0;
2338 - size_t filename_len = 0;
2339 - size_t dirname_len = LT_STRLEN (dirname);
2340 +tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
2341 + const char *dirname, const char *dlname,
2342 + lt_dladvise advise)
2345 + char *filename = 0;
2346 + size_t filename_len = 0;
2347 + size_t dirname_len = LT_STRLEN (dirname);
2352 -#ifdef LT_DIRSEP_CHAR
2353 +#if defined(LT_DIRSEP_CHAR)
2354 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2355 should make it into this function: */
2356 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
2359 - if (dirname[dirname_len -1] == '/')
2361 + if (dirname_len > 0)
2362 + if (dirname[dirname_len -1] == '/')
2364 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
2366 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2367 The PREFIX (if any) is handled below. */
2368 - filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
2369 + filename = MALLOC (char, filename_len + 1);
2373 @@ -1998,31 +509,28 @@
2374 shuffled. Otherwise, attempt to open FILENAME as a module. */
2377 - error += tryall_dlopen_module (handle,
2378 - (const char *) 0, prefix, filename);
2379 + error += tryall_dlopen_module (handle, (const char *) 0,
2380 + prefix, filename, advise);
2382 - else if (tryall_dlopen (handle, filename) != 0)
2383 + else if (tryall_dlopen (handle, filename, advise, 0) != 0)
2388 - LT_DLFREE (filename);
2394 -find_module (handle, dir, libdir, dlname, old_name, installed)
2395 - lt_dlhandle *handle;
2397 - const char *libdir;
2398 - const char *dlname;
2399 - const char *old_name;
2401 +find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
2402 + const char *dlname, const char *old_name, int installed,
2403 + lt_dladvise advise)
2405 /* Try to open the old library first; if it was dlpreopened,
2406 we want the preopened version of it, even if a dlopenable
2407 module is available. */
2408 - if (old_name && tryall_dlopen (handle, old_name) == 0)
2409 + if (old_name && tryall_dlopen (handle, old_name,
2410 + advise, lt_dlloader_find ("lt_preopen") ) == 0)
2414 @@ -2032,24 +540,25 @@
2416 /* try to open the installed module */
2417 if (installed && libdir)
2419 - if (tryall_dlopen_module (handle,
2420 - (const char *) 0, libdir, dlname) == 0)
2424 + if (tryall_dlopen_module (handle, (const char *) 0,
2425 + libdir, dlname, advise) == 0)
2429 /* try to open the not-installed module */
2432 - if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2436 + if (tryall_dlopen_module (handle, dir, objdir,
2437 + dlname, advise) == 0)
2441 /* maybe it was moved to another directory */
2443 - if (tryall_dlopen_module (handle,
2444 - (const char *) 0, dir, dlname) == 0)
2446 + if (dir && (tryall_dlopen_module (handle, (const char *) 0,
2447 + dir, dlname, advise) == 0))
2452 @@ -2058,16 +567,14 @@
2456 -canonicalize_path (path, pcanonical)
2458 - char **pcanonical;
2459 +canonicalize_path (const char *path, char **pcanonical)
2461 char *canonical = 0;
2463 assert (path && *path);
2464 assert (pcanonical);
2466 - canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2467 + canonical = MALLOC (char, 1+ LT_STRLEN (path));
2471 @@ -2076,38 +583,38 @@
2473 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2475 - /* Path separators are not copied to the beginning or end of
2476 - the destination, or if another separator would follow
2478 - if (path[src] == LT_PATHSEP_CHAR)
2481 - || (path[1+ src] == LT_PATHSEP_CHAR)
2482 - || (path[1+ src] == LT_EOS_CHAR))
2486 - /* Anything other than a directory separator is copied verbatim. */
2487 - if ((path[src] != '/')
2488 -#ifdef LT_DIRSEP_CHAR
2489 - && (path[src] != LT_DIRSEP_CHAR)
2493 - canonical[dest++] = path[src];
2495 - /* Directory separators are converted and copied only if they are
2496 - not at the end of a path -- i.e. before a path separator or
2497 - NULL terminator. */
2498 - else if ((path[1+ src] != LT_PATHSEP_CHAR)
2499 - && (path[1+ src] != LT_EOS_CHAR)
2500 -#ifdef LT_DIRSEP_CHAR
2501 - && (path[1+ src] != LT_DIRSEP_CHAR)
2503 - && (path[1+ src] != '/'))
2505 - canonical[dest++] = '/';
2507 + /* Path separators are not copied to the beginning or end of
2508 + the destination, or if another separator would follow
2510 + if (path[src] == LT_PATHSEP_CHAR)
2513 + || (path[1+ src] == LT_PATHSEP_CHAR)
2514 + || (path[1+ src] == LT_EOS_CHAR))
2518 + /* Anything other than a directory separator is copied verbatim. */
2519 + if ((path[src] != '/')
2520 +#if defined(LT_DIRSEP_CHAR)
2521 + && (path[src] != LT_DIRSEP_CHAR)
2525 + canonical[dest++] = path[src];
2527 + /* Directory separators are converted and copied only if they are
2528 + not at the end of a path -- i.e. before a path separator or
2529 + NULL terminator. */
2530 + else if ((path[1+ src] != LT_PATHSEP_CHAR)
2531 + && (path[1+ src] != LT_EOS_CHAR)
2532 +#if defined(LT_DIRSEP_CHAR)
2533 + && (path[1+ src] != LT_DIRSEP_CHAR)
2535 + && (path[1+ src] != '/'))
2537 + canonical[dest++] = '/';
2541 /* Add an end-of-string marker at the end. */
2542 @@ -2121,10 +628,7 @@
2546 -argzize_path (path, pargz, pargz_len)
2549 - size_t *pargz_len;
2550 +argzize_path (const char *path, char **pargz, size_t *pargz_len)
2554 @@ -2135,14 +639,14 @@
2555 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2560 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2563 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2568 + LT__SETERROR (NO_MEMORY);
2571 + LT__SETERROR (UNKNOWN);
2577 @@ -2155,26 +659,20 @@
2578 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2579 it is appended to each SEARCH_PATH element before FUNC is called. */
2581 -foreach_dirinpath (search_path, base_name, func, data1, data2)
2582 - const char *search_path;
2583 - const char *base_name;
2584 - foreach_callback_func *func;
2589 - int filenamesize = 0;
2590 - size_t lenbase = LT_STRLEN (base_name);
2591 - size_t argz_len = 0;
2593 - char *filename = 0;
2594 - char *canonical = 0;
2596 - LT_DLMUTEX_LOCK ();
2597 +foreach_dirinpath (const char *search_path, const char *base_name,
2598 + foreach_callback_func *func, void *data1, void *data2)
2601 + size_t filenamesize = 0;
2602 + size_t lenbase = LT_STRLEN (base_name);
2603 + size_t argz_len = 0;
2605 + char *filename = 0;
2606 + char *canonical = 0;
2608 if (!search_path || !*search_path)
2610 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2611 + LT__SETERROR (FILE_NOT_FOUND);
2615 @@ -2188,38 +686,38 @@
2617 while ((dir_name = argz_next (argz, argz_len, dir_name)))
2619 - size_t lendir = LT_STRLEN (dir_name);
2620 + size_t lendir = LT_STRLEN (dir_name);
2622 - if (lendir +1 +lenbase >= filenamesize)
2624 - LT_DLFREE (filename);
2625 - filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2626 - filename = LT_EMALLOC (char, filenamesize);
2631 - strncpy (filename, dir_name, lendir);
2632 - if (base_name && *base_name)
2634 - if (filename[lendir -1] != '/')
2635 - filename[lendir++] = '/';
2636 - strcpy (filename +lendir, base_name);
2639 - if ((result = (*func) (filename, data1, data2)))
2643 + if (1+ lendir + lenbase >= filenamesize)
2646 + filenamesize = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */
2647 + filename = MALLOC (char, filenamesize);
2652 + assert (filenamesize > lendir);
2653 + strcpy (filename, dir_name);
2655 + if (base_name && *base_name)
2657 + if (filename[lendir -1] != '/')
2658 + filename[lendir++] = '/';
2659 + strcpy (filename +lendir, base_name);
2662 + if ((result = (*func) (filename, data1, data2)))
2671 - LT_DLFREE (canonical);
2672 - LT_DLFREE (filename);
2674 - LT_DLMUTEX_UNLOCK ();
2681 @@ -2228,14 +726,11 @@
2682 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2683 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2685 -find_file_callback (filename, data1, data2)
2690 - char **pdir = (char **) data1;
2691 - FILE **pfile = (FILE **) data2;
2693 +find_file_callback (char *filename, void *data1, void *data2)
2695 + char **pdir = (char **) data1;
2696 + FILE **pfile = (FILE **) data2;
2699 assert (filename && *filename);
2701 @@ -2246,10 +741,10 @@
2702 char *dirend = strrchr (filename, '/');
2704 if (dirend > filename)
2705 - *dirend = LT_EOS_CHAR;
2706 + *dirend = LT_EOS_CHAR;
2708 - LT_DLFREE (*pdir);
2709 - *pdir = lt_estrdup (filename);
2711 + *pdir = lt__strdup (filename);
2712 is_done = (*pdir == 0) ? -1 : 1;
2715 @@ -2257,10 +752,7 @@
2719 -find_file (search_path, base_name, pdir)
2720 - const char *search_path;
2721 - const char *base_name;
2723 +find_file (const char *search_path, const char *base_name, char **pdir)
2727 @@ -2270,22 +762,20 @@
2731 -find_handle_callback (filename, data, ignored)
2735 +find_handle_callback (char *filename, void *data, void *data2)
2737 - lt_dlhandle *handle = (lt_dlhandle *) data;
2738 - int found = access (filename, R_OK);
2739 + lt_dlhandle *phandle = (lt_dlhandle *) data;
2740 + int notfound = access (filename, R_OK);
2741 + lt_dladvise advise = (lt_dladvise) data2;
2743 /* Bail out if file cannot be read... */
2748 /* Try to dlopen the file, but do not continue searching in any
2750 - if (tryall_dlopen (handle, filename) != 0)
2752 + if (tryall_dlopen (phandle, filename, advise, 0) != 0)
2757 @@ -2293,91 +783,87 @@
2758 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2759 found but could not be opened, *HANDLE will be set to 0. */
2760 static lt_dlhandle *
2761 -find_handle (search_path, base_name, handle)
2762 - const char *search_path;
2763 - const char *base_name;
2764 - lt_dlhandle *handle;
2765 +find_handle (const char *search_path, const char *base_name,
2766 + lt_dlhandle *phandle, lt_dladvise advise)
2771 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2780 +#if !defined(LTDL_DLOPEN_DEPLIBS)
2782 +load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs)
2784 + handle->depcount = 0;
2788 +#else /* defined(LTDL_DLOPEN_DEPLIBS) */
2790 -load_deplibs (handle, deplibs)
2791 - lt_dlhandle handle;
2793 +load_deplibs (lt_dlhandle handle, char *deplibs)
2795 -#if LTDL_DLOPEN_DEPLIBS
2796 - char *p, *save_search_path = 0;
2797 + char *p, *save_search_path = 0;
2807 handle->depcount = 0;
2809 -#if LTDL_DLOPEN_DEPLIBS
2816 - LT_DLMUTEX_LOCK ();
2817 if (user_search_path)
2819 - save_search_path = lt_estrdup (user_search_path);
2820 + save_search_path = lt__strdup (user_search_path);
2821 if (!save_search_path)
2826 /* extract search paths and count deplibs */
2830 - if (!isspace ((int) *p))
2833 - while (*end && !isspace((int) *end))
2838 - if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2841 - *end = 0; /* set a temporary string terminator */
2842 - if (lt_dladdsearchdir(p+2))
2852 + if (!isspace ((unsigned char) *p))
2855 + while (*end && !isspace((unsigned char) *end))
2860 + if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2863 + *end = 0; /* set a temporary string terminator */
2864 + if (lt_dladdsearchdir(p+2))
2888 - /* restore the old search path */
2889 - LT_DLFREE (user_search_path);
2890 - user_search_path = save_search_path;
2892 - LT_DLMUTEX_UNLOCK ();
2896 @@ -2385,7 +871,7 @@
2900 - names = LT_EMALLOC (char *, depcount * sizeof (char*));
2901 + names = MALLOC (char *, depcount);
2905 @@ -2395,40 +881,40 @@
2908 if (isspace ((unsigned char) *p))
2918 - while (*end && !isspace ((unsigned char) *end))
2923 - if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2927 - *end = 0; /* set a temporary string terminator */
2928 - if (strncmp(p, "-l", 2) == 0)
2930 - size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2931 - name = LT_EMALLOC (char, 1+ name_len);
2933 - sprintf (name, "lib%s", p+2);
2936 - name = lt_estrdup(p);
2939 - goto cleanup_names;
2941 - names[depcount++] = name;
2948 + while (*end && !isspace ((unsigned char) *end))
2953 + if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2957 + *end = 0; /* set a temporary string terminator */
2958 + if (strncmp(p, "-l", 2) == 0)
2960 + size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2961 + name = MALLOC (char, 1+ name_len);
2963 + sprintf (name, "lib%s", p+2);
2966 + name = lt__strdup(p);
2969 + goto cleanup_names;
2971 + names[depcount++] = name;
2978 /* load the deplibs (in reverse order)
2979 @@ -2438,80 +924,87 @@
2980 later on if the loaded module cannot resolve all of its symbols. */
2984 + lt_dlhandle cur = handle;
2987 - handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2988 - if (!handle->deplibs)
2990 + cur->deplibs = MALLOC (lt_dlhandle, depcount);
2991 + if (!cur->deplibs)
2992 + goto cleanup_names;
2994 for (i = 0; i < depcount; ++i)
2996 - handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
2997 - if (handle->deplibs[j])
3003 + cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
3004 + if (cur->deplibs[j])
3010 - handle->depcount = j; /* Number of successfully loaded deplibs */
3012 + cur->depcount = j; /* Number of successfully loaded deplibs */
3017 for (i = 0; i < depcount; ++i)
3019 - LT_DLFREE (names[i]);
3024 - LT_DLFREE (names);
3027 + /* restore the old search path */
3028 + if (save_search_path) {
3029 + MEMREASSIGN (user_search_path, save_search_path);
3034 +#endif /* defined(LTDL_DLOPEN_DEPLIBS) */
3037 -unload_deplibs (handle)
3038 - lt_dlhandle handle;
3039 +unload_deplibs (lt_dlhandle handle)
3043 + lt_dlhandle cur = handle;
3045 - if (handle->depcount)
3046 + if (cur->depcount)
3048 - for (i = 0; i < handle->depcount; ++i)
3050 - if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
3052 - errors += lt_dlclose (handle->deplibs[i]);
3055 + for (i = 0; i < cur->depcount; ++i)
3057 + if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
3059 + errors += lt_dlclose (cur->deplibs[i]);
3062 + FREE (cur->deplibs);
3072 +trim (char **dest, const char *str)
3074 /* remove the leading and trailing "'" from str
3075 and store the result in dest */
3076 const char *end = strrchr (str, '\'');
3077 - size_t len = LT_STRLEN (str);
3078 + size_t len = LT_STRLEN (str);
3081 - LT_DLFREE (*dest);
3087 if (len > 3 && str[0] == '\'')
3089 - tmp = LT_EMALLOC (char, end - str);
3090 + tmp = MALLOC (char, end - str);
3095 - strncpy(tmp, &str[1], (end - str) - 1);
3096 - tmp[len-3] = LT_EOS_CHAR;
3097 + memcpy(tmp, &str[1], (end - str) - 1);
3098 + tmp[(end - str) - 1] = LT_EOS_CHAR;
3102 @@ -2522,67 +1015,187 @@
3106 +/* Read the .la file FILE. */
3108 -free_vars (dlname, oldname, libdir, deplibs)
3114 - LT_DLFREE (dlname);
3115 - LT_DLFREE (oldname);
3116 - LT_DLFREE (libdir);
3117 - LT_DLFREE (deplibs);
3118 +parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs,
3119 + char **old_name, int *installed)
3122 + size_t line_len = LT_FILENAME_MAX;
3123 + char * line = MALLOC (char, line_len);
3128 + LT__SETERROR (FILE_NOT_FOUND);
3132 + while (!feof (file))
3134 + line[line_len-2] = '\0';
3135 + if (!fgets (line, (int) line_len, file))
3140 + /* Handle the case where we occasionally need to read a line
3141 + that is longer than the initial buffer size.
3142 + Behave even if the file contains NUL bytes due to corruption. */
3143 + while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file))
3145 + line = REALLOC (char, line, line_len *2);
3151 + line[line_len * 2 - 2] = '\0';
3152 + if (!fgets (&line[line_len -1], (int) line_len +1, file))
3159 + if (line[0] == '\n' || line[0] == '#')
3165 +#define STR_DLNAME "dlname="
3166 + if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3168 + errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]);
3171 +#undef STR_OLD_LIBRARY
3172 +#define STR_OLD_LIBRARY "old_library="
3173 + else if (strncmp (line, STR_OLD_LIBRARY,
3174 + sizeof (STR_OLD_LIBRARY) - 1) == 0)
3176 + errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3179 +#define STR_LIBDIR "libdir="
3180 + else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3182 + errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]);
3185 +#undef STR_DL_DEPLIBS
3186 +#define STR_DL_DEPLIBS "dependency_libs="
3187 + else if (strncmp (line, STR_DL_DEPLIBS,
3188 + sizeof (STR_DL_DEPLIBS) - 1) == 0)
3190 + errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3192 + else if (streq (line, "installed=yes\n"))
3196 + else if (streq (line, "installed=no\n"))
3201 +#undef STR_LIBRARY_NAMES
3202 +#define STR_LIBRARY_NAMES "library_names="
3203 + else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES,
3204 + sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3206 + char *last_libname;
3207 + errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3210 + && (last_libname = strrchr (*dlname, ' ')) != 0)
3212 + last_libname = lt__strdup (last_libname + 1);
3213 + if (!last_libname)
3218 + MEMREASSIGN (*dlname, last_libname);
3231 +/* Try to open FILENAME as a module. */
3233 -try_dlopen (phandle, filename)
3234 - lt_dlhandle *phandle;
3235 - const char *filename;
3237 - const char * ext = 0;
3238 - const char * saved_error = 0;
3239 - char * canonical = 0;
3240 - char * base_name = 0;
3244 - lt_dlhandle newhandle;
3245 +try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
3246 + lt_dladvise advise)
3248 + const char * saved_error = 0;
3249 + char * archive_name = 0;
3250 + char * canonical = 0;
3251 + char * base_name = 0;
3254 + char * attempt = 0;
3256 + lt_dlhandle newhandle;
3259 assert (*phandle == 0);
3261 - LT_DLMUTEX_GETERROR (saved_error);
3262 +#ifdef LT_DEBUG_LOADERS
3263 + fprintf (stderr, "try_dlopen (%s, %s)\n",
3264 + filename ? filename : "(null)",
3265 + ext ? ext : "(null)");
3268 + LT__GETERROR (saved_error);
3273 - *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3274 + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
3279 - memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3280 - newhandle = *phandle;
3281 + newhandle = *phandle;
3283 /* lt_dlclose()ing yourself is very bad! Disallow it. */
3284 - LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
3285 + newhandle->info.is_resident = 1;
3287 - if (tryall_dlopen (&newhandle, 0) != 0)
3289 - LT_DLFREE (*phandle);
3292 + if (tryall_dlopen (&newhandle, 0, advise, 0) != 0)
3298 goto register_handle;
3301 assert (filename && *filename);
3305 + attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1);
3309 + sprintf(attempt, "%s%s", filename, ext);
3313 + attempt = lt__strdup (filename);
3318 /* Doing this immediately allows internal functions to safely
3319 assume only canonicalized paths are passed. */
3320 - if (canonicalize_path (filename, &canonical) != 0)
3321 + if (canonicalize_path (attempt, &canonical) != 0)
3325 @@ -2595,12 +1208,12 @@
3327 size_t dirlen = (1+ base_name) - canonical;
3329 - dir = LT_EMALLOC (char, 1+ dirlen);
3330 + dir = MALLOC (char, 1+ dirlen);
3341 strncpy (dir, canonical, dirlen);
3342 dir[dirlen] = LT_EOS_CHAR;
3343 @@ -2608,447 +1221,476 @@
3347 - LT_DLMEM_REASSIGN (base_name, canonical);
3348 + MEMREASSIGN (base_name, canonical);
3350 assert (base_name && *base_name);
3352 - /* Check whether we are opening a libtool module (.la extension). */
3353 ext = strrchr (base_name, '.');
3354 - if (ext && strcmp (ext, archive_ext) == 0)
3357 - /* this seems to be a libtool module */
3359 - char * dlname = 0;
3360 - char * old_name = 0;
3361 - char * libdir = 0;
3362 - char * deplibs = 0;
3365 + ext = base_name + LT_STRLEN (base_name);
3368 - /* if we can't find the installed flag, it is probably an
3369 - installed libtool archive, produced with an old version
3371 - int installed = 1;
3373 - /* extract the module name from the file name */
3374 - name = LT_EMALLOC (char, ext - base_name + 1);
3380 + /* extract the module name from the file name */
3381 + name = MALLOC (char, ext - base_name + 1);
3388 - /* canonicalize the module name */
3389 + /* canonicalize the module name */
3392 + for (i = 0; i < ext - base_name; ++i)
3395 - for (i = 0; i < ext - base_name; ++i)
3397 - if (isalnum ((unsigned char)(base_name[i])))
3399 - name[i] = base_name[i];
3406 - name[ext - base_name] = LT_EOS_CHAR;
3407 + if (isalnum ((unsigned char)(base_name[i])))
3409 + name[i] = base_name[i];
3416 + name[ext - base_name] = LT_EOS_CHAR;
3419 + /* Before trawling through the filesystem in search of a module,
3420 + check whether we are opening a preloaded module. */
3423 + const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen");
3427 + /* name + "." + libext + NULL */
3428 + archive_name = MALLOC (char, LT_STRLEN (name) + LT_STRLEN (libext) + 2);
3429 + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
3431 + if ((*phandle == NULL) || (archive_name == NULL))
3436 + newhandle = *phandle;
3438 + /* Preloaded modules are always named according to their old
3440 + sprintf (archive_name, "%s.%s", name, libext);
3442 + if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0)
3444 + goto register_handle;
3447 + /* If we're still here, there was no matching preloaded module,
3448 + so put things back as we found them, and continue searching. */
3454 + /* If we are allowing only preloaded modules, and we didn't find
3455 + anything yet, give up on the search here. */
3456 + if (advise && advise->try_preload_only)
3461 + /* Check whether we are opening a libtool module (.la extension). */
3462 + if (ext && streq (ext, archive_ext))
3464 + /* this seems to be a libtool module */
3466 + char * dlname = 0;
3467 + char * old_name = 0;
3468 + char * libdir = 0;
3469 + char * deplibs = 0;
3471 + /* if we can't find the installed flag, it is probably an
3472 + installed libtool archive, produced with an old version
3474 + int installed = 1;
3476 /* Now try to open the .la file. If there is no directory name
3477 - component, try to find it first in user_search_path and then other
3478 - prescribed paths. Otherwise (or in any case if the module was not
3479 - yet found) try opening just the module name as passed. */
3480 + component, try to find it first in user_search_path and then other
3481 + prescribed paths. Otherwise (or in any case if the module was not
3482 + yet found) try opening just the module name as passed. */
3485 - const char *search_path;
3487 + const char *search_path = user_search_path;
3490 + file = find_file (user_search_path, base_name, &dir);
3492 - LT_DLMUTEX_LOCK ();
3493 - search_path = user_search_path;
3495 - file = find_file (user_search_path, base_name, &dir);
3496 - LT_DLMUTEX_UNLOCK ();
3500 - search_path = getenv (LTDL_SEARCHPATH_VAR);
3502 - file = find_file (search_path, base_name, &dir);
3505 -#ifdef LTDL_SHLIBPATH_VAR
3508 - search_path = getenv (LTDL_SHLIBPATH_VAR);
3510 - file = find_file (search_path, base_name, &dir);
3513 -#ifdef LTDL_SYSSEARCHPATH
3514 - if (!file && sys_search_path)
3516 - file = find_file (sys_search_path, base_name, &dir);
3520 + search_path = getenv (LTDL_SEARCHPATH_VAR);
3522 + file = find_file (search_path, base_name, &dir);
3525 +#if defined(LT_MODULE_PATH_VAR)
3528 + search_path = getenv (LT_MODULE_PATH_VAR);
3530 + file = find_file (search_path, base_name, &dir);
3533 +#if defined(LT_DLSEARCH_PATH)
3534 + if (!file && *sys_dlsearch_path)
3536 + file = find_file (sys_dlsearch_path, base_name, &dir);
3542 - file = fopen (filename, LT_READTEXT_MODE);
3547 + file = fopen (attempt, LT_READTEXT_MODE);
3550 /* If we didn't find the file by now, it really isn't there. Set
3551 - the status flag, and bail out. */
3552 + the status flag, and bail out. */
3555 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3560 - line_len = LT_FILENAME_MAX;
3561 - line = LT_EMALLOC (char, line_len);
3569 + LT__SETERROR (FILE_NOT_FOUND);
3574 /* read the .la file */
3575 - while (!feof (file))
3577 - if (!fgets (line, (int) line_len, file))
3582 - /* Handle the case where we occasionally need to read a line
3583 - that is longer than the initial buffer size. */
3584 - while (line[LT_STRLEN(line) -1] != '\n')
3586 - line = LT_DLREALLOC (char, line, line_len *2);
3587 - if (!fgets (&line[line_len -1], (int) line_len +1, file))
3594 - if (line[0] == '\n' || line[0] == '#')
3600 -#define STR_DLNAME "dlname="
3601 - if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3603 - errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
3606 -#undef STR_OLD_LIBRARY
3607 -#define STR_OLD_LIBRARY "old_library="
3608 - else if (strncmp (line, STR_OLD_LIBRARY,
3609 - sizeof (STR_OLD_LIBRARY) - 1) == 0)
3611 - errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3614 -#define STR_LIBDIR "libdir="
3615 - else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3617 - errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
3620 -#undef STR_DL_DEPLIBS
3621 -#define STR_DL_DEPLIBS "dependency_libs="
3622 - else if (strncmp (line, STR_DL_DEPLIBS,
3623 - sizeof (STR_DL_DEPLIBS) - 1) == 0)
3625 - errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3627 - else if (strcmp (line, "installed=yes\n") == 0)
3631 - else if (strcmp (line, "installed=no\n") == 0)
3636 -#undef STR_LIBRARY_NAMES
3637 -#define STR_LIBRARY_NAMES "library_names="
3638 - else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
3639 - sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3641 - char *last_libname;
3642 - errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3645 - && (last_libname = strrchr (dlname, ' ')) != 0)
3647 - last_libname = lt_estrdup (last_libname + 1);
3648 - if (!last_libname)
3653 - LT_DLMEM_REASSIGN (dlname, last_libname);
3660 + if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
3661 + &old_name, &installed) != 0)
3667 /* allocate the handle */
3668 - *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3669 + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
3676 - free_vars (dlname, old_name, libdir, deplibs);
3677 - LT_DLFREE (*phandle);
3691 - memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3692 if (load_deplibs (*phandle, deplibs) == 0)
3694 - newhandle = *phandle;
3695 - /* find_module may replace newhandle */
3696 - if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
3698 - unload_deplibs (*phandle);
3703 + newhandle = *phandle;
3704 + /* find_module may replace newhandle */
3705 + if (find_module (&newhandle, dir, libdir, dlname, old_name,
3706 + installed, advise))
3708 + unload_deplibs (*phandle);
3725 - free_vars (dlname, old_name, libdir, deplibs);
3728 - LT_DLFREE (*phandle);
3736 if (*phandle != newhandle)
3738 - unload_deplibs (*phandle);
3741 + unload_deplibs (*phandle);
3746 /* not a libtool module */
3747 - *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3748 + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
3759 - memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3760 newhandle = *phandle;
3762 /* If the module has no directory name component, try to find it
3763 - first in user_search_path and then other prescribed paths.
3764 - Otherwise (or in any case if the module was not yet found) try
3765 - opening just the module name as passed. */
3766 - if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
3767 - && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3769 -#ifdef LTDL_SHLIBPATH_VAR
3770 - && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
3773 -#ifdef LTDL_SYSSEARCHPATH
3774 - && !find_handle (sys_search_path, base_name, &newhandle)
3778 - tryall_dlopen (&newhandle, filename);
3780 + first in user_search_path and then other prescribed paths.
3781 + Otherwise (or in any case if the module was not yet found) try
3782 + opening just the module name as passed. */
3783 + if ((dir || (!find_handle (user_search_path, base_name,
3784 + &newhandle, advise)
3785 + && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3786 + &newhandle, advise)
3787 +#if defined(LT_MODULE_PATH_VAR)
3788 + && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name,
3789 + &newhandle, advise)
3791 +#if defined(LT_DLSEARCH_PATH)
3792 + && !find_handle (sys_dlsearch_path, base_name,
3793 + &newhandle, advise)
3797 + if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0)
3805 - LT_DLFREE (*phandle);
3817 - LT_DLMEM_REASSIGN (*phandle, newhandle);
3818 + MEMREASSIGN (*phandle, newhandle);
3820 if ((*phandle)->info.ref_count == 0)
3822 - (*phandle)->info.ref_count = 1;
3823 - LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
3824 + (*phandle)->info.ref_count = 1;
3825 + MEMREASSIGN ((*phandle)->info.name, name);
3827 - LT_DLMUTEX_LOCK ();
3828 - (*phandle)->next = handles;
3829 - handles = *phandle;
3830 - LT_DLMUTEX_UNLOCK ();
3831 + (*phandle)->next = handles;
3832 + handles = *phandle;
3835 - LT_DLMUTEX_SETERROR (saved_error);
3836 + LT__SETERRORSTR (saved_error);
3841 - LT_DLFREE (canonical);
3845 + if (!canonical) /* was MEMREASSIGNed */
3848 + FREE (archive_name);
3854 -lt_dlopen (filename)
3855 - const char *filename;
3857 - lt_dlhandle handle = 0;
3859 - /* Just incase we missed a code path in try_dlopen() that reports
3860 - an error, but forgets to reset handle... */
3861 - if (try_dlopen (&handle, filename) != 0)
3867 /* If the last error messge store was `FILE_NOT_FOUND', then return
3871 +file_not_found (void)
3873 const char *error = 0;
3875 - LT_DLMUTEX_GETERROR (error);
3876 - if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
3877 + LT__GETERROR (error);
3878 + if (error == LT__STRERROR (FILE_NOT_FOUND))
3884 -/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3885 - open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3886 - and if a file is still not found try again with SHLIB_EXT appended
3889 -lt_dlopenext (filename)
3890 - const char *filename;
3892 - lt_dlhandle handle = 0;
3900 - return lt_dlopen (filename);
3902 +/* Unless FILENAME already bears a suitable library extension, then
3905 +has_library_ext (const char *filename)
3911 - len = LT_STRLEN (filename);
3912 ext = strrchr (filename, '.');
3914 - /* If FILENAME already bears a suitable extension, there is no need
3915 - to try appending additional extensions. */
3916 - if (ext && ((strcmp (ext, archive_ext) == 0)
3917 -#ifdef LTDL_SHLIB_EXT
3918 - || (strcmp (ext, shlib_ext) == 0)
3919 + if (ext && ((streq (ext, archive_ext))
3920 +#if defined(LT_MODULE_EXT)
3921 + || (streq (ext, shlib_ext))
3926 - return lt_dlopen (filename);
3930 - /* First try appending ARCHIVE_EXT. */
3931 - tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
3937 - strcpy (tmp, filename);
3938 - strcat (tmp, archive_ext);
3939 - errors = try_dlopen (&handle, tmp);
3941 - /* If we found FILENAME, stop searching -- whether we were able to
3942 - load the file as a module or not. If the file exists but loading
3943 - failed, it is better to return an error message here than to
3944 - report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3945 - in the module search path. */
3946 - if (handle || ((errors > 0) && file_not_found ()))
3952 -#ifdef LTDL_SHLIB_EXT
3953 - /* Try appending SHLIB_EXT. */
3954 - if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
3957 - tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
3960 +/* Initialise and configure a user lt_dladvise opaque object. */
3962 - strcpy (tmp, filename);
3966 +lt_dladvise_init (lt_dladvise *padvise)
3968 + lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise));
3969 + *padvise = advise;
3970 + return (advise ? 0 : 1);
3974 +lt_dladvise_destroy (lt_dladvise *padvise)
3982 +lt_dladvise_ext (lt_dladvise *padvise)
3984 + assert (padvise && *padvise);
3985 + (*padvise)->try_ext = 1;
3990 +lt_dladvise_resident (lt_dladvise *padvise)
3992 + assert (padvise && *padvise);
3993 + (*padvise)->is_resident = 1;
3998 +lt_dladvise_local (lt_dladvise *padvise)
4000 + assert (padvise && *padvise);
4001 + (*padvise)->is_symlocal = 1;
4006 +lt_dladvise_global (lt_dladvise *padvise)
4008 + assert (padvise && *padvise);
4009 + (*padvise)->is_symglobal = 1;
4014 +lt_dladvise_preload (lt_dladvise *padvise)
4016 + assert (padvise && *padvise);
4017 + (*padvise)->try_preload_only = 1;
4021 +/* Libtool-1.5.x interface for loading a new module named FILENAME. */
4023 +lt_dlopen (const char *filename)
4025 + return lt_dlopenadvise (filename, NULL);
4029 +/* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
4030 + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
4031 + and if a file is still not found try again with MODULE_EXT appended
4034 +lt_dlopenext (const char *filename)
4036 + lt_dlhandle handle = 0;
4037 + lt_dladvise advise;
4039 + if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise))
4040 + handle = lt_dlopenadvise (filename, advise);
4042 + lt_dladvise_destroy (&advise);
4048 +lt_dlopenadvise (const char *filename, lt_dladvise advise)
4050 + lt_dlhandle handle = 0;
4053 + /* Can't have symbols hidden and visible at the same time! */
4054 + if (advise && advise->is_symlocal && advise->is_symglobal)
4056 - tmp[len] = LT_EOS_CHAR;
4057 + LT__SETERROR (CONFLICTING_FLAGS);
4061 - strcat(tmp, shlib_ext);
4062 - errors = try_dlopen (&handle, tmp);
4065 + || !advise->try_ext
4066 + || has_library_ext (filename))
4068 + /* Just incase we missed a code path in try_dlopen() that reports
4069 + an error, but forgot to reset handle... */
4070 + if (try_dlopen (&handle, filename, NULL, advise) != 0)
4073 - /* As before, if the file was found but loading failed, return now
4074 - with the current error message. */
4075 - if (handle || ((errors > 0) && file_not_found ()))
4080 + else if (filename && *filename)
4083 + /* First try appending ARCHIVE_EXT. */
4084 + errors += try_dlopen (&handle, filename, archive_ext, advise);
4086 + /* If we found FILENAME, stop searching -- whether we were able to
4087 + load the file as a module or not. If the file exists but loading
4088 + failed, it is better to return an error message here than to
4089 + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
4090 + in the module search path. */
4091 + if (handle || ((errors > 0) && !file_not_found ()))
4094 +#if defined(LT_MODULE_EXT)
4095 + /* Try appending SHLIB_EXT. */
4096 + errors = try_dlopen (&handle, filename, shlib_ext, advise);
4098 + /* As before, if the file was found but loading failed, return now
4099 + with the current error message. */
4100 + if (handle || ((errors > 0) && !file_not_found ()))
4105 /* Still here? Then we really did fail to locate any of the file
4107 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
4109 + LT__SETERROR (FILE_NOT_FOUND);
4115 -lt_argz_insert (pargz, pargz_len, before, entry)
4117 - size_t *pargz_len;
4119 - const char *entry;
4120 +lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
4121 + const char *entry)
4125 - if ((error = argz_insert (pargz, pargz_len, before, entry)))
4126 + /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
4127 + pargz_len, NULL, entry) failed with EINVAL. */
4129 + error = argz_insert (pargz, pargz_len, before, entry);
4131 + error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
4138 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
4141 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
4146 + LT__SETERROR (NO_MEMORY);
4149 + LT__SETERROR (UNKNOWN);
4155 @@ -3056,10 +1698,7 @@
4159 -lt_argz_insertinorder (pargz, pargz_len, entry)
4161 - size_t *pargz_len;
4162 - const char *entry;
4163 +lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
4167 @@ -3070,42 +1709,39 @@
4169 while ((before = argz_next (*pargz, *pargz_len, before)))
4171 - int cmp = strcmp (entry, before);
4172 + int cmp = strcmp (entry, before);
4174 - if (cmp < 0) break;
4175 - if (cmp == 0) return 0; /* No duplicates! */
4176 + if (cmp < 0) break;
4177 + if (cmp == 0) return 0; /* No duplicates! */
4180 return lt_argz_insert (pargz, pargz_len, before, entry);
4184 -lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
4186 - size_t *pargz_len;
4187 - const char *dirnam;
4188 - struct dirent *dp;
4189 +lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
4190 + struct dirent *dp)
4197 size_t end_offset = 0;
4206 dir_len = LT_STRLEN (dirnam);
4207 - end = dp->d_name + LT_D_NAMLEN(dp);
4208 + end = dp->d_name + D_NAMLEN(dp);
4210 /* Ignore version numbers. */
4213 for (p = end; p -1 > dp->d_name; --p)
4214 if (strchr (".0123456789", p[-1]) == 0)
4220 @@ -3116,16 +1752,16 @@
4222 for (p = end -1; p > dp->d_name; --p)
4234 /* Prepend the directory name. */
4235 - end_offset = end - dp->d_name;
4236 - buf_len = dir_len + 1+ end_offset;
4237 - buf = LT_EMALLOC (char, 1+ buf_len);
4238 + end_offset = end - dp->d_name;
4239 + buf_len = dir_len + 1+ end_offset;
4240 + buf = MALLOC (char, 1+ buf_len);
4244 @@ -3140,19 +1776,16 @@
4245 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
4255 -list_files_by_dir (dirnam, pargz, pargz_len)
4256 - const char *dirnam;
4258 - size_t *pargz_len;
4259 +list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
4266 assert (dirnam && *dirnam);
4268 @@ -3162,15 +1795,15 @@
4269 dirp = opendir (dirnam);
4272 - struct dirent *dp = 0;
4273 + struct dirent *dp = 0;
4275 while ((dp = readdir (dirp)))
4276 - if (dp->d_name[0] != '.')
4277 - if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
4282 + if (dp->d_name[0] != '.')
4283 + if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
4291 @@ -3184,15 +1817,11 @@
4292 /* If there are any files in DIRNAME, call the function passed in
4293 DATA1 (with the name of each file and DATA2 as arguments). */
4295 -foreachfile_callback (dirname, data1, data2)
4299 +foreachfile_callback (char *dirname, void *data1, void *data2)
4301 - int (*func) LT_PARAMS((const char *filename, lt_ptr data))
4302 - = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
4303 + file_worker_func *func = *(file_worker_func **) data1;
4308 size_t argz_len = 0;
4310 @@ -3205,11 +1834,11 @@
4312 while ((filename = argz_next (argz, argz_len, filename)))
4313 if ((is_done = (*func) (filename, data2)))
4324 @@ -3222,44 +1851,44 @@
4325 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
4326 then the same directories that lt_dlopen would search are examined. */
4328 -lt_dlforeachfile (search_path, func, data)
4329 - const char *search_path;
4330 - int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
4332 +lt_dlforeachfile (const char *search_path,
4333 + int (*func) (const char *filename, void *data),
4337 + file_worker_func **fpptr = &func;
4341 /* If a specific path was passed, search only the directories
4344 is_done = foreach_dirinpath (search_path, 0,
4345 - foreachfile_callback, func, data);
4346 + foreachfile_callback, fpptr, data);
4350 /* Otherwise search the default paths. */
4351 is_done = foreach_dirinpath (user_search_path, 0,
4352 - foreachfile_callback, func, data);
4353 + foreachfile_callback, fpptr, data);
4356 - is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
4357 - foreachfile_callback, func, data);
4360 + is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
4361 + foreachfile_callback, fpptr, data);
4364 -#ifdef LTDL_SHLIBPATH_VAR
4367 - is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
4368 - foreachfile_callback, func, data);
4371 -#ifdef LTDL_SYSSEARCHPATH
4372 +#if defined(LT_MODULE_PATH_VAR)
4375 - is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
4376 - foreachfile_callback, func, data);
4379 + is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
4380 + foreachfile_callback, fpptr, data);
4383 +#if defined(LT_DLSEARCH_PATH)
4384 + if (!is_done && *sys_dlsearch_path)
4386 + is_done = foreach_dirinpath (sys_dlsearch_path, 0,
4387 + foreachfile_callback, fpptr, data);
4392 @@ -3267,14 +1896,11 @@
4396 -lt_dlclose (handle)
4397 - lt_dlhandle handle;
4398 +lt_dlclose (lt_dlhandle handle)
4400 lt_dlhandle cur, last;
4403 - LT_DLMUTEX_LOCK ();
4405 /* check whether the handle is valid */
4406 last = cur = handles;
4407 while (cur && handle != cur)
4408 @@ -3285,80 +1911,80 @@
4412 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4413 + LT__SETERROR (INVALID_HANDLE);
4418 - handle->info.ref_count--;
4420 + cur->info.ref_count--;
4422 /* Note that even with resident modules, we must track the ref_count
4423 correctly incase the user decides to reset the residency flag
4424 later (even though the API makes no provision for that at the
4426 - if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
4427 + if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
4429 - lt_user_data data = handle->loader->dlloader_data;
4430 + lt_user_data data = cur->vtable->dlloader_data;
4432 - if (handle != handles)
4434 - last->next = handle->next;
4436 + if (cur != handles)
4438 + last->next = cur->next;
4442 - handles = handle->next;
4445 + handles = cur->next;
4448 - errors += handle->loader->module_close (data, handle->module);
4449 - errors += unload_deplibs(handle);
4450 + errors += cur->vtable->module_close (data, cur->module);
4451 + errors += unload_deplibs (handle);
4453 /* It is up to the callers to free the data itself. */
4454 - LT_DLFREE (handle->caller_data);
4455 + FREE (cur->interface_data);
4457 - LT_DLFREE (handle->info.filename);
4458 - LT_DLFREE (handle->info.name);
4459 - LT_DLFREE (handle);
4460 + FREE (cur->info.filename);
4461 + FREE (cur->info.name);
4467 if (LT_DLIS_RESIDENT (handle))
4469 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
4470 + LT__SETERROR (CLOSE_RESIDENT_MODULE);
4475 - LT_DLMUTEX_UNLOCK ();
4481 -lt_dlsym (handle, symbol)
4482 - lt_dlhandle handle;
4483 - const char *symbol;
4485 +lt_dlsym (lt_dlhandle place, const char *symbol)
4488 - char lsym[LT_SYMBOL_LENGTH];
4491 + char lsym[LT_SYMBOL_LENGTH];
4495 + lt_dlhandle handle;
4500 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4501 + LT__SETERROR (INVALID_HANDLE);
4509 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
4510 + LT__SETERROR (SYMBOL_NOT_FOUND);
4514 - lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
4515 - + LT_STRLEN (handle->info.name);
4516 + lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)
4517 + + LT_STRLEN (handle->info.name);
4519 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
4521 @@ -3366,52 +1992,52 @@
4525 - sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
4526 + sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
4529 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
4533 + LT__SETERROR (BUFFER_OVERFLOW);
4538 - data = handle->loader->dlloader_data;
4539 + data = handle->vtable->dlloader_data;
4540 if (handle->info.name)
4542 const char *saved_error;
4544 - LT_DLMUTEX_GETERROR (saved_error);
4545 + LT__GETERROR (saved_error);
4547 /* this is a libtool module */
4548 - if (handle->loader->sym_prefix)
4550 - strcpy(sym, handle->loader->sym_prefix);
4551 - strcat(sym, handle->info.name);
4553 + if (handle->vtable->sym_prefix)
4555 + strcpy(sym, handle->vtable->sym_prefix);
4556 + strcat(sym, handle->info.name);
4560 - strcpy(sym, handle->info.name);
4563 + strcpy(sym, handle->info.name);
4566 strcat(sym, "_LTX_");
4567 strcat(sym, symbol);
4569 /* try "modulename_LTX_symbol" */
4570 - address = handle->loader->find_sym (data, handle->module, sym);
4571 + address = handle->vtable->find_sym (data, handle->module, sym);
4580 - LT_DLMUTEX_SETERROR (saved_error);
4588 + LT__SETERRORSTR (saved_error);
4591 /* otherwise try "symbol" */
4592 - if (handle->loader->sym_prefix)
4593 + if (handle->vtable->sym_prefix)
4595 - strcpy(sym, handle->loader->sym_prefix);
4596 + strcpy(sym, handle->vtable->sym_prefix);
4597 strcat(sym, symbol);
4600 @@ -3419,36 +2045,33 @@
4601 strcpy(sym, symbol);
4604 - address = handle->loader->find_sym (data, handle->module, sym);
4605 + address = handle->vtable->find_sym (data, handle->module, sym);
4621 - LT_DLMUTEX_GETERROR (error);
4622 - LT_DLMUTEX_SETERROR (0);
4623 + LT__GETERROR (error);
4624 + LT__SETERRORSTR (0);
4626 - return error ? error : LT_DLSTRERROR (UNKNOWN);
4627 + return error ? error : NULL;
4631 -lt_dlpath_insertdir (ppath, before, dir)
4635 +lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
4638 - char *canonical = 0;
4640 - size_t argz_len = 0;
4642 + char *canonical = 0;
4644 + size_t argz_len = 0;
4647 assert (dir && *dir);
4648 @@ -3464,14 +2087,14 @@
4649 /* If *PPATH is empty, set it to DIR. */
4652 - assert (!before); /* BEFORE cannot be set without PPATH. */
4653 - assert (dir); /* Without DIR, don't call this function! */
4654 + assert (!before); /* BEFORE cannot be set without PPATH. */
4655 + assert (dir); /* Without DIR, don't call this function! */
4657 - *ppath = lt_estrdup (dir);
4658 + *ppath = lt__strdup (dir);
4667 assert (ppath && *ppath);
4668 @@ -3490,7 +2113,7 @@
4671 assert (*ppath <= before);
4672 - assert (before - *ppath <= strlen (*ppath));
4673 + assert ((int) (before - *ppath) <= (int) strlen (*ppath));
4675 before = before - *ppath + argz;
4677 @@ -3502,127 +2125,108 @@
4680 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
4681 - LT_DLMEM_REASSIGN (*ppath, argz);
4682 + MEMREASSIGN(*ppath, argz);
4685 - LT_DLFREE (canonical);
4694 -lt_dladdsearchdir (search_dir)
4695 - const char *search_dir;
4696 +lt_dladdsearchdir (const char *search_dir)
4700 if (search_dir && *search_dir)
4702 - LT_DLMUTEX_LOCK ();
4703 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
4705 - LT_DLMUTEX_UNLOCK ();
4713 -lt_dlinsertsearchdir (before, search_dir)
4714 - const char *before;
4715 - const char *search_dir;
4716 +lt_dlinsertsearchdir (const char *before, const char *search_dir)
4722 - LT_DLMUTEX_LOCK ();
4723 if ((before < user_search_path)
4724 - || (before >= user_search_path + LT_STRLEN (user_search_path)))
4726 - LT_DLMUTEX_UNLOCK ();
4727 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
4730 - LT_DLMUTEX_UNLOCK ();
4731 + || (before >= user_search_path + LT_STRLEN (user_search_path)))
4733 + LT__SETERROR (INVALID_POSITION);
4738 if (search_dir && *search_dir)
4740 - LT_DLMUTEX_LOCK ();
4741 if (lt_dlpath_insertdir (&user_search_path,
4742 - (char *) before, search_dir) != 0)
4746 - LT_DLMUTEX_UNLOCK ();
4747 + (char *) before, search_dir) != 0)
4757 -lt_dlsetsearchpath (search_path)
4758 - const char *search_path;
4759 +lt_dlsetsearchpath (const char *search_path)
4764 - LT_DLMUTEX_LOCK ();
4765 - LT_DLFREE (user_search_path);
4766 - LT_DLMUTEX_UNLOCK ();
4767 + FREE (user_search_path);
4769 if (!search_path || !LT_STRLEN (search_path))
4774 - LT_DLMUTEX_LOCK ();
4775 if (canonicalize_path (search_path, &user_search_path) != 0)
4777 - LT_DLMUTEX_UNLOCK ();
4783 -lt_dlgetsearchpath ()
4784 +lt_dlgetsearchpath (void)
4786 const char *saved_path;
4788 - LT_DLMUTEX_LOCK ();
4789 saved_path = user_search_path;
4790 - LT_DLMUTEX_UNLOCK ();
4796 -lt_dlmakeresident (handle)
4797 - lt_dlhandle handle;
4798 +lt_dlmakeresident (lt_dlhandle handle)
4804 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4805 + LT__SETERROR (INVALID_HANDLE);
4810 - LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4811 + handle->info.is_resident = 1;
4818 -lt_dlisresident (handle)
4819 - lt_dlhandle handle;
4820 +lt_dlisresident (lt_dlhandle handle)
4824 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4825 + LT__SETERROR (INVALID_HANDLE);
4829 @@ -3631,369 +2235,187 @@
4834 /* --- MODULE INFORMATION --- */
4837 -lt_dlgetinfo (handle)
4838 - lt_dlhandle handle;
4842 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4846 - return &(handle->info);
4850 -lt_dlhandle_next (place)
4851 - lt_dlhandle place;
4853 - return place ? place->next : handles;
4857 -lt_dlforeach (func, data)
4858 - int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
4864 - LT_DLMUTEX_LOCK ();
4869 - lt_dlhandle tmp = cur;
4872 - if ((*func) (tmp, data))
4878 + const char *id_string;
4879 + lt_dlhandle_interface *iface;
4880 +} lt__interface_id;
4883 +lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
4885 + lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);
4887 + /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
4888 + can then be detected with lt_dlerror() if we return 0. */
4891 + interface_id->id_string = lt__strdup (id_string);
4892 + if (!interface_id->id_string)
4893 + FREE (interface_id);
4895 + interface_id->iface = iface;
4898 - LT_DLMUTEX_UNLOCK ();
4901 + return (lt_dlinterface_id) interface_id;
4905 -lt_dlcaller_register ()
4906 +void lt_dlinterface_free (lt_dlinterface_id key)
4908 - static lt_dlcaller_id last_caller_id = 0;
4911 - LT_DLMUTEX_LOCK ();
4912 - result = ++last_caller_id;
4913 - LT_DLMUTEX_UNLOCK ();
4916 + lt__interface_id *interface_id = (lt__interface_id *)key;
4917 + FREE (interface_id->id_string);
4918 + FREE (interface_id);
4922 -lt_dlcaller_set_data (key, handle, data)
4923 - lt_dlcaller_id key;
4924 - lt_dlhandle handle;
4927 +lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
4930 - lt_ptr stale = (lt_ptr) 0;
4931 + void *stale = (void *) 0;
4932 + lt_dlhandle cur = handle;
4935 - /* This needs to be locked so that the caller data can be updated
4936 - simultaneously by different threads. */
4937 - LT_DLMUTEX_LOCK ();
4939 - if (handle->caller_data)
4940 - while (handle->caller_data[n_elements].key)
4941 + if (cur->interface_data)
4942 + while (cur->interface_data[n_elements].key)
4945 for (i = 0; i < n_elements; ++i)
4947 - if (handle->caller_data[i].key == key)
4949 - stale = handle->caller_data[i].data;
4952 + if (cur->interface_data[i].key == key)
4954 + stale = cur->interface_data[i].data;
4959 - /* Ensure that there is enough room in this handle's caller_data
4960 + /* Ensure that there is enough room in this handle's interface_data
4961 array to accept a new element (and an empty end marker). */
4962 if (i == n_elements)
4964 - lt_caller_data *temp
4965 - = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
4966 + lt_interface_data *temp
4967 + = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
4979 - handle->caller_data = temp;
4980 + cur->interface_data = temp;
4982 - /* We only need this if we needed to allocate a new caller_data. */
4983 - handle->caller_data[i].key = key;
4984 - handle->caller_data[1+ i].key = 0;
4985 + /* We only need this if we needed to allocate a new interface_data. */
4986 + cur->interface_data[i].key = key;
4987 + cur->interface_data[1+ i].key = 0;
4990 - handle->caller_data[i].data = data;
4991 + cur->interface_data[i].data = data;
4994 - LT_DLMUTEX_UNLOCK ();
5000 -lt_dlcaller_get_data (key, handle)
5001 - lt_dlcaller_id key;
5002 - lt_dlhandle handle;
5004 - lt_ptr result = (lt_ptr) 0;
5006 - /* This needs to be locked so that the caller data isn't updated by
5007 - another thread part way through this function. */
5008 - LT_DLMUTEX_LOCK ();
5010 +lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
5012 + void *result = (void *) 0;
5013 + lt_dlhandle cur = handle;
5015 /* Locate the index of the element with a matching KEY. */
5018 - for (i = 0; handle->caller_data[i].key; ++i)
5020 - if (handle->caller_data[i].key == key)
5022 - result = handle->caller_data[i].data;
5028 - LT_DLMUTEX_UNLOCK ();
5029 + if (cur->interface_data)
5032 + for (i = 0; cur->interface_data[i].key; ++i)
5034 + if (cur->interface_data[i].key == key)
5036 + result = cur->interface_data[i].data;
5047 -/* --- USER MODULE LOADER API --- */
5051 -lt_dlloader_add (place, dlloader, loader_name)
5052 - lt_dlloader *place;
5053 - const struct lt_user_dlloader *dlloader;
5054 - const char *loader_name;
5056 +lt_dlgetinfo (lt_dlhandle handle)
5059 - lt_dlloader *node = 0, *ptr = 0;
5061 - if ((dlloader == 0) /* diagnose null parameters */
5062 - || (dlloader->module_open == 0)
5063 - || (dlloader->module_close == 0)
5064 - || (dlloader->find_sym == 0))
5066 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5070 - /* Create a new dlloader node with copies of the user callbacks. */
5071 - node = LT_EMALLOC (lt_dlloader, 1);
5076 - node->loader_name = loader_name;
5077 - node->sym_prefix = dlloader->sym_prefix;
5078 - node->dlloader_exit = dlloader->dlloader_exit;
5079 - node->module_open = dlloader->module_open;
5080 - node->module_close = dlloader->module_close;
5081 - node->find_sym = dlloader->find_sym;
5082 - node->dlloader_data = dlloader->dlloader_data;
5084 - LT_DLMUTEX_LOCK ();
5087 - /* If there are no loaders, NODE becomes the list! */
5092 - /* If PLACE is not set, add NODE to the end of the
5094 - for (ptr = loaders; ptr->next; ptr = ptr->next)
5101 - else if (loaders == place)
5103 - /* If PLACE is the first loader, NODE goes first. */
5104 - node->next = place;
5110 - /* Find the node immediately preceding PLACE. */
5111 - for (ptr = loaders; ptr->next != place; ptr = ptr->next)
5116 - if (ptr->next != place)
5118 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5123 - /* Insert NODE between PTR and PLACE. */
5124 - node->next = place;
5127 + LT__SETERROR (INVALID_HANDLE);
5131 - LT_DLMUTEX_UNLOCK ();
5134 + return &(handle->info);
5138 -lt_dlloader_remove (loader_name)
5139 - const char *loader_name;
5141 - lt_dlloader *place = lt_dlloader_find (loader_name);
5142 - lt_dlhandle handle;
5147 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5151 - LT_DLMUTEX_LOCK ();
5153 +lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
5155 + lt_dlhandle handle = place;
5156 + lt__interface_id *iterator = (lt__interface_id *) iface;
5158 - /* Fail if there are any open modules which use this loader. */
5159 - for (handle = handles; handle; handle = handle->next)
5161 - if (handle->loader == place)
5163 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
5168 + assert (iface); /* iface is a required argument */
5170 - if (place == loaders)
5172 - /* PLACE is the first loader in the list. */
5173 - loaders = loaders->next;
5179 - /* Find the loader before the one being removed. */
5180 - lt_dlloader *prev;
5181 - for (prev = loaders; prev->next; prev = prev->next)
5183 - if (!strcmp (prev->next->loader_name, loader_name))
5188 + handle = handle->next;
5190 - place = prev->next;
5191 - prev->next = prev->next->next;
5194 - if (place->dlloader_exit)
5195 + /* advance while the interface check fails */
5196 + while (handle && iterator->iface
5197 + && ((*iterator->iface) (handle, iterator->id_string) != 0))
5199 - errors = place->dlloader_exit (place->dlloader_data);
5200 + handle = handle->next;
5203 - LT_DLFREE (place);
5206 - LT_DLMUTEX_UNLOCK ();
5213 -lt_dlloader_next (place)
5214 - lt_dlloader *place;
5216 - lt_dlloader *next;
5218 - LT_DLMUTEX_LOCK ();
5219 - next = place ? place->next : loaders;
5220 - LT_DLMUTEX_UNLOCK ();
5226 -lt_dlloader_name (place)
5227 - lt_dlloader *place;
5229 +lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
5231 - const char *name = 0;
5232 + lt_dlhandle handle = 0;
5236 - LT_DLMUTEX_LOCK ();
5237 - name = place ? place->loader_name : 0;
5238 - LT_DLMUTEX_UNLOCK ();
5241 + assert (iface); /* iface is a required argument */
5243 + while ((handle = lt_dlhandle_iterate (iface, handle)))
5245 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5246 + lt_dlhandle cur = handle;
5247 + if (cur && cur->info.name && streq (cur->info.name, module_name))
5256 -lt_dlloader_data (place)
5257 - lt_dlloader *place;
5260 +lt_dlhandle_map (lt_dlinterface_id iface,
5261 + int (*func) (lt_dlhandle handle, void *data), void *data)
5263 - lt_user_data *data = 0;
5264 + lt__interface_id *iterator = (lt__interface_id *) iface;
5265 + lt_dlhandle cur = handles;
5269 - LT_DLMUTEX_LOCK ();
5270 - data = place ? &(place->dlloader_data) : 0;
5271 - LT_DLMUTEX_UNLOCK ();
5275 - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5277 + assert (iface); /* iface is a required argument */
5283 + int errorcode = 0;
5286 -lt_dlloader_find (loader_name)
5287 - const char *loader_name;
5289 - lt_dlloader *place = 0;
5290 + /* advance while the interface check fails */
5291 + while (cur && iterator->iface
5292 + && ((*iterator->iface) (cur, iterator->id_string) != 0))
5297 - LT_DLMUTEX_LOCK ();
5298 - for (place = loaders; place; place = place->next)
5300 - if (strcmp (place->loader_name, loader_name) == 0)
5304 + if ((errorcode = (*func) (cur, data)) != 0)
5307 - LT_DLMUTEX_UNLOCK ();