1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
3 Originally by Thomas Tanner <tanner@ffii.org>
4 This file is part of GNU Libtool.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 As a special exception to the GNU Lesser General Public License,
12 if you distribute this file as part of a program or library that
13 is built using GNU libtool, you may include it under the same
14 distribution terms that you use for the rest of that program.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
40 /* Include the header defining malloc. On K&R C compilers,
41 that's <malloc.h>, on ANSI C and ISO C compilers, that's <stdlib.h>. */
78 #undef LT_USE_POSIX_DIRENT
83 # define LT_USE_POSIX_DIRENT
84 # endif /* HAVE_DIRENT_H */
85 # endif /* HAVE_READDIR */
86 # endif /* HAVE_OPENDIR */
87 #endif /* HAVE_CLOSEDIR */
90 #undef LT_USE_WINDOWS_DIRENT_EMULATION
91 #ifndef LT_USE_POSIX_DIRENT
93 # define LT_USE_WINDOWS_DIRENT_EMULATION
94 # endif /* __WINDOWS__ */
95 #endif /* LT_USE_POSIX_DIRENT */
98 #ifdef LT_USE_POSIX_DIRENT
100 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
102 # ifdef LT_USE_WINDOWS_DIRENT_EMULATION
103 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
105 # define dirent direct
106 # define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
108 # include <sys/ndir.h>
111 # include <sys/dir.h>
126 # define assert(arg) ((void) 0)
132 # include <dmalloc.h>
138 /* --- WINDOWS SUPPORT --- */
142 # define LT_GLOBAL_DATA __declspec(dllexport)
144 # define LT_GLOBAL_DATA
147 /* fopen() mode flags for reading a text file */
148 #undef LT_READTEXT_MODE
150 # define LT_READTEXT_MODE "rt"
152 # define LT_READTEXT_MODE "r"
155 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
159 #define dirent lt_dirent
171 WIN32_FIND_DATA Win32FindData;
173 struct dirent file_info;
176 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
179 /* --- MANIFEST CONSTANTS --- */
182 /* Standard libltdl search path environment variable name */
183 #undef LTDL_SEARCHPATH_VAR
184 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
186 /* Standard libtool archive file extension. */
187 #undef LTDL_ARCHIVE_EXT
188 #define LTDL_ARCHIVE_EXT ".la"
190 /* max. filename length */
191 #ifndef LT_FILENAME_MAX
192 # define LT_FILENAME_MAX 1024
195 /* This is the maximum symbol size that won't require malloc/free */
196 #undef LT_SYMBOL_LENGTH
197 #define LT_SYMBOL_LENGTH 128
199 /* This accounts for the _LTX_ separator */
200 #undef LT_SYMBOL_OVERHEAD
201 #define LT_SYMBOL_OVERHEAD 5
206 /* --- MEMORY HANDLING --- */
209 /* These are the functions used internally. In addition to making
210 use of the associated function pointers above, they also perform
212 static char *lt_estrdup LT_PARAMS((const char *str));
213 static lt_ptr lt_emalloc LT_PARAMS((size_t size));
214 static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size));
216 /* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */
217 #define rpl_realloc realloc
219 /* These are the pointers that can be changed by the caller: */
220 LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
221 = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
222 LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size))
223 = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
224 LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
225 = (void (*) LT_PARAMS((lt_ptr))) free;
227 /* The following macros reduce the amount of typing needed to cast
231 #define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
232 #define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
233 #define LT_DLFREE(p) \
234 LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
236 #define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
237 #define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
241 #define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
242 #define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((p), (n) * sizeof(tp)))
243 #define LT_DLFREE(p) \
244 LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
246 #define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
247 #define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
251 #define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
252 if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \
256 /* --- REPLACEMENT FUNCTIONS --- */
260 #define strdup rpl_strdup
262 static char *strdup LT_PARAMS((const char *str));
272 tmp = LT_DLMALLOC (char, 1+ strlen (str));
286 #define strcmp rpl_strcmp
288 static int strcmp LT_PARAMS((const char *str1, const char *str2));
302 for (;*str1 && *str2; ++str1, ++str2)
308 return (int)(*str1 - *str2);
316 # define strchr index
318 # define strchr rpl_strchr
320 static const char *strchr LT_PARAMS((const char *str, int ch));
329 for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
332 return (*p == (char)ch) ? p : 0;
336 #endif /* !HAVE_STRCHR */
342 # define strrchr rindex
344 # define strrchr rpl_strrchr
346 static const char *strrchr LT_PARAMS((const char *str, int ch));
353 const char *p, *q = 0;
355 for (p = str; *p != LT_EOS_CHAR; ++p)
369 /* NOTE: Neither bcopy nor the memcpy implementation below can
370 reliably handle copying in overlapping areas of memory. Use
371 memmove (for which there is a fallback implmentation below)
372 if you need that behaviour. */
376 # define memcpy(dest, src, size) bcopy (src, dest, size)
378 # define memcpy rpl_memcpy
380 static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
383 memcpy (dest, src, size)
388 const char * s = src;
392 for (i = 0; i < size; ++i)
400 # endif /* !HAVE_BCOPY */
401 #endif /* !HAVE_MEMCPY */
404 # define memmove rpl_memmove
406 static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
409 memmove (dest, src, size)
414 const char * s = src;
419 for (i = 0; i < size; ++i)
423 else if (d > s && size > 0)
424 for (i = size -1; ; --i)
434 #endif /* !HAVE_MEMMOVE */
436 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
438 static void closedir LT_PARAMS((DIR *entry));
444 assert(entry != (DIR *) NULL);
445 FindClose(entry->hSearch);
446 lt_dlfree((lt_ptr)entry);
450 static DIR * opendir LT_PARAMS((const char *path));
456 char file_specification[LT_FILENAME_MAX];
459 assert(path != (char *) NULL);
460 (void) strncpy(file_specification,path,LT_FILENAME_MAX-1);
461 (void) strcat(file_specification,"\\");
462 entry = LT_DLMALLOC (DIR,sizeof(DIR));
463 if (entry != (DIR *) 0)
465 entry->firsttime = TRUE;
466 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
468 if (entry->hSearch == INVALID_HANDLE_VALUE)
470 (void) strcat(file_specification,"\\*.*");
471 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
472 if (entry->hSearch == INVALID_HANDLE_VALUE)
482 static struct dirent *readdir LT_PARAMS((DIR *entry));
484 static struct dirent *readdir(entry)
490 if (entry == (DIR *) 0)
491 return((struct dirent *) 0);
492 if (!entry->firsttime)
494 status = FindNextFile(entry->hSearch,&entry->Win32FindData);
496 return((struct dirent *) 0);
498 entry->firsttime = FALSE;
499 (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
501 entry->file_info.d_namlen = strlen(entry->file_info.d_name);
502 return(&entry->file_info);
505 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
507 /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
508 ``realloc is not entirely portable''
509 In any case we want to use the allocator supplied by the user without
510 burdening them with an lt_dlrealloc function pointer to maintain.
511 Instead implement our own version (with known boundary conditions)
512 using lt_dlmalloc and lt_dlfree. */
515 #define realloc rpl_realloc
518 /* You can't (re)define realloc unless you also (re)define malloc.
519 Right now, this code uses the size of the *destination* to decide
520 how much to copy. That's not right, but you can't know the size
521 of the source unless you know enough about, or wrote malloc. So
522 this code is disabled... */
531 /* For zero or less bytes, free the original memory */
541 /* Allow reallocation of a NULL pointer. */
542 return lt_dlmalloc (size);
546 /* Allocate a new block, copy and free the old block. */
547 lt_ptr mem = lt_dlmalloc (size);
551 memcpy (mem, ptr, size);
555 /* Note that the contents of PTR are not damaged if there is
556 insufficient memory to realloc. */
563 #if ! HAVE_ARGZ_APPEND
564 # define argz_append rpl_argz_append
566 static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
567 const char *buf, size_t buf_len));
570 argz_append (pargz, pargz_len, buf, buf_len)
581 assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
583 /* If nothing needs to be appended, no more work is required. */
587 /* Ensure there is enough room to append BUF_LEN. */
588 argz_len = *pargz_len + buf_len;
589 argz = LT_DLREALLOC (char, *pargz, argz_len);
593 /* Copy characters from BUF after terminating '\0' in ARGZ. */
594 memcpy (argz + *pargz_len, buf, buf_len);
596 /* Assign new values. */
598 *pargz_len = argz_len;
602 #endif /* !HAVE_ARGZ_APPEND */
605 #if ! HAVE_ARGZ_CREATE_SEP
606 # define argz_create_sep rpl_argz_create_sep
608 static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
609 char **pargz, size_t *pargz_len));
612 argz_create_sep (str, delim, pargz, pargz_len)
625 /* Make a copy of STR, but replacing each occurence of
627 argz_len = 1+ LT_STRLEN (str);
633 argz = LT_DLMALLOC (char, argz_len);
637 for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
641 /* Ignore leading delimiters, and fold consecutive
642 delimiters in STR into a single '\0' in ARGZ. */
643 if ((q > argz) && (q[-1] != LT_EOS_CHAR))
651 /* Copy terminating LT_EOS_CHAR. */
655 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
659 /* Assign new values. */
661 *pargz_len = argz_len;
665 #endif /* !HAVE_ARGZ_CREATE_SEP */
668 #if ! HAVE_ARGZ_INSERT
669 # define argz_insert rpl_argz_insert
671 static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
672 char *before, const char *entry));
675 argz_insert (pargz, pargz_len, before, entry)
683 assert (entry && *entry);
685 /* No BEFORE address indicates ENTRY should be inserted after the
686 current last element. */
688 return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
690 /* This probably indicates a programmer error, but to preserve
691 semantics, scan back to the start of an entry if BEFORE points
692 into the middle of it. */
693 while ((before > *pargz) && (before[-1] != LT_EOS_CHAR))
697 size_t entry_len = 1+ LT_STRLEN (entry);
698 size_t argz_len = *pargz_len + entry_len;
699 size_t offset = before - *pargz;
700 char *argz = LT_DLREALLOC (char, *pargz, argz_len);
705 /* Make BEFORE point to the equivalent offset in ARGZ that it
706 used to have in *PARGZ incase realloc() moved the block. */
707 before = argz + offset;
709 /* Move the ARGZ entries starting at BEFORE up into the new
710 space at the end -- making room to copy ENTRY into the
712 memmove (before + entry_len, before, *pargz_len - offset);
713 memcpy (before, entry, entry_len);
715 /* Assign new values. */
717 *pargz_len = argz_len;
722 #endif /* !HAVE_ARGZ_INSERT */
726 # define argz_next rpl_argz_next
728 static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
732 argz_next (argz, argz_len, entry)
737 assert ((argz && argz_len) || (!argz && !argz_len));
741 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
742 within the ARGZ vector. */
743 assert ((!argz && !argz_len)
744 || ((argz <= entry) && (entry < (argz + argz_len))));
746 /* Move to the char immediately after the terminating
748 entry = 1+ strchr (entry, LT_EOS_CHAR);
750 /* Return either the new ENTRY, or else NULL if ARGZ is
752 return (entry >= argz + argz_len) ? 0 : (char *) entry;
756 /* This should probably be flagged as a programmer error,
757 since starting an argz_next loop with the iterator set
758 to ARGZ is safer. To preserve semantics, handle the NULL
759 case by returning the start of ARGZ (if any). */
766 #endif /* !HAVE_ARGZ_NEXT */
770 #if ! HAVE_ARGZ_STRINGIFY
771 # define argz_stringify rpl_argz_stringify
773 static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
777 argz_stringify (argz, argz_len, sep)
782 assert ((argz && argz_len) || (!argz && !argz_len));
786 --argz_len; /* don't stringify the terminating EOS */
787 while (--argz_len > 0)
789 if (argz[argz_len] == LT_EOS_CHAR)
790 argz[argz_len] = sep;
794 #endif /* !HAVE_ARGZ_STRINGIFY */
799 /* --- TYPE DEFINITIONS -- */
802 /* This type is used for the array of caller data sets in each handler. */
811 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
814 /* Extract the diagnostic strings from the error table macro in the same
815 order as the enumerated indices in ltdl.h. */
817 static const char *lt_dlerror_strings[] =
819 #define LT_ERROR(name, diagnostic) (diagnostic),
826 /* This structure is used for the list of registered loaders. */
828 struct lt_dlloader *next;
829 const char *loader_name; /* identifying name for each loader */
830 const char *sym_prefix; /* prefix for symbols */
831 lt_module_open *module_open;
832 lt_module_close *module_close;
833 lt_find_sym *find_sym;
834 lt_dlloader_exit *dlloader_exit;
835 lt_user_data dlloader_data;
838 struct lt_dlhandle_struct {
839 struct lt_dlhandle_struct *next;
840 lt_dlloader *loader; /* dlopening interface */
842 int depcount; /* number of dependencies */
843 lt_dlhandle *deplibs; /* dependencies */
844 lt_module module; /* system module handle */
845 lt_ptr system; /* system specific data */
846 lt_caller_data *caller_data; /* per caller associated data */
847 int flags; /* various boolean stats */
850 /* Various boolean flags can be stored in the flags field of an
851 lt_dlhandle_struct... */
852 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
853 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
855 #define LT_DLRESIDENT_FLAG (0x01 << 0)
856 /* ...add more flags here... */
858 #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
861 #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
863 static const char objdir[] = LTDL_OBJDIR;
864 static const char archive_ext[] = LTDL_ARCHIVE_EXT;
865 #ifdef LTDL_SHLIB_EXT
866 static const char shlib_ext[] = LTDL_SHLIB_EXT;
868 #ifdef LTDL_SYSSEARCHPATH
869 static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
875 /* --- MUTEX LOCKING --- */
878 /* Macros to make it easier to run the lock functions only if they have
879 been registered. The reason for the complicated lock macro is to
880 ensure that the stored error message from the last error is not
881 accidentally erased if the current function doesn't generate an
883 #define LT_DLMUTEX_LOCK() LT_STMT_START { \
884 if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
886 #define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
887 if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
889 #define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
890 if (lt_dlmutex_seterror_func) \
891 (*lt_dlmutex_seterror_func) (errormsg); \
892 else lt_dllast_error = (errormsg); } LT_STMT_END
893 #define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
894 if (lt_dlmutex_seterror_func) \
895 (errormsg) = (*lt_dlmutex_geterror_func) (); \
896 else (errormsg) = lt_dllast_error; } LT_STMT_END
898 /* The mutex functions stored here are global, and are necessarily the
899 same for all threads that wish to share access to libltdl. */
900 static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
901 static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
902 static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
903 static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
904 static const char *lt_dllast_error = 0;
907 /* Either set or reset the mutex functions. Either all the arguments must
908 be valid functions, or else all can be NULL to turn off locking entirely.
909 The registered functions should be manipulating a static global lock
910 from the lock() and unlock() callbacks, which needs to be reentrant. */
912 lt_dlmutex_register (lock, unlock, seterror, geterror)
913 lt_dlmutex_lock *lock;
914 lt_dlmutex_unlock *unlock;
915 lt_dlmutex_seterror *seterror;
916 lt_dlmutex_geterror *geterror;
918 lt_dlmutex_unlock *old_unlock = unlock;
921 /* Lock using the old lock() callback, if any. */
924 if ((lock && unlock && seterror && geterror)
925 || !(lock || unlock || seterror || geterror))
927 lt_dlmutex_lock_func = lock;
928 lt_dlmutex_unlock_func = unlock;
929 lt_dlmutex_geterror_func = geterror;
933 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
937 /* Use the old unlock() callback we saved earlier, if any. Otherwise
938 record any errors using internal storage. */
942 /* Return the number of errors encountered during the execution of
950 /* --- ERROR HANDLING --- */
953 static const char **user_error_strings = 0;
954 static int errorcount = LT_ERROR_MAX;
957 lt_dladderror (diagnostic)
958 const char *diagnostic;
962 const char **temp = (const char **) 0;
968 errindex = errorcount - LT_ERROR_MAX;
969 temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
972 user_error_strings = temp;
973 user_error_strings[errindex] = diagnostic;
974 result = errorcount++;
977 LT_DLMUTEX_UNLOCK ();
983 lt_dlseterror (errindex)
990 if (errindex >= errorcount || errindex < 0)
992 /* Ack! Error setting the error message! */
993 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
996 else if (errindex < LT_ERROR_MAX)
998 /* No error setting the error message! */
999 LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
1003 /* No error setting the error message! */
1004 LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
1007 LT_DLMUTEX_UNLOCK ();
1016 lt_ptr mem = lt_dlmalloc (size);
1018 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1023 lt_erealloc (addr, size)
1027 lt_ptr mem = lt_dlrealloc (addr, size);
1029 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1037 char *copy = strdup (str);
1038 if (LT_STRLEN (str) && !copy)
1039 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1046 /* --- DLOPEN() INTERFACE LOADER --- */
1051 /* dynamic linking with dlopen/dlsym */
1058 # include <sys/dl.h>
1062 # define LT_GLOBAL RTLD_GLOBAL
1065 # define LT_GLOBAL DL_GLOBAL
1067 #endif /* !RTLD_GLOBAL */
1069 # define LT_GLOBAL 0
1070 #endif /* !LT_GLOBAL */
1072 /* We may have to define LT_LAZY_OR_NOW in the command line if we
1073 find out it does not work in some platform. */
1074 #ifndef LT_LAZY_OR_NOW
1076 # define LT_LAZY_OR_NOW RTLD_LAZY
1079 # define LT_LAZY_OR_NOW DL_LAZY
1081 # endif /* !RTLD_LAZY */
1083 #ifndef LT_LAZY_OR_NOW
1085 # define LT_LAZY_OR_NOW RTLD_NOW
1088 # define LT_LAZY_OR_NOW DL_NOW
1090 # endif /* !RTLD_NOW */
1092 #ifndef LT_LAZY_OR_NOW
1093 # define LT_LAZY_OR_NOW 0
1094 #endif /* !LT_LAZY_OR_NOW */
1097 # define DLERROR(arg) dlerror ()
1099 # define DLERROR(arg) LT_DLSTRERROR (arg)
1103 sys_dl_open (loader_data, filename)
1104 lt_user_data loader_data;
1105 const char *filename;
1107 lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
1111 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
1118 sys_dl_close (loader_data, module)
1119 lt_user_data loader_data;
1124 if (dlclose (module) != 0)
1126 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
1134 sys_dl_sym (loader_data, module, symbol)
1135 lt_user_data loader_data;
1139 lt_ptr address = dlsym (module, symbol);
1143 LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
1149 static struct lt_user_dlloader sys_dl =
1156 sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
1159 #endif /* HAVE_LIBDL */
1163 /* --- SHL_LOAD() INTERFACE LOADER --- */
1167 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1173 /* some flags are missing on some systems, so we provide
1174 * harmless defaults.
1177 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1178 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1181 * BIND_FIRST - Place the library at the head of the symbol search
1183 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1184 * unsatisfied symbols as fatal. This flag allows
1185 * binding of unsatisfied code symbols to be deferred
1187 * [Perl: For certain libraries, like DCE, deferred
1188 * binding often causes run time problems. Adding
1189 * BIND_NONFATAL to BIND_IMMEDIATE still allows
1190 * unresolved references in situations like this.]
1191 * BIND_NOSTART - Do not call the initializer for the shared library
1192 * when the library is loaded, nor on a future call to
1194 * BIND_VERBOSE - Print verbose messages concerning possible
1195 * unsatisfied symbols.
1197 * hp9000s700/hp9000s800:
1198 * BIND_RESTRICTED - Restrict symbols visible by the library to those
1199 * present at library load time.
1200 * DYNAMIC_PATH - Allow the loader to dynamically search for the
1201 * library specified by the path argument.
1204 #ifndef DYNAMIC_PATH
1205 # define DYNAMIC_PATH 0
1207 #ifndef BIND_RESTRICTED
1208 # define BIND_RESTRICTED 0
1211 #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1214 sys_shl_open (loader_data, filename)
1215 lt_user_data loader_data;
1216 const char *filename;
1218 static shl_t self = (shl_t) 0;
1219 lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1221 /* Since searching for a symbol against a NULL module handle will also
1222 look in everything else that was already loaded and exported with
1223 the -E compiler flag, we always cache a handle saved before any
1224 modules are loaded. */
1228 shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1237 module = shl_load (filename, LT_BIND_FLAGS, 0L);
1241 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1249 sys_shl_close (loader_data, module)
1250 lt_user_data loader_data;
1255 if (module && (shl_unload ((shl_t) (module)) != 0))
1257 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1265 sys_shl_sym (loader_data, module, symbol)
1266 lt_user_data loader_data;
1272 /* sys_shl_open should never return a NULL module handle */
1273 if (module == (lt_module) 0)
1275 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1277 else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
1281 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1288 static struct lt_user_dlloader sys_shl = {
1289 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
1292 #endif /* HAVE_SHL_LOAD */
1297 /* --- LOADLIBRARY() INTERFACE LOADER --- */
1301 /* dynamic linking for Win32 */
1303 #include <windows.h>
1305 /* Forward declaration; required to implement handle search below. */
1306 static lt_dlhandle handles;
1309 sys_wll_open (loader_data, filename)
1310 lt_user_data loader_data;
1311 const char *filename;
1314 lt_module module = 0;
1315 const char *errormsg = 0;
1316 char *searchname = 0;
1318 char self_name_buf[MAX_PATH];
1322 /* Get the name of main module */
1324 GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
1325 filename = ext = self_name_buf;
1329 ext = strrchr (filename, '.');
1334 /* FILENAME already has an extension. */
1335 searchname = lt_estrdup (filename);
1339 /* Append a `.' to stop Windows from adding an
1340 implicit `.dll' extension. */
1341 searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
1343 sprintf (searchname, "%s.", filename);
1350 char wpath[MAX_PATH];
1351 cygwin_conv_to_full_win32_path(searchname, wpath);
1352 module = LoadLibrary(wpath);
1355 module = LoadLibrary (searchname);
1357 LT_DLFREE (searchname);
1359 /* libltdl expects this function to fail if it is unable
1360 to physically load the library. Sadly, LoadLibrary
1361 will search the loaded libraries for a match and return
1362 one of them if the path search load fails.
1364 We check whether LoadLibrary is returning a handle to
1365 an already loaded module, and simulate failure if we
1377 if (cur->module == module)
1384 LT_DLMUTEX_UNLOCK ();
1388 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1396 sys_wll_close (loader_data, module)
1397 lt_user_data loader_data;
1402 if (FreeLibrary(module) == 0)
1404 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1412 sys_wll_sym (loader_data, module, symbol)
1413 lt_user_data loader_data;
1417 lt_ptr address = GetProcAddress (module, symbol);
1421 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1427 static struct lt_user_dlloader sys_wll = {
1428 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1431 #endif /* __WINDOWS__ */
1436 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1441 /* dynamic linking for BeOS */
1443 #include <kernel/image.h>
1446 sys_bedl_open (loader_data, filename)
1447 lt_user_data loader_data;
1448 const char *filename;
1454 image = load_add_on (filename);
1460 if (get_next_image_info (0, &cookie, &info) == B_OK)
1461 image = load_add_on (info.name);
1466 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1470 return (lt_module) image;
1474 sys_bedl_close (loader_data, module)
1475 lt_user_data loader_data;
1480 if (unload_add_on ((image_id) module) != B_OK)
1482 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1490 sys_bedl_sym (loader_data, module, symbol)
1491 lt_user_data loader_data;
1496 image_id image = (image_id) module;
1498 if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1500 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1507 static struct lt_user_dlloader sys_bedl = {
1508 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1511 #endif /* __BEOS__ */
1516 /* --- DLD_LINK() INTERFACE LOADER --- */
1521 /* dynamic linking with dld */
1528 sys_dld_open (loader_data, filename)
1529 lt_user_data loader_data;
1530 const char *filename;
1532 lt_module module = strdup (filename);
1534 if (dld_link (filename) != 0)
1536 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1545 sys_dld_close (loader_data, module)
1546 lt_user_data loader_data;
1551 if (dld_unlink_by_file ((char*)(module), 1) != 0)
1553 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1565 sys_dld_sym (loader_data, module, symbol)
1566 lt_user_data loader_data;
1570 lt_ptr address = dld_get_func (symbol);
1574 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1580 static struct lt_user_dlloader sys_dld = {
1581 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1584 #endif /* HAVE_DLD */
1586 /* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
1590 #if HAVE_MACH_O_DYLD_H
1591 #if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
1592 /* Is this correct? Does it still function properly? */
1593 #define __private_extern__ extern
1595 # include <mach-o/dyld.h>
1597 #include <mach-o/getsect.h>
1599 /* We have to put some stuff here that isn't in older dyld.h files */
1600 #ifndef ENUM_DYLD_BOOL
1601 # define ENUM_DYLD_BOOL
1610 # define LC_REQ_DYLD 0x80000000
1612 #ifndef LC_LOAD_WEAK_DYLIB
1613 # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
1615 static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0;
1616 static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0;
1617 static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0;
1618 static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0;
1620 #ifndef NSADDIMAGE_OPTION_NONE
1621 #define NSADDIMAGE_OPTION_NONE 0x0
1623 #ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
1624 #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
1626 #ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
1627 #define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
1629 #ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1630 #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
1632 #ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
1633 #define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
1635 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
1636 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
1638 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1639 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
1641 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
1642 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
1644 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1645 #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
1650 lt_int_dyld_error(othererror)
1653 /* return the dyld error string, or the passed in error string if none */
1654 NSLinkEditErrors ler;
1658 NSLinkEditError(&ler,&lerno,&file,&errstr);
1659 if (!errstr || !strlen(errstr)) errstr = othererror;
1663 static const struct mach_header *
1664 lt_int_dyld_get_mach_header_from_nsmodule(module)
1667 /* There should probably be an apple dyld api for this */
1668 int i=_dyld_image_count();
1670 const char *modname=NSNameOfModule(module);
1671 const struct mach_header *mh=NULL;
1672 if (!modname) return NULL;
1673 for (j = 0; j < i; j++)
1675 if (!strcmp(_dyld_get_image_name(j),modname))
1677 mh=_dyld_get_image_header(j);
1684 static const char* lt_int_dyld_lib_install_name(mh)
1685 const struct mach_header *mh;
1687 /* NSAddImage is also used to get the loaded image, but it only works if the lib
1688 is installed, for uninstalled libs we need to check the install_names against
1689 each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
1690 different lib was loaded as a result
1693 struct load_command *lc;
1694 unsigned long offset = sizeof(struct mach_header);
1695 const char* retStr=NULL;
1696 for (j = 0; j < mh->ncmds; j++)
1698 lc = (struct load_command*)(((unsigned long)mh) + offset);
1699 if (LC_ID_DYLIB == lc->cmd)
1701 retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset +
1704 offset += lc->cmdsize;
1709 static const struct mach_header *
1710 lt_int_dyld_match_loaded_lib_by_install_name(const char *name)
1712 int i=_dyld_image_count();
1714 const struct mach_header *mh=NULL;
1715 const char *id=NULL;
1716 for (j = 0; j < i; j++)
1718 id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j));
1719 if ((id) && (!strcmp(id,name)))
1721 mh=_dyld_get_image_header(j);
1729 lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh)
1731 const struct mach_header *mh;
1733 /* Safe to assume our mh is good */
1735 struct load_command *lc;
1736 unsigned long offset = sizeof(struct mach_header);
1737 NSSymbol retSym = 0;
1738 const struct mach_header *mh1;
1739 if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) )
1741 for (j = 0; j < mh->ncmds; j++)
1743 lc = (struct load_command*)(((unsigned long)mh) + offset);
1744 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
1746 mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1747 (unsigned long)lc));
1750 /* Maybe NSAddImage can find it */
1751 mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1753 NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +
1754 NSADDIMAGE_OPTION_WITH_SEARCHING +
1755 NSADDIMAGE_OPTION_RETURN_ON_ERROR );
1759 retSym = ltdl_NSLookupSymbolInImage(mh1,
1761 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1762 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1767 offset += lc->cmdsize;
1778 if (!_dyld_present()) {
1782 err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage);
1783 err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage);
1784 err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage);
1785 err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic);
1791 sys_dyld_open (loader_data, filename)
1792 lt_user_data loader_data;
1793 const char *filename;
1795 lt_module module = 0;
1796 NSObjectFileImage ofi = 0;
1797 NSObjectFileImageReturnCode ofirc;
1800 return (lt_module)-1;
1801 ofirc = NSCreateObjectFileImageFromFile(filename, &ofi);
1804 case NSObjectFileImageSuccess:
1805 module = NSLinkModule(ofi, filename,
1806 NSLINKMODULE_OPTION_RETURN_ON_ERROR
1807 | NSLINKMODULE_OPTION_PRIVATE
1808 | NSLINKMODULE_OPTION_BINDNOW);
1809 NSDestroyObjectFileImage(ofi);
1811 ltdl_NSMakePrivateModulePublic(module);
1813 case NSObjectFileImageInappropriateFile:
1814 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1816 module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
1820 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1823 if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1828 sys_dyld_close (loader_data, module)
1829 lt_user_data loader_data;
1834 if (module == (lt_module)-1) return 0;
1835 #ifdef __BIG_ENDIAN__
1836 if (((struct mach_header *)module)->magic == MH_MAGIC)
1838 if (((struct mach_header *)module)->magic == MH_CIGAM)
1841 LT_DLMUTEX_SETERROR("Can not close a dylib");
1847 /* Currently, if a module contains c++ static destructors and it is unloaded, we
1848 get a segfault in atexit(), due to compiler and dynamic loader differences of
1849 opinion, this works around that.
1851 if ((const struct section *)NULL !=
1852 getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module),
1853 "__DATA","__mod_term_func"))
1855 flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
1859 flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
1861 if (!NSUnLinkModule(module,flags))
1864 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE)));
1872 sys_dyld_sym (loader_data, module, symbol)
1873 lt_user_data loader_data;
1878 NSSymbol *nssym = 0;
1880 const struct mach_header *mh=NULL;
1881 char saveError[256] = "Symbol not found";
1882 if (module == (lt_module)-1)
1884 _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused);
1887 #ifdef __BIG_ENDIAN__
1888 if (((struct mach_header *)module)->magic == MH_MAGIC)
1890 if (((struct mach_header *)module)->magic == MH_CIGAM)
1893 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1896 if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol))
1898 nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module,
1900 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1901 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1908 nssym = NSLookupSymbolInModule(module, symbol);
1912 strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255);
1914 if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module);
1915 nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh);
1919 LT_DLMUTEX_SETERROR (saveError);
1922 return NSAddressOfSymbol(nssym);
1925 static struct lt_user_dlloader sys_dyld =
1926 { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
1929 #endif /* HAVE_DYLD */
1932 /* --- DLPREOPEN() INTERFACE LOADER --- */
1935 /* emulate dynamic linking using preloaded_symbols */
1937 typedef struct lt_dlsymlists_t
1939 struct lt_dlsymlists_t *next;
1940 const lt_dlsymlist *syms;
1943 static const lt_dlsymlist *default_preloaded_symbols = 0;
1944 static lt_dlsymlists_t *preloaded_symbols = 0;
1947 presym_init (loader_data)
1948 lt_user_data loader_data;
1954 preloaded_symbols = 0;
1955 if (default_preloaded_symbols)
1957 errors = lt_dlpreload (default_preloaded_symbols);
1960 LT_DLMUTEX_UNLOCK ();
1966 presym_free_symlists ()
1968 lt_dlsymlists_t *lists;
1972 lists = preloaded_symbols;
1975 lt_dlsymlists_t *tmp = lists;
1977 lists = lists->next;
1980 preloaded_symbols = 0;
1982 LT_DLMUTEX_UNLOCK ();
1988 presym_exit (loader_data)
1989 lt_user_data loader_data;
1991 presym_free_symlists ();
1996 presym_add_symlist (preloaded)
1997 const lt_dlsymlist *preloaded;
1999 lt_dlsymlists_t *tmp;
2000 lt_dlsymlists_t *lists;
2005 lists = preloaded_symbols;
2008 if (lists->syms == preloaded)
2012 lists = lists->next;
2015 tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
2018 memset (tmp, 0, sizeof(lt_dlsymlists_t));
2019 tmp->syms = preloaded;
2020 tmp->next = preloaded_symbols;
2021 preloaded_symbols = tmp;
2029 LT_DLMUTEX_UNLOCK ();
2034 presym_open (loader_data, filename)
2035 lt_user_data loader_data;
2036 const char *filename;
2038 lt_dlsymlists_t *lists;
2039 lt_module module = (lt_module) 0;
2042 lists = preloaded_symbols;
2046 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
2050 /* Can't use NULL as the reflective symbol header, as NULL is
2051 used to mark the end of the entire symbol list. Self-dlpreopened
2052 symbols follow this magic number, chosen to be an unlikely
2053 clash with a real module name. */
2056 filename = "@PROGRAM@";
2061 const lt_dlsymlist *syms = lists->syms;
2065 if (!syms->address && strcmp(syms->name, filename) == 0)
2067 module = (lt_module) syms;
2073 lists = lists->next;
2076 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2079 LT_DLMUTEX_UNLOCK ();
2084 presym_close (loader_data, module)
2085 lt_user_data loader_data;
2088 /* Just to silence gcc -Wall */
2094 presym_sym (loader_data, module, symbol)
2095 lt_user_data loader_data;
2099 lt_dlsymlist *syms = (lt_dlsymlist*) module;
2102 while (syms->address)
2104 if (strcmp(syms->name, symbol) == 0)
2106 return syms->address;
2112 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
2117 static struct lt_user_dlloader presym = {
2118 0, presym_open, presym_close, presym_sym, presym_exit, 0
2125 /* --- DYNAMIC MODULE LOADING --- */
2128 /* The type of a function used at each iteration of foreach_dirinpath(). */
2129 typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
2132 static int foreach_dirinpath LT_PARAMS((const char *search_path,
2133 const char *base_name,
2134 foreach_callback_func *func,
2135 lt_ptr data1, lt_ptr data2));
2137 static int find_file_callback LT_PARAMS((char *filename, lt_ptr data,
2139 static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data,
2141 static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1,
2145 static int canonicalize_path LT_PARAMS((const char *path,
2146 char **pcanonical));
2147 static int argzize_path LT_PARAMS((const char *path,
2149 size_t *pargz_len));
2150 static FILE *find_file LT_PARAMS((const char *search_path,
2151 const char *base_name,
2153 static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
2154 const char *base_name,
2155 lt_dlhandle *handle));
2156 static int find_module LT_PARAMS((lt_dlhandle *handle,
2160 const char *old_name,
2162 static int free_vars LT_PARAMS((char *dlname, char *oldname,
2163 char *libdir, char *deplibs));
2164 static int load_deplibs LT_PARAMS((lt_dlhandle handle,
2166 static int trim LT_PARAMS((char **dest,
2168 static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
2169 const char *filename));
2170 static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
2171 const char *filename));
2172 static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
2173 static int lt_argz_insert LT_PARAMS((char **pargz,
2176 const char *entry));
2177 static int lt_argz_insertinorder LT_PARAMS((char **pargz,
2179 const char *entry));
2180 static int lt_argz_insertdir LT_PARAMS((char **pargz,
2183 struct dirent *dp));
2184 static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
2187 static int list_files_by_dir LT_PARAMS((const char *dirnam,
2189 size_t *pargz_len));
2190 static int file_not_found LT_PARAMS((void));
2192 static char *user_search_path= 0;
2193 static lt_dlloader *loaders = 0;
2194 static lt_dlhandle handles = 0;
2195 static int initialized = 0;
2197 /* Initialize libltdl. */
2205 /* Initialize only at first call. */
2206 if (++initialized == 1)
2209 user_search_path = 0; /* empty search path */
2212 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
2215 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
2218 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
2221 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
2224 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
2227 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld");
2228 errors += sys_dyld_init();
2230 errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
2232 if (presym_init (presym.dlloader_data))
2234 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
2237 else if (errors != 0)
2239 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
2244 LT_DLMUTEX_UNLOCK ();
2250 lt_dlpreload (preloaded)
2251 const lt_dlsymlist *preloaded;
2257 errors = presym_add_symlist (preloaded);
2261 presym_free_symlists();
2264 if (default_preloaded_symbols)
2266 errors = lt_dlpreload (default_preloaded_symbols);
2268 LT_DLMUTEX_UNLOCK ();
2275 lt_dlpreload_default (preloaded)
2276 const lt_dlsymlist *preloaded;
2279 default_preloaded_symbols = preloaded;
2280 LT_DLMUTEX_UNLOCK ();
2287 /* shut down libltdl */
2288 lt_dlloader *loader;
2296 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
2301 /* shut down only at last call. */
2302 if (--initialized == 0)
2306 while (handles && LT_DLIS_RESIDENT (handles))
2308 handles = handles->next;
2311 /* close all modules */
2312 for (level = 1; handles; ++level)
2314 lt_dlhandle cur = handles;
2315 int saw_nonresident = 0;
2319 lt_dlhandle tmp = cur;
2321 if (!LT_DLIS_RESIDENT (tmp))
2322 saw_nonresident = 1;
2323 if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
2325 if (lt_dlclose (tmp))
2331 /* done if only resident modules are left */
2332 if (!saw_nonresident)
2336 /* close all loaders */
2339 lt_dlloader *next = loader->next;
2340 lt_user_data data = loader->dlloader_data;
2341 if (loader->dlloader_exit && loader->dlloader_exit (data))
2346 LT_DLMEM_REASSIGN (loader, next);
2350 LT_DLFREE (user_search_path);
2354 LT_DLMUTEX_UNLOCK ();
2359 tryall_dlopen (handle, filename)
2360 lt_dlhandle *handle;
2361 const char *filename;
2364 lt_dlloader *loader;
2365 const char *saved_error;
2368 LT_DLMUTEX_GETERROR (saved_error);
2374 /* check whether the module was already opened */
2377 /* try to dlopen the program itself? */
2378 if (!cur->info.filename && !filename)
2383 if (cur->info.filename && filename
2384 && strcmp (cur->info.filename, filename) == 0)
2394 ++cur->info.ref_count;
2402 /* Comment out the check of file permissions using access.
2403 This call seems to always return -1 with error EACCES.
2405 /* We need to catch missing file errors early so that
2406 file_not_found() can detect what happened.
2407 if (access (filename, R_OK) != 0)
2409 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2414 cur->info.filename = lt_estrdup (filename);
2415 if (!cur->info.filename)
2423 cur->info.filename = 0;
2428 lt_user_data data = loader->dlloader_data;
2430 cur->module = loader->module_open (data, filename);
2432 if (cur->module != 0)
2436 loader = loader->next;
2441 LT_DLFREE (cur->info.filename);
2446 cur->loader = loader;
2447 LT_DLMUTEX_SETERROR (saved_error);
2450 LT_DLMUTEX_UNLOCK ();
2456 tryall_dlopen_module (handle, prefix, dirname, dlname)
2457 lt_dlhandle *handle;
2459 const char *dirname;
2464 size_t filename_len = 0;
2465 size_t dirname_len = LT_STRLEN (dirname);
2470 #ifdef LT_DIRSEP_CHAR
2471 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2472 should make it into this function: */
2473 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
2476 if (dirname_len > 0)
2477 if (dirname[dirname_len -1] == '/')
2479 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
2481 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2482 The PREFIX (if any) is handled below. */
2483 filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
2487 sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
2489 /* Now that we have combined DIRNAME and MODULENAME, if there is
2490 also a PREFIX to contend with, simply recurse with the arguments
2491 shuffled. Otherwise, attempt to open FILENAME as a module. */
2494 error += tryall_dlopen_module (handle,
2495 (const char *) 0, prefix, filename);
2497 else if (tryall_dlopen (handle, filename) != 0)
2502 LT_DLFREE (filename);
2507 find_module (handle, dir, libdir, dlname, old_name, installed)
2508 lt_dlhandle *handle;
2512 const char *old_name;
2515 /* Try to open the old library first; if it was dlpreopened,
2516 we want the preopened version of it, even if a dlopenable
2517 module is available. */
2518 if (old_name && tryall_dlopen (handle, old_name) == 0)
2523 /* Try to open the dynamic library. */
2526 /* try to open the installed module */
2527 if (installed && libdir)
2529 if (tryall_dlopen_module (handle,
2530 (const char *) 0, libdir, dlname) == 0)
2534 /* try to open the not-installed module */
2537 if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2541 /* maybe it was moved to another directory */
2543 if (tryall_dlopen_module (handle,
2544 (const char *) 0, dir, dlname) == 0)
2554 canonicalize_path (path, pcanonical)
2558 char *canonical = 0;
2560 assert (path && *path);
2561 assert (pcanonical);
2563 canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2570 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2572 /* Path separators are not copied to the beginning or end of
2573 the destination, or if another separator would follow
2575 if (path[src] == LT_PATHSEP_CHAR)
2578 || (path[1+ src] == LT_PATHSEP_CHAR)
2579 || (path[1+ src] == LT_EOS_CHAR))
2583 /* Anything other than a directory separator is copied verbatim. */
2584 if ((path[src] != '/')
2585 #ifdef LT_DIRSEP_CHAR
2586 && (path[src] != LT_DIRSEP_CHAR)
2590 canonical[dest++] = path[src];
2592 /* Directory separators are converted and copied only if they are
2593 not at the end of a path -- i.e. before a path separator or
2595 else if ((path[1+ src] != LT_PATHSEP_CHAR)
2596 && (path[1+ src] != LT_EOS_CHAR)
2597 #ifdef LT_DIRSEP_CHAR
2598 && (path[1+ src] != LT_DIRSEP_CHAR)
2600 && (path[1+ src] != '/'))
2602 canonical[dest++] = '/';
2606 /* Add an end-of-string marker at the end. */
2607 canonical[dest] = LT_EOS_CHAR;
2610 /* Assign new value. */
2611 *pcanonical = canonical;
2617 argzize_path (path, pargz, pargz_len)
2628 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2633 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2636 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2646 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2647 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2648 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2649 it is appended to each SEARCH_PATH element before FUNC is called. */
2651 foreach_dirinpath (search_path, base_name, func, data1, data2)
2652 const char *search_path;
2653 const char *base_name;
2654 foreach_callback_func *func;
2659 int filenamesize = 0;
2660 size_t lenbase = LT_STRLEN (base_name);
2661 size_t argz_len = 0;
2664 char *canonical = 0;
2668 if (!search_path || !*search_path)
2670 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2674 if (canonicalize_path (search_path, &canonical) != 0)
2677 if (argzize_path (canonical, &argz, &argz_len) != 0)
2682 while ((dir_name = argz_next (argz, argz_len, dir_name)))
2684 size_t lendir = LT_STRLEN (dir_name);
2686 if (lendir +1 +lenbase >= filenamesize)
2688 LT_DLFREE (filename);
2689 filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2690 filename = LT_EMALLOC (char, filenamesize);
2695 assert (filenamesize > lendir);
2696 strcpy (filename, dir_name);
2698 if (base_name && *base_name)
2700 if (filename[lendir -1] != '/')
2701 filename[lendir++] = '/';
2702 strcpy (filename +lendir, base_name);
2705 if ((result = (*func) (filename, data1, data2)))
2714 LT_DLFREE (canonical);
2715 LT_DLFREE (filename);
2717 LT_DLMUTEX_UNLOCK ();
2722 /* If FILEPATH can be opened, store the name of the directory component
2723 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2724 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2726 find_file_callback (filename, data1, data2)
2731 char **pdir = (char **) data1;
2732 FILE **pfile = (FILE **) data2;
2735 assert (filename && *filename);
2739 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
2741 char *dirend = strrchr (filename, '/');
2743 if (dirend > filename)
2744 *dirend = LT_EOS_CHAR;
2747 *pdir = lt_estrdup (filename);
2748 is_done = (*pdir == 0) ? -1 : 1;
2755 find_file (search_path, base_name, pdir)
2756 const char *search_path;
2757 const char *base_name;
2762 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
2768 find_handle_callback (filename, data, ignored)
2773 lt_dlhandle *handle = (lt_dlhandle *) data;
2774 int notfound = access (filename, R_OK);
2776 /* Bail out if file cannot be read... */
2780 /* Try to dlopen the file, but do not continue searching in any
2782 if (tryall_dlopen (handle, filename) != 0)
2788 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2789 found but could not be opened, *HANDLE will be set to 0. */
2790 static lt_dlhandle *
2791 find_handle (search_path, base_name, handle)
2792 const char *search_path;
2793 const char *base_name;
2794 lt_dlhandle *handle;
2799 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2807 load_deplibs (handle, deplibs)
2811 #if LTDL_DLOPEN_DEPLIBS
2812 char *p, *save_search_path = 0;
2819 handle->depcount = 0;
2821 #if LTDL_DLOPEN_DEPLIBS
2829 if (user_search_path)
2831 save_search_path = lt_estrdup (user_search_path);
2832 if (!save_search_path)
2836 /* extract search paths and count deplibs */
2840 if (!isspace ((int) *p))
2843 while (*end && !isspace((int) *end))
2848 if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2851 *end = 0; /* set a temporary string terminator */
2852 if (lt_dladdsearchdir(p+2))
2871 /* restore the old search path */
2872 LT_DLFREE (user_search_path);
2873 user_search_path = save_search_path;
2875 LT_DLMUTEX_UNLOCK ();
2883 names = LT_EMALLOC (char *, depcount * sizeof (char*));
2887 /* now only extract the actual deplibs */
2892 if (isspace ((int) *p))
2899 while (*end && !isspace ((int) *end))
2904 if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2908 *end = 0; /* set a temporary string terminator */
2909 if (strncmp(p, "-l", 2) == 0)
2911 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2912 name = LT_EMALLOC (char, 1+ name_len);
2914 sprintf (name, "lib%s", p+2);
2917 name = lt_estrdup(p);
2922 names[depcount++] = name;
2929 /* load the deplibs (in reverse order)
2930 At this stage, don't worry if the deplibs do not load correctly,
2931 they may already be statically linked into the loading application
2932 for instance. There will be a more enlightening error message
2933 later on if the loaded module cannot resolve all of its symbols. */
2938 handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2939 if (!handle->deplibs)
2942 for (i = 0; i < depcount; ++i)
2944 handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
2945 if (handle->deplibs[j])
2951 handle->depcount = j; /* Number of successfully loaded deplibs */
2956 for (i = 0; i < depcount; ++i)
2958 LT_DLFREE (names[i]);
2969 unload_deplibs (handle)
2975 if (handle->depcount)
2977 for (i = 0; i < handle->depcount; ++i)
2979 if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
2981 errors += lt_dlclose (handle->deplibs[i]);
2994 /* remove the leading and trailing "'" from str
2995 and store the result in dest */
2996 const char *end = strrchr (str, '\'');
2997 size_t len = LT_STRLEN (str);
3002 if (len > 3 && str[0] == '\'')
3004 tmp = LT_EMALLOC (char, end - str);
3008 strncpy(tmp, &str[1], (end - str) - 1);
3009 tmp[len-3] = LT_EOS_CHAR;
3021 free_vars (dlname, oldname, libdir, deplibs)
3028 LT_DLFREE (oldname);
3030 LT_DLFREE (deplibs);
3036 try_dlopen (phandle, filename)
3037 lt_dlhandle *phandle;
3038 const char *filename;
3040 const char * ext = 0;
3041 const char * saved_error = 0;
3042 char * canonical = 0;
3043 char * base_name = 0;
3047 int free_base_name = 0;
3048 lt_dlhandle newhandle;
3051 assert (*phandle == 0);
3053 LT_DLMUTEX_GETERROR (saved_error);
3058 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3062 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3063 newhandle = *phandle;
3065 /* lt_dlclose()ing yourself is very bad! Disallow it. */
3066 LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
3068 if (tryall_dlopen (&newhandle, 0) != 0)
3070 LT_DLFREE (*phandle);
3074 goto register_handle;
3077 assert (filename && *filename);
3079 /* Doing this immediately allows internal functions to safely
3080 assume only canonicalized paths are passed. */
3081 if (canonicalize_path (filename, &canonical) != 0)
3087 /* If the canonical module name is a path (relative or absolute)
3088 then split it into a directory part and a name part. */
3089 base_name = strrchr (canonical, '/');
3092 size_t dirlen = (1+ base_name) - canonical;
3094 dir = LT_EMALLOC (char, 1+ dirlen);
3101 strncpy (dir, canonical, dirlen);
3102 dir[dirlen] = LT_EOS_CHAR;
3107 LT_DLMEM_REASSIGN (base_name, canonical);
3111 assert (base_name && *base_name);
3113 /* Check whether we are opening a libtool module (.la extension). */
3114 ext = strrchr (base_name, '.');
3115 if (ext && strcmp (ext, archive_ext) == 0)
3117 /* this seems to be a libtool module */
3120 char * old_name = 0;
3126 /* if we can't find the installed flag, it is probably an
3127 installed libtool archive, produced with an old version
3131 /* extract the module name from the file name */
3132 name = LT_EMALLOC (char, ext - base_name + 1);
3139 /* canonicalize the module name */
3142 for (i = 0; i < ext - base_name; ++i)
3144 if (isalnum ((int)(base_name[i])))
3146 name[i] = base_name[i];
3153 name[ext - base_name] = LT_EOS_CHAR;
3156 /* Now try to open the .la file. If there is no directory name
3157 component, try to find it first in user_search_path and then other
3158 prescribed paths. Otherwise (or in any case if the module was not
3159 yet found) try opening just the module name as passed. */
3162 const char *search_path;
3165 search_path = user_search_path;
3167 file = find_file (user_search_path, base_name, &dir);
3168 LT_DLMUTEX_UNLOCK ();
3172 search_path = getenv (LTDL_SEARCHPATH_VAR);
3174 file = find_file (search_path, base_name, &dir);
3177 #ifdef LTDL_SHLIBPATH_VAR
3180 search_path = getenv (LTDL_SHLIBPATH_VAR);
3182 file = find_file (search_path, base_name, &dir);
3185 #ifdef LTDL_SYSSEARCHPATH
3186 if (!file && sys_search_path)
3188 file = find_file (sys_search_path, base_name, &dir);
3194 file = fopen (filename, LT_READTEXT_MODE);
3197 /* If we didn't find the file by now, it really isn't there. Set
3198 the status flag, and bail out. */
3201 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3206 line_len = LT_FILENAME_MAX;
3207 line = LT_EMALLOC (char, line_len);
3215 /* read the .la file */
3216 while (!feof (file))
3218 if (!fgets (line, (int) line_len, file))
3223 /* Handle the case where we occasionally need to read a line
3224 that is longer than the initial buffer size. */
3225 while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file)))
3227 line = LT_DLREALLOC (char, line, line_len *2);
3228 if (!fgets (&line[line_len -1], (int) line_len +1, file))
3235 if (line[0] == '\n' || line[0] == '#')
3241 #define STR_DLNAME "dlname="
3242 if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3244 errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
3247 #undef STR_OLD_LIBRARY
3248 #define STR_OLD_LIBRARY "old_library="
3249 else if (strncmp (line, STR_OLD_LIBRARY,
3250 sizeof (STR_OLD_LIBRARY) - 1) == 0)
3252 errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3255 #define STR_LIBDIR "libdir="
3256 else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3258 errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
3261 #undef STR_DL_DEPLIBS
3262 #define STR_DL_DEPLIBS "dependency_libs="
3263 else if (strncmp (line, STR_DL_DEPLIBS,
3264 sizeof (STR_DL_DEPLIBS) - 1) == 0)
3266 errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3268 else if (strcmp (line, "installed=yes\n") == 0)
3272 else if (strcmp (line, "installed=no\n") == 0)
3277 #undef STR_LIBRARY_NAMES
3278 #define STR_LIBRARY_NAMES "library_names="
3279 else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
3280 sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3283 errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3286 && (last_libname = strrchr (dlname, ' ')) != 0)
3288 last_libname = lt_estrdup (last_libname + 1);
3294 LT_DLMEM_REASSIGN (dlname, last_libname);
3305 /* allocate the handle */
3306 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3312 free_vars (dlname, old_name, libdir, deplibs);
3313 LT_DLFREE (*phandle);
3319 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3320 if (load_deplibs (*phandle, deplibs) == 0)
3322 newhandle = *phandle;
3323 /* find_module may replace newhandle */
3324 if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
3326 unload_deplibs (*phandle);
3335 free_vars (dlname, old_name, libdir, deplibs);
3338 LT_DLFREE (*phandle);
3342 if (*phandle != newhandle)
3344 unload_deplibs (*phandle);
3349 /* not a libtool module */
3350 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3357 memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3358 newhandle = *phandle;
3360 /* If the module has no directory name component, try to find it
3361 first in user_search_path and then other prescribed paths.
3362 Otherwise (or in any case if the module was not yet found) try
3363 opening just the module name as passed. */
3364 if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
3365 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3367 #ifdef LTDL_SHLIBPATH_VAR
3368 && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
3371 #ifdef LTDL_SYSSEARCHPATH
3372 && !find_handle (sys_search_path, base_name, &newhandle)
3376 if (tryall_dlopen (&newhandle, filename) != 0)
3384 LT_DLFREE (*phandle);
3391 LT_DLMEM_REASSIGN (*phandle, newhandle);
3393 if ((*phandle)->info.ref_count == 0)
3395 (*phandle)->info.ref_count = 1;
3396 LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
3399 (*phandle)->next = handles;
3401 LT_DLMUTEX_UNLOCK ();
3404 LT_DLMUTEX_SETERROR (saved_error);
3409 LT_DLFREE (canonical);
3410 if (free_base_name) LT_DLFREE (base_name);
3416 lt_dlopen (filename)
3417 const char *filename;
3419 lt_dlhandle handle = 0;
3421 /* Just incase we missed a code path in try_dlopen() that reports
3422 an error, but forgets to reset handle... */
3423 if (try_dlopen (&handle, filename) != 0)
3429 /* If the last error messge store was `FILE_NOT_FOUND', then return
3434 const char *error = 0;
3436 LT_DLMUTEX_GETERROR (error);
3437 if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
3443 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3444 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3445 and if a file is still not found try again with SHLIB_EXT appended
3448 lt_dlopenext (filename)
3449 const char *filename;
3451 lt_dlhandle handle = 0;
3459 return lt_dlopen (filename);
3464 len = LT_STRLEN (filename);
3465 ext = strrchr (filename, '.');
3467 /* If FILENAME already bears a suitable extension, there is no need
3468 to try appending additional extensions. */
3469 if (ext && ((strcmp (ext, archive_ext) == 0)
3470 #ifdef LTDL_SHLIB_EXT
3471 || (strcmp (ext, shlib_ext) == 0)
3475 return lt_dlopen (filename);
3478 /* First try appending ARCHIVE_EXT. */
3479 tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
3483 strcpy (tmp, filename);
3484 strcat (tmp, archive_ext);
3485 errors = try_dlopen (&handle, tmp);
3486 if (errors) return 0;
3488 /* If we found FILENAME, stop searching -- whether we were able to
3489 load the file as a module or not. If the file exists but loading
3490 failed, it is better to return an error message here than to
3491 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3492 in the module search path. */
3493 if (handle || ((errors > 0) && !file_not_found ()))
3499 #ifdef LTDL_SHLIB_EXT
3500 /* Try appending SHLIB_EXT. */
3501 if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
3504 tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
3508 strcpy (tmp, filename);
3512 tmp[len] = LT_EOS_CHAR;
3515 strcat(tmp, shlib_ext);
3516 errors = try_dlopen (&handle, tmp);
3517 if (errors) return 0;
3519 /* As before, if the file was found but loading failed, return now
3520 with the current error message. */
3521 if (handle || ((errors > 0) && !file_not_found ()))
3528 /* Still here? Then we really did fail to locate any of the file
3530 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3537 lt_argz_insert (pargz, pargz_len, before, entry)
3545 if ((error = argz_insert (pargz, pargz_len, before, entry)))
3550 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3553 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3563 lt_argz_insertinorder (pargz, pargz_len, entry)
3572 assert (entry && *entry);
3575 while ((before = argz_next (*pargz, *pargz_len, before)))
3577 int cmp = strcmp (entry, before);
3580 if (cmp == 0) return 0; /* No duplicates! */
3583 return lt_argz_insert (pargz, pargz_len, before, entry);
3587 lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
3596 size_t end_offset = 0;
3604 dir_len = LT_STRLEN (dirnam);
3605 end = dp->d_name + LT_D_NAMLEN(dp);
3607 /* Ignore version numbers. */
3610 for (p = end; p -1 > dp->d_name; --p)
3611 if (strchr (".0123456789", p[-1]) == 0)
3618 /* Ignore filename extension. */
3621 for (p = end -1; p > dp->d_name; --p)
3629 /* Prepend the directory name. */
3630 end_offset = end - dp->d_name;
3631 buf_len = dir_len + 1+ end_offset;
3632 buf = LT_EMALLOC (char, 1+ buf_len);
3638 strcpy (buf, dirnam);
3640 strncat (buf, dp->d_name, end_offset);
3641 buf[buf_len] = LT_EOS_CHAR;
3643 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3644 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3653 list_files_by_dir (dirnam, pargz, pargz_len)
3661 assert (dirnam && *dirnam);
3664 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
3666 dirp = opendir (dirnam);
3669 struct dirent *dp = 0;
3671 while ((dp = readdir (dirp)))
3672 if (dp->d_name[0] != '.')
3673 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3688 /* If there are any files in DIRNAME, call the function passed in
3689 DATA1 (with the name of each file and DATA2 as arguments). */
3691 foreachfile_callback (dirname, data1, data2)
3696 int (*func) LT_PARAMS((const char *filename, lt_ptr data))
3697 = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
3701 size_t argz_len = 0;
3703 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3710 while ((filename = argz_next (argz, argz_len, filename)))
3711 if ((is_done = (*func) (filename, data2)))
3722 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3723 with DATA. The filenames passed to FUNC would be suitable for
3724 passing to lt_dlopenext. The extensions are stripped so that
3725 individual modules do not generate several entries (e.g. libfoo.la,
3726 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3727 then the same directories that lt_dlopen would search are examined. */
3729 lt_dlforeachfile (search_path, func, data)
3730 const char *search_path;
3731 int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
3738 /* If a specific path was passed, search only the directories
3740 is_done = foreach_dirinpath (search_path, 0,
3741 foreachfile_callback, func, data);
3745 /* Otherwise search the default paths. */
3746 is_done = foreach_dirinpath (user_search_path, 0,
3747 foreachfile_callback, func, data);
3750 is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3751 foreachfile_callback, func, data);
3754 #ifdef LTDL_SHLIBPATH_VAR
3757 is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
3758 foreachfile_callback, func, data);
3761 #ifdef LTDL_SYSSEARCHPATH
3764 is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
3765 foreachfile_callback, func, data);
3777 lt_dlhandle cur, last;
3782 /* check whether the handle is valid */
3783 last = cur = handles;
3784 while (cur && handle != cur)
3792 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3797 handle->info.ref_count--;
3799 /* Note that even with resident modules, we must track the ref_count
3800 correctly incase the user decides to reset the residency flag
3801 later (even though the API makes no provision for that at the
3803 if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
3805 lt_user_data data = handle->loader->dlloader_data;
3807 if (handle != handles)
3809 last->next = handle->next;
3813 handles = handle->next;
3816 errors += handle->loader->module_close (data, handle->module);
3817 errors += unload_deplibs(handle);
3819 /* It is up to the callers to free the data itself. */
3820 LT_DLFREE (handle->caller_data);
3822 LT_DLFREE (handle->info.filename);
3823 LT_DLFREE (handle->info.name);
3829 if (LT_DLIS_RESIDENT (handle))
3831 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3836 LT_DLMUTEX_UNLOCK ();
3842 lt_dlsym (handle, symbol)
3847 char lsym[LT_SYMBOL_LENGTH];
3854 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3860 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3864 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3865 + LT_STRLEN (handle->info.name);
3867 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3873 sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3876 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3881 data = handle->loader->dlloader_data;
3882 if (handle->info.name)
3884 const char *saved_error;
3886 LT_DLMUTEX_GETERROR (saved_error);
3888 /* this is a libtool module */
3889 if (handle->loader->sym_prefix)
3891 strcpy(sym, handle->loader->sym_prefix);
3892 strcat(sym, handle->info.name);
3896 strcpy(sym, handle->info.name);
3899 strcat(sym, "_LTX_");
3900 strcat(sym, symbol);
3902 /* try "modulename_LTX_symbol" */
3903 address = handle->loader->find_sym (data, handle->module, sym);
3912 LT_DLMUTEX_SETERROR (saved_error);
3915 /* otherwise try "symbol" */
3916 if (handle->loader->sym_prefix)
3918 strcpy(sym, handle->loader->sym_prefix);
3919 strcat(sym, symbol);
3923 strcpy(sym, symbol);
3926 address = handle->loader->find_sym (data, handle->module, sym);
3940 LT_DLMUTEX_GETERROR (error);
3941 LT_DLMUTEX_SETERROR (0);
3943 return error ? error : NULL;
3947 lt_dlpath_insertdir (ppath, before, dir)
3953 char *canonical = 0;
3955 size_t argz_len = 0;
3958 assert (dir && *dir);
3960 if (canonicalize_path (dir, &canonical) != 0)
3966 assert (canonical && *canonical);
3968 /* If *PPATH is empty, set it to DIR. */
3971 assert (!before); /* BEFORE cannot be set without PPATH. */
3972 assert (dir); /* Without DIR, don't call this function! */
3974 *ppath = lt_estrdup (dir);
3981 assert (ppath && *ppath);
3983 if (argzize_path (*ppath, &argz, &argz_len) != 0)
3989 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
3990 if *PPATH is already canonicalized, and hence does not change length
3991 with respect to ARGZ. We canonicalize each entry as it is added to
3992 the search path, and don't call this function with (uncanonicalized)
3993 user paths, so this is a fair assumption. */
3996 assert (*ppath <= before);
3997 assert (before - *ppath <= strlen (*ppath));
3999 before = before - *ppath + argz;
4002 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
4008 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
4009 LT_DLMEM_REASSIGN (*ppath, argz);
4012 LT_DLFREE (canonical);
4019 lt_dladdsearchdir (search_dir)
4020 const char *search_dir;
4024 if (search_dir && *search_dir)
4027 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
4029 LT_DLMUTEX_UNLOCK ();
4036 lt_dlinsertsearchdir (before, search_dir)
4038 const char *search_dir;
4045 if ((before < user_search_path)
4046 || (before >= user_search_path + LT_STRLEN (user_search_path)))
4048 LT_DLMUTEX_UNLOCK ();
4049 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
4052 LT_DLMUTEX_UNLOCK ();
4055 if (search_dir && *search_dir)
4058 if (lt_dlpath_insertdir (&user_search_path,
4059 (char *) before, search_dir) != 0)
4063 LT_DLMUTEX_UNLOCK ();
4070 lt_dlsetsearchpath (search_path)
4071 const char *search_path;
4076 LT_DLFREE (user_search_path);
4077 LT_DLMUTEX_UNLOCK ();
4079 if (!search_path || !LT_STRLEN (search_path))
4085 if (canonicalize_path (search_path, &user_search_path) != 0)
4087 LT_DLMUTEX_UNLOCK ();
4093 lt_dlgetsearchpath ()
4095 const char *saved_path;
4098 saved_path = user_search_path;
4099 LT_DLMUTEX_UNLOCK ();
4105 lt_dlmakeresident (handle)
4112 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4117 LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4124 lt_dlisresident (handle)
4129 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4133 return LT_DLIS_RESIDENT (handle);
4139 /* --- MODULE INFORMATION --- */
4142 lt_dlgetinfo (handle)
4147 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4151 return &(handle->info);
4155 lt_dlhandle_next (place)
4158 return place ? place->next : handles;
4162 lt_dlforeach (func, data)
4163 int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
4174 lt_dlhandle tmp = cur;
4177 if ((*func) (tmp, data))
4184 LT_DLMUTEX_UNLOCK ();
4190 lt_dlcaller_register ()
4192 static lt_dlcaller_id last_caller_id = 0;
4196 result = ++last_caller_id;
4197 LT_DLMUTEX_UNLOCK ();
4203 lt_dlcaller_set_data (key, handle, data)
4209 lt_ptr stale = (lt_ptr) 0;
4212 /* This needs to be locked so that the caller data can be updated
4213 simultaneously by different threads. */
4216 if (handle->caller_data)
4217 while (handle->caller_data[n_elements].key)
4220 for (i = 0; i < n_elements; ++i)
4222 if (handle->caller_data[i].key == key)
4224 stale = handle->caller_data[i].data;
4229 /* Ensure that there is enough room in this handle's caller_data
4230 array to accept a new element (and an empty end marker). */
4231 if (i == n_elements)
4233 lt_caller_data *temp
4234 = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
4242 handle->caller_data = temp;
4244 /* We only need this if we needed to allocate a new caller_data. */
4245 handle->caller_data[i].key = key;
4246 handle->caller_data[1+ i].key = 0;
4249 handle->caller_data[i].data = data;
4252 LT_DLMUTEX_UNLOCK ();
4258 lt_dlcaller_get_data (key, handle)
4262 lt_ptr result = (lt_ptr) 0;
4264 /* This needs to be locked so that the caller data isn't updated by
4265 another thread part way through this function. */
4268 /* Locate the index of the element with a matching KEY. */
4271 for (i = 0; handle->caller_data[i].key; ++i)
4273 if (handle->caller_data[i].key == key)
4275 result = handle->caller_data[i].data;
4281 LT_DLMUTEX_UNLOCK ();
4288 /* --- USER MODULE LOADER API --- */
4292 lt_dlloader_add (place, dlloader, loader_name)
4294 const struct lt_user_dlloader *dlloader;
4295 const char *loader_name;
4298 lt_dlloader *node = 0, *ptr = 0;
4300 if ((dlloader == 0) /* diagnose null parameters */
4301 || (dlloader->module_open == 0)
4302 || (dlloader->module_close == 0)
4303 || (dlloader->find_sym == 0))
4305 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4309 /* Create a new dlloader node with copies of the user callbacks. */
4310 node = LT_EMALLOC (lt_dlloader, 1);
4315 node->loader_name = loader_name;
4316 node->sym_prefix = dlloader->sym_prefix;
4317 node->dlloader_exit = dlloader->dlloader_exit;
4318 node->module_open = dlloader->module_open;
4319 node->module_close = dlloader->module_close;
4320 node->find_sym = dlloader->find_sym;
4321 node->dlloader_data = dlloader->dlloader_data;
4326 /* If there are no loaders, NODE becomes the list! */
4331 /* If PLACE is not set, add NODE to the end of the
4333 for (ptr = loaders; ptr->next; ptr = ptr->next)
4340 else if (loaders == place)
4342 /* If PLACE is the first loader, NODE goes first. */
4348 /* Find the node immediately preceding PLACE. */
4349 for (ptr = loaders; ptr->next != place; ptr = ptr->next)
4354 if (ptr->next != place)
4356 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4361 /* Insert NODE between PTR and PLACE. */
4367 LT_DLMUTEX_UNLOCK ();
4373 lt_dlloader_remove (loader_name)
4374 const char *loader_name;
4376 lt_dlloader *place = lt_dlloader_find (loader_name);
4382 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4388 /* Fail if there are any open modules which use this loader. */
4389 for (handle = handles; handle; handle = handle->next)
4391 if (handle->loader == place)
4393 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
4399 if (place == loaders)
4401 /* PLACE is the first loader in the list. */
4402 loaders = loaders->next;
4406 /* Find the loader before the one being removed. */
4408 for (prev = loaders; prev->next; prev = prev->next)
4410 if (!strcmp (prev->next->loader_name, loader_name))
4417 prev->next = prev->next->next;
4420 if (place->dlloader_exit)
4422 errors = place->dlloader_exit (place->dlloader_data);
4428 LT_DLMUTEX_UNLOCK ();
4434 lt_dlloader_next (place)
4440 next = place ? place->next : loaders;
4441 LT_DLMUTEX_UNLOCK ();
4447 lt_dlloader_name (place)
4450 const char *name = 0;
4455 name = place ? place->loader_name : 0;
4456 LT_DLMUTEX_UNLOCK ();
4460 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4467 lt_dlloader_data (place)
4470 lt_user_data *data = 0;
4475 data = place ? &(place->dlloader_data) : 0;
4476 LT_DLMUTEX_UNLOCK ();
4480 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4487 lt_dlloader_find (loader_name)
4488 const char *loader_name;
4490 lt_dlloader *place = 0;
4493 for (place = loaders; place; place = place->next)
4495 if (strcmp (place->loader_name, loader_name) == 0)
4500 LT_DLMUTEX_UNLOCK ();