1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
3 Originally by Thomas Tanner <tanner@ffii.org>
4 This file is part of GNU Libtool.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 As a special exception to the GNU Lesser General Public License,
12 if you distribute this file as part of a program or library that
13 is built using GNU libtool, you may include it under the same
14 distribution terms that you use for the rest of that program.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 #include "llvm/Config/config.h"
43 /* Include the header defining malloc. On K&R C compilers,
44 that's <malloc.h>, on ANSI C and ISO C compilers, that's <stdlib.h>. */
81 #undef LT_USE_POSIX_DIRENT
86 # define LT_USE_POSIX_DIRENT
87 # endif /* HAVE_DIRENT_H */
88 # endif /* HAVE_READDIR */
89 # endif /* HAVE_OPENDIR */
90 #endif /* HAVE_CLOSEDIR */
93 #undef LT_USE_WINDOWS_DIRENT_EMULATION
94 #ifndef LT_USE_POSIX_DIRENT
96 # define LT_USE_WINDOWS_DIRENT_EMULATION
97 # endif /* __WINDOWS__ */
98 #endif /* LT_USE_POSIX_DIRENT */
101 #ifdef LT_USE_POSIX_DIRENT
103 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
105 # ifdef LT_USE_WINDOWS_DIRENT_EMULATION
106 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
108 # define dirent direct
109 # define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
111 # include <sys/ndir.h>
114 # include <sys/dir.h>
129 # define assert(arg) ((void) 0)
135 # include <dmalloc.h>
141 /* --- WINDOWS SUPPORT --- */
145 # define LT_GLOBAL_DATA __declspec(dllexport)
147 # define LT_GLOBAL_DATA
150 /* fopen() mode flags for reading a text file */
151 #undef LT_READTEXT_MODE
153 # define LT_READTEXT_MODE "rt"
155 # define LT_READTEXT_MODE "r"
158 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
162 #define dirent lt_dirent
174 WIN32_FIND_DATA Win32FindData;
176 struct dirent file_info;
179 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
182 /* --- MANIFEST CONSTANTS --- */
185 /* Standard libltdl search path environment variable name */
186 #undef LTDL_SEARCHPATH_VAR
187 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
189 /* Standard libtool archive file extension. */
190 #undef LTDL_ARCHIVE_EXT
191 #define LTDL_ARCHIVE_EXT ".la"
193 /* max. filename length */
194 #ifndef LT_FILENAME_MAX
195 # define LT_FILENAME_MAX 1024
198 /* This is the maximum symbol size that won't require malloc/free */
199 #undef LT_SYMBOL_LENGTH
200 #define LT_SYMBOL_LENGTH 128
202 /* This accounts for the _LTX_ separator */
203 #undef LT_SYMBOL_OVERHEAD
204 #define LT_SYMBOL_OVERHEAD 5
209 /* --- MEMORY HANDLING --- */
212 /* These are the functions used internally. In addition to making
213 use of the associated function pointers above, they also perform
215 static char *lt_estrdup LT_PARAMS((const char *str));
216 static lt_ptr lt_emalloc LT_PARAMS((size_t size));
217 static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size));
219 /* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */
220 #define rpl_realloc realloc
222 /* These are the pointers that can be changed by the caller: */
223 LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
224 = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
225 LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size))
226 = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
227 LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
228 = (void (*) LT_PARAMS((lt_ptr))) free;
230 /* The following macros reduce the amount of typing needed to cast
234 #define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
235 #define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
236 #define LT_DLFREE(p) \
237 LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
239 #define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
240 #define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
244 #define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
245 #define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((p), (n) * sizeof(tp)))
246 #define LT_DLFREE(p) \
247 LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
249 #define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
250 #define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
254 #define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
255 if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \
259 /* --- REPLACEMENT FUNCTIONS --- */
263 #define strdup rpl_strdup
265 static char *strdup LT_PARAMS((const char *str));
275 tmp = LT_DLMALLOC (char, 1+ strlen (str));
289 #define strcmp rpl_strcmp
291 static int strcmp LT_PARAMS((const char *str1, const char *str2));
305 for (;*str1 && *str2; ++str1, ++str2)
311 return (int)(*str1 - *str2);
319 # define strchr index
321 # define strchr rpl_strchr
323 static const char *strchr LT_PARAMS((const char *str, int ch));
332 for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
335 return (*p == (char)ch) ? p : 0;
339 #endif /* !HAVE_STRCHR */
345 # define strrchr rindex
347 # define strrchr rpl_strrchr
349 static const char *strrchr LT_PARAMS((const char *str, int ch));
356 const char *p, *q = 0;
358 for (p = str; *p != LT_EOS_CHAR; ++p)
372 /* NOTE: Neither bcopy nor the memcpy implementation below can
373 reliably handle copying in overlapping areas of memory. Use
374 memmove (for which there is a fallback implmentation below)
375 if you need that behaviour. */
379 # define memcpy(dest, src, size) bcopy (src, dest, size)
381 # define memcpy rpl_memcpy
383 static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
386 memcpy (dest, src, size)
391 const char * s = src;
395 for (i = 0; i < size; ++i)
403 # endif /* !HAVE_BCOPY */
404 #endif /* !HAVE_MEMCPY */
407 # define memmove rpl_memmove
409 static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
412 memmove (dest, src, size)
417 const char * s = src;
422 for (i = 0; i < size; ++i)
426 else if (d > s && size > 0)
427 for (i = size -1; ; --i)
437 #endif /* !HAVE_MEMMOVE */
439 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
441 static void closedir LT_PARAMS((DIR *entry));
447 assert(entry != (DIR *) NULL);
448 FindClose(entry->hSearch);
449 lt_dlfree((lt_ptr)entry);
453 static DIR * opendir LT_PARAMS((const char *path));
459 char file_specification[LT_FILENAME_MAX];
462 assert(path != (char *) NULL);
463 (void) strncpy(file_specification,path,LT_FILENAME_MAX-1);
464 (void) strcat(file_specification,"\\");
465 entry = LT_DLMALLOC (DIR,sizeof(DIR));
466 if (entry != (DIR *) 0)
468 entry->firsttime = TRUE;
469 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
471 if (entry->hSearch == INVALID_HANDLE_VALUE)
473 (void) strcat(file_specification,"\\*.*");
474 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
475 if (entry->hSearch == INVALID_HANDLE_VALUE)
485 static struct dirent *readdir LT_PARAMS((DIR *entry));
487 static struct dirent *readdir(entry)
493 if (entry == (DIR *) 0)
494 return((struct dirent *) 0);
495 if (!entry->firsttime)
497 status = FindNextFile(entry->hSearch,&entry->Win32FindData);
499 return((struct dirent *) 0);
501 entry->firsttime = FALSE;
502 (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
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 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 (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 --- */
1168 #if HAVE_SHL_LOAD && !defined(__llvm__)
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);
1353 char wpath[MAX_PATH];
1354 cygwin_conv_to_full_win32_path(searchname, wpath);
1355 module = LoadLibrary(wpath);
1358 module = LoadLibrary (searchname);
1360 LT_DLFREE (searchname);
1362 /* libltdl expects this function to fail if it is unable
1363 to physically load the library. Sadly, LoadLibrary
1364 will search the loaded libraries for a match and return
1365 one of them if the path search load fails.
1367 We check whether LoadLibrary is returning a handle to
1368 an already loaded module, and simulate failure if we
1380 if (cur->module == module)
1387 LT_DLMUTEX_UNLOCK ();
1391 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1399 sys_wll_close (loader_data, module)
1400 lt_user_data loader_data;
1405 if (FreeLibrary(module) == 0)
1407 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1415 sys_wll_sym (loader_data, module, symbol)
1416 lt_user_data loader_data;
1420 lt_ptr address = GetProcAddress (module, symbol);
1424 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1430 static struct lt_user_dlloader sys_wll = {
1431 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1434 #endif /* __WINDOWS__ */
1439 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1444 /* dynamic linking for BeOS */
1446 #include <kernel/image.h>
1449 sys_bedl_open (loader_data, filename)
1450 lt_user_data loader_data;
1451 const char *filename;
1457 image = load_add_on (filename);
1463 if (get_next_image_info (0, &cookie, &info) == B_OK)
1464 image = load_add_on (info.name);
1469 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1473 return (lt_module) image;
1477 sys_bedl_close (loader_data, module)
1478 lt_user_data loader_data;
1483 if (unload_add_on ((image_id) module) != B_OK)
1485 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1493 sys_bedl_sym (loader_data, module, symbol)
1494 lt_user_data loader_data;
1499 image_id image = (image_id) module;
1501 if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1503 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1510 static struct lt_user_dlloader sys_bedl = {
1511 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1514 #endif /* __BEOS__ */
1519 /* --- DLD_LINK() INTERFACE LOADER --- */
1524 /* dynamic linking with dld */
1531 sys_dld_open (loader_data, filename)
1532 lt_user_data loader_data;
1533 const char *filename;
1535 lt_module module = strdup (filename);
1537 if (dld_link (filename) != 0)
1539 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1548 sys_dld_close (loader_data, module)
1549 lt_user_data loader_data;
1554 if (dld_unlink_by_file ((char*)(module), 1) != 0)
1556 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1568 sys_dld_sym (loader_data, module, symbol)
1569 lt_user_data loader_data;
1573 lt_ptr address = dld_get_func (symbol);
1577 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1583 static struct lt_user_dlloader sys_dld = {
1584 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1587 #endif /* HAVE_DLD */
1589 /* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
1593 #if HAVE_MACH_O_DYLD_H
1594 #if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
1595 /* Is this correct? Does it still function properly? */
1596 #define __private_extern__ extern
1598 # include <mach-o/dyld.h>
1600 #include <mach-o/getsect.h>
1602 /* We have to put some stuff here that isn't in older dyld.h files */
1603 #ifndef ENUM_DYLD_BOOL
1604 # define ENUM_DYLD_BOOL
1613 # define LC_REQ_DYLD 0x80000000
1615 #ifndef LC_LOAD_WEAK_DYLIB
1616 # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
1618 static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0;
1619 static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0;
1620 static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0;
1621 static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0;
1623 #ifndef NSADDIMAGE_OPTION_NONE
1624 #define NSADDIMAGE_OPTION_NONE 0x0
1626 #ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
1627 #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
1629 #ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
1630 #define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
1632 #ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1633 #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
1635 #ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
1636 #define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
1638 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
1639 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
1641 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1642 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
1644 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
1645 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
1647 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1648 #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
1653 lt_int_dyld_error(othererror)
1656 /* return the dyld error string, or the passed in error string if none */
1657 NSLinkEditErrors ler;
1661 NSLinkEditError(&ler,&lerno,&file,&errstr);
1662 if (!errstr || !strlen(errstr)) errstr = othererror;
1666 static const struct mach_header *
1667 lt_int_dyld_get_mach_header_from_nsmodule(module)
1670 /* There should probably be an apple dyld api for this */
1671 int i=_dyld_image_count();
1673 const char *modname=NSNameOfModule(module);
1674 const struct mach_header *mh=NULL;
1675 if (!modname) return NULL;
1676 for (j = 0; j < i; j++)
1678 if (!strcmp(_dyld_get_image_name(j),modname))
1680 mh=_dyld_get_image_header(j);
1687 static const char* lt_int_dyld_lib_install_name(mh)
1688 const struct mach_header *mh;
1690 /* NSAddImage is also used to get the loaded image, but it only works if the lib
1691 is installed, for uninstalled libs we need to check the install_names against
1692 each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
1693 different lib was loaded as a result
1696 struct load_command *lc;
1697 unsigned long offset = sizeof(struct mach_header);
1698 const char* retStr=NULL;
1699 for (j = 0; j < mh->ncmds; j++)
1701 lc = (struct load_command*)(((unsigned long)mh) + offset);
1702 if (LC_ID_DYLIB == lc->cmd)
1704 retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset +
1707 offset += lc->cmdsize;
1712 static const struct mach_header *
1713 lt_int_dyld_match_loaded_lib_by_install_name(const char *name)
1715 int i=_dyld_image_count();
1717 const struct mach_header *mh=NULL;
1718 const char *id=NULL;
1719 for (j = 0; j < i; j++)
1721 id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j));
1722 if ((id) && (!strcmp(id,name)))
1724 mh=_dyld_get_image_header(j);
1732 lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh)
1734 const struct mach_header *mh;
1736 /* Safe to assume our mh is good */
1738 struct load_command *lc;
1739 unsigned long offset = sizeof(struct mach_header);
1740 NSSymbol retSym = 0;
1741 const struct mach_header *mh1;
1742 if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) )
1744 for (j = 0; j < mh->ncmds; j++)
1746 lc = (struct load_command*)(((unsigned long)mh) + offset);
1747 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
1749 mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1750 (unsigned long)lc));
1753 /* Maybe NSAddImage can find it */
1754 mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1756 NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +
1757 NSADDIMAGE_OPTION_WITH_SEARCHING +
1758 NSADDIMAGE_OPTION_RETURN_ON_ERROR );
1762 retSym = ltdl_NSLookupSymbolInImage(mh1,
1764 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1765 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1770 offset += lc->cmdsize;
1781 if (!_dyld_present()) {
1785 err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage);
1786 err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage);
1787 err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage);
1788 err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic);
1794 sys_dyld_open (loader_data, filename)
1795 lt_user_data loader_data;
1796 const char *filename;
1798 lt_module module = 0;
1799 NSObjectFileImage ofi = 0;
1800 NSObjectFileImageReturnCode ofirc;
1803 return (lt_module)-1;
1804 ofirc = NSCreateObjectFileImageFromFile(filename, &ofi);
1807 case NSObjectFileImageSuccess:
1808 module = NSLinkModule(ofi, filename,
1809 NSLINKMODULE_OPTION_RETURN_ON_ERROR
1810 | NSLINKMODULE_OPTION_PRIVATE
1811 | NSLINKMODULE_OPTION_BINDNOW);
1812 NSDestroyObjectFileImage(ofi);
1814 ltdl_NSMakePrivateModulePublic(module);
1816 case NSObjectFileImageInappropriateFile:
1817 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1819 module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
1823 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1826 if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1831 sys_dyld_close (loader_data, module)
1832 lt_user_data loader_data;
1837 if (module == (lt_module)-1) return 0;
1838 #ifdef __BIG_ENDIAN__
1839 if (((struct mach_header *)module)->magic == MH_MAGIC)
1841 if (((struct mach_header *)module)->magic == MH_CIGAM)
1844 LT_DLMUTEX_SETERROR("Can not close a dylib");
1850 /* Currently, if a module contains c++ static destructors and it is unloaded, we
1851 get a segfault in atexit(), due to compiler and dynamic loader differences of
1852 opinion, this works around that.
1854 if ((const struct section *)NULL !=
1855 getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module),
1856 "__DATA","__mod_term_func"))
1858 flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
1862 flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
1864 if (!NSUnLinkModule(module,flags))
1867 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE)));
1875 sys_dyld_sym (loader_data, module, symbol)
1876 lt_user_data loader_data;
1881 NSSymbol *nssym = 0;
1883 const struct mach_header *mh=NULL;
1884 char saveError[256] = "Symbol not found";
1885 if (module == (lt_module)-1)
1887 _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused);
1890 #ifdef __BIG_ENDIAN__
1891 if (((struct mach_header *)module)->magic == MH_MAGIC)
1893 if (((struct mach_header *)module)->magic == MH_CIGAM)
1896 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1899 if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol))
1901 nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module,
1903 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1904 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1911 nssym = NSLookupSymbolInModule(module, symbol);
1915 strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255);
1917 if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module);
1918 nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh);
1922 LT_DLMUTEX_SETERROR (saveError);
1925 return NSAddressOfSymbol(nssym);
1928 static struct lt_user_dlloader sys_dyld =
1929 { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
1932 #endif /* HAVE_DYLD */
1935 /* --- DLPREOPEN() INTERFACE LOADER --- */
1938 /* emulate dynamic linking using preloaded_symbols */
1940 typedef struct lt_dlsymlists_t
1942 struct lt_dlsymlists_t *next;
1943 const lt_dlsymlist *syms;
1946 static const lt_dlsymlist *default_preloaded_symbols = 0;
1947 static lt_dlsymlists_t *preloaded_symbols = 0;
1950 presym_init (loader_data)
1951 lt_user_data loader_data;
1957 preloaded_symbols = 0;
1958 if (default_preloaded_symbols)
1960 errors = lt_dlpreload (default_preloaded_symbols);
1963 LT_DLMUTEX_UNLOCK ();
1969 presym_free_symlists ()
1971 lt_dlsymlists_t *lists;
1975 lists = preloaded_symbols;
1978 lt_dlsymlists_t *tmp = lists;
1980 lists = lists->next;
1983 preloaded_symbols = 0;
1985 LT_DLMUTEX_UNLOCK ();
1991 presym_exit (loader_data)
1992 lt_user_data loader_data;
1994 presym_free_symlists ();
1999 presym_add_symlist (preloaded)
2000 const lt_dlsymlist *preloaded;
2002 lt_dlsymlists_t *tmp;
2003 lt_dlsymlists_t *lists;
2008 lists = preloaded_symbols;
2011 if (lists->syms == preloaded)
2015 lists = lists->next;
2018 tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
2021 memset (tmp, 0, sizeof(lt_dlsymlists_t));
2022 tmp->syms = preloaded;
2023 tmp->next = preloaded_symbols;
2024 preloaded_symbols = tmp;
2032 LT_DLMUTEX_UNLOCK ();
2037 presym_open (loader_data, filename)
2038 lt_user_data loader_data;
2039 const char *filename;
2041 lt_dlsymlists_t *lists;
2042 lt_module module = (lt_module) 0;
2045 lists = preloaded_symbols;
2049 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
2053 /* Can't use NULL as the reflective symbol header, as NULL is
2054 used to mark the end of the entire symbol list. Self-dlpreopened
2055 symbols follow this magic number, chosen to be an unlikely
2056 clash with a real module name. */
2059 filename = "@PROGRAM@";
2064 const lt_dlsymlist *syms = lists->syms;
2068 if (!syms->address && strcmp(syms->name, filename) == 0)
2070 module = (lt_module) syms;
2076 lists = lists->next;
2079 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2082 LT_DLMUTEX_UNLOCK ();
2087 presym_close (loader_data, module)
2088 lt_user_data loader_data;
2091 /* Just to silence gcc -Wall */
2097 presym_sym (loader_data, module, symbol)
2098 lt_user_data loader_data;
2102 lt_dlsymlist *syms = (lt_dlsymlist*) module;
2105 while (syms->address)
2107 if (strcmp(syms->name, symbol) == 0)
2109 return syms->address;
2115 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
2120 static struct lt_user_dlloader presym = {
2121 0, presym_open, presym_close, presym_sym, presym_exit, 0
2128 /* --- DYNAMIC MODULE LOADING --- */
2131 /* The type of a function used at each iteration of foreach_dirinpath(). */
2132 typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
2135 static int foreach_dirinpath LT_PARAMS((const char *search_path,
2136 const char *base_name,
2137 foreach_callback_func *func,
2138 lt_ptr data1, lt_ptr data2));
2140 static int find_file_callback LT_PARAMS((char *filename, lt_ptr data,
2142 static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data,
2144 static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1,
2148 static int canonicalize_path LT_PARAMS((const char *path,
2149 char **pcanonical));
2150 static int argzize_path LT_PARAMS((const char *path,
2152 size_t *pargz_len));
2153 static FILE *find_file LT_PARAMS((const char *search_path,
2154 const char *base_name,
2156 static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
2157 const char *base_name,
2158 lt_dlhandle *handle));
2159 static int find_module LT_PARAMS((lt_dlhandle *handle,
2163 const char *old_name,
2165 static int free_vars LT_PARAMS((char *dlname, char *oldname,
2166 char *libdir, char *deplibs));
2167 static int load_deplibs LT_PARAMS((lt_dlhandle handle,
2169 static int trim LT_PARAMS((char **dest,
2171 static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
2172 const char *filename));
2173 static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
2174 const char *filename));
2175 static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
2176 static int lt_argz_insert LT_PARAMS((char **pargz,
2179 const char *entry));
2180 static int lt_argz_insertinorder LT_PARAMS((char **pargz,
2182 const char *entry));
2183 static int lt_argz_insertdir LT_PARAMS((char **pargz,
2186 struct dirent *dp));
2187 static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
2190 static int list_files_by_dir LT_PARAMS((const char *dirnam,
2192 size_t *pargz_len));
2193 static int file_not_found LT_PARAMS((void));
2195 static char *user_search_path= 0;
2196 static lt_dlloader *loaders = 0;
2197 static lt_dlhandle handles = 0;
2198 static int initialized = 0;
2200 /* Initialize libltdl. */
2208 /* Initialize only at first call. */
2209 if (++initialized == 1)
2212 user_search_path = 0; /* empty search path */
2215 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
2217 #if HAVE_SHL_LOAD && !defined(__llvm__)
2218 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
2221 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
2224 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
2227 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
2230 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld");
2231 errors += sys_dyld_init();
2233 errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
2235 if (presym_init (presym.dlloader_data))
2237 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
2240 else if (errors != 0)
2242 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
2247 LT_DLMUTEX_UNLOCK ();
2253 lt_dlpreload (preloaded)
2254 const lt_dlsymlist *preloaded;
2260 errors = presym_add_symlist (preloaded);
2264 presym_free_symlists();
2267 if (default_preloaded_symbols)
2269 errors = lt_dlpreload (default_preloaded_symbols);
2271 LT_DLMUTEX_UNLOCK ();
2278 lt_dlpreload_default (preloaded)
2279 const lt_dlsymlist *preloaded;
2282 default_preloaded_symbols = preloaded;
2283 LT_DLMUTEX_UNLOCK ();
2290 /* shut down libltdl */
2291 lt_dlloader *loader;
2299 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
2304 /* shut down only at last call. */
2305 if (--initialized == 0)
2309 while (handles && LT_DLIS_RESIDENT (handles))
2311 handles = handles->next;
2314 /* close all modules */
2315 for (level = 1; handles; ++level)
2317 lt_dlhandle cur = handles;
2318 int saw_nonresident = 0;
2322 lt_dlhandle tmp = cur;
2324 if (!LT_DLIS_RESIDENT (tmp))
2325 saw_nonresident = 1;
2326 if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
2328 if (lt_dlclose (tmp))
2334 /* done if only resident modules are left */
2335 if (!saw_nonresident)
2339 /* close all loaders */
2342 lt_dlloader *next = loader->next;
2343 lt_user_data data = loader->dlloader_data;
2344 if (loader->dlloader_exit && loader->dlloader_exit (data))
2349 LT_DLMEM_REASSIGN (loader, next);
2355 LT_DLMUTEX_UNLOCK ();
2360 tryall_dlopen (handle, filename)
2361 lt_dlhandle *handle;
2362 const char *filename;
2365 lt_dlloader *loader;
2366 const char *saved_error;
2369 LT_DLMUTEX_GETERROR (saved_error);
2375 /* check whether the module was already opened */
2378 /* try to dlopen the program itself? */
2379 if (!cur->info.filename && !filename)
2384 if (cur->info.filename && filename
2385 && strcmp (cur->info.filename, filename) == 0)
2395 ++cur->info.ref_count;
2403 /* Comment out the check of file permissions using access.
2404 This call seems to always return -1 with error EACCES.
2406 /* We need to catch missing file errors early so that
2407 file_not_found() can detect what happened.
2408 if (access (filename, R_OK) != 0)
2410 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2415 cur->info.filename = lt_estrdup (filename);
2416 if (!cur->info.filename)
2424 cur->info.filename = 0;
2429 lt_user_data data = loader->dlloader_data;
2431 cur->module = loader->module_open (data, filename);
2433 if (cur->module != 0)
2437 loader = loader->next;
2442 LT_DLFREE (cur->info.filename);
2447 cur->loader = loader;
2448 LT_DLMUTEX_SETERROR (saved_error);
2451 LT_DLMUTEX_UNLOCK ();
2457 tryall_dlopen_module (handle, prefix, dirname, dlname)
2458 lt_dlhandle *handle;
2460 const char *dirname;
2465 size_t filename_len = 0;
2466 size_t dirname_len = LT_STRLEN (dirname);
2471 #ifdef LT_DIRSEP_CHAR
2472 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2473 should make it into this function: */
2474 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
2477 if (dirname_len > 0)
2478 if (dirname[dirname_len -1] == '/')
2480 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
2482 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2483 The PREFIX (if any) is handled below. */
2484 filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
2488 sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
2490 /* Now that we have combined DIRNAME and MODULENAME, if there is
2491 also a PREFIX to contend with, simply recurse with the arguments
2492 shuffled. Otherwise, attempt to open FILENAME as a module. */
2495 error += tryall_dlopen_module (handle,
2496 (const char *) 0, prefix, filename);
2498 else if (tryall_dlopen (handle, filename) != 0)
2503 LT_DLFREE (filename);
2508 find_module (handle, dir, libdir, dlname, old_name, installed)
2509 lt_dlhandle *handle;
2513 const char *old_name;
2516 /* Try to open the old library first; if it was dlpreopened,
2517 we want the preopened version of it, even if a dlopenable
2518 module is available. */
2519 if (old_name && tryall_dlopen (handle, old_name) == 0)
2524 /* Try to open the dynamic library. */
2527 /* try to open the installed module */
2528 if (installed && libdir)
2530 if (tryall_dlopen_module (handle,
2531 (const char *) 0, libdir, dlname) == 0)
2535 /* try to open the not-installed module */
2538 if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2542 /* maybe it was moved to another directory */
2544 if (tryall_dlopen_module (handle,
2545 (const char *) 0, dir, dlname) == 0)
2555 canonicalize_path (path, pcanonical)
2559 char *canonical = 0;
2561 assert (path && *path);
2562 assert (pcanonical);
2564 canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2571 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2573 /* Path separators are not copied to the beginning or end of
2574 the destination, or if another separator would follow
2576 if (path[src] == LT_PATHSEP_CHAR)
2579 || (path[1+ src] == LT_PATHSEP_CHAR)
2580 || (path[1+ src] == LT_EOS_CHAR))
2584 /* Anything other than a directory separator is copied verbatim. */
2585 if ((path[src] != '/')
2586 #ifdef LT_DIRSEP_CHAR
2587 && (path[src] != LT_DIRSEP_CHAR)
2591 canonical[dest++] = path[src];
2593 /* Directory separators are converted and copied only if they are
2594 not at the end of a path -- i.e. before a path separator or
2596 else if ((path[1+ src] != LT_PATHSEP_CHAR)
2597 && (path[1+ src] != LT_EOS_CHAR)
2598 #ifdef LT_DIRSEP_CHAR
2599 && (path[1+ src] != LT_DIRSEP_CHAR)
2601 && (path[1+ src] != '/'))
2603 canonical[dest++] = '/';
2607 /* Add an end-of-string marker at the end. */
2608 canonical[dest] = LT_EOS_CHAR;
2611 /* Assign new value. */
2612 *pcanonical = canonical;
2618 argzize_path (path, pargz, pargz_len)
2629 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2634 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2637 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2647 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2648 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2649 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2650 it is appended to each SEARCH_PATH element before FUNC is called. */
2652 foreach_dirinpath (search_path, base_name, func, data1, data2)
2653 const char *search_path;
2654 const char *base_name;
2655 foreach_callback_func *func;
2660 int filenamesize = 0;
2661 size_t lenbase = LT_STRLEN (base_name);
2662 size_t argz_len = 0;
2665 char *canonical = 0;
2669 if (!search_path || !*search_path)
2671 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2675 if (canonicalize_path (search_path, &canonical) != 0)
2678 if (argzize_path (canonical, &argz, &argz_len) != 0)
2683 while ((dir_name = argz_next (argz, argz_len, dir_name)))
2685 size_t lendir = LT_STRLEN (dir_name);
2687 if (lendir +1 +lenbase >= (size_t)filenamesize)
2689 LT_DLFREE (filename);
2690 filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2691 filename = LT_EMALLOC (char, filenamesize);
2696 assert ((size_t)filenamesize > lendir);
2697 strcpy (filename, dir_name);
2699 if (base_name && *base_name)
2701 if (filename[lendir -1] != '/')
2702 filename[lendir++] = '/';
2703 strcpy (filename +lendir, base_name);
2706 if ((result = (*func) (filename, data1, data2)))
2715 LT_DLFREE (canonical);
2716 LT_DLFREE (filename);
2718 LT_DLMUTEX_UNLOCK ();
2723 /* If FILEPATH can be opened, store the name of the directory component
2724 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2725 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2727 find_file_callback (filename, data1, data2)
2732 char **pdir = (char **) data1;
2733 FILE **pfile = (FILE **) data2;
2736 assert (filename && *filename);
2740 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
2742 char *dirend = strrchr (filename, '/');
2744 if (dirend > filename)
2745 *dirend = LT_EOS_CHAR;
2748 *pdir = lt_estrdup (filename);
2749 is_done = (*pdir == 0) ? -1 : 1;
2756 find_file (search_path, base_name, pdir)
2757 const char *search_path;
2758 const char *base_name;
2763 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
2769 find_handle_callback (filename, data, ignored)
2774 lt_dlhandle *handle = (lt_dlhandle *) data;
2775 int notfound = access (filename, R_OK);
2777 /* Bail out if file cannot be read... */
2781 /* Try to dlopen the file, but do not continue searching in any
2783 if (tryall_dlopen (handle, filename) != 0)
2789 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2790 found but could not be opened, *HANDLE will be set to 0. */
2791 static lt_dlhandle *
2792 find_handle (search_path, base_name, handle)
2793 const char *search_path;
2794 const char *base_name;
2795 lt_dlhandle *handle;
2800 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2808 load_deplibs (handle, deplibs)
2812 #if LTDL_DLOPEN_DEPLIBS
2813 char *p, *save_search_path = 0;
2820 handle->depcount = 0;
2822 #if LTDL_DLOPEN_DEPLIBS
2830 if (user_search_path)
2832 save_search_path = lt_estrdup (user_search_path);
2833 if (!save_search_path)
2837 /* extract search paths and count deplibs */
2841 if (!isspace ((int) *p))
2844 while (*end && !isspace((int) *end))
2849 if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2852 *end = 0; /* set a temporary string terminator */
2853 if (lt_dladdsearchdir(p+2))
2872 /* restore the old search path */
2873 LT_DLFREE (user_search_path);
2874 user_search_path = save_search_path;
2876 LT_DLMUTEX_UNLOCK ();
2884 names = LT_EMALLOC (char *, depcount * sizeof (char*));
2888 /* now only extract the actual deplibs */
2893 if (isspace ((int) *p))
2900 while (*end && !isspace ((int) *end))
2905 if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2909 *end = 0; /* set a temporary string terminator */
2910 if (strncmp(p, "-l", 2) == 0)
2912 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2913 name = LT_EMALLOC (char, 1+ name_len);
2915 sprintf (name, "lib%s", p+2);
2918 name = lt_estrdup(p);
2923 names[depcount++] = name;
2930 /* load the deplibs (in reverse order)
2931 At this stage, don't worry if the deplibs do not load correctly,
2932 they may already be statically linked into the loading application
2933 for instance. There will be a more enlightening error message
2934 later on if the loaded module cannot resolve all of its symbols. */
2939 handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2940 if (!handle->deplibs)
2943 for (i = 0; i < depcount; ++i)
2945 handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
2946 if (handle->deplibs[j])
2952 handle->depcount = j; /* Number of successfully loaded deplibs */
2957 for (i = 0; i < depcount; ++i)
2959 LT_DLFREE (names[i]);
2970 unload_deplibs (handle)
2976 if (handle->depcount)
2978 for (i = 0; i < handle->depcount; ++i)
2980 if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
2982 errors += lt_dlclose (handle->deplibs[i]);
2995 /* remove the leading and trailing "'" from str
2996 and store the result in dest */
2997 const char *end = strrchr (str, '\'');
2998 size_t len = LT_STRLEN (str);
3003 if (len > 3 && str[0] == '\'')
3005 tmp = LT_EMALLOC (char, end - str);
3009 strncpy(tmp, &str[1], (end - str) - 1);
3010 tmp[len-3] = LT_EOS_CHAR;
3022 free_vars (dlname, oldname, libdir, deplibs)
3029 LT_DLFREE (oldname);
3031 LT_DLFREE (deplibs);
3037 try_dlopen (phandle, filename)
3038 lt_dlhandle *phandle;
3039 const char *filename;
3041 const char * ext = 0;
3042 const char * saved_error = 0;
3043 char * canonical = 0;
3044 char * base_name = 0;
3048 lt_dlhandle newhandle;
3051 assert (*phandle == 0);
3053 LT_DLMUTEX_GETERROR (saved_error);
3058 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3062 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3063 newhandle = *phandle;
3065 /* lt_dlclose()ing yourself is very bad! Disallow it. */
3066 LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
3068 if (tryall_dlopen (&newhandle, 0) != 0)
3070 LT_DLFREE (*phandle);
3074 goto register_handle;
3077 assert (filename && *filename);
3079 /* Doing this immediately allows internal functions to safely
3080 assume only canonicalized paths are passed. */
3081 if (canonicalize_path (filename, &canonical) != 0)
3087 /* If the canonical module name is a path (relative or absolute)
3088 then split it into a directory part and a name part. */
3089 base_name = strrchr (canonical, '/');
3092 size_t dirlen = (1+ base_name) - canonical;
3094 dir = LT_EMALLOC (char, 1+ dirlen);
3101 strncpy (dir, canonical, dirlen);
3102 dir[dirlen] = LT_EOS_CHAR;
3107 LT_DLMEM_REASSIGN (base_name, canonical);
3109 assert (base_name && *base_name);
3111 /* Check whether we are opening a libtool module (.la extension). */
3112 ext = strrchr (base_name, '.');
3113 if (ext && strcmp (ext, archive_ext) == 0)
3115 /* this seems to be a libtool module */
3118 char * old_name = 0;
3124 /* if we can't find the installed flag, it is probably an
3125 installed libtool archive, produced with an old version
3129 /* extract the module name from the file name */
3130 name = LT_EMALLOC (char, ext - base_name + 1);
3137 /* canonicalize the module name */
3140 for (i = 0; i < (size_t)(ext - base_name); ++i)
3142 if (isalnum ((int)(base_name[i])))
3144 name[i] = base_name[i];
3151 name[ext - base_name] = LT_EOS_CHAR;
3154 /* Now try to open the .la file. If there is no directory name
3155 component, try to find it first in user_search_path and then other
3156 prescribed paths. Otherwise (or in any case if the module was not
3157 yet found) try opening just the module name as passed. */
3160 const char *search_path;
3163 search_path = user_search_path;
3165 file = find_file (user_search_path, base_name, &dir);
3166 LT_DLMUTEX_UNLOCK ();
3170 search_path = getenv (LTDL_SEARCHPATH_VAR);
3172 file = find_file (search_path, base_name, &dir);
3175 #ifdef LTDL_SHLIBPATH_VAR
3178 search_path = getenv (LTDL_SHLIBPATH_VAR);
3180 file = find_file (search_path, base_name, &dir);
3183 #ifdef LTDL_SYSSEARCHPATH
3184 if (!file && sys_search_path)
3186 file = find_file (sys_search_path, base_name, &dir);
3192 file = fopen (filename, LT_READTEXT_MODE);
3195 /* If we didn't find the file by now, it really isn't there. Set
3196 the status flag, and bail out. */
3199 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3204 line_len = LT_FILENAME_MAX;
3205 line = LT_EMALLOC (char, line_len);
3213 /* read the .la file */
3214 while (!feof (file))
3216 if (!fgets (line, (int) line_len, file))
3221 /* Handle the case where we occasionally need to read a line
3222 that is longer than the initial buffer size. */
3223 while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file)))
3225 line = LT_DLREALLOC (char, line, line_len *2);
3226 if (!fgets (&line[line_len -1], (int) line_len +1, file))
3233 if (line[0] == '\n' || line[0] == '#')
3239 #define STR_DLNAME "dlname="
3240 if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3242 errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
3245 #undef STR_OLD_LIBRARY
3246 #define STR_OLD_LIBRARY "old_library="
3247 else if (strncmp (line, STR_OLD_LIBRARY,
3248 sizeof (STR_OLD_LIBRARY) - 1) == 0)
3250 errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3253 #define STR_LIBDIR "libdir="
3254 else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3256 errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
3259 #undef STR_DL_DEPLIBS
3260 #define STR_DL_DEPLIBS "dependency_libs="
3261 else if (strncmp (line, STR_DL_DEPLIBS,
3262 sizeof (STR_DL_DEPLIBS) - 1) == 0)
3264 errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3266 else if (strcmp (line, "installed=yes\n") == 0)
3270 else if (strcmp (line, "installed=no\n") == 0)
3275 #undef STR_LIBRARY_NAMES
3276 #define STR_LIBRARY_NAMES "library_names="
3277 else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
3278 sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3281 errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3284 && (last_libname = strrchr (dlname, ' ')) != 0)
3286 last_libname = lt_estrdup (last_libname + 1);
3292 LT_DLMEM_REASSIGN (dlname, last_libname);
3303 /* allocate the handle */
3304 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3310 free_vars (dlname, old_name, libdir, deplibs);
3311 LT_DLFREE (*phandle);
3317 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3318 if (load_deplibs (*phandle, deplibs) == 0)
3320 newhandle = *phandle;
3321 /* find_module may replace newhandle */
3322 if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
3324 unload_deplibs (*phandle);
3333 free_vars (dlname, old_name, libdir, deplibs);
3336 LT_DLFREE (*phandle);
3340 if (*phandle != newhandle)
3342 unload_deplibs (*phandle);
3347 /* not a libtool module */
3348 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3355 memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3356 newhandle = *phandle;
3358 /* If the module has no directory name component, try to find it
3359 first in user_search_path and then other prescribed paths.
3360 Otherwise (or in any case if the module was not yet found) try
3361 opening just the module name as passed. */
3362 if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
3363 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3365 #ifdef LTDL_SHLIBPATH_VAR
3366 && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
3369 #ifdef LTDL_SYSSEARCHPATH
3370 && !find_handle (sys_search_path, base_name, &newhandle)
3374 if (tryall_dlopen (&newhandle, filename) != 0)
3382 LT_DLFREE (*phandle);
3389 LT_DLMEM_REASSIGN (*phandle, newhandle);
3391 if ((*phandle)->info.ref_count == 0)
3393 (*phandle)->info.ref_count = 1;
3394 LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
3397 (*phandle)->next = handles;
3399 LT_DLMUTEX_UNLOCK ();
3402 LT_DLMUTEX_SETERROR (saved_error);
3407 LT_DLFREE (canonical);
3413 lt_dlopen (filename)
3414 const char *filename;
3416 lt_dlhandle handle = 0;
3418 /* Just incase we missed a code path in try_dlopen() that reports
3419 an error, but forgets to reset handle... */
3420 if (try_dlopen (&handle, filename) != 0)
3426 /* If the last error messge store was `FILE_NOT_FOUND', then return
3431 const char *error = 0;
3433 LT_DLMUTEX_GETERROR (error);
3434 if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
3440 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3441 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3442 and if a file is still not found try again with SHLIB_EXT appended
3445 lt_dlopenext (filename)
3446 const char *filename;
3448 lt_dlhandle handle = 0;
3456 return lt_dlopen (filename);
3461 len = LT_STRLEN (filename);
3462 ext = strrchr (filename, '.');
3464 /* If FILENAME already bears a suitable extension, there is no need
3465 to try appending additional extensions. */
3466 if (ext && ((strcmp (ext, archive_ext) == 0)
3467 #ifdef LTDL_SHLIB_EXT
3468 || (strcmp (ext, shlib_ext) == 0)
3472 return lt_dlopen (filename);
3475 /* First try appending ARCHIVE_EXT. */
3476 tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
3480 strcpy (tmp, filename);
3481 strcat (tmp, archive_ext);
3482 errors = try_dlopen (&handle, tmp);
3484 /* If we found FILENAME, stop searching -- whether we were able to
3485 load the file as a module or not. If the file exists but loading
3486 failed, it is better to return an error message here than to
3487 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3488 in the module search path. */
3489 if (handle || ((errors > 0) && !file_not_found ()))
3495 #ifdef LTDL_SHLIB_EXT
3496 /* Try appending SHLIB_EXT. */
3497 if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
3500 tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
3504 strcpy (tmp, filename);
3508 tmp[len] = LT_EOS_CHAR;
3511 strcat(tmp, shlib_ext);
3512 errors = try_dlopen (&handle, tmp);
3514 /* As before, if the file was found but loading failed, return now
3515 with the current error message. */
3516 if (handle || ((errors > 0) && !file_not_found ()))
3523 /* Still here? Then we really did fail to locate any of the file
3525 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3532 lt_argz_insert (pargz, pargz_len, before, entry)
3540 if ((error = argz_insert (pargz, pargz_len, before, entry)))
3545 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3548 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3558 lt_argz_insertinorder (pargz, pargz_len, entry)
3567 assert (entry && *entry);
3570 while ((before = argz_next (*pargz, *pargz_len, before)))
3572 int cmp = strcmp (entry, before);
3575 if (cmp == 0) return 0; /* No duplicates! */
3578 return lt_argz_insert (pargz, pargz_len, before, entry);
3582 lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
3591 size_t end_offset = 0;
3599 dir_len = LT_STRLEN (dirnam);
3600 end = dp->d_name + LT_D_NAMLEN(dp);
3602 /* Ignore version numbers. */
3605 for (p = end; p -1 > dp->d_name; --p)
3606 if (strchr (".0123456789", p[-1]) == 0)
3613 /* Ignore filename extension. */
3616 for (p = end -1; p > dp->d_name; --p)
3624 /* Prepend the directory name. */
3625 end_offset = end - dp->d_name;
3626 buf_len = dir_len + 1+ end_offset;
3627 buf = LT_EMALLOC (char, 1+ buf_len);
3633 strcpy (buf, dirnam);
3635 strncat (buf, dp->d_name, end_offset);
3636 buf[buf_len] = LT_EOS_CHAR;
3638 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3639 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3648 list_files_by_dir (dirnam, pargz, pargz_len)
3656 assert (dirnam && *dirnam);
3659 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
3661 dirp = opendir (dirnam);
3664 struct dirent *dp = 0;
3666 while ((dp = readdir (dirp)))
3667 if (dp->d_name[0] != '.')
3668 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3683 /* If there are any files in DIRNAME, call the function passed in
3684 DATA1 (with the name of each file and DATA2 as arguments). */
3686 foreachfile_callback (dirname, data1, data2)
3691 int (*func) LT_PARAMS((const char *filename, lt_ptr data))
3692 = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
3696 size_t argz_len = 0;
3698 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3705 while ((filename = argz_next (argz, argz_len, filename)))
3706 if ((is_done = (*func) (filename, data2)))
3717 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3718 with DATA. The filenames passed to FUNC would be suitable for
3719 passing to lt_dlopenext. The extensions are stripped so that
3720 individual modules do not generate several entries (e.g. libfoo.la,
3721 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3722 then the same directories that lt_dlopen would search are examined. */
3724 lt_dlforeachfile (search_path, func, data)
3725 const char *search_path;
3726 int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
3733 /* If a specific path was passed, search only the directories
3735 is_done = foreach_dirinpath (search_path, 0,
3736 foreachfile_callback, func, data);
3740 /* Otherwise search the default paths. */
3741 is_done = foreach_dirinpath (user_search_path, 0,
3742 foreachfile_callback, func, data);
3745 is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3746 foreachfile_callback, func, data);
3749 #ifdef LTDL_SHLIBPATH_VAR
3752 is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
3753 foreachfile_callback, func, data);
3756 #ifdef LTDL_SYSSEARCHPATH
3759 is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
3760 foreachfile_callback, func, data);
3772 lt_dlhandle cur, last;
3777 /* check whether the handle is valid */
3778 last = cur = handles;
3779 while (cur && handle != cur)
3787 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3792 handle->info.ref_count--;
3794 /* Note that even with resident modules, we must track the ref_count
3795 correctly incase the user decides to reset the residency flag
3796 later (even though the API makes no provision for that at the
3798 if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
3800 lt_user_data data = handle->loader->dlloader_data;
3802 if (handle != handles)
3804 last->next = handle->next;
3808 handles = handle->next;
3811 errors += handle->loader->module_close (data, handle->module);
3812 errors += unload_deplibs(handle);
3814 /* It is up to the callers to free the data itself. */
3815 LT_DLFREE (handle->caller_data);
3817 LT_DLFREE (handle->info.filename);
3818 LT_DLFREE (handle->info.name);
3824 if (LT_DLIS_RESIDENT (handle))
3826 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3831 LT_DLMUTEX_UNLOCK ();
3837 lt_dlsym (handle, symbol)
3842 char lsym[LT_SYMBOL_LENGTH];
3849 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3855 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3859 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3860 + LT_STRLEN (handle->info.name);
3862 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3868 sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3871 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3876 data = handle->loader->dlloader_data;
3877 if (handle->info.name)
3879 const char *saved_error;
3881 LT_DLMUTEX_GETERROR (saved_error);
3883 /* this is a libtool module */
3884 if (handle->loader->sym_prefix)
3886 strcpy(sym, handle->loader->sym_prefix);
3887 strcat(sym, handle->info.name);
3891 strcpy(sym, handle->info.name);
3894 strcat(sym, "_LTX_");
3895 strcat(sym, symbol);
3897 /* try "modulename_LTX_symbol" */
3898 address = handle->loader->find_sym (data, handle->module, sym);
3907 LT_DLMUTEX_SETERROR (saved_error);
3910 /* otherwise try "symbol" */
3911 if (handle->loader->sym_prefix)
3913 strcpy(sym, handle->loader->sym_prefix);
3914 strcat(sym, symbol);
3918 strcpy(sym, symbol);
3921 address = handle->loader->find_sym (data, handle->module, sym);
3935 LT_DLMUTEX_GETERROR (error);
3936 LT_DLMUTEX_SETERROR (0);
3938 return error ? error : NULL;
3942 lt_dlpath_insertdir (ppath, before, dir)
3948 char *canonical = 0;
3950 size_t argz_len = 0;
3953 assert (dir && *dir);
3955 if (canonicalize_path (dir, &canonical) != 0)
3961 assert (canonical && *canonical);
3963 /* If *PPATH is empty, set it to DIR. */
3966 assert (!before); /* BEFORE cannot be set without PPATH. */
3967 assert (dir); /* Without DIR, don't call this function! */
3969 *ppath = lt_estrdup (dir);
3976 assert (ppath && *ppath);
3978 if (argzize_path (*ppath, &argz, &argz_len) != 0)
3984 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
3985 if *PPATH is already canonicalized, and hence does not change length
3986 with respect to ARGZ. We canonicalize each entry as it is added to
3987 the search path, and don't call this function with (uncanonicalized)
3988 user paths, so this is a fair assumption. */
3991 assert (*ppath <= before);
3992 assert (before - *ppath <= (int)strlen (*ppath));
3994 before = before - *ppath + argz;
3997 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
4003 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
4004 LT_DLMEM_REASSIGN (*ppath, argz);
4007 LT_DLFREE (canonical);
4014 lt_dladdsearchdir (search_dir)
4015 const char *search_dir;
4019 if (search_dir && *search_dir)
4022 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
4024 LT_DLMUTEX_UNLOCK ();
4031 lt_dlinsertsearchdir (before, search_dir)
4033 const char *search_dir;
4040 if ((before < user_search_path)
4041 || (before >= user_search_path + LT_STRLEN (user_search_path)))
4043 LT_DLMUTEX_UNLOCK ();
4044 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
4047 LT_DLMUTEX_UNLOCK ();
4050 if (search_dir && *search_dir)
4053 if (lt_dlpath_insertdir (&user_search_path,
4054 (char *) before, search_dir) != 0)
4058 LT_DLMUTEX_UNLOCK ();
4065 lt_dlsetsearchpath (search_path)
4066 const char *search_path;
4071 LT_DLFREE (user_search_path);
4072 LT_DLMUTEX_UNLOCK ();
4074 if (!search_path || !LT_STRLEN (search_path))
4080 if (canonicalize_path (search_path, &user_search_path) != 0)
4082 LT_DLMUTEX_UNLOCK ();
4088 lt_dlgetsearchpath ()
4090 const char *saved_path;
4093 saved_path = user_search_path;
4094 LT_DLMUTEX_UNLOCK ();
4100 lt_dlmakeresident (handle)
4107 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4112 LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4119 lt_dlisresident (handle)
4124 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4128 return LT_DLIS_RESIDENT (handle);
4134 /* --- MODULE INFORMATION --- */
4137 lt_dlgetinfo (handle)
4142 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4146 return &(handle->info);
4150 lt_dlhandle_next (place)
4153 return place ? place->next : handles;
4157 lt_dlforeach (func, data)
4158 int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
4169 lt_dlhandle tmp = cur;
4172 if ((*func) (tmp, data))
4179 LT_DLMUTEX_UNLOCK ();
4185 lt_dlcaller_register ()
4187 static lt_dlcaller_id last_caller_id = 0;
4191 result = ++last_caller_id;
4192 LT_DLMUTEX_UNLOCK ();
4198 lt_dlcaller_set_data (key, handle, data)
4204 lt_ptr stale = (lt_ptr) 0;
4207 /* This needs to be locked so that the caller data can be updated
4208 simultaneously by different threads. */
4211 if (handle->caller_data)
4212 while (handle->caller_data[n_elements].key)
4215 for (i = 0; i < n_elements; ++i)
4217 if (handle->caller_data[i].key == key)
4219 stale = handle->caller_data[i].data;
4224 /* Ensure that there is enough room in this handle's caller_data
4225 array to accept a new element (and an empty end marker). */
4226 if (i == n_elements)
4228 lt_caller_data *temp
4229 = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
4237 handle->caller_data = temp;
4239 /* We only need this if we needed to allocate a new caller_data. */
4240 handle->caller_data[i].key = key;
4241 handle->caller_data[1+ i].key = 0;
4244 handle->caller_data[i].data = data;
4247 LT_DLMUTEX_UNLOCK ();
4253 lt_dlcaller_get_data (key, handle)
4257 lt_ptr result = (lt_ptr) 0;
4259 /* This needs to be locked so that the caller data isn't updated by
4260 another thread part way through this function. */
4263 /* Locate the index of the element with a matching KEY. */
4266 for (i = 0; handle->caller_data[i].key; ++i)
4268 if (handle->caller_data[i].key == key)
4270 result = handle->caller_data[i].data;
4276 LT_DLMUTEX_UNLOCK ();
4283 /* --- USER MODULE LOADER API --- */
4287 lt_dlloader_add (place, dlloader, loader_name)
4289 const struct lt_user_dlloader *dlloader;
4290 const char *loader_name;
4293 lt_dlloader *node = 0, *ptr = 0;
4295 if ((dlloader == 0) /* diagnose null parameters */
4296 || (dlloader->module_open == 0)
4297 || (dlloader->module_close == 0)
4298 || (dlloader->find_sym == 0))
4300 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4304 /* Create a new dlloader node with copies of the user callbacks. */
4305 node = LT_EMALLOC (lt_dlloader, 1);
4310 node->loader_name = loader_name;
4311 node->sym_prefix = dlloader->sym_prefix;
4312 node->dlloader_exit = dlloader->dlloader_exit;
4313 node->module_open = dlloader->module_open;
4314 node->module_close = dlloader->module_close;
4315 node->find_sym = dlloader->find_sym;
4316 node->dlloader_data = dlloader->dlloader_data;
4321 /* If there are no loaders, NODE becomes the list! */
4326 /* If PLACE is not set, add NODE to the end of the
4328 for (ptr = loaders; ptr->next; ptr = ptr->next)
4335 else if (loaders == place)
4337 /* If PLACE is the first loader, NODE goes first. */
4343 /* Find the node immediately preceding PLACE. */
4344 for (ptr = loaders; ptr->next != place; ptr = ptr->next)
4349 if (ptr->next != place)
4351 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4356 /* Insert NODE between PTR and PLACE. */
4362 LT_DLMUTEX_UNLOCK ();
4368 lt_dlloader_remove (loader_name)
4369 const char *loader_name;
4371 lt_dlloader *place = lt_dlloader_find (loader_name);
4377 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4383 /* Fail if there are any open modules which use this loader. */
4384 for (handle = handles; handle; handle = handle->next)
4386 if (handle->loader == place)
4388 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
4394 if (place == loaders)
4396 /* PLACE is the first loader in the list. */
4397 loaders = loaders->next;
4401 /* Find the loader before the one being removed. */
4403 for (prev = loaders; prev->next; prev = prev->next)
4405 if (!strcmp (prev->next->loader_name, loader_name))
4412 prev->next = prev->next->next;
4415 if (place->dlloader_exit)
4417 errors = place->dlloader_exit (place->dlloader_data);
4423 LT_DLMUTEX_UNLOCK ();
4429 lt_dlloader_next (place)
4435 next = place ? place->next : loaders;
4436 LT_DLMUTEX_UNLOCK ();
4442 lt_dlloader_name (place)
4445 const char *name = 0;
4450 name = place ? place->loader_name : 0;
4451 LT_DLMUTEX_UNLOCK ();
4455 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4462 lt_dlloader_data (place)
4465 lt_user_data *data = 0;
4470 data = place ? &(place->dlloader_data) : 0;
4471 LT_DLMUTEX_UNLOCK ();
4475 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4482 lt_dlloader_find (loader_name)
4483 const char *loader_name;
4485 lt_dlloader *place = 0;
4488 for (place = loaders; place; place = place->next)
4490 if (strcmp (place->loader_name, loader_name) == 0)
4495 LT_DLMUTEX_UNLOCK ();