1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000, 2004, 2005 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., 51 Franklin Street, Fifth Floor, 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 /* allow space for: path + '\\' '\\' '*' '.' '*' + '\0' */
461 (void) strncpy (file_specification, path, LT_FILENAME_MAX-6);
462 file_specification[LT_FILENAME_MAX-6] = LT_EOS_CHAR;
463 (void) strcat(file_specification,"\\");
464 entry = LT_DLMALLOC (DIR,sizeof(DIR));
465 if (entry != (DIR *) 0)
467 entry->firsttime = TRUE;
468 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
470 if (entry->hSearch == INVALID_HANDLE_VALUE)
472 (void) strcat(file_specification,"\\*.*");
473 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
474 if (entry->hSearch == INVALID_HANDLE_VALUE)
484 static struct dirent *readdir LT_PARAMS((DIR *entry));
486 static struct dirent *readdir(entry)
492 if (entry == (DIR *) 0)
493 return((struct dirent *) 0);
494 if (!entry->firsttime)
496 status = FindNextFile(entry->hSearch,&entry->Win32FindData);
498 return((struct dirent *) 0);
500 entry->firsttime = FALSE;
501 (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
503 entry->file_info.d_name[LT_FILENAME_MAX - 1] = LT_EOS_CHAR;
504 entry->file_info.d_namlen = strlen(entry->file_info.d_name);
505 return(&entry->file_info);
508 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
510 /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
511 ``realloc is not entirely portable''
512 In any case we want to use the allocator supplied by the user without
513 burdening them with an lt_dlrealloc function pointer to maintain.
514 Instead implement our own version (with known boundary conditions)
515 using lt_dlmalloc and lt_dlfree. */
518 #define realloc rpl_realloc
521 /* You can't (re)define realloc unless you also (re)define malloc.
522 Right now, this code uses the size of the *destination* to decide
523 how much to copy. That's not right, but you can't know the size
524 of the source unless you know enough about, or wrote malloc. So
525 this code is disabled... */
534 /* For zero or less bytes, free the original memory */
544 /* Allow reallocation of a NULL pointer. */
545 return lt_dlmalloc (size);
549 /* Allocate a new block, copy and free the old block. */
550 lt_ptr mem = lt_dlmalloc (size);
554 memcpy (mem, ptr, size);
558 /* Note that the contents of PTR are not damaged if there is
559 insufficient memory to realloc. */
566 #if ! HAVE_ARGZ_APPEND
567 # define argz_append rpl_argz_append
569 static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
570 const char *buf, size_t buf_len));
573 argz_append (pargz, pargz_len, buf, buf_len)
584 assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
586 /* If nothing needs to be appended, no more work is required. */
590 /* Ensure there is enough room to append BUF_LEN. */
591 argz_len = *pargz_len + buf_len;
592 argz = LT_DLREALLOC (char, *pargz, argz_len);
596 /* Copy characters from BUF after terminating '\0' in ARGZ. */
597 memcpy (argz + *pargz_len, buf, buf_len);
599 /* Assign new values. */
601 *pargz_len = argz_len;
605 #endif /* !HAVE_ARGZ_APPEND */
608 #if ! HAVE_ARGZ_CREATE_SEP
609 # define argz_create_sep rpl_argz_create_sep
611 static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
612 char **pargz, size_t *pargz_len));
615 argz_create_sep (str, delim, pargz, pargz_len)
628 /* Make a copy of STR, but replacing each occurrence of
630 argz_len = 1+ LT_STRLEN (str);
636 argz = LT_DLMALLOC (char, argz_len);
640 for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
644 /* Ignore leading delimiters, and fold consecutive
645 delimiters in STR into a single '\0' in ARGZ. */
646 if ((q > argz) && (q[-1] != LT_EOS_CHAR))
654 /* Copy terminating LT_EOS_CHAR. */
658 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
662 /* Assign new values. */
664 *pargz_len = argz_len;
668 #endif /* !HAVE_ARGZ_CREATE_SEP */
671 #if ! HAVE_ARGZ_INSERT
672 # define argz_insert rpl_argz_insert
674 static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
675 char *before, const char *entry));
678 argz_insert (pargz, pargz_len, before, entry)
686 assert (entry && *entry);
688 /* No BEFORE address indicates ENTRY should be inserted after the
689 current last element. */
691 return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
693 /* This probably indicates a programmer error, but to preserve
694 semantics, scan back to the start of an entry if BEFORE points
695 into the middle of it. */
696 while ((before > *pargz) && (before[-1] != LT_EOS_CHAR))
700 size_t entry_len = 1+ LT_STRLEN (entry);
701 size_t argz_len = *pargz_len + entry_len;
702 size_t offset = before - *pargz;
703 char *argz = LT_DLREALLOC (char, *pargz, argz_len);
708 /* Make BEFORE point to the equivalent offset in ARGZ that it
709 used to have in *PARGZ incase realloc() moved the block. */
710 before = argz + offset;
712 /* Move the ARGZ entries starting at BEFORE up into the new
713 space at the end -- making room to copy ENTRY into the
715 memmove (before + entry_len, before, *pargz_len - offset);
716 memcpy (before, entry, entry_len);
718 /* Assign new values. */
720 *pargz_len = argz_len;
725 #endif /* !HAVE_ARGZ_INSERT */
729 # define argz_next rpl_argz_next
731 static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
735 argz_next (argz, argz_len, entry)
740 assert ((argz && argz_len) || (!argz && !argz_len));
744 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
745 within the ARGZ vector. */
746 assert ((!argz && !argz_len)
747 || ((argz <= entry) && (entry < (argz + argz_len))));
749 /* Move to the char immediately after the terminating
751 entry = 1+ strchr (entry, LT_EOS_CHAR);
753 /* Return either the new ENTRY, or else NULL if ARGZ is
755 return (entry >= argz + argz_len) ? 0 : (char *) entry;
759 /* This should probably be flagged as a programmer error,
760 since starting an argz_next loop with the iterator set
761 to ARGZ is safer. To preserve semantics, handle the NULL
762 case by returning the start of ARGZ (if any). */
769 #endif /* !HAVE_ARGZ_NEXT */
773 #if ! HAVE_ARGZ_STRINGIFY
774 # define argz_stringify rpl_argz_stringify
776 static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
780 argz_stringify (argz, argz_len, sep)
785 assert ((argz && argz_len) || (!argz && !argz_len));
789 --argz_len; /* don't stringify the terminating EOS */
790 while (--argz_len > 0)
792 if (argz[argz_len] == LT_EOS_CHAR)
793 argz[argz_len] = sep;
797 #endif /* !HAVE_ARGZ_STRINGIFY */
802 /* --- TYPE DEFINITIONS -- */
805 /* This type is used for the array of caller data sets in each handler. */
814 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
817 /* Extract the diagnostic strings from the error table macro in the same
818 order as the enumerated indices in ltdl.h. */
820 static const char *lt_dlerror_strings[] =
822 #define LT_ERROR(name, diagnostic) (diagnostic),
829 /* This structure is used for the list of registered loaders. */
831 struct lt_dlloader *next;
832 const char *loader_name; /* identifying name for each loader */
833 const char *sym_prefix; /* prefix for symbols */
834 lt_module_open *module_open;
835 lt_module_close *module_close;
836 lt_find_sym *find_sym;
837 lt_dlloader_exit *dlloader_exit;
838 lt_user_data dlloader_data;
841 struct lt_dlhandle_struct {
842 struct lt_dlhandle_struct *next;
843 lt_dlloader *loader; /* dlopening interface */
845 int depcount; /* number of dependencies */
846 lt_dlhandle *deplibs; /* dependencies */
847 lt_module module; /* system module handle */
848 lt_ptr system; /* system specific data */
849 lt_caller_data *caller_data; /* per caller associated data */
850 int flags; /* various boolean stats */
853 /* Various boolean flags can be stored in the flags field of an
854 lt_dlhandle_struct... */
855 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
856 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
858 #define LT_DLRESIDENT_FLAG (0x01 << 0)
859 /* ...add more flags here... */
861 #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
864 #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
866 static const char objdir[] = LTDL_OBJDIR;
867 static const char archive_ext[] = LTDL_ARCHIVE_EXT;
868 #ifdef LTDL_SHLIB_EXT
869 static const char shlib_ext[] = LTDL_SHLIB_EXT;
871 #ifdef LTDL_SYSSEARCHPATH
872 static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
878 /* --- MUTEX LOCKING --- */
881 /* Macros to make it easier to run the lock functions only if they have
882 been registered. The reason for the complicated lock macro is to
883 ensure that the stored error message from the last error is not
884 accidentally erased if the current function doesn't generate an
886 #define LT_DLMUTEX_LOCK() LT_STMT_START { \
887 if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
889 #define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
890 if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
892 #define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
893 if (lt_dlmutex_seterror_func) \
894 (*lt_dlmutex_seterror_func) (errormsg); \
895 else lt_dllast_error = (errormsg); } LT_STMT_END
896 #define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
897 if (lt_dlmutex_seterror_func) \
898 (errormsg) = (*lt_dlmutex_geterror_func) (); \
899 else (errormsg) = lt_dllast_error; } LT_STMT_END
901 /* The mutex functions stored here are global, and are necessarily the
902 same for all threads that wish to share access to libltdl. */
903 static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
904 static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
905 static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
906 static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
907 static const char *lt_dllast_error = 0;
910 /* Either set or reset the mutex functions. Either all the arguments must
911 be valid functions, or else all can be NULL to turn off locking entirely.
912 The registered functions should be manipulating a static global lock
913 from the lock() and unlock() callbacks, which needs to be reentrant. */
915 lt_dlmutex_register (lock, unlock, seterror, geterror)
916 lt_dlmutex_lock *lock;
917 lt_dlmutex_unlock *unlock;
918 lt_dlmutex_seterror *seterror;
919 lt_dlmutex_geterror *geterror;
921 lt_dlmutex_unlock *old_unlock = unlock;
924 /* Lock using the old lock() callback, if any. */
927 if ((lock && unlock && seterror && geterror)
928 || !(lock || unlock || seterror || geterror))
930 lt_dlmutex_lock_func = lock;
931 lt_dlmutex_unlock_func = unlock;
932 lt_dlmutex_geterror_func = geterror;
936 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
940 /* Use the old unlock() callback we saved earlier, if any. Otherwise
941 record any errors using internal storage. */
945 /* Return the number of errors encountered during the execution of
953 /* --- ERROR HANDLING --- */
956 static const char **user_error_strings = 0;
957 static int errorcount = LT_ERROR_MAX;
960 lt_dladderror (diagnostic)
961 const char *diagnostic;
965 const char **temp = (const char **) 0;
971 errindex = errorcount - LT_ERROR_MAX;
972 temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
975 user_error_strings = temp;
976 user_error_strings[errindex] = diagnostic;
977 result = errorcount++;
980 LT_DLMUTEX_UNLOCK ();
986 lt_dlseterror (errindex)
993 if (errindex >= errorcount || errindex < 0)
995 /* Ack! Error setting the error message! */
996 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
999 else if (errindex < LT_ERROR_MAX)
1001 /* No error setting the error message! */
1002 LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
1006 /* No error setting the error message! */
1007 LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
1010 LT_DLMUTEX_UNLOCK ();
1019 lt_ptr mem = lt_dlmalloc (size);
1021 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1026 lt_erealloc (addr, size)
1030 lt_ptr mem = lt_dlrealloc (addr, size);
1032 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1040 char *copy = strdup (str);
1041 if (LT_STRLEN (str) && !copy)
1042 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1049 /* --- DLOPEN() INTERFACE LOADER --- */
1054 /* dynamic linking with dlopen/dlsym */
1061 # include <sys/dl.h>
1065 # define LT_GLOBAL RTLD_GLOBAL
1068 # define LT_GLOBAL DL_GLOBAL
1070 #endif /* !RTLD_GLOBAL */
1072 # define LT_GLOBAL 0
1073 #endif /* !LT_GLOBAL */
1075 /* We may have to define LT_LAZY_OR_NOW in the command line if we
1076 find out it does not work in some platform. */
1077 #ifndef LT_LAZY_OR_NOW
1079 # define LT_LAZY_OR_NOW RTLD_LAZY
1082 # define LT_LAZY_OR_NOW DL_LAZY
1084 # endif /* !RTLD_LAZY */
1086 #ifndef LT_LAZY_OR_NOW
1088 # define LT_LAZY_OR_NOW RTLD_NOW
1091 # define LT_LAZY_OR_NOW DL_NOW
1093 # endif /* !RTLD_NOW */
1095 #ifndef LT_LAZY_OR_NOW
1096 # define LT_LAZY_OR_NOW 0
1097 #endif /* !LT_LAZY_OR_NOW */
1100 # define DLERROR(arg) dlerror ()
1102 # define DLERROR(arg) LT_DLSTRERROR (arg)
1106 sys_dl_open (loader_data, filename)
1107 lt_user_data loader_data;
1108 const char *filename;
1110 lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
1114 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
1121 sys_dl_close (loader_data, module)
1122 lt_user_data loader_data;
1127 if (dlclose (module) != 0)
1129 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
1137 sys_dl_sym (loader_data, module, symbol)
1138 lt_user_data loader_data;
1142 lt_ptr address = dlsym (module, symbol);
1146 LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
1152 static struct lt_user_dlloader sys_dl =
1159 sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
1162 #endif /* HAVE_LIBDL */
1166 /* --- SHL_LOAD() INTERFACE LOADER --- */
1170 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1176 /* some flags are missing on some systems, so we provide
1177 * harmless defaults.
1180 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1181 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1184 * BIND_FIRST - Place the library at the head of the symbol search
1186 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1187 * unsatisfied symbols as fatal. This flag allows
1188 * binding of unsatisfied code symbols to be deferred
1190 * [Perl: For certain libraries, like DCE, deferred
1191 * binding often causes run time problems. Adding
1192 * BIND_NONFATAL to BIND_IMMEDIATE still allows
1193 * unresolved references in situations like this.]
1194 * BIND_NOSTART - Do not call the initializer for the shared library
1195 * when the library is loaded, nor on a future call to
1197 * BIND_VERBOSE - Print verbose messages concerning possible
1198 * unsatisfied symbols.
1200 * hp9000s700/hp9000s800:
1201 * BIND_RESTRICTED - Restrict symbols visible by the library to those
1202 * present at library load time.
1203 * DYNAMIC_PATH - Allow the loader to dynamically search for the
1204 * library specified by the path argument.
1207 #ifndef DYNAMIC_PATH
1208 # define DYNAMIC_PATH 0
1210 #ifndef BIND_RESTRICTED
1211 # define BIND_RESTRICTED 0
1214 #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1217 sys_shl_open (loader_data, filename)
1218 lt_user_data loader_data;
1219 const char *filename;
1221 static shl_t self = (shl_t) 0;
1222 lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1224 /* Since searching for a symbol against a NULL module handle will also
1225 look in everything else that was already loaded and exported with
1226 the -E compiler flag, we always cache a handle saved before any
1227 modules are loaded. */
1231 shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1240 module = shl_load (filename, LT_BIND_FLAGS, 0L);
1244 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1252 sys_shl_close (loader_data, module)
1253 lt_user_data loader_data;
1258 if (module && (shl_unload ((shl_t) (module)) != 0))
1260 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1268 sys_shl_sym (loader_data, module, symbol)
1269 lt_user_data loader_data;
1275 /* sys_shl_open should never return a NULL module handle */
1276 if (module == (lt_module) 0)
1278 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1280 else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
1284 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1291 static struct lt_user_dlloader sys_shl = {
1292 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
1295 #endif /* HAVE_SHL_LOAD */
1300 /* --- LOADLIBRARY() INTERFACE LOADER --- */
1304 /* dynamic linking for Win32 */
1306 #include <windows.h>
1308 /* Forward declaration; required to implement handle search below. */
1309 static lt_dlhandle handles;
1312 sys_wll_open (loader_data, filename)
1313 lt_user_data loader_data;
1314 const char *filename;
1317 lt_module module = 0;
1318 const char *errormsg = 0;
1319 char *searchname = 0;
1321 char self_name_buf[MAX_PATH];
1325 /* Get the name of main module */
1327 GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
1328 filename = ext = self_name_buf;
1332 ext = strrchr (filename, '.');
1337 /* FILENAME already has an extension. */
1338 searchname = lt_estrdup (filename);
1342 /* Append a `.' to stop Windows from adding an
1343 implicit `.dll' extension. */
1344 searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
1346 sprintf (searchname, "%s.", filename);
1352 /* Silence dialog from LoadLibrary on some failures.
1353 No way to get the error mode, but to set it,
1354 so set it twice to preserve any previous flags. */
1355 UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS);
1356 SetErrorMode(errormode | SEM_FAILCRITICALERRORS);
1358 #if defined(__CYGWIN__)
1360 char wpath[MAX_PATH];
1361 cygwin_conv_to_full_win32_path (searchname, wpath);
1362 module = LoadLibrary (wpath);
1365 module = LoadLibrary (searchname);
1368 /* Restore the error mode. */
1369 SetErrorMode(errormode);
1372 LT_DLFREE (searchname);
1374 /* libltdl expects this function to fail if it is unable
1375 to physically load the library. Sadly, LoadLibrary
1376 will search the loaded libraries for a match and return
1377 one of them if the path search load fails.
1379 We check whether LoadLibrary is returning a handle to
1380 an already loaded module, and simulate failure if we
1392 if (cur->module == module)
1399 LT_DLMUTEX_UNLOCK ();
1403 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1411 sys_wll_close (loader_data, module)
1412 lt_user_data loader_data;
1417 if (FreeLibrary(module) == 0)
1419 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1427 sys_wll_sym (loader_data, module, symbol)
1428 lt_user_data loader_data;
1432 lt_ptr address = GetProcAddress (module, symbol);
1436 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1442 static struct lt_user_dlloader sys_wll = {
1443 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1446 #endif /* __WINDOWS__ */
1451 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1456 /* dynamic linking for BeOS */
1458 #include <kernel/image.h>
1461 sys_bedl_open (loader_data, filename)
1462 lt_user_data loader_data;
1463 const char *filename;
1469 image = load_add_on (filename);
1475 if (get_next_image_info (0, &cookie, &info) == B_OK)
1476 image = load_add_on (info.name);
1481 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1485 return (lt_module) image;
1489 sys_bedl_close (loader_data, module)
1490 lt_user_data loader_data;
1495 if (unload_add_on ((image_id) module) != B_OK)
1497 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1505 sys_bedl_sym (loader_data, module, symbol)
1506 lt_user_data loader_data;
1511 image_id image = (image_id) module;
1513 if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1515 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1522 static struct lt_user_dlloader sys_bedl = {
1523 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1526 #endif /* __BEOS__ */
1531 /* --- DLD_LINK() INTERFACE LOADER --- */
1536 /* dynamic linking with dld */
1543 sys_dld_open (loader_data, filename)
1544 lt_user_data loader_data;
1545 const char *filename;
1547 lt_module module = strdup (filename);
1549 if (dld_link (filename) != 0)
1551 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1560 sys_dld_close (loader_data, module)
1561 lt_user_data loader_data;
1566 if (dld_unlink_by_file ((char*)(module), 1) != 0)
1568 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1580 sys_dld_sym (loader_data, module, symbol)
1581 lt_user_data loader_data;
1585 lt_ptr address = dld_get_func (symbol);
1589 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1595 static struct lt_user_dlloader sys_dld = {
1596 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1599 #endif /* HAVE_DLD */
1601 /* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
1605 #if HAVE_MACH_O_DYLD_H
1606 #if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
1607 /* Is this correct? Does it still function properly? */
1608 #define __private_extern__ extern
1610 # include <mach-o/dyld.h>
1612 #include <mach-o/getsect.h>
1614 /* We have to put some stuff here that isn't in older dyld.h files */
1615 #ifndef ENUM_DYLD_BOOL
1616 # define ENUM_DYLD_BOOL
1625 # define LC_REQ_DYLD 0x80000000
1627 #ifndef LC_LOAD_WEAK_DYLIB
1628 # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
1630 static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0;
1631 static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0;
1632 static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0;
1633 static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0;
1635 #ifndef NSADDIMAGE_OPTION_NONE
1636 #define NSADDIMAGE_OPTION_NONE 0x0
1638 #ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
1639 #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
1641 #ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
1642 #define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
1644 #ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1645 #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
1647 #ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
1648 #define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
1650 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
1651 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
1653 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1654 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
1656 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
1657 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
1659 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1660 #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
1665 lt_int_dyld_error(othererror)
1668 /* return the dyld error string, or the passed in error string if none */
1669 NSLinkEditErrors ler;
1673 NSLinkEditError(&ler,&lerno,&file,&errstr);
1674 if (!errstr || !strlen(errstr)) errstr = othererror;
1678 static const struct mach_header *
1679 lt_int_dyld_get_mach_header_from_nsmodule(module)
1682 /* There should probably be an apple dyld api for this */
1683 int i=_dyld_image_count();
1685 const char *modname=NSNameOfModule(module);
1686 const struct mach_header *mh=NULL;
1687 if (!modname) return NULL;
1688 for (j = 0; j < i; j++)
1690 if (!strcmp(_dyld_get_image_name(j),modname))
1692 mh=_dyld_get_image_header(j);
1699 static const char* lt_int_dyld_lib_install_name(mh)
1700 const struct mach_header *mh;
1702 /* NSAddImage is also used to get the loaded image, but it only works if the lib
1703 is installed, for uninstalled libs we need to check the install_names against
1704 each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
1705 different lib was loaded as a result
1708 struct load_command *lc;
1709 unsigned long offset = sizeof(struct mach_header);
1710 const char* retStr=NULL;
1711 for (j = 0; j < mh->ncmds; j++)
1713 lc = (struct load_command*)(((unsigned long)mh) + offset);
1714 if (LC_ID_DYLIB == lc->cmd)
1716 retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset +
1719 offset += lc->cmdsize;
1724 static const struct mach_header *
1725 lt_int_dyld_match_loaded_lib_by_install_name(const char *name)
1727 int i=_dyld_image_count();
1729 const struct mach_header *mh=NULL;
1730 const char *id=NULL;
1731 for (j = 0; j < i; j++)
1733 id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j));
1734 if ((id) && (!strcmp(id,name)))
1736 mh=_dyld_get_image_header(j);
1744 lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh)
1746 const struct mach_header *mh;
1748 /* Safe to assume our mh is good */
1750 struct load_command *lc;
1751 unsigned long offset = sizeof(struct mach_header);
1752 NSSymbol retSym = 0;
1753 const struct mach_header *mh1;
1754 if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) )
1756 for (j = 0; j < mh->ncmds; j++)
1758 lc = (struct load_command*)(((unsigned long)mh) + offset);
1759 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
1761 mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1762 (unsigned long)lc));
1765 /* Maybe NSAddImage can find it */
1766 mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1768 NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +
1769 NSADDIMAGE_OPTION_WITH_SEARCHING +
1770 NSADDIMAGE_OPTION_RETURN_ON_ERROR );
1774 retSym = ltdl_NSLookupSymbolInImage(mh1,
1776 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1777 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1782 offset += lc->cmdsize;
1793 if (!_dyld_present()) {
1797 err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage);
1798 err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage);
1799 err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage);
1800 err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic);
1806 sys_dyld_open (loader_data, filename)
1807 lt_user_data loader_data;
1808 const char *filename;
1810 lt_module module = 0;
1811 NSObjectFileImage ofi = 0;
1812 NSObjectFileImageReturnCode ofirc;
1815 return (lt_module)-1;
1816 ofirc = NSCreateObjectFileImageFromFile(filename, &ofi);
1819 case NSObjectFileImageSuccess:
1820 module = NSLinkModule(ofi, filename,
1821 NSLINKMODULE_OPTION_RETURN_ON_ERROR
1822 | NSLINKMODULE_OPTION_PRIVATE
1823 | NSLINKMODULE_OPTION_BINDNOW);
1824 NSDestroyObjectFileImage(ofi);
1826 ltdl_NSMakePrivateModulePublic(module);
1828 case NSObjectFileImageInappropriateFile:
1829 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1831 module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
1835 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1838 if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1843 sys_dyld_close (loader_data, module)
1844 lt_user_data loader_data;
1849 if (module == (lt_module)-1) return 0;
1850 #ifdef __BIG_ENDIAN__
1851 if (((struct mach_header *)module)->magic == MH_MAGIC)
1853 if (((struct mach_header *)module)->magic == MH_CIGAM)
1856 LT_DLMUTEX_SETERROR("Can not close a dylib");
1862 /* Currently, if a module contains c++ static destructors and it is unloaded, we
1863 get a segfault in atexit(), due to compiler and dynamic loader differences of
1864 opinion, this works around that.
1866 if ((const struct section *)NULL !=
1867 getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module),
1868 "__DATA","__mod_term_func"))
1870 flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
1874 flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
1876 if (!NSUnLinkModule(module,flags))
1879 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE)));
1887 sys_dyld_sym (loader_data, module, symbol)
1888 lt_user_data loader_data;
1893 NSSymbol *nssym = 0;
1895 const struct mach_header *mh=NULL;
1896 char saveError[256] = "Symbol not found";
1897 if (module == (lt_module)-1)
1899 _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused);
1902 #ifdef __BIG_ENDIAN__
1903 if (((struct mach_header *)module)->magic == MH_MAGIC)
1905 if (((struct mach_header *)module)->magic == MH_CIGAM)
1908 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1911 if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol))
1913 nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module,
1915 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1916 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1923 nssym = NSLookupSymbolInModule(module, symbol);
1927 strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255);
1929 if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module);
1930 nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh);
1934 LT_DLMUTEX_SETERROR (saveError);
1937 return NSAddressOfSymbol(nssym);
1940 static struct lt_user_dlloader sys_dyld =
1941 { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
1944 #endif /* HAVE_DYLD */
1947 /* --- DLPREOPEN() INTERFACE LOADER --- */
1950 /* emulate dynamic linking using preloaded_symbols */
1952 typedef struct lt_dlsymlists_t
1954 struct lt_dlsymlists_t *next;
1955 const lt_dlsymlist *syms;
1958 static const lt_dlsymlist *default_preloaded_symbols = 0;
1959 static lt_dlsymlists_t *preloaded_symbols = 0;
1962 presym_init (loader_data)
1963 lt_user_data loader_data;
1969 preloaded_symbols = 0;
1970 if (default_preloaded_symbols)
1972 errors = lt_dlpreload (default_preloaded_symbols);
1975 LT_DLMUTEX_UNLOCK ();
1981 presym_free_symlists ()
1983 lt_dlsymlists_t *lists;
1987 lists = preloaded_symbols;
1990 lt_dlsymlists_t *tmp = lists;
1992 lists = lists->next;
1995 preloaded_symbols = 0;
1997 LT_DLMUTEX_UNLOCK ();
2003 presym_exit (loader_data)
2004 lt_user_data loader_data;
2006 presym_free_symlists ();
2011 presym_add_symlist (preloaded)
2012 const lt_dlsymlist *preloaded;
2014 lt_dlsymlists_t *tmp;
2015 lt_dlsymlists_t *lists;
2020 lists = preloaded_symbols;
2023 if (lists->syms == preloaded)
2027 lists = lists->next;
2030 tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
2033 memset (tmp, 0, sizeof(lt_dlsymlists_t));
2034 tmp->syms = preloaded;
2035 tmp->next = preloaded_symbols;
2036 preloaded_symbols = tmp;
2044 LT_DLMUTEX_UNLOCK ();
2049 presym_open (loader_data, filename)
2050 lt_user_data loader_data;
2051 const char *filename;
2053 lt_dlsymlists_t *lists;
2054 lt_module module = (lt_module) 0;
2057 lists = preloaded_symbols;
2061 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
2065 /* Can't use NULL as the reflective symbol header, as NULL is
2066 used to mark the end of the entire symbol list. Self-dlpreopened
2067 symbols follow this magic number, chosen to be an unlikely
2068 clash with a real module name. */
2071 filename = "@PROGRAM@";
2076 const lt_dlsymlist *syms = lists->syms;
2080 if (!syms->address && strcmp(syms->name, filename) == 0)
2082 module = (lt_module) syms;
2088 lists = lists->next;
2091 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2094 LT_DLMUTEX_UNLOCK ();
2099 presym_close (loader_data, module)
2100 lt_user_data loader_data;
2103 /* Just to silence gcc -Wall */
2109 presym_sym (loader_data, module, symbol)
2110 lt_user_data loader_data;
2114 lt_dlsymlist *syms = (lt_dlsymlist*) module;
2117 while (syms->address)
2119 if (strcmp(syms->name, symbol) == 0)
2121 return syms->address;
2127 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
2132 static struct lt_user_dlloader presym = {
2133 0, presym_open, presym_close, presym_sym, presym_exit, 0
2140 /* --- DYNAMIC MODULE LOADING --- */
2143 /* The type of a function used at each iteration of foreach_dirinpath(). */
2144 typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
2147 static int foreach_dirinpath LT_PARAMS((const char *search_path,
2148 const char *base_name,
2149 foreach_callback_func *func,
2150 lt_ptr data1, lt_ptr data2));
2152 static int find_file_callback LT_PARAMS((char *filename, lt_ptr data,
2154 static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data,
2156 static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1,
2160 static int canonicalize_path LT_PARAMS((const char *path,
2161 char **pcanonical));
2162 static int argzize_path LT_PARAMS((const char *path,
2164 size_t *pargz_len));
2165 static FILE *find_file LT_PARAMS((const char *search_path,
2166 const char *base_name,
2168 static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
2169 const char *base_name,
2170 lt_dlhandle *handle));
2171 static int find_module LT_PARAMS((lt_dlhandle *handle,
2175 const char *old_name,
2177 static int free_vars LT_PARAMS((char *dlname, char *oldname,
2178 char *libdir, char *deplibs));
2179 static int load_deplibs LT_PARAMS((lt_dlhandle handle,
2181 static int trim LT_PARAMS((char **dest,
2183 static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
2184 const char *filename));
2185 static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
2186 const char *filename,
2187 const char * useloader));
2188 static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
2189 static int lt_argz_insert LT_PARAMS((char **pargz,
2192 const char *entry));
2193 static int lt_argz_insertinorder LT_PARAMS((char **pargz,
2195 const char *entry));
2196 static int lt_argz_insertdir LT_PARAMS((char **pargz,
2199 struct dirent *dp));
2200 static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
2203 static int list_files_by_dir LT_PARAMS((const char *dirnam,
2205 size_t *pargz_len));
2206 static int file_not_found LT_PARAMS((void));
2208 static char *user_search_path= 0;
2209 static lt_dlloader *loaders = 0;
2210 static lt_dlhandle handles = 0;
2211 static int initialized = 0;
2213 /* Initialize libltdl. */
2221 /* Initialize only at first call. */
2222 if (++initialized == 1)
2225 user_search_path = 0; /* empty search path */
2228 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
2231 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
2234 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
2237 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
2240 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
2243 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld");
2244 errors += sys_dyld_init();
2246 errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
2248 if (presym_init (presym.dlloader_data))
2250 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
2253 else if (errors != 0)
2255 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
2260 LT_DLMUTEX_UNLOCK ();
2266 lt_dlpreload (preloaded)
2267 const lt_dlsymlist *preloaded;
2273 errors = presym_add_symlist (preloaded);
2277 presym_free_symlists();
2280 if (default_preloaded_symbols)
2282 errors = lt_dlpreload (default_preloaded_symbols);
2284 LT_DLMUTEX_UNLOCK ();
2291 lt_dlpreload_default (preloaded)
2292 const lt_dlsymlist *preloaded;
2295 default_preloaded_symbols = preloaded;
2296 LT_DLMUTEX_UNLOCK ();
2303 /* shut down libltdl */
2304 lt_dlloader *loader;
2312 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
2317 /* shut down only at last call. */
2318 if (--initialized == 0)
2322 while (handles && LT_DLIS_RESIDENT (handles))
2324 handles = handles->next;
2327 /* close all modules */
2328 for (level = 1; handles; ++level)
2330 lt_dlhandle cur = handles;
2331 int saw_nonresident = 0;
2335 lt_dlhandle tmp = cur;
2337 if (!LT_DLIS_RESIDENT (tmp))
2338 saw_nonresident = 1;
2339 if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
2341 if (lt_dlclose (tmp))
2347 /* done if only resident modules are left */
2348 if (!saw_nonresident)
2352 /* close all loaders */
2355 lt_dlloader *next = loader->next;
2356 lt_user_data data = loader->dlloader_data;
2357 if (loader->dlloader_exit && loader->dlloader_exit (data))
2362 LT_DLMEM_REASSIGN (loader, next);
2366 LT_DLFREE (user_search_path);
2370 LT_DLMUTEX_UNLOCK ();
2375 tryall_dlopen (handle, filename, useloader)
2376 lt_dlhandle *handle;
2377 const char *filename;
2378 const char *useloader;
2381 lt_dlloader *loader;
2382 const char *saved_error;
2385 LT_DLMUTEX_GETERROR (saved_error);
2391 /* check whether the module was already opened */
2394 /* try to dlopen the program itself? */
2395 if (!cur->info.filename && !filename)
2400 if (cur->info.filename && filename
2401 && strcmp (cur->info.filename, filename) == 0)
2411 ++cur->info.ref_count;
2419 /* Comment out the check of file permissions using access.
2420 This call seems to always return -1 with error EACCES.
2422 /* We need to catch missing file errors early so that
2423 file_not_found() can detect what happened.
2424 if (access (filename, R_OK) != 0)
2426 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2431 cur->info.filename = lt_estrdup (filename);
2432 if (!cur->info.filename)
2440 cur->info.filename = 0;
2445 if (useloader && strcmp(loader->loader_name, useloader))
2447 loader = loader->next;
2450 lt_user_data data = loader->dlloader_data;
2452 cur->module = loader->module_open (data, filename);
2454 if (cur->module != 0)
2458 loader = loader->next;
2463 LT_DLFREE (cur->info.filename);
2468 cur->loader = loader;
2469 LT_DLMUTEX_SETERROR (saved_error);
2472 LT_DLMUTEX_UNLOCK ();
2478 tryall_dlopen_module (handle, prefix, dirname, dlname)
2479 lt_dlhandle *handle;
2481 const char *dirname;
2486 size_t filename_len = 0;
2487 size_t dirname_len = LT_STRLEN (dirname);
2492 #ifdef LT_DIRSEP_CHAR
2493 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2494 should make it into this function: */
2495 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
2498 if (dirname_len > 0)
2499 if (dirname[dirname_len -1] == '/')
2501 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
2503 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2504 The PREFIX (if any) is handled below. */
2505 filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
2509 sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
2511 /* Now that we have combined DIRNAME and MODULENAME, if there is
2512 also a PREFIX to contend with, simply recurse with the arguments
2513 shuffled. Otherwise, attempt to open FILENAME as a module. */
2516 error += tryall_dlopen_module (handle,
2517 (const char *) 0, prefix, filename);
2519 else if (tryall_dlopen (handle, filename, NULL) != 0)
2524 LT_DLFREE (filename);
2529 find_module (handle, dir, libdir, dlname, old_name, installed)
2530 lt_dlhandle *handle;
2534 const char *old_name;
2537 /* Try to open the old library first; if it was dlpreopened,
2538 we want the preopened version of it, even if a dlopenable
2539 module is available. */
2540 if (old_name && tryall_dlopen (handle, old_name, "dlpreload") == 0)
2545 /* Try to open the dynamic library. */
2548 /* try to open the installed module */
2549 if (installed && libdir)
2551 if (tryall_dlopen_module (handle,
2552 (const char *) 0, libdir, dlname) == 0)
2556 /* try to open the not-installed module */
2559 if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2563 /* maybe it was moved to another directory */
2565 if (dir && (tryall_dlopen_module (handle,
2566 (const char *) 0, dir, dlname) == 0))
2576 canonicalize_path (path, pcanonical)
2580 char *canonical = 0;
2582 assert (path && *path);
2583 assert (pcanonical);
2585 canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2592 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2594 /* Path separators are not copied to the beginning or end of
2595 the destination, or if another separator would follow
2597 if (path[src] == LT_PATHSEP_CHAR)
2600 || (path[1+ src] == LT_PATHSEP_CHAR)
2601 || (path[1+ src] == LT_EOS_CHAR))
2605 /* Anything other than a directory separator is copied verbatim. */
2606 if ((path[src] != '/')
2607 #ifdef LT_DIRSEP_CHAR
2608 && (path[src] != LT_DIRSEP_CHAR)
2612 canonical[dest++] = path[src];
2614 /* Directory separators are converted and copied only if they are
2615 not at the end of a path -- i.e. before a path separator or
2617 else if ((path[1+ src] != LT_PATHSEP_CHAR)
2618 && (path[1+ src] != LT_EOS_CHAR)
2619 #ifdef LT_DIRSEP_CHAR
2620 && (path[1+ src] != LT_DIRSEP_CHAR)
2622 && (path[1+ src] != '/'))
2624 canonical[dest++] = '/';
2628 /* Add an end-of-string marker at the end. */
2629 canonical[dest] = LT_EOS_CHAR;
2632 /* Assign new value. */
2633 *pcanonical = canonical;
2639 argzize_path (path, pargz, pargz_len)
2650 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2655 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2658 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2668 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2669 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2670 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2671 it is appended to each SEARCH_PATH element before FUNC is called. */
2673 foreach_dirinpath (search_path, base_name, func, data1, data2)
2674 const char *search_path;
2675 const char *base_name;
2676 foreach_callback_func *func;
2681 int filenamesize = 0;
2682 size_t lenbase = LT_STRLEN (base_name);
2683 size_t argz_len = 0;
2686 char *canonical = 0;
2690 if (!search_path || !*search_path)
2692 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2696 if (canonicalize_path (search_path, &canonical) != 0)
2699 if (argzize_path (canonical, &argz, &argz_len) != 0)
2704 while ((dir_name = argz_next (argz, argz_len, dir_name)))
2706 size_t lendir = LT_STRLEN (dir_name);
2708 if (lendir +1 +lenbase >= filenamesize)
2710 LT_DLFREE (filename);
2711 filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2712 filename = LT_EMALLOC (char, filenamesize);
2717 assert (filenamesize > lendir);
2718 strcpy (filename, dir_name);
2720 if (base_name && *base_name)
2722 if (filename[lendir -1] != '/')
2723 filename[lendir++] = '/';
2724 strcpy (filename +lendir, base_name);
2727 if ((result = (*func) (filename, data1, data2)))
2736 LT_DLFREE (canonical);
2737 LT_DLFREE (filename);
2739 LT_DLMUTEX_UNLOCK ();
2744 /* If FILEPATH can be opened, store the name of the directory component
2745 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2746 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2748 find_file_callback (filename, data1, data2)
2753 char **pdir = (char **) data1;
2754 FILE **pfile = (FILE **) data2;
2757 assert (filename && *filename);
2761 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
2763 char *dirend = strrchr (filename, '/');
2765 if (dirend > filename)
2766 *dirend = LT_EOS_CHAR;
2769 *pdir = lt_estrdup (filename);
2770 is_done = (*pdir == 0) ? -1 : 1;
2777 find_file (search_path, base_name, pdir)
2778 const char *search_path;
2779 const char *base_name;
2784 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
2790 find_handle_callback (filename, data, ignored)
2795 lt_dlhandle *handle = (lt_dlhandle *) data;
2796 int notfound = access (filename, R_OK);
2798 /* Bail out if file cannot be read... */
2802 /* Try to dlopen the file, but do not continue searching in any
2804 if (tryall_dlopen (handle, filename,NULL) != 0)
2810 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2811 found but could not be opened, *HANDLE will be set to 0. */
2812 static lt_dlhandle *
2813 find_handle (search_path, base_name, handle)
2814 const char *search_path;
2815 const char *base_name;
2816 lt_dlhandle *handle;
2821 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2829 load_deplibs (handle, deplibs)
2833 #if LTDL_DLOPEN_DEPLIBS
2834 char *p, *save_search_path = 0;
2841 handle->depcount = 0;
2843 #if LTDL_DLOPEN_DEPLIBS
2851 if (user_search_path)
2853 save_search_path = lt_estrdup (user_search_path);
2854 if (!save_search_path)
2858 /* extract search paths and count deplibs */
2862 if (!isspace ((int) *p))
2865 while (*end && !isspace((int) *end))
2870 if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2873 *end = 0; /* set a temporary string terminator */
2874 if (lt_dladdsearchdir(p+2))
2899 names = LT_EMALLOC (char *, depcount * sizeof (char*));
2903 /* now only extract the actual deplibs */
2908 if (isspace ((int) *p))
2915 while (*end && !isspace ((int) *end))
2920 if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2924 *end = 0; /* set a temporary string terminator */
2925 if (strncmp(p, "-l", 2) == 0)
2927 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2928 name = LT_EMALLOC (char, 1+ name_len);
2930 sprintf (name, "lib%s", p+2);
2933 name = lt_estrdup(p);
2938 names[depcount++] = name;
2945 /* load the deplibs (in reverse order)
2946 At this stage, don't worry if the deplibs do not load correctly,
2947 they may already be statically linked into the loading application
2948 for instance. There will be a more enlightening error message
2949 later on if the loaded module cannot resolve all of its symbols. */
2954 handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2955 if (!handle->deplibs)
2958 for (i = 0; i < depcount; ++i)
2960 handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
2961 if (handle->deplibs[j])
2967 handle->depcount = j; /* Number of successfully loaded deplibs */
2972 for (i = 0; i < depcount; ++i)
2974 LT_DLFREE (names[i]);
2979 /* restore the old search path */
2980 if (user_search_path) {
2981 LT_DLFREE (user_search_path);
2982 user_search_path = save_search_path;
2984 LT_DLMUTEX_UNLOCK ();
2992 unload_deplibs (handle)
2998 if (handle->depcount)
3000 for (i = 0; i < handle->depcount; ++i)
3002 if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
3004 errors += lt_dlclose (handle->deplibs[i]);
3017 /* remove the leading and trailing "'" from str
3018 and store the result in dest */
3019 const char *end = strrchr (str, '\'');
3020 size_t len = LT_STRLEN (str);
3028 if (len > 3 && str[0] == '\'')
3030 tmp = LT_EMALLOC (char, end - str);
3034 strncpy(tmp, &str[1], (end - str) - 1);
3035 tmp[len-3] = LT_EOS_CHAR;
3047 free_vars (dlname, oldname, libdir, deplibs)
3054 LT_DLFREE (oldname);
3056 LT_DLFREE (deplibs);
3062 try_dlopen (phandle, filename)
3063 lt_dlhandle *phandle;
3064 const char *filename;
3066 const char * ext = 0;
3067 const char * saved_error = 0;
3068 char * canonical = 0;
3069 char * base_name = 0;
3073 lt_dlhandle newhandle;
3076 assert (*phandle == 0);
3078 LT_DLMUTEX_GETERROR (saved_error);
3083 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3087 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3088 newhandle = *phandle;
3090 /* lt_dlclose()ing yourself is very bad! Disallow it. */
3091 LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
3093 if (tryall_dlopen (&newhandle, 0, NULL) != 0)
3095 LT_DLFREE (*phandle);
3099 goto register_handle;
3102 assert (filename && *filename);
3104 /* Doing this immediately allows internal functions to safely
3105 assume only canonicalized paths are passed. */
3106 if (canonicalize_path (filename, &canonical) != 0)
3112 /* If the canonical module name is a path (relative or absolute)
3113 then split it into a directory part and a name part. */
3114 base_name = strrchr (canonical, '/');
3117 size_t dirlen = (1+ base_name) - canonical;
3119 dir = LT_EMALLOC (char, 1+ dirlen);
3126 strncpy (dir, canonical, dirlen);
3127 dir[dirlen] = LT_EOS_CHAR;
3132 base_name = canonical;
3134 assert (base_name && *base_name);
3136 /* Check whether we are opening a libtool module (.la extension). */
3137 ext = strrchr (base_name, '.');
3138 if (ext && strcmp (ext, archive_ext) == 0)
3140 /* this seems to be a libtool module */
3143 char * old_name = 0;
3149 /* if we can't find the installed flag, it is probably an
3150 installed libtool archive, produced with an old version
3154 /* extract the module name from the file name */
3155 name = LT_EMALLOC (char, ext - base_name + 1);
3162 /* canonicalize the module name */
3165 for (i = 0; i < ext - base_name; ++i)
3167 if (isalnum ((int)(base_name[i])))
3169 name[i] = base_name[i];
3176 name[ext - base_name] = LT_EOS_CHAR;
3179 /* Now try to open the .la file. If there is no directory name
3180 component, try to find it first in user_search_path and then other
3181 prescribed paths. Otherwise (or in any case if the module was not
3182 yet found) try opening just the module name as passed. */
3185 const char *search_path;
3188 search_path = user_search_path;
3190 file = find_file (user_search_path, base_name, &dir);
3191 LT_DLMUTEX_UNLOCK ();
3195 search_path = getenv (LTDL_SEARCHPATH_VAR);
3197 file = find_file (search_path, base_name, &dir);
3200 #ifdef LTDL_SHLIBPATH_VAR
3203 search_path = getenv (LTDL_SHLIBPATH_VAR);
3205 file = find_file (search_path, base_name, &dir);
3208 #ifdef LTDL_SYSSEARCHPATH
3209 if (!file && sys_search_path)
3211 file = find_file (sys_search_path, base_name, &dir);
3217 file = fopen (filename, LT_READTEXT_MODE);
3220 /* If we didn't find the file by now, it really isn't there. Set
3221 the status flag, and bail out. */
3224 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3229 line_len = LT_FILENAME_MAX;
3230 line = LT_EMALLOC (char, line_len);
3238 /* read the .la file */
3239 while (!feof (file))
3241 if (!fgets (line, (int) line_len, file))
3246 /* Handle the case where we occasionally need to read a line
3247 that is longer than the initial buffer size. */
3248 while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file)))
3250 line = LT_DLREALLOC (char, line, line_len *2);
3251 if (!fgets (&line[line_len -1], (int) line_len +1, file))
3258 if (line[0] == '\n' || line[0] == '#')
3264 #define STR_DLNAME "dlname="
3265 if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3267 errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
3270 #undef STR_OLD_LIBRARY
3271 #define STR_OLD_LIBRARY "old_library="
3272 else if (strncmp (line, STR_OLD_LIBRARY,
3273 sizeof (STR_OLD_LIBRARY) - 1) == 0)
3275 errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3278 #define STR_LIBDIR "libdir="
3279 else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3281 errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
3284 #undef STR_DL_DEPLIBS
3285 #define STR_DL_DEPLIBS "dependency_libs="
3286 else if (strncmp (line, STR_DL_DEPLIBS,
3287 sizeof (STR_DL_DEPLIBS) - 1) == 0)
3289 errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3291 else if (strcmp (line, "installed=yes\n") == 0)
3295 else if (strcmp (line, "installed=no\n") == 0)
3300 #undef STR_LIBRARY_NAMES
3301 #define STR_LIBRARY_NAMES "library_names="
3302 else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
3303 sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3306 errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3309 && (last_libname = strrchr (dlname, ' ')) != 0)
3311 last_libname = lt_estrdup (last_libname + 1);
3317 LT_DLMEM_REASSIGN (dlname, last_libname);
3328 /* allocate the handle */
3329 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3335 free_vars (dlname, old_name, libdir, deplibs);
3336 LT_DLFREE (*phandle);
3342 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3343 if (load_deplibs (*phandle, deplibs) == 0)
3345 newhandle = *phandle;
3346 /* find_module may replace newhandle */
3347 if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
3349 unload_deplibs (*phandle);
3358 free_vars (dlname, old_name, libdir, deplibs);
3361 LT_DLFREE (*phandle);
3365 if (*phandle != newhandle)
3367 unload_deplibs (*phandle);
3372 /* not a libtool module */
3373 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3380 memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3381 newhandle = *phandle;
3383 /* If the module has no directory name component, try to find it
3384 first in user_search_path and then other prescribed paths.
3385 Otherwise (or in any case if the module was not yet found) try
3386 opening just the module name as passed. */
3387 if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
3388 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3390 #ifdef LTDL_SHLIBPATH_VAR
3391 && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
3394 #ifdef LTDL_SYSSEARCHPATH
3395 && !find_handle (sys_search_path, base_name, &newhandle)
3399 if (tryall_dlopen (&newhandle, filename, NULL) != 0)
3407 LT_DLFREE (*phandle);
3414 LT_DLMEM_REASSIGN (*phandle, newhandle);
3416 if ((*phandle)->info.ref_count == 0)
3418 (*phandle)->info.ref_count = 1;
3419 LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
3422 (*phandle)->next = handles;
3424 LT_DLMUTEX_UNLOCK ();
3427 LT_DLMUTEX_SETERROR (saved_error);
3432 LT_DLFREE (canonical);
3438 lt_dlopen (filename)
3439 const char *filename;
3441 lt_dlhandle handle = 0;
3443 /* Just incase we missed a code path in try_dlopen() that reports
3444 an error, but forgets to reset handle... */
3445 if (try_dlopen (&handle, filename) != 0)
3451 /* If the last error messge store was `FILE_NOT_FOUND', then return
3456 const char *error = 0;
3458 LT_DLMUTEX_GETERROR (error);
3459 if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
3465 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3466 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3467 and if a file is still not found try again with SHLIB_EXT appended
3470 lt_dlopenext (filename)
3471 const char *filename;
3473 lt_dlhandle handle = 0;
3481 return lt_dlopen (filename);
3486 len = LT_STRLEN (filename);
3487 ext = strrchr (filename, '.');
3489 /* If FILENAME already bears a suitable extension, there is no need
3490 to try appending additional extensions. */
3491 if (ext && ((strcmp (ext, archive_ext) == 0)
3492 #ifdef LTDL_SHLIB_EXT
3493 || (strcmp (ext, shlib_ext) == 0)
3497 return lt_dlopen (filename);
3500 /* First try appending ARCHIVE_EXT. */
3501 tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
3505 strcpy (tmp, filename);
3506 strcat (tmp, archive_ext);
3507 errors = try_dlopen (&handle, tmp);
3508 if (handle && errors) {
3509 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
3510 return 0; /* leaks tmp and handle */
3512 if (handle && errors) {
3513 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
3514 return 0; /* leaks tmp and handle */
3517 /* If we found FILENAME, stop searching -- whether we were able to
3518 load the file as a module or not. If the file exists but loading
3519 failed, it is better to return an error message here than to
3520 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3521 in the module search path. */
3522 if (handle || ((errors > 0) && !file_not_found ()))
3528 #ifdef LTDL_SHLIB_EXT
3529 /* Try appending SHLIB_EXT. */
3530 if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
3533 tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
3537 strcpy (tmp, filename);
3541 tmp[len] = LT_EOS_CHAR;
3542 if (handle && errors) {
3543 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
3544 return 0; /* leaks tmp and handle */
3548 strcat(tmp, shlib_ext);
3549 errors = try_dlopen (&handle, tmp);
3550 if (handle && errors) {
3551 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
3552 return 0; /* leaks tmp and handle */
3555 /* As before, if the file was found but loading failed, return now
3556 with the current error message. */
3557 if (handle || ((errors > 0) && !file_not_found ()))
3564 /* Still here? Then we really did fail to locate any of the file
3566 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3573 lt_argz_insert (pargz, pargz_len, before, entry)
3581 /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
3582 pargz_len, NULL, entry) failed with EINVAL. */
3584 error = argz_insert (pargz, pargz_len, before, entry);
3586 error = argz_append (pargz, pargz_len, entry, 1 + LT_STRLEN (entry));
3593 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3596 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3606 lt_argz_insertinorder (pargz, pargz_len, entry)
3615 assert (entry && *entry);
3618 while ((before = argz_next (*pargz, *pargz_len, before)))
3620 int cmp = strcmp (entry, before);
3623 if (cmp == 0) return 0; /* No duplicates! */
3626 return lt_argz_insert (pargz, pargz_len, before, entry);
3630 lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
3639 size_t end_offset = 0;
3647 dir_len = LT_STRLEN (dirnam);
3648 end = dp->d_name + LT_D_NAMLEN(dp);
3650 /* Ignore version numbers. */
3653 for (p = end; p -1 > dp->d_name; --p)
3654 if (strchr (".0123456789", p[-1]) == 0)
3661 /* Ignore filename extension. */
3664 for (p = end -1; p > dp->d_name; --p)
3672 /* Prepend the directory name. */
3673 end_offset = end - dp->d_name;
3674 buf_len = dir_len + 1+ end_offset;
3675 buf = LT_EMALLOC (char, 1+ buf_len);
3681 strcpy (buf, dirnam);
3683 strncat (buf, dp->d_name, end_offset);
3684 buf[buf_len] = LT_EOS_CHAR;
3686 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3687 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3696 list_files_by_dir (dirnam, pargz, pargz_len)
3704 assert (dirnam && *dirnam);
3707 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
3709 dirp = opendir (dirnam);
3712 struct dirent *dp = 0;
3714 while ((dp = readdir (dirp)))
3715 if (dp->d_name[0] != '.')
3716 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3731 /* If there are any files in DIRNAME, call the function passed in
3732 DATA1 (with the name of each file and DATA2 as arguments). */
3734 foreachfile_callback (dirname, data1, data2)
3739 int (*func) LT_PARAMS((const char *filename, lt_ptr data))
3740 = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
3744 size_t argz_len = 0;
3746 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3753 while ((filename = argz_next (argz, argz_len, filename)))
3754 if ((is_done = (*func) (filename, data2)))
3765 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3766 with DATA. The filenames passed to FUNC would be suitable for
3767 passing to lt_dlopenext. The extensions are stripped so that
3768 individual modules do not generate several entries (e.g. libfoo.la,
3769 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3770 then the same directories that lt_dlopen would search are examined. */
3772 lt_dlforeachfile (search_path, func, data)
3773 const char *search_path;
3774 int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
3781 /* If a specific path was passed, search only the directories
3783 is_done = foreach_dirinpath (search_path, 0,
3784 foreachfile_callback, func, data);
3788 /* Otherwise search the default paths. */
3789 is_done = foreach_dirinpath (user_search_path, 0,
3790 foreachfile_callback, func, data);
3793 is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3794 foreachfile_callback, func, data);
3797 #ifdef LTDL_SHLIBPATH_VAR
3800 is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
3801 foreachfile_callback, func, data);
3804 #ifdef LTDL_SYSSEARCHPATH
3807 is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
3808 foreachfile_callback, func, data);
3820 lt_dlhandle cur, last;
3825 /* check whether the handle is valid */
3826 last = cur = handles;
3827 while (cur && handle != cur)
3835 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3840 handle->info.ref_count--;
3842 /* Note that even with resident modules, we must track the ref_count
3843 correctly incase the user decides to reset the residency flag
3844 later (even though the API makes no provision for that at the
3846 if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
3848 lt_user_data data = handle->loader->dlloader_data;
3850 if (handle != handles)
3852 last->next = handle->next;
3856 handles = handle->next;
3859 errors += handle->loader->module_close (data, handle->module);
3860 errors += unload_deplibs(handle);
3862 /* It is up to the callers to free the data itself. */
3863 LT_DLFREE (handle->caller_data);
3865 LT_DLFREE (handle->info.filename);
3866 LT_DLFREE (handle->info.name);
3872 if (LT_DLIS_RESIDENT (handle))
3874 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3879 LT_DLMUTEX_UNLOCK ();
3885 lt_dlsym (handle, symbol)
3890 char lsym[LT_SYMBOL_LENGTH];
3897 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3903 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3907 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3908 + LT_STRLEN (handle->info.name);
3910 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3916 sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3919 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3924 data = handle->loader->dlloader_data;
3925 if (handle->info.name)
3927 const char *saved_error;
3929 LT_DLMUTEX_GETERROR (saved_error);
3931 /* this is a libtool module */
3932 if (handle->loader->sym_prefix)
3934 strcpy(sym, handle->loader->sym_prefix);
3935 strcat(sym, handle->info.name);
3939 strcpy(sym, handle->info.name);
3942 strcat(sym, "_LTX_");
3943 strcat(sym, symbol);
3945 /* try "modulename_LTX_symbol" */
3946 address = handle->loader->find_sym (data, handle->module, sym);
3955 LT_DLMUTEX_SETERROR (saved_error);
3958 /* otherwise try "symbol" */
3959 if (handle->loader->sym_prefix)
3961 strcpy(sym, handle->loader->sym_prefix);
3962 strcat(sym, symbol);
3966 strcpy(sym, symbol);
3969 address = handle->loader->find_sym (data, handle->module, sym);
3983 LT_DLMUTEX_GETERROR (error);
3984 LT_DLMUTEX_SETERROR (0);
3986 return error ? error : NULL;
3990 lt_dlpath_insertdir (ppath, before, dir)
3996 char *canonical = 0;
3998 size_t argz_len = 0;
4001 assert (dir && *dir);
4003 if (canonicalize_path (dir, &canonical) != 0)
4009 assert (canonical && *canonical);
4011 /* If *PPATH is empty, set it to DIR. */
4014 assert (!before); /* BEFORE cannot be set without PPATH. */
4015 assert (dir); /* Without DIR, don't call this function! */
4017 *ppath = lt_estrdup (dir);
4024 assert (ppath && *ppath);
4026 if (argzize_path (*ppath, &argz, &argz_len) != 0)
4032 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
4033 if *PPATH is already canonicalized, and hence does not change length
4034 with respect to ARGZ. We canonicalize each entry as it is added to
4035 the search path, and don't call this function with (uncanonicalized)
4036 user paths, so this is a fair assumption. */
4039 assert (*ppath <= before);
4040 assert (before - *ppath <= strlen (*ppath));
4042 before = before - *ppath + argz;
4045 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
4051 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
4052 LT_DLMEM_REASSIGN (*ppath, argz);
4055 LT_DLFREE (canonical);
4062 lt_dladdsearchdir (search_dir)
4063 const char *search_dir;
4067 if (search_dir && *search_dir)
4070 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
4072 LT_DLMUTEX_UNLOCK ();
4079 lt_dlinsertsearchdir (before, search_dir)
4081 const char *search_dir;
4088 if ((before < user_search_path)
4089 || (before >= user_search_path + LT_STRLEN (user_search_path)))
4091 LT_DLMUTEX_UNLOCK ();
4092 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
4095 LT_DLMUTEX_UNLOCK ();
4098 if (search_dir && *search_dir)
4101 if (lt_dlpath_insertdir (&user_search_path,
4102 (char *) before, search_dir) != 0)
4106 LT_DLMUTEX_UNLOCK ();
4113 lt_dlsetsearchpath (search_path)
4114 const char *search_path;
4119 LT_DLFREE (user_search_path);
4120 LT_DLMUTEX_UNLOCK ();
4122 if (!search_path || !LT_STRLEN (search_path))
4128 if (canonicalize_path (search_path, &user_search_path) != 0)
4130 LT_DLMUTEX_UNLOCK ();
4136 lt_dlgetsearchpath ()
4138 const char *saved_path;
4141 saved_path = user_search_path;
4142 LT_DLMUTEX_UNLOCK ();
4148 lt_dlmakeresident (handle)
4155 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4160 LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4167 lt_dlisresident (handle)
4172 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4176 return LT_DLIS_RESIDENT (handle);
4182 /* --- MODULE INFORMATION --- */
4185 lt_dlgetinfo (handle)
4190 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4194 return &(handle->info);
4198 lt_dlhandle_next (place)
4201 return place ? place->next : handles;
4205 lt_dlforeach (func, data)
4206 int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
4217 lt_dlhandle tmp = cur;
4220 if ((*func) (tmp, data))
4227 LT_DLMUTEX_UNLOCK ();
4233 lt_dlcaller_register ()
4235 static lt_dlcaller_id last_caller_id = 0;
4239 result = ++last_caller_id;
4240 LT_DLMUTEX_UNLOCK ();
4246 lt_dlcaller_set_data (key, handle, data)
4252 lt_ptr stale = (lt_ptr) 0;
4255 /* This needs to be locked so that the caller data can be updated
4256 simultaneously by different threads. */
4259 if (handle->caller_data)
4260 while (handle->caller_data[n_elements].key)
4263 for (i = 0; i < n_elements; ++i)
4265 if (handle->caller_data[i].key == key)
4267 stale = handle->caller_data[i].data;
4272 /* Ensure that there is enough room in this handle's caller_data
4273 array to accept a new element (and an empty end marker). */
4274 if (i == n_elements)
4276 lt_caller_data *temp
4277 = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
4285 handle->caller_data = temp;
4287 /* We only need this if we needed to allocate a new caller_data. */
4288 handle->caller_data[i].key = key;
4289 handle->caller_data[1+ i].key = 0;
4292 handle->caller_data[i].data = data;
4295 LT_DLMUTEX_UNLOCK ();
4301 lt_dlcaller_get_data (key, handle)
4305 lt_ptr result = (lt_ptr) 0;
4307 /* This needs to be locked so that the caller data isn't updated by
4308 another thread part way through this function. */
4311 /* Locate the index of the element with a matching KEY. */
4314 for (i = 0; handle->caller_data[i].key; ++i)
4316 if (handle->caller_data[i].key == key)
4318 result = handle->caller_data[i].data;
4324 LT_DLMUTEX_UNLOCK ();
4331 /* --- USER MODULE LOADER API --- */
4335 lt_dlloader_add (place, dlloader, loader_name)
4337 const struct lt_user_dlloader *dlloader;
4338 const char *loader_name;
4341 lt_dlloader *node = 0, *ptr = 0;
4343 if ((dlloader == 0) /* diagnose null parameters */
4344 || (dlloader->module_open == 0)
4345 || (dlloader->module_close == 0)
4346 || (dlloader->find_sym == 0))
4348 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4352 /* Create a new dlloader node with copies of the user callbacks. */
4353 node = LT_EMALLOC (lt_dlloader, 1);
4358 node->loader_name = loader_name;
4359 node->sym_prefix = dlloader->sym_prefix;
4360 node->dlloader_exit = dlloader->dlloader_exit;
4361 node->module_open = dlloader->module_open;
4362 node->module_close = dlloader->module_close;
4363 node->find_sym = dlloader->find_sym;
4364 node->dlloader_data = dlloader->dlloader_data;
4369 /* If there are no loaders, NODE becomes the list! */
4374 /* If PLACE is not set, add NODE to the end of the
4376 for (ptr = loaders; ptr->next; ptr = ptr->next)
4383 else if (loaders == place)
4385 /* If PLACE is the first loader, NODE goes first. */
4391 /* Find the node immediately preceding PLACE. */
4392 for (ptr = loaders; ptr->next != place; ptr = ptr->next)
4397 if (ptr->next != place)
4399 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4404 /* Insert NODE between PTR and PLACE. */
4410 LT_DLMUTEX_UNLOCK ();
4416 lt_dlloader_remove (loader_name)
4417 const char *loader_name;
4419 lt_dlloader *place = lt_dlloader_find (loader_name);
4425 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4431 /* Fail if there are any open modules which use this loader. */
4432 for (handle = handles; handle; handle = handle->next)
4434 if (handle->loader == place)
4436 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
4442 if (place == loaders)
4444 /* PLACE is the first loader in the list. */
4445 loaders = loaders->next;
4449 /* Find the loader before the one being removed. */
4451 for (prev = loaders; prev->next; prev = prev->next)
4453 if (!strcmp (prev->next->loader_name, loader_name))
4460 prev->next = prev->next->next;
4463 if (place->dlloader_exit)
4465 errors = place->dlloader_exit (place->dlloader_data);
4471 LT_DLMUTEX_UNLOCK ();
4477 lt_dlloader_next (place)
4483 next = place ? place->next : loaders;
4484 LT_DLMUTEX_UNLOCK ();
4490 lt_dlloader_name (place)
4493 const char *name = 0;
4498 name = place ? place->loader_name : 0;
4499 LT_DLMUTEX_UNLOCK ();
4503 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4510 lt_dlloader_data (place)
4513 lt_user_data *data = 0;
4518 data = place ? &(place->dlloader_data) : 0;
4519 LT_DLMUTEX_UNLOCK ();
4523 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4530 lt_dlloader_find (loader_name)
4531 const char *loader_name;
4533 lt_dlloader *place = 0;
4536 for (place = loaders; place; place = place->next)
4538 if (strcmp (place->loader_name, loader_name) == 0)
4543 LT_DLMUTEX_UNLOCK ();