1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000 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 */
181 /* --- MANIFEST CONSTANTS --- */
184 /* Standard libltdl search path environment variable name */
185 #undef LTDL_SEARCHPATH_VAR
186 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
188 /* Standard libtool archive file extension. */
189 #undef LTDL_ARCHIVE_EXT
190 #define LTDL_ARCHIVE_EXT ".la"
194 # define LTDL_OBJDIR LT_OBJDIR
198 #ifndef LTDL_SHLIBPATH_VAR
199 # ifdef LT_MODULE_PATH_VAR
200 # define LTDL_SHLIBPATH_VAR LT_MODULE_PATH_VAR
204 #ifndef LTDL_SHLIB_EXT
205 # ifdef LT_MODULE_EXT
206 # define LTDL_SHLIB_EXT LT_MODULE_EXT
210 #ifndef LTDL_SYSSEARCHPATH
211 # ifdef LT_DLSEARCH_PATH
212 # define LTDL_SYSSEARCHPATH LT_DLSEARCH_PATH
216 /* max. filename length */
217 #ifndef LT_FILENAME_MAX
218 # define LT_FILENAME_MAX 1024
221 /* This is the maximum symbol size that won't require malloc/free */
222 #undef LT_SYMBOL_LENGTH
223 #define LT_SYMBOL_LENGTH 128
225 /* This accounts for the _LTX_ separator */
226 #undef LT_SYMBOL_OVERHEAD
227 #define LT_SYMBOL_OVERHEAD 5
232 /* --- MEMORY HANDLING --- */
235 /* These are the functions used internally. In addition to making
236 use of the associated function pointers above, they also perform
238 static char *lt_estrdup LT_PARAMS((const char *str));
239 static lt_ptr lt_emalloc LT_PARAMS((size_t size));
240 static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size));
242 /* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */
243 #define rpl_realloc realloc
245 /* These are the pointers that can be changed by the caller: */
246 LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
247 = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
248 LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size))
249 = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
250 LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
251 = (void (*) LT_PARAMS((lt_ptr))) free;
253 /* The following macros reduce the amount of typing needed to cast
257 #define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
258 #define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
259 #define LT_DLFREE(p) \
260 LT_STMT_START { if (p) { xfree (p); (p) = 0; } } LT_STMT_END
262 #define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
263 #define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
267 #define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
268 #define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((p), (n) * sizeof(tp)))
269 #define LT_DLFREE(p) \
270 LT_STMT_START { if (p) { lt_dlfree (p); (p) = 0; } } LT_STMT_END
272 #define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
273 #define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
277 #define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
278 if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \
282 /* --- REPLACEMENT FUNCTIONS --- */
286 #define strdup rpl_strdup
288 static char *strdup LT_PARAMS((const char *str));
291 strdup(const char *str)
297 tmp = LT_DLMALLOC (char, 1+ strlen (str));
300 memcpy(tmp, str, 1+ strlen (str));
312 #define strcmp rpl_strcmp
314 static int strcmp LT_PARAMS((const char *str1, const char *str2));
317 strcmp (const char *str1, const char *str2)
326 for (;*str1 && *str2; ++str1, ++str2)
332 return (int)(*str1 - *str2);
340 # define strchr index
342 # define strchr rpl_strchr
344 static const char *strchr LT_PARAMS((const char *str, int ch));
347 strchr(const char *str, int ch)
351 for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
354 return (*p == (char)ch) ? p : 0;
358 #endif /* !HAVE_STRCHR */
364 # define strrchr rindex
366 # define strrchr rpl_strrchr
368 static const char *strrchr LT_PARAMS((const char *str, int ch));
371 strrchr(const char *str, int ch)
373 const char *p, *q = 0;
375 for (p = str; *p != LT_EOS_CHAR; ++p)
389 /* NOTE: Neither bcopy nor the memcpy implementation below can
390 reliably handle copying in overlapping areas of memory. Use
391 memmove (for which there is a fallback implementation below)
392 if you need that behaviour. */
396 # define memcpy(dest, src, size) bcopy (src, dest, size)
398 # define memcpy rpl_memcpy
400 static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
403 memcpy (lt_ptr dest, const lt_ptr src, size_t size)
407 unsigned char *dest1 = (unsigned char *)dest;
408 unsigned char *src1 = (unsigned char *)src;
410 for (i = 0; i < size; ++i)
418 # endif /* !HAVE_BCOPY */
419 #endif /* !HAVE_MEMCPY */
422 # define memmove rpl_memmove
424 static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
427 memmove (lt_ptr dest, const lt_ptr src, size_t size)
431 unsigned char *dest1 = (unsigned char *)dest;
432 unsigned char *src1 = (unsigned char *)src;
435 for (i = 0; i < size; ++i)
440 for (i = size; i > 0; --i)
442 dest1[i-1] = src1[i-1];
448 #endif /* !HAVE_MEMMOVE */
450 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
452 static void closedir LT_PARAMS((DIR *entry));
457 assert(entry != (DIR *) NULL);
458 FindClose(entry->hSearch);
459 lt_dlfree((lt_ptr)entry);
463 static DIR * opendir LT_PARAMS((const char *path));
466 opendir (const char *path)
468 char file_specification[LT_FILENAME_MAX];
471 assert(path != (char *) NULL);
472 (void) strncpy(file_specification,path,LT_FILENAME_MAX-1);
473 (void) strcat(file_specification,"\\");
474 entry = LT_DLMALLOC (DIR,sizeof(DIR));
475 if (entry != (DIR *) 0)
477 entry->firsttime = TRUE;
478 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
480 if (entry->hSearch == INVALID_HANDLE_VALUE)
482 (void) strcat(file_specification,"\\*.*");
483 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
484 if (entry->hSearch == INVALID_HANDLE_VALUE)
494 static struct dirent *readdir LT_PARAMS((DIR *entry));
496 static struct dirent *readdir(DIR *entry)
501 if (entry == (DIR *) 0)
502 return((struct dirent *) 0);
503 if (!entry->firsttime)
505 status = FindNextFile(entry->hSearch,&entry->Win32FindData);
507 return((struct dirent *) 0);
509 entry->firsttime = FALSE;
510 (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
512 entry->file_info.d_namlen = strlen(entry->file_info.d_name);
513 return(&entry->file_info);
516 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
518 /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
519 ``realloc is not entirely portable''
520 In any case we want to use the allocator supplied by the user without
521 burdening them with an lt_dlrealloc function pointer to maintain.
522 Instead implement our own version (with known boundary conditions)
523 using lt_dlmalloc and lt_dlfree. */
526 #define realloc rpl_realloc
529 /* You can't (re)define realloc unless you also (re)define malloc.
530 Right now, this code uses the size of the *destination* to decide
531 how much to copy. That's not right, but you can't know the size
532 of the source unless you know enough about, or wrote malloc. So
533 this code is disabled... */
542 /* For zero or less bytes, free the original memory */
552 /* Allow reallocation of a NULL pointer. */
553 return lt_dlmalloc (size);
557 /* Allocate a new block, copy and free the old block. */
558 lt_ptr mem = lt_dlmalloc (size);
562 memcpy (mem, ptr, size);
566 /* Note that the contents of PTR are not damaged if there is
567 insufficient memory to realloc. */
574 #if ! HAVE_ARGZ_APPEND
575 # define argz_append rpl_argz_append
577 static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
578 const char *buf, size_t buf_len));
581 argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len)
588 assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
590 /* If nothing needs to be appended, no more work is required. */
594 /* Ensure there is enough room to append BUF_LEN. */
595 argz_len = *pargz_len + buf_len;
596 argz = LT_DLREALLOC (char, *pargz, argz_len);
600 /* Copy characters from BUF after terminating '\0' in ARGZ. */
601 memcpy (argz + *pargz_len, buf, buf_len);
603 /* Assign new values. */
605 *pargz_len = argz_len;
609 #endif /* !HAVE_ARGZ_APPEND */
612 #if ! HAVE_ARGZ_CREATE_SEP
613 # define argz_create_sep rpl_argz_create_sep
615 static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
616 char **pargz, size_t *pargz_len));
619 argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len)
628 /* Make a copy of STR, but replacing each occurence 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 (char **pargz, size_t *pargz_len, char *before, const char *entry)
682 assert (entry && *entry);
684 /* No BEFORE address indicates ENTRY should be inserted after the
685 current last element. */
687 return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
689 /* This probably indicates a programmer error, but to preserve
690 semantics, scan back to the start of an entry if BEFORE points
691 into the middle of it. */
692 while ((before > *pargz) && (before[-1] != LT_EOS_CHAR))
696 size_t entry_len = 1+ LT_STRLEN (entry);
697 size_t argz_len = *pargz_len + entry_len;
698 size_t offset = before - *pargz;
699 char *argz = LT_DLREALLOC (char, *pargz, argz_len);
704 /* Make BEFORE point to the equivalent offset in ARGZ that it
705 used to have in *PARGZ incase realloc() moved the block. */
706 before = argz + offset;
708 /* Move the ARGZ entries starting at BEFORE up into the new
709 space at the end -- making room to copy ENTRY into the
711 memmove (before + entry_len, before, *pargz_len - offset);
712 memcpy (before, entry, entry_len);
714 /* Assign new values. */
716 *pargz_len = argz_len;
721 #endif /* !HAVE_ARGZ_INSERT */
725 # define argz_next rpl_argz_next
727 static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
731 argz_next (char *argz, size_t argz_len, const char *entry)
733 assert ((argz && argz_len) || (!argz && !argz_len));
737 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
738 within the ARGZ vector. */
739 assert ((!argz && !argz_len)
740 || ((argz <= entry) && (entry < (argz + argz_len))));
742 /* Move to the char immediately after the terminating
744 entry = 1+ strchr (entry, LT_EOS_CHAR);
746 /* Return either the new ENTRY, or else NULL if ARGZ is
748 return (entry >= argz + argz_len) ? 0 : (char *) entry;
752 /* This should probably be flagged as a programmer error,
753 since starting an argz_next loop with the iterator set
754 to ARGZ is safer. To preserve semantics, handle the NULL
755 case by returning the start of ARGZ (if any). */
762 #endif /* !HAVE_ARGZ_NEXT */
766 #if ! HAVE_ARGZ_STRINGIFY
767 # define argz_stringify rpl_argz_stringify
769 static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
773 argz_stringify (char *argz, size_t argz_len, int sep)
775 assert ((argz && argz_len) || (!argz && !argz_len));
779 --argz_len; /* don't stringify the terminating EOS */
780 while (--argz_len > 0)
782 if (argz[argz_len] == LT_EOS_CHAR)
783 argz[argz_len] = sep;
787 #endif /* !HAVE_ARGZ_STRINGIFY */
792 /* --- TYPE DEFINITIONS -- */
795 /* This type is used for the array of caller data sets in each handler. */
804 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
807 /* Extract the diagnostic strings from the error table macro in the same
808 order as the enumerated indices in ltdl.h. */
810 static const char *lt_dlerror_strings[] =
812 #define LT_ERROR(name, diagnostic) (diagnostic),
819 /* This structure is used for the list of registered loaders. */
821 struct lt_dlloader *next;
822 const char *loader_name; /* identifying name for each loader */
823 const char *sym_prefix; /* prefix for symbols */
824 lt_module_open *module_open;
825 lt_module_close *module_close;
826 lt_find_sym *find_sym;
827 lt_dlloader_exit *dlloader_exit;
828 lt_user_data dlloader_data;
831 struct lt_dlhandle_struct {
832 struct lt_dlhandle_struct *next;
833 lt_dlloader *loader; /* dlopening interface */
835 int depcount; /* number of dependencies */
836 lt_dlhandle *deplibs; /* dependencies */
837 lt_module module; /* system module handle */
838 lt_ptr system; /* system specific data */
839 lt_caller_data *caller_data; /* per caller associated data */
840 int flags; /* various boolean stats */
843 /* Various boolean flags can be stored in the flags field of an
844 lt_dlhandle_struct... */
845 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
846 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
848 #define LT_DLRESIDENT_FLAG (0x01 << 0)
849 /* ...add more flags here... */
851 #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
854 #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
856 static const char objdir[] = LTDL_OBJDIR;
857 static const char archive_ext[] = LTDL_ARCHIVE_EXT;
858 #ifdef LTDL_SHLIB_EXT
859 static const char shlib_ext[] = LTDL_SHLIB_EXT;
861 #ifdef LTDL_SYSSEARCHPATH
862 static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
868 /* --- MUTEX LOCKING --- */
871 /* Macros to make it easier to run the lock functions only if they have
872 been registered. The reason for the complicated lock macro is to
873 ensure that the stored error message from the last error is not
874 accidentally erased if the current function doesn't generate an
876 #define LT_DLMUTEX_LOCK() LT_STMT_START { \
877 if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
879 #define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
880 if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
882 #define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
883 if (lt_dlmutex_seterror_func) \
884 (*lt_dlmutex_seterror_func) (errormsg); \
885 else lt_dllast_error = (errormsg); } LT_STMT_END
886 #define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
887 if (lt_dlmutex_seterror_func) \
888 (errormsg) = (*lt_dlmutex_geterror_func) (); \
889 else (errormsg) = lt_dllast_error; } LT_STMT_END
891 /* The mutex functions stored here are global, and are necessarily the
892 same for all threads that wish to share access to libltdl. */
893 static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
894 static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
895 static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
896 static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
897 static const char *lt_dllast_error = 0;
900 /* Either set or reset the mutex functions. Either all the arguments must
901 be valid functions, or else all can be NULL to turn off locking entirely.
902 The registered functions should be manipulating a static global lock
903 from the lock() and unlock() callbacks, which needs to be reentrant. */
905 lt_dlmutex_register (
906 lt_dlmutex_lock *lock,
907 lt_dlmutex_unlock *unlock,
908 lt_dlmutex_seterror *seterror,
909 lt_dlmutex_geterror *geterror)
911 lt_dlmutex_unlock *old_unlock = unlock;
914 /* Lock using the old lock() callback, if any. */
917 if ((lock && unlock && seterror && geterror)
918 || !(lock || unlock || seterror || geterror))
920 lt_dlmutex_lock_func = lock;
921 lt_dlmutex_unlock_func = unlock;
922 lt_dlmutex_geterror_func = geterror;
926 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
930 /* Use the old unlock() callback we saved earlier, if any. Otherwise
931 record any errors using internal storage. */
935 /* Return the number of errors encountered during the execution of
943 /* --- ERROR HANDLING --- */
946 static const char **user_error_strings = 0;
947 static int errorcount = LT_ERROR_MAX;
950 lt_dladderror (const char *diagnostic)
954 const char **temp = (const char **) 0;
960 errindex = errorcount - LT_ERROR_MAX;
961 temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
964 user_error_strings = temp;
965 user_error_strings[errindex] = diagnostic;
966 result = errorcount++;
969 LT_DLMUTEX_UNLOCK ();
975 lt_dlseterror (int errindex)
981 if (errindex >= errorcount || errindex < 0)
983 /* Ack! Error setting the error message! */
984 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
987 else if (errindex < LT_ERROR_MAX)
989 /* No error setting the error message! */
990 LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
994 /* No error setting the error message! */
995 LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
998 LT_DLMUTEX_UNLOCK ();
1004 lt_emalloc (size_t size)
1006 lt_ptr mem = lt_dlmalloc (size);
1008 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1013 lt_erealloc (lt_ptr addr, size_t size)
1015 lt_ptr mem = lt_dlrealloc (addr, size);
1017 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1022 lt_estrdup (const char *str)
1024 char *copy = strdup (str);
1025 if (LT_STRLEN (str) && !copy)
1026 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1033 /* --- DLOPEN() INTERFACE LOADER --- */
1038 /* dynamic linking with dlopen/dlsym */
1045 # include <sys/dl.h>
1049 # define LT_GLOBAL RTLD_GLOBAL
1052 # define LT_GLOBAL DL_GLOBAL
1054 #endif /* !RTLD_GLOBAL */
1056 # define LT_GLOBAL 0
1057 #endif /* !LT_GLOBAL */
1059 /* We may have to define LT_LAZY_OR_NOW in the command line if we
1060 find out it does not work in some platform. */
1061 #ifndef LT_LAZY_OR_NOW
1063 # define LT_LAZY_OR_NOW RTLD_LAZY
1066 # define LT_LAZY_OR_NOW DL_LAZY
1068 # endif /* !RTLD_LAZY */
1070 #ifndef LT_LAZY_OR_NOW
1072 # define LT_LAZY_OR_NOW RTLD_NOW
1075 # define LT_LAZY_OR_NOW DL_NOW
1077 # endif /* !RTLD_NOW */
1079 #ifndef LT_LAZY_OR_NOW
1080 # define LT_LAZY_OR_NOW 0
1081 #endif /* !LT_LAZY_OR_NOW */
1084 # define DLERROR(arg) dlerror ()
1086 # define DLERROR(arg) LT_DLSTRERROR (arg)
1090 sys_dl_open (lt_user_data loader_data, const char *filename)
1092 lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
1096 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
1103 sys_dl_close (lt_user_data loader_data, lt_module module)
1107 if (dlclose (module) != 0)
1109 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
1118 lt_user_data loader_data,
1122 lt_ptr address = dlsym (module, symbol);
1126 LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
1132 static struct lt_user_dlloader sys_dl =
1139 sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
1142 #endif /* HAVE_LIBDL */
1146 /* --- SHL_LOAD() INTERFACE LOADER --- */
1150 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1156 /* some flags are missing on some systems, so we provide
1157 * harmless defaults.
1160 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1161 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1164 * BIND_FIRST - Place the library at the head of the symbol search
1166 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1167 * unsatisfied symbols as fatal. This flag allows
1168 * binding of unsatisfied code symbols to be deferred
1170 * [Perl: For certain libraries, like DCE, deferred
1171 * binding often causes run time problems. Adding
1172 * BIND_NONFATAL to BIND_IMMEDIATE still allows
1173 * unresolved references in situations like this.]
1174 * BIND_NOSTART - Do not call the initializer for the shared library
1175 * when the library is loaded, nor on a future call to
1177 * BIND_VERBOSE - Print verbose messages concerning possible
1178 * unsatisfied symbols.
1180 * hp9000s700/hp9000s800:
1181 * BIND_RESTRICTED - Restrict symbols visible by the library to those
1182 * present at library load time.
1183 * DYNAMIC_PATH - Allow the loader to dynamically search for the
1184 * library specified by the path argument.
1187 #ifndef DYNAMIC_PATH
1188 # define DYNAMIC_PATH 0
1190 #ifndef BIND_RESTRICTED
1191 # define BIND_RESTRICTED 0
1194 #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1197 sys_shl_open (lt_user_data loader_data, const char *filename)
1199 static shl_t self = (shl_t) 0;
1200 lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1202 /* Since searching for a symbol against a NULL module handle will also
1203 look in everything else that was already loaded and exported with
1204 the -E compiler flag, we always cache a handle saved before any
1205 modules are loaded. */
1209 shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1218 module = shl_load (filename, LT_BIND_FLAGS, 0L);
1222 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1230 sys_shl_close (lt_user_data loader_data, lt_module module)
1234 if (module && (shl_unload ((shl_t) (module)) != 0))
1236 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1245 lt_user_data loader_data,
1251 /* sys_shl_open should never return a NULL module handle */
1252 if (module == (lt_module) 0)
1254 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1256 else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
1260 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1267 static struct lt_user_dlloader sys_shl = {
1268 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
1271 #endif /* HAVE_SHL_LOAD */
1276 /* --- LOADLIBRARY() INTERFACE LOADER --- */
1280 /* dynamic linking for Win32 */
1282 #include <windows.h>
1284 /* Forward declaration; required to implement handle search below. */
1285 static lt_dlhandle handles;
1288 sys_wll_open (lt_user_data loader_data, const char *filename)
1291 lt_module module = 0;
1292 const char *errormsg = 0;
1293 char *searchname = 0;
1295 char self_name_buf[MAX_PATH];
1299 /* Get the name of main module */
1301 GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
1302 filename = ext = self_name_buf;
1306 ext = strrchr (filename, '.');
1311 /* FILENAME already has an extension. */
1312 searchname = lt_estrdup (filename);
1316 /* Append a `.' to stop Windows from adding an
1317 implicit `.dll' extension. */
1318 searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
1320 sprintf (searchname, "%s.", filename);
1327 char wpath[MAX_PATH];
1328 cygwin_conv_to_full_win32_path(searchname, wpath);
1329 module = LoadLibrary(wpath);
1332 module = LoadLibrary (searchname);
1334 LT_DLFREE (searchname);
1336 /* libltdl expects this function to fail if it is unable
1337 to physically load the library. Sadly, LoadLibrary
1338 will search the loaded libraries for a match and return
1339 one of them if the path search load fails.
1341 We check whether LoadLibrary is returning a handle to
1342 an already loaded module, and simulate failure if we
1354 if (cur->module == module)
1361 LT_DLMUTEX_UNLOCK ();
1365 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1373 sys_wll_close (lt_user_data loader_data, lt_module module)
1377 if (FreeLibrary(module) == 0)
1379 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1388 lt_user_data loader_data,
1392 lt_ptr address = GetProcAddress (module, symbol);
1396 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1402 static struct lt_user_dlloader sys_wll = {
1403 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1406 #endif /* __WINDOWS__ */
1411 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1416 /* dynamic linking for BeOS */
1418 #include <kernel/image.h>
1421 sys_bedl_open (lt_user_data loader_data, const char *filename)
1427 image = load_add_on (filename);
1433 if (get_next_image_info (0, &cookie, &info) == B_OK)
1434 image = load_add_on (info.name);
1439 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1443 return (lt_module) image;
1447 sys_bedl_close (lt_user_data loader_data, lt_module module)
1451 if (unload_add_on ((image_id) module) != B_OK)
1453 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1462 lt_user_data loader_data,
1467 image_id image = (image_id) module;
1469 if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1471 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1478 static struct lt_user_dlloader sys_bedl = {
1479 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1482 #endif /* __BEOS__ */
1487 /* --- DLD_LINK() INTERFACE LOADER --- */
1492 /* dynamic linking with dld */
1499 sys_dld_open (lt_user_data loader_data, const char *filename)
1501 lt_module module = strdup (filename);
1503 if (dld_link (filename) != 0)
1505 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1514 sys_dld_close (lt_user_data loader_data, lt_module module)
1518 if (dld_unlink_by_file ((char*)(module), 1) != 0)
1520 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1533 lt_user_data loader_data,
1537 lt_ptr address = dld_get_func (symbol);
1541 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1547 static struct lt_user_dlloader sys_dld = {
1548 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1551 #endif /* HAVE_DLD */
1553 /* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
1557 #if HAVE_MACH_O_DYLD_H
1558 #if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
1559 /* Is this correct? Does it still function properly? */
1560 #define __private_extern__ extern
1562 # include <mach-o/dyld.h>
1564 #include <mach-o/getsect.h>
1566 /* We have to put some stuff here that isn't in older dyld.h files */
1567 #ifndef ENUM_DYLD_BOOL
1568 # define ENUM_DYLD_BOOL
1577 # define LC_REQ_DYLD 0x80000000
1579 #ifndef LC_LOAD_WEAK_DYLIB
1580 # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
1582 static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0;
1583 static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0;
1584 static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0;
1585 static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0;
1587 #ifndef NSADDIMAGE_OPTION_NONE
1588 #define NSADDIMAGE_OPTION_NONE 0x0
1590 #ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
1591 #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
1593 #ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
1594 #define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
1596 #ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1597 #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
1599 #ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
1600 #define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
1602 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
1603 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
1605 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1606 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
1608 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
1609 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
1611 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1612 #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
1617 lt_int_dyld_error(char* othererror)
1619 /* return the dyld error string, or the passed in error string if none */
1620 NSLinkEditErrors ler;
1624 NSLinkEditError(&ler,&lerno,&file,&errstr);
1625 if (!errstr || !strlen(errstr)) errstr = othererror;
1629 static const struct mach_header *
1630 lt_int_dyld_get_mach_header_from_nsmodule(NSModule module)
1632 /* There should probably be an apple dyld api for this */
1633 int i=_dyld_image_count();
1635 const char *modname=NSNameOfModule(module);
1636 const struct mach_header *mh=NULL;
1637 if (!modname) return NULL;
1638 for (j = 0; j < i; j++)
1640 if (!strcmp(_dyld_get_image_name(j),modname))
1642 mh=_dyld_get_image_header(j);
1649 static const char* lt_int_dyld_lib_install_name(const struct mach_header *mh)
1651 /* NSAddImage is also used to get the loaded image, but it only works if the lib
1652 is installed, for uninstalled libs we need to check the install_names against
1653 each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
1654 different lib was loaded as a result
1657 struct load_command *lc;
1658 unsigned long offset = sizeof(struct mach_header);
1659 const char* retStr=NULL;
1660 for (j = 0; j < mh->ncmds; j++)
1662 lc = (struct load_command*)(((unsigned long)mh) + offset);
1663 if (LC_ID_DYLIB == lc->cmd)
1665 retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset +
1668 offset += lc->cmdsize;
1673 static const struct mach_header *
1674 lt_int_dyld_match_loaded_lib_by_install_name(const char *name)
1676 int i=_dyld_image_count();
1678 const struct mach_header *mh=NULL;
1679 const char *id=NULL;
1680 for (j = 0; j < i; j++)
1682 id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j));
1683 if ((id) && (!strcmp(id,name)))
1685 mh=_dyld_get_image_header(j);
1693 lt_int_dyld_NSlookupSymbolInLinkedLibs(const char *symbol, const struct mach_header *mh)
1695 /* Safe to assume our mh is good */
1697 struct load_command *lc;
1698 unsigned long offset = sizeof(struct mach_header);
1699 NSSymbol retSym = 0;
1700 const struct mach_header *mh1;
1701 if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) )
1703 for (j = 0; j < mh->ncmds; j++)
1705 lc = (struct load_command*)(((unsigned long)mh) + offset);
1706 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
1708 mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1709 (unsigned long)lc));
1712 /* Maybe NSAddImage can find it */
1713 mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1715 NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +
1716 NSADDIMAGE_OPTION_WITH_SEARCHING +
1717 NSADDIMAGE_OPTION_RETURN_ON_ERROR );
1721 retSym = ltdl_NSLookupSymbolInImage(mh1,
1723 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1724 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1729 offset += lc->cmdsize;
1740 if (!_dyld_present()) {
1744 err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage);
1745 err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage);
1746 err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage);
1747 err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic);
1753 sys_dyld_open (lt_user_data loader_data, const char *filename)
1755 lt_module module = 0;
1756 NSObjectFileImage ofi = 0;
1757 NSObjectFileImageReturnCode ofirc;
1760 return (lt_module)-1;
1761 ofirc = NSCreateObjectFileImageFromFile(filename, &ofi);
1764 case NSObjectFileImageSuccess:
1765 module = NSLinkModule(ofi, filename,
1766 NSLINKMODULE_OPTION_RETURN_ON_ERROR
1767 | NSLINKMODULE_OPTION_PRIVATE
1768 | NSLINKMODULE_OPTION_BINDNOW);
1769 NSDestroyObjectFileImage(ofi);
1771 ltdl_NSMakePrivateModulePublic(module);
1773 case NSObjectFileImageInappropriateFile:
1774 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1776 module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
1780 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1783 if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1788 sys_dyld_close (lt_user_data loader_data, lt_module module)
1792 if (module == (lt_module)-1) return 0;
1793 #ifdef __BIG_ENDIAN__
1794 if (((struct mach_header *)module)->magic == MH_MAGIC)
1796 if (((struct mach_header *)module)->magic == MH_CIGAM)
1799 LT_DLMUTEX_SETERROR("Can not close a dylib");
1805 /* Currently, if a module contains c++ static destructors and it is unloaded, we
1806 get a segfault in atexit(), due to compiler and dynamic loader differences of
1807 opinion, this works around that.
1809 if ((const struct section *)NULL !=
1810 getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module),
1811 "__DATA","__mod_term_func"))
1813 flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
1817 flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
1819 if (!NSUnLinkModule(module,flags))
1822 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE)));
1831 lt_user_data loader_data,
1836 NSSymbol *nssym = 0;
1838 const struct mach_header *mh=NULL;
1839 char saveError[256] = "Symbol not found";
1840 if (module == (lt_module)-1)
1842 _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused);
1845 #ifdef __BIG_ENDIAN__
1846 if (((struct mach_header *)module)->magic == MH_MAGIC)
1848 if (((struct mach_header *)module)->magic == MH_CIGAM)
1851 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1854 if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol))
1856 nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module,
1858 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1859 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1866 nssym = NSLookupSymbolInModule(module, symbol);
1870 strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255);
1872 if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module);
1873 nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh);
1877 LT_DLMUTEX_SETERROR (saveError);
1880 return NSAddressOfSymbol(nssym);
1883 static struct lt_user_dlloader sys_dyld =
1884 { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
1887 #endif /* HAVE_DYLD */
1890 /* --- DLPREOPEN() INTERFACE LOADER --- */
1893 /* emulate dynamic linking using preloaded_symbols */
1895 typedef struct lt_dlsymlists_t
1897 struct lt_dlsymlists_t *next;
1898 const lt_dlsymlist *syms;
1901 static const lt_dlsymlist *default_preloaded_symbols = 0;
1902 static lt_dlsymlists_t *preloaded_symbols = 0;
1905 presym_init (lt_user_data loader_data)
1911 preloaded_symbols = 0;
1912 if (default_preloaded_symbols)
1914 errors = lt_dlpreload (default_preloaded_symbols);
1917 LT_DLMUTEX_UNLOCK ();
1923 presym_free_symlists ()
1925 lt_dlsymlists_t *lists;
1929 lists = preloaded_symbols;
1932 lt_dlsymlists_t *tmp = lists;
1934 lists = lists->next;
1937 preloaded_symbols = 0;
1939 LT_DLMUTEX_UNLOCK ();
1945 presym_exit (lt_user_data loader_data)
1947 presym_free_symlists ();
1952 presym_add_symlist (const lt_dlsymlist *preloaded)
1954 lt_dlsymlists_t *tmp;
1955 lt_dlsymlists_t *lists;
1960 lists = preloaded_symbols;
1963 if (lists->syms == preloaded)
1967 lists = lists->next;
1970 tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
1973 memset (tmp, 0, sizeof(lt_dlsymlists_t));
1974 tmp->syms = preloaded;
1975 tmp->next = preloaded_symbols;
1976 preloaded_symbols = tmp;
1984 LT_DLMUTEX_UNLOCK ();
1989 presym_open (lt_user_data loader_data, const char *filename)
1991 lt_dlsymlists_t *lists;
1992 lt_module module = (lt_module) 0;
1995 lists = preloaded_symbols;
1999 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
2003 /* Can't use NULL as the reflective symbol header, as NULL is
2004 used to mark the end of the entire symbol list. Self-dlpreopened
2005 symbols follow this magic number, chosen to be an unlikely
2006 clash with a real module name. */
2009 filename = "@PROGRAM@";
2014 const lt_dlsymlist *syms = lists->syms;
2018 if (!syms->address && strcmp(syms->name, filename) == 0)
2020 module = syms->address;
2026 lists = lists->next;
2029 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2032 LT_DLMUTEX_UNLOCK ();
2037 presym_close (lt_user_data loader_data, lt_module module)
2039 /* Just to silence gcc -Wall */
2046 lt_user_data loader_data,
2050 lt_dlsymlist *syms = (lt_dlsymlist*) module;
2053 while (syms->address)
2055 if (strcmp(syms->name, symbol) == 0)
2057 return syms->address;
2063 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
2068 static struct lt_user_dlloader presym = {
2069 0, presym_open, presym_close, presym_sym, presym_exit, 0
2076 /* --- DYNAMIC MODULE LOADING --- */
2079 /* The type of a function used at each iteration of foreach_dirinpath(). */
2080 typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
2083 static int foreach_dirinpath LT_PARAMS((const char *search_path,
2084 const char *base_name,
2085 foreach_callback_func *func,
2086 lt_ptr data1, lt_ptr data2));
2088 static int find_file_callback LT_PARAMS((char *filename, lt_ptr data,
2090 static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data,
2092 static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1,
2096 static int canonicalize_path LT_PARAMS((const char *path,
2097 char **pcanonical));
2098 static int argzize_path LT_PARAMS((const char *path,
2100 size_t *pargz_len));
2101 static FILE *find_file LT_PARAMS((const char *search_path,
2102 const char *base_name,
2104 static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
2105 const char *base_name,
2106 lt_dlhandle *handle));
2107 static int find_module LT_PARAMS((lt_dlhandle *handle,
2111 const char *old_name,
2113 static int free_vars LT_PARAMS((char *dlname, char *oldname,
2114 char *libdir, char *deplibs));
2115 static int load_deplibs LT_PARAMS((lt_dlhandle handle,
2117 static int trim LT_PARAMS((char **dest,
2119 static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
2120 const char *filename));
2121 static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
2122 const char *filename));
2123 static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
2124 static int lt_argz_insert LT_PARAMS((char **pargz,
2127 const char *entry));
2128 static int lt_argz_insertinorder LT_PARAMS((char **pargz,
2130 const char *entry));
2131 static int lt_argz_insertdir LT_PARAMS((char **pargz,
2134 struct dirent *dp));
2135 static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
2138 static int list_files_by_dir LT_PARAMS((const char *dirnam,
2140 size_t *pargz_len));
2141 static int file_not_found LT_PARAMS((void));
2143 static char *user_search_path= 0;
2144 static lt_dlloader *loaders = 0;
2145 static lt_dlhandle handles = 0;
2146 static int initialized = 0;
2148 /* Initialize libltdl. */
2156 /* Initialize only at first call. */
2157 if (++initialized == 1)
2160 user_search_path = 0; /* empty search path */
2163 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
2166 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
2169 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
2172 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
2175 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
2178 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld");
2179 errors += sys_dyld_init();
2181 errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
2183 if (presym_init (presym.dlloader_data))
2185 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
2188 else if (errors != 0)
2190 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
2195 LT_DLMUTEX_UNLOCK ();
2201 lt_dlpreload (const lt_dlsymlist *preloaded)
2207 errors = presym_add_symlist (preloaded);
2211 presym_free_symlists();
2214 if (default_preloaded_symbols)
2216 errors = lt_dlpreload (default_preloaded_symbols);
2218 LT_DLMUTEX_UNLOCK ();
2225 lt_dlpreload_default (const lt_dlsymlist *preloaded)
2228 default_preloaded_symbols = preloaded;
2229 LT_DLMUTEX_UNLOCK ();
2236 /* shut down libltdl */
2237 lt_dlloader *loader;
2245 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
2250 /* shut down only at last call. */
2251 if (--initialized == 0)
2255 while (handles && LT_DLIS_RESIDENT (handles))
2257 handles = handles->next;
2260 /* close all modules */
2261 for (level = 1; handles; ++level)
2263 lt_dlhandle cur = handles;
2264 int saw_nonresident = 0;
2268 lt_dlhandle tmp = cur;
2270 if (!LT_DLIS_RESIDENT (tmp))
2271 saw_nonresident = 1;
2272 if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
2274 if (lt_dlclose (tmp))
2280 /* done if only resident modules are left */
2281 if (!saw_nonresident)
2285 /* close all loaders */
2288 lt_dlloader *next = loader->next;
2289 lt_user_data data = loader->dlloader_data;
2290 if (loader->dlloader_exit && loader->dlloader_exit (data))
2295 LT_DLMEM_REASSIGN (loader, next);
2301 LT_DLMUTEX_UNLOCK ();
2306 tryall_dlopen (lt_dlhandle *handle, const char *filename)
2309 lt_dlloader *loader;
2310 const char *saved_error;
2313 LT_DLMUTEX_GETERROR (saved_error);
2319 /* check whether the module was already opened */
2322 /* try to dlopen the program itself? */
2323 if (!cur->info.filename && !filename)
2328 if (cur->info.filename && filename
2329 && strcmp (cur->info.filename, filename) == 0)
2339 ++cur->info.ref_count;
2347 /* Comment out the check of file permissions using access.
2348 This call seems to always return -1 with error EACCES.
2350 /* We need to catch missing file errors early so that
2351 file_not_found() can detect what happened.
2352 if (access (filename, R_OK) != 0)
2354 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2359 cur->info.filename = lt_estrdup (filename);
2360 if (!cur->info.filename)
2368 cur->info.filename = 0;
2373 lt_user_data data = loader->dlloader_data;
2375 cur->module = loader->module_open (data, filename);
2377 if (cur->module != 0)
2381 loader = loader->next;
2386 LT_DLFREE (cur->info.filename);
2391 cur->loader = loader;
2392 LT_DLMUTEX_SETERROR (saved_error);
2395 LT_DLMUTEX_UNLOCK ();
2401 tryall_dlopen_module (
2402 lt_dlhandle *handle,
2404 const char *dirname,
2409 size_t filename_len = 0;
2410 size_t dirname_len = LT_STRLEN (dirname);
2415 #ifdef LT_DIRSEP_CHAR
2416 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2417 should make it into this function: */
2418 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
2421 if (dirname_len > 0)
2422 if (dirname[dirname_len -1] == '/')
2424 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
2426 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2427 The PREFIX (if any) is handled below. */
2428 filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
2432 snprintf (filename, dirname_len + 1 + filename_len + 1, "%.*s/%s", (int) dirname_len, dirname, dlname);
2434 /* Now that we have combined DIRNAME and MODULENAME, if there is
2435 also a PREFIX to contend with, simply recurse with the arguments
2436 shuffled. Otherwise, attempt to open FILENAME as a module. */
2439 error += tryall_dlopen_module (handle,
2440 (const char *) 0, prefix, filename);
2442 else if (tryall_dlopen (handle, filename) != 0)
2447 LT_DLFREE (filename);
2453 lt_dlhandle *handle,
2457 const char *old_name,
2460 /* Try to open the old library first; if it was dlpreopened,
2461 we want the preopened version of it, even if a dlopenable
2462 module is available. */
2463 if (old_name && tryall_dlopen (handle, old_name) == 0)
2468 /* Try to open the dynamic library. */
2471 /* try to open the installed module */
2472 if (installed && libdir)
2474 if (tryall_dlopen_module (handle,
2475 (const char *) 0, libdir, dlname) == 0)
2479 /* try to open the not-installed module */
2482 if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2486 /* maybe it was moved to another directory */
2488 if (tryall_dlopen_module (handle,
2489 (const char *) 0, dir, dlname) == 0)
2503 char *canonical = 0;
2505 assert (path && *path);
2506 assert (pcanonical);
2508 canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2515 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2517 /* Path separators are not copied to the beginning or end of
2518 the destination, or if another separator would follow
2520 if (path[src] == LT_PATHSEP_CHAR)
2523 || (path[1+ src] == LT_PATHSEP_CHAR)
2524 || (path[1+ src] == LT_EOS_CHAR))
2528 /* Anything other than a directory separator is copied verbatim. */
2529 if ((path[src] != '/')
2530 #ifdef LT_DIRSEP_CHAR
2531 && (path[src] != LT_DIRSEP_CHAR)
2535 canonical[dest++] = path[src];
2537 /* Directory separators are converted and copied only if they are
2538 not at the end of a path -- i.e. before a path separator or
2540 else if ((path[1+ src] != LT_PATHSEP_CHAR)
2541 && (path[1+ src] != LT_EOS_CHAR)
2542 #ifdef LT_DIRSEP_CHAR
2543 && (path[1+ src] != LT_DIRSEP_CHAR)
2545 && (path[1+ src] != '/'))
2547 canonical[dest++] = '/';
2551 /* Add an end-of-string marker at the end. */
2552 canonical[dest] = LT_EOS_CHAR;
2555 /* Assign new value. */
2556 *pcanonical = canonical;
2573 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2578 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2581 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2591 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2592 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2593 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2594 it is appended to each SEARCH_PATH element before FUNC is called. */
2597 const char *search_path,
2598 const char *base_name,
2599 foreach_callback_func *func,
2604 int filenamesize = 0;
2605 size_t lenbase = LT_STRLEN (base_name);
2606 size_t argz_len = 0;
2609 char *canonical = 0;
2613 if (!search_path || !*search_path)
2615 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2619 if (canonicalize_path (search_path, &canonical) != 0)
2622 if (argzize_path (canonical, &argz, &argz_len) != 0)
2627 while ((dir_name = argz_next (argz, argz_len, dir_name)))
2629 size_t lendir = LT_STRLEN (dir_name);
2631 if ((int)(lendir +1 +lenbase) >= filenamesize)
2633 LT_DLFREE (filename);
2634 filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2635 filename = LT_EMALLOC (char, filenamesize);
2640 assert ((int)lendir > 0);
2641 assert (filenamesize > (int)lendir);
2642 strncpy (filename, dir_name, filenamesize);
2644 if (base_name && *base_name)
2646 if (filename[lendir -1] != '/')
2647 filename[lendir++] = '/';
2649 strncpy (filename + lendir, base_name, filenamesize - lendir);
2652 if ((result = (*func) (filename, data1, data2)))
2661 LT_DLFREE (canonical);
2662 LT_DLFREE (filename);
2664 LT_DLMUTEX_UNLOCK ();
2669 /* If FILEPATH can be opened, store the name of the directory component
2670 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2671 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2673 find_file_callback (
2678 char **pdir = (char **) data1;
2679 FILE **pfile = (FILE **) data2;
2682 assert (filename && *filename);
2686 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
2688 char *dirend = const_cast<char *>(strrchr (filename, '/'));
2691 *dirend = LT_EOS_CHAR;
2694 *pdir = lt_estrdup (filename);
2695 is_done = (*pdir == 0) ? -1 : 1;
2703 const char *search_path,
2704 const char *base_name,
2709 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
2715 find_handle_callback (
2720 lt_dlhandle *handle = (lt_dlhandle *) data;
2721 int notfound = access (filename, R_OK);
2723 /* Bail out if file cannot be read... */
2727 /* Try to dlopen the file, but do not continue searching in any
2729 if (tryall_dlopen (handle, filename) != 0)
2735 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2736 found but could not be opened, *HANDLE will be set to 0. */
2737 static lt_dlhandle *
2739 const char *search_path,
2740 const char *base_name,
2741 lt_dlhandle *handle)
2746 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2758 #if LTDL_DLOPEN_DEPLIBS
2759 char *p, *save_search_path = 0;
2766 handle->depcount = 0;
2768 #if LTDL_DLOPEN_DEPLIBS
2776 if (user_search_path)
2778 save_search_path = lt_estrdup (user_search_path);
2779 if (!save_search_path)
2783 /* extract search paths and count deplibs */
2787 if (!isspace ((int) *p))
2790 while (*end && !isspace((int) *end))
2795 if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2798 *end = 0; /* set a temporary string terminator */
2799 if (lt_dladdsearchdir(p+2))
2818 /* restore the old search path */
2819 LT_DLFREE (user_search_path);
2820 user_search_path = save_search_path;
2822 LT_DLMUTEX_UNLOCK ();
2830 names = LT_EMALLOC (char *, depcount * sizeof (char*));
2834 /* now only extract the actual deplibs */
2839 if (isspace ((int) *p))
2846 while (*end && !isspace ((int) *end))
2851 if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2855 *end = 0; /* set a temporary string terminator */
2856 if (strncmp(p, "-l", 2) == 0)
2858 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2859 name = LT_EMALLOC (char, 1+ name_len);
2861 sprintf (name, "lib%s", p+2);
2864 name = lt_estrdup(p);
2869 names[depcount++] = name;
2876 /* load the deplibs (in reverse order)
2877 At this stage, don't worry if the deplibs do not load correctly,
2878 they may already be statically linked into the loading application
2879 for instance. There will be a more enlightening error message
2880 later on if the loaded module cannot resolve all of its symbols. */
2885 handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2886 if (!handle->deplibs)
2889 for (i = 0; i < depcount; ++i)
2891 handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
2892 if (handle->deplibs[j])
2898 handle->depcount = j; /* Number of successfully loaded deplibs */
2903 for (i = 0; i < depcount; ++i)
2905 LT_DLFREE (names[i]);
2922 if (handle->depcount)
2924 for (i = 0; i < handle->depcount; ++i)
2926 if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
2928 errors += lt_dlclose (handle->deplibs[i]);
2941 /* remove the leading and trailing "'" from str
2942 and store the result in dest */
2943 const char *end = strrchr (str, '\'');
2944 size_t len = LT_STRLEN (str);
2949 if (len > 3 && str[0] == '\'')
2951 tmp = LT_EMALLOC (char, end - str);
2955 strncpy(tmp, &str[1], (end - str) - 1);
2956 tmp[len-3] = LT_EOS_CHAR;
2975 LT_DLFREE (oldname);
2977 LT_DLFREE (deplibs);
2984 lt_dlhandle *phandle,
2985 const char *filename)
2987 const char * ext = 0;
2988 const char * saved_error = 0;
2989 char * canonical = 0;
2990 char * base_name = 0;
2994 lt_dlhandle newhandle;
2997 assert (*phandle == 0);
2999 LT_DLMUTEX_GETERROR (saved_error);
3004 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3008 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3009 newhandle = *phandle;
3011 /* lt_dlclose()ing yourself is very bad! Disallow it. */
3012 LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
3014 if (tryall_dlopen (&newhandle, 0) != 0)
3016 LT_DLFREE (*phandle);
3020 goto register_handle;
3023 assert (filename && *filename);
3025 /* Doing this immediately allows internal functions to safely
3026 assume only canonicalized paths are passed. */
3027 if (canonicalize_path (filename, &canonical) != 0)
3033 /* If the canonical module name is a path (relative or absolute)
3034 then split it into a directory part and a name part. */
3035 base_name = const_cast<char *>(strrchr (canonical, '/'));
3038 size_t dirlen = (1+ base_name) - canonical;
3040 dir = LT_EMALLOC (char, 1+ dirlen);
3047 strncpy (dir, canonical, dirlen);
3048 dir[dirlen] = LT_EOS_CHAR;
3054 LT_DLMEM_REASSIGN (base_name, canonical);
3055 canonical = base_name;
3058 assert (base_name && *base_name);
3060 /* Check whether we are opening a libtool module (.la extension). */
3061 ext = strrchr (base_name, '.');
3062 if (ext && strcmp (ext, archive_ext) == 0)
3064 /* this seems to be a libtool module */
3067 char * old_name = 0;
3073 /* if we can't find the installed flag, it is probably an
3074 installed libtool archive, produced with an old version
3078 /* extract the module name from the file name */
3079 name = LT_EMALLOC (char, ext - base_name + 1);
3086 /* canonicalize the module name */
3089 for (i = 0; i < ext - base_name; ++i)
3091 if (isalnum ((int)(base_name[i])))
3093 name[i] = base_name[i];
3100 name[ext - base_name] = LT_EOS_CHAR;
3103 /* Now try to open the .la file. If there is no directory name
3104 component, try to find it first in user_search_path and then other
3105 prescribed paths. Otherwise (or in any case if the module was not
3106 yet found) try opening just the module name as passed. */
3109 const char *search_path;
3112 search_path = user_search_path;
3114 file = find_file (user_search_path, base_name, &dir);
3115 LT_DLMUTEX_UNLOCK ();
3119 search_path = getenv (LTDL_SEARCHPATH_VAR);
3121 file = find_file (search_path, base_name, &dir);
3124 #ifdef LTDL_SHLIBPATH_VAR
3127 search_path = getenv (LTDL_SHLIBPATH_VAR);
3129 file = find_file (search_path, base_name, &dir);
3132 #ifdef LTDL_SYSSEARCHPATH
3135 file = find_file (sys_search_path, base_name, &dir);
3141 file = fopen (filename, LT_READTEXT_MODE);
3144 /* If we didn't find the file by now, it really isn't there. Set
3145 the status flag, and bail out. */
3148 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3153 line_len = LT_FILENAME_MAX;
3154 line = LT_EMALLOC (char, line_len);
3162 /* read the .la file */
3163 while (!feof (file))
3165 if (!fgets (line, (int) line_len, file))
3170 /* Handle the case where we occasionally need to read a line
3171 that is longer than the initial buffer size. */
3172 while (((LT_STRLEN(line) >= 1) && (line[LT_STRLEN(line) -1] != '\n')) && (!feof (file)))
3174 line = LT_DLREALLOC (char, line, line_len *2);
3175 if (!fgets (&line[line_len -1], (int) line_len +1, file))
3182 if (line[0] == '\n' || line[0] == '#')
3188 #define STR_DLNAME "dlname="
3189 if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3191 errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
3194 #undef STR_OLD_LIBRARY
3195 #define STR_OLD_LIBRARY "old_library="
3196 else if (strncmp (line, STR_OLD_LIBRARY,
3197 sizeof (STR_OLD_LIBRARY) - 1) == 0)
3199 errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3202 #define STR_LIBDIR "libdir="
3203 else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3205 errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
3208 #undef STR_DL_DEPLIBS
3209 #define STR_DL_DEPLIBS "dependency_libs="
3210 else if (strncmp (line, STR_DL_DEPLIBS,
3211 sizeof (STR_DL_DEPLIBS) - 1) == 0)
3213 errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3215 else if (strcmp (line, "installed=yes\n") == 0)
3219 else if (strcmp (line, "installed=no\n") == 0)
3224 #undef STR_LIBRARY_NAMES
3225 #define STR_LIBRARY_NAMES "library_names="
3226 else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
3227 sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3230 errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3233 && (last_libname = const_cast<char *>(strrchr (dlname, ' '))) != 0)
3235 last_libname = lt_estrdup (last_libname + 1);
3242 LT_DLMEM_REASSIGN (dlname, last_libname);
3253 /* allocate the handle */
3254 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3260 free_vars (dlname, old_name, libdir, deplibs);
3261 LT_DLFREE (*phandle);
3267 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3268 if (load_deplibs (*phandle, deplibs) == 0)
3270 newhandle = *phandle;
3271 /* find_module may replace newhandle */
3272 if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
3274 unload_deplibs (*phandle);
3283 free_vars (dlname, old_name, libdir, deplibs);
3286 LT_DLFREE (*phandle);
3290 if (*phandle != newhandle)
3292 unload_deplibs (*phandle);
3297 /* not a libtool module */
3298 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3305 memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3306 newhandle = *phandle;
3308 /* If the module has no directory name component, try to find it
3309 first in user_search_path and then other prescribed paths.
3310 Otherwise (or in any case if the module was not yet found) try
3311 opening just the module name as passed. */
3312 if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
3313 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3315 #ifdef LTDL_SHLIBPATH_VAR
3316 && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
3319 #ifdef LTDL_SYSSEARCHPATH
3320 && !find_handle (sys_search_path, base_name, &newhandle)
3324 if (tryall_dlopen (&newhandle, filename) != 0)
3332 LT_DLFREE (*phandle);
3339 LT_DLMEM_REASSIGN (*phandle, newhandle);
3341 if ((*phandle)->info.ref_count == 0)
3343 (*phandle)->info.ref_count = 1;
3344 LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
3347 (*phandle)->next = handles;
3349 LT_DLMUTEX_UNLOCK ();
3352 LT_DLMUTEX_SETERROR (saved_error);
3357 LT_DLFREE (canonical);
3364 const char *filename)
3366 lt_dlhandle handle = 0;
3368 /* Just incase we missed a code path in try_dlopen() that reports
3369 an error, but forgets to reset handle... */
3370 if (try_dlopen (&handle, filename) != 0)
3376 /* If the last error messge store was `FILE_NOT_FOUND', then return
3381 const char *error = 0;
3383 LT_DLMUTEX_GETERROR (error);
3384 if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
3390 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3391 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3392 and if a file is still not found try again with SHLIB_EXT appended
3396 const char *filename)
3398 lt_dlhandle handle = 0;
3406 return lt_dlopen (filename);
3411 len = LT_STRLEN (filename);
3412 ext = const_cast<char *>(strrchr (const_cast<char *>(filename), '.'));
3414 /* If FILENAME already bears a suitable extension, there is no need
3415 to try appending additional extensions. */
3416 if (ext && ((strcmp (ext, archive_ext) == 0)
3417 #ifdef LTDL_SHLIB_EXT
3418 || (strcmp (ext, shlib_ext) == 0)
3422 return lt_dlopen (filename);
3425 /* First try appending ARCHIVE_EXT. */
3426 tmp = LT_EMALLOC (char, len + strlen (archive_ext) + 1);
3430 strncpy (tmp, filename, len + strlen (archive_ext) + 1);
3431 strncat (tmp, archive_ext, (len + strlen (archive_ext) + 1) - strlen (tmp) - 1);
3432 tmp[len + strlen (archive_ext)] = LT_EOS_CHAR;
3433 errors = try_dlopen (&handle, tmp);
3435 /* If we found FILENAME, stop searching -- whether we were able to
3436 load the file as a module or not. If the file exists but loading
3437 failed, it is better to return an error message here than to
3438 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3439 in the module search path. */
3440 if (handle || ((errors > 0) && !file_not_found ()))
3446 #ifdef LTDL_SHLIB_EXT
3447 /* Try appending SHLIB_EXT. */
3448 if (strlen (shlib_ext) > strlen (archive_ext))
3451 tmp = LT_EMALLOC (char, len + strlen (shlib_ext) + 1);
3455 strncpy (tmp, filename, len + strlen (shlib_ext) + 1);
3459 tmp[len] = LT_EOS_CHAR;
3462 strncat(tmp, shlib_ext,(len + strlen (shlib_ext) + 1) - strlen (tmp) - 1);
3463 tmp[len + strlen (shlib_ext)] = LT_EOS_CHAR;
3464 errors = try_dlopen (&handle, tmp);
3466 /* As before, if the file was found but loading failed, return now
3467 with the current error message. */
3468 if (handle || ((errors > 0) && !file_not_found ()))
3475 /* Still here? Then we really did fail to locate any of the file
3477 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3492 if ((error = argz_insert (pargz, pargz_len, before, entry)))
3497 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3500 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3510 lt_argz_insertinorder (
3519 assert (entry && *entry);
3522 while ((before = argz_next (*pargz, *pargz_len, before)))
3524 int cmp = strcmp (entry, before);
3527 if (cmp == 0) return 0; /* No duplicates! */
3530 return lt_argz_insert (pargz, pargz_len, before, entry);
3543 size_t end_offset = 0;
3551 dir_len = LT_STRLEN (dirnam);
3552 end = dp->d_name + LT_D_NAMLEN(dp);
3554 /* Ignore version numbers. */
3557 for (p = end; p -1 > dp->d_name; --p)
3558 if (strchr (".0123456789", p[-1]) == 0)
3565 /* Ignore filename extension. */
3568 for (p = end -1; p > dp->d_name; --p)
3576 /* Prepend the directory name. */
3577 end_offset = end - dp->d_name;
3578 buf_len = dir_len + 1+ end_offset;
3579 buf = LT_EMALLOC (char, 1+ buf_len);
3585 strncpy (buf, dirnam, 1+ buf_len);
3586 strncat (buf, "/", (1+ buf_len) - strlen(buf) - 1);
3587 strncat (buf, dp->d_name, end_offset);
3588 buf[buf_len] = LT_EOS_CHAR;
3590 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3591 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3608 assert (dirnam && *dirnam);
3611 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
3613 dirp = opendir (dirnam);
3616 struct dirent *dp = 0;
3618 while ((dp = readdir (dirp)))
3619 if (dp->d_name[0] != '.')
3620 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3635 /* If there are any files in DIRNAME, call the function passed in
3636 DATA1 (with the name of each file and DATA2 as arguments). */
3638 foreachfile_callback (
3643 int (*func) LT_PARAMS((const char *filename, lt_ptr data))
3644 = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
3648 size_t argz_len = 0;
3650 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3657 while ((filename = argz_next (argz, argz_len, filename)))
3658 if ((is_done = (*func) (filename, data2)))
3669 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3670 with DATA. The filenames passed to FUNC would be suitable for
3671 passing to lt_dlopenext. The extensions are stripped so that
3672 individual modules do not generate several entries (e.g. libfoo.la,
3673 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3674 then the same directories that lt_dlopen would search are examined. */
3677 const char *search_path,
3678 int (*func) LT_PARAMS ((const char *filename, lt_ptr data)),
3685 /* If a specific path was passed, search only the directories
3687 is_done = foreach_dirinpath (search_path, 0,
3688 foreachfile_callback, (void*)func, data);
3692 /* Otherwise search the default paths. */
3693 is_done = foreach_dirinpath (user_search_path, 0,
3694 foreachfile_callback, (void*)func, data);
3697 is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3698 foreachfile_callback, (void*)func, data);
3701 #ifdef LTDL_SHLIBPATH_VAR
3704 is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
3705 foreachfile_callback, (void*)func, data);
3708 #ifdef LTDL_SYSSEARCHPATH
3711 is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
3712 foreachfile_callback, (void*)func, data);
3724 lt_dlhandle cur, last;
3729 /* check whether the handle is valid */
3730 last = cur = handles;
3731 while (cur && handle != cur)
3739 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3744 handle->info.ref_count--;
3746 /* Note that even with resident modules, we must track the ref_count
3747 correctly incase the user decides to reset the residency flag
3748 later (even though the API makes no provision for that at the
3750 if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
3752 lt_user_data data = handle->loader->dlloader_data;
3754 if (handle != handles)
3756 last->next = handle->next;
3760 handles = handle->next;
3763 errors += handle->loader->module_close (data, handle->module);
3764 errors += unload_deplibs(handle);
3766 /* It is up to the callers to free the data itself. */
3767 LT_DLFREE (handle->caller_data);
3769 LT_DLFREE (handle->info.filename);
3770 LT_DLFREE (handle->info.name);
3776 if (LT_DLIS_RESIDENT (handle))
3778 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3783 LT_DLMUTEX_UNLOCK ();
3794 char lsym[LT_SYMBOL_LENGTH];
3801 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3807 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3811 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3812 + LT_STRLEN (handle->info.name);
3814 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3817 lensym = LT_SYMBOL_LENGTH;
3821 sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3822 lensym = lensym + LT_SYMBOL_OVERHEAD + 1;
3825 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3830 data = handle->loader->dlloader_data;
3831 if (handle->info.name)
3833 const char *saved_error;
3835 LT_DLMUTEX_GETERROR (saved_error);
3837 /* this is a libtool module */
3838 if (handle->loader->sym_prefix)
3840 strncpy(sym, handle->loader->sym_prefix, lensym - 1);
3841 strncat(sym, handle->info.name, lensym - strlen(sym) - 1);
3845 strncpy(sym, handle->info.name, lensym - 1);
3848 strncat(sym, "_LTX_", lensym - strlen(sym) - 1);
3849 strncat(sym, symbol, lensym - strlen(sym) - 1);
3851 /* try "modulename_LTX_symbol" */
3852 address = handle->loader->find_sym (data, handle->module, sym);
3861 LT_DLMUTEX_SETERROR (saved_error);
3864 /* otherwise try "symbol" */
3865 if (handle->loader->sym_prefix)
3867 strncpy(sym, handle->loader->sym_prefix, lensym - 1);
3868 strncat(sym, symbol, lensym - strlen(sym) - 1);
3872 strncpy(sym, symbol, lensym - 1);
3875 address = handle->loader->find_sym (data, handle->module, sym);
3889 LT_DLMUTEX_GETERROR (error);
3890 LT_DLMUTEX_SETERROR (0);
3892 return error ? error : NULL;
3896 lt_dlpath_insertdir (
3902 char *canonical = 0;
3904 size_t argz_len = 0;
3907 assert (dir && *dir);
3909 if (canonicalize_path (dir, &canonical) != 0)
3915 assert (canonical && *canonical);
3917 /* If *PPATH is empty, set it to DIR. */
3920 assert (!before); /* BEFORE cannot be set without PPATH. */
3921 assert (dir); /* Without DIR, don't call this function! */
3923 *ppath = lt_estrdup (dir);
3930 assert (ppath && *ppath);
3932 if (argzize_path (*ppath, &argz, &argz_len) != 0)
3938 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
3939 if *PPATH is already canonicalized, and hence does not change length
3940 with respect to ARGZ. We canonicalize each entry as it is added to
3941 the search path, and don't call this function with (uncanonicalized)
3942 user paths, so this is a fair assumption. */
3945 assert (*ppath <= before);
3946 assert (before - *ppath <= (int)strlen (*ppath));
3948 before = before - *ppath + argz;
3951 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
3957 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
3958 LT_DLMEM_REASSIGN (*ppath, argz);
3961 LT_DLFREE (canonical);
3969 const char *search_dir)
3973 if (search_dir && *search_dir)
3976 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
3978 LT_DLMUTEX_UNLOCK ();
3985 lt_dlinsertsearchdir (
3987 const char *search_dir)
3994 if ((before < user_search_path)
3995 || (before >= user_search_path + LT_STRLEN (user_search_path)))
3997 LT_DLMUTEX_UNLOCK ();
3998 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
4001 LT_DLMUTEX_UNLOCK ();
4004 if (search_dir && *search_dir)
4007 if (lt_dlpath_insertdir (&user_search_path,
4008 const_cast<char*>(before), search_dir) != 0)
4012 LT_DLMUTEX_UNLOCK ();
4019 lt_dlsetsearchpath (
4020 const char *search_path)
4025 LT_DLFREE (user_search_path);
4026 LT_DLMUTEX_UNLOCK ();
4028 if (!search_path || !LT_STRLEN (search_path))
4034 if (canonicalize_path (search_path, &user_search_path) != 0)
4036 LT_DLMUTEX_UNLOCK ();
4042 lt_dlgetsearchpath ()
4044 const char *saved_path;
4047 saved_path = user_search_path;
4048 LT_DLMUTEX_UNLOCK ();
4061 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4066 LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4078 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4082 return LT_DLIS_RESIDENT (handle);
4088 /* --- MODULE INFORMATION --- */
4096 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4100 return &(handle->info);
4107 return place ? place->next : handles;
4112 int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data)),
4123 lt_dlhandle tmp = cur;
4126 if ((*func) (tmp, data))
4133 LT_DLMUTEX_UNLOCK ();
4139 lt_dlcaller_register ()
4141 static lt_dlcaller_id last_caller_id = 0;
4145 result = ++last_caller_id;
4146 LT_DLMUTEX_UNLOCK ();
4152 lt_dlcaller_set_data (
4158 lt_ptr stale = (lt_ptr) 0;
4161 /* This needs to be locked so that the caller data can be updated
4162 simultaneously by different threads. */
4165 if (handle->caller_data)
4166 while (handle->caller_data[n_elements].key)
4169 for (i = 0; i < n_elements; ++i)
4171 if (handle->caller_data[i].key == key)
4173 stale = handle->caller_data[i].data;
4178 /* Ensure that there is enough room in this handle's caller_data
4179 array to accept a new element (and an empty end marker). */
4180 if (i == n_elements)
4182 lt_caller_data *temp
4183 = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
4191 handle->caller_data = temp;
4193 /* We only need this if we needed to allocate a new caller_data. */
4194 handle->caller_data[i].key = key;
4195 handle->caller_data[1+ i].key = 0;
4198 handle->caller_data[i].data = data;
4201 LT_DLMUTEX_UNLOCK ();
4207 lt_dlcaller_get_data (
4211 lt_ptr result = (lt_ptr) 0;
4213 /* This needs to be locked so that the caller data isn't updated by
4214 another thread part way through this function. */
4217 /* Locate the index of the element with a matching KEY. */
4220 for (i = 0; handle->caller_data[i].key; ++i)
4222 if (handle->caller_data[i].key == key)
4224 result = handle->caller_data[i].data;
4230 LT_DLMUTEX_UNLOCK ();
4237 /* --- USER MODULE LOADER API --- */
4243 const struct lt_user_dlloader *dlloader,
4244 const char *loader_name)
4247 lt_dlloader *node = 0, *ptr = 0;
4249 if ((dlloader == 0) /* diagnose null parameters */
4250 || (dlloader->module_open == 0)
4251 || (dlloader->module_close == 0)
4252 || (dlloader->find_sym == 0))
4254 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4258 /* Create a new dlloader node with copies of the user callbacks. */
4259 node = LT_EMALLOC (lt_dlloader, 1);
4264 node->loader_name = loader_name;
4265 node->sym_prefix = dlloader->sym_prefix;
4266 node->dlloader_exit = dlloader->dlloader_exit;
4267 node->module_open = dlloader->module_open;
4268 node->module_close = dlloader->module_close;
4269 node->find_sym = dlloader->find_sym;
4270 node->dlloader_data = dlloader->dlloader_data;
4275 /* If there are no loaders, NODE becomes the list! */
4280 /* If PLACE is not set, add NODE to the end of the
4282 for (ptr = loaders; ptr->next; ptr = ptr->next)
4289 else if (loaders == place)
4291 /* If PLACE is the first loader, NODE goes first. */
4297 /* Find the node immediately preceding PLACE. */
4298 for (ptr = loaders; ptr->next != place; ptr = ptr->next)
4303 if (ptr->next != place)
4305 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4310 /* Insert NODE between PTR and PLACE. */
4316 LT_DLMUTEX_UNLOCK ();
4322 lt_dlloader_remove (
4323 const char *loader_name)
4325 lt_dlloader *place = lt_dlloader_find (loader_name);
4331 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4337 /* Fail if there are any open modules which use this loader. */
4338 for (handle = handles; handle; handle = handle->next)
4340 if (handle->loader == place)
4342 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
4348 if (place == loaders)
4350 /* PLACE is the first loader in the list. */
4351 loaders = loaders->next;
4355 /* Find the loader before the one being removed. */
4357 for (prev = loaders; prev->next; prev = prev->next)
4359 if (!strcmp (prev->next->loader_name, loader_name))
4366 if (prev->next) prev->next = prev->next->next;
4369 if (place && place->dlloader_exit)
4371 errors = place->dlloader_exit (place->dlloader_data);
4377 LT_DLMUTEX_UNLOCK ();
4389 next = place ? place->next : loaders;
4390 LT_DLMUTEX_UNLOCK ();
4399 const char *name = 0;
4404 name = place->loader_name;
4405 LT_DLMUTEX_UNLOCK ();
4409 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4419 lt_user_data *data = 0;
4424 data = &(place->dlloader_data);
4425 LT_DLMUTEX_UNLOCK ();
4429 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4437 const char *loader_name)
4439 lt_dlloader *place = 0;
4442 for (place = loaders; place; place = place->next)
4444 if (strcmp (place->loader_name, loader_name) == 0)
4449 LT_DLMUTEX_UNLOCK ();