1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
3 Originally by Thomas Tanner <tanner@ffii.org>
4 This file is part of GNU Libtool.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 As a special exception to the GNU Lesser General Public License,
12 if you distribute this file as part of a program or library that
13 is built using GNU libtool, you may include it under the same
14 distribution terms that you use for the rest of that program.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
40 /* Include the header defining malloc. On K&R C compilers,
41 that's <malloc.h>, on ANSI C and ISO C compilers, that's <stdlib.h>. */
78 #undef LT_USE_POSIX_DIRENT
83 # define LT_USE_POSIX_DIRENT
84 # endif /* HAVE_DIRENT_H */
85 # endif /* HAVE_READDIR */
86 # endif /* HAVE_OPENDIR */
87 #endif /* HAVE_CLOSEDIR */
90 #undef LT_USE_WINDOWS_DIRENT_EMULATION
91 #ifndef LT_USE_POSIX_DIRENT
93 # define LT_USE_WINDOWS_DIRENT_EMULATION
94 # endif /* __WINDOWS__ */
95 #endif /* LT_USE_POSIX_DIRENT */
98 #ifdef LT_USE_POSIX_DIRENT
100 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
102 # ifdef LT_USE_WINDOWS_DIRENT_EMULATION
103 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
105 # define dirent direct
106 # define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
108 # include <sys/ndir.h>
111 # include <sys/dir.h>
126 # define assert(arg) ((void) 0)
132 # include <dmalloc.h>
138 /* --- WINDOWS SUPPORT --- */
140 /* DLL building support on win32 hosts; mostly to workaround their
141 ridiculous implementation of data symbol exporting. */
142 #ifndef LT_GLOBAL_DATA
143 # if defined(__WINDOWS__) || defined(__CYGWIN__)
144 # ifdef DLL_EXPORT /* defined by libtool (if required) */
145 # define LT_GLOBAL_DATA __declspec(dllexport)
148 # ifndef LT_GLOBAL_DATA /* static linking or !__WINDOWS__ */
149 # define LT_GLOBAL_DATA
153 /* fopen() mode flags for reading a text file */
154 #undef LT_READTEXT_MODE
155 #if defined(__WINDOWS__) || defined(__CYGWIN__)
156 # define LT_READTEXT_MODE "rt"
158 # define LT_READTEXT_MODE "r"
161 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
165 #define dirent lt_dirent
177 WIN32_FIND_DATA Win32FindData
;
179 struct dirent file_info
;
182 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
185 /* --- MANIFEST CONSTANTS --- */
188 /* Standard libltdl search path environment variable name */
189 #undef LTDL_SEARCHPATH_VAR
190 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
192 /* Standard libtool archive file extension. */
193 #undef LTDL_ARCHIVE_EXT
194 #define LTDL_ARCHIVE_EXT ".la"
196 /* max. filename length */
197 #ifndef LT_FILENAME_MAX
198 # define LT_FILENAME_MAX 1024
201 /* This is the maximum symbol size that won't require malloc/free */
202 #undef LT_SYMBOL_LENGTH
203 #define LT_SYMBOL_LENGTH 128
205 /* This accounts for the _LTX_ separator */
206 #undef LT_SYMBOL_OVERHEAD
207 #define LT_SYMBOL_OVERHEAD 5
212 /* --- MEMORY HANDLING --- */
215 /* These are the functions used internally. In addition to making
216 use of the associated function pointers above, they also perform
218 static char *lt_estrdup
LT_PARAMS((const char *str
));
219 static lt_ptr lt_emalloc
LT_PARAMS((size_t size
));
220 static lt_ptr lt_erealloc
LT_PARAMS((lt_ptr addr
, size_t size
));
222 /* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */
223 #define rpl_realloc realloc
225 /* These are the pointers that can be changed by the caller: */
226 LT_GLOBAL_DATA
lt_ptr (*lt_dlmalloc
) LT_PARAMS((size_t size
))
227 = (lt_ptr (*) LT_PARAMS((size_t))) malloc
;
228 LT_GLOBAL_DATA
lt_ptr (*lt_dlrealloc
) LT_PARAMS((lt_ptr ptr
, size_t size
))
229 = (lt_ptr (*) LT_PARAMS((lt_ptr
, size_t))) rpl_realloc
;
230 LT_GLOBAL_DATA
void (*lt_dlfree
) LT_PARAMS((lt_ptr ptr
))
231 = (void (*) LT_PARAMS((lt_ptr
))) free
;
233 /* The following macros reduce the amount of typing needed to cast
237 #define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
238 #define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
239 #define LT_DLFREE(p) \
240 LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
242 #define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
243 #define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
247 #define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
248 #define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((p), (n) * sizeof(tp)))
249 #define LT_DLFREE(p) \
250 LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
252 #define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
253 #define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
257 #define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
258 if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \
262 /* --- REPLACEMENT FUNCTIONS --- */
266 #define strdup rpl_strdup
268 static char *strdup
LT_PARAMS((const char *str
));
278 tmp
= LT_DLMALLOC (char, 1+ strlen (str
));
292 #define strcmp rpl_strcmp
294 static int strcmp
LT_PARAMS((const char *str1
, const char *str2
));
308 for (;*str1
&& *str2
; ++str1
, ++str2
)
314 return (int)(*str1
- *str2
);
322 # define strchr index
324 # define strchr rpl_strchr
326 static const char *strchr
LT_PARAMS((const char *str
, int ch
));
335 for (p
= str
; *p
!= (char)ch
&& *p
!= LT_EOS_CHAR
; ++p
)
338 return (*p
== (char)ch
) ? p
: 0;
342 #endif /* !HAVE_STRCHR */
348 # define strrchr rindex
350 # define strrchr rpl_strrchr
352 static const char *strrchr
LT_PARAMS((const char *str
, int ch
));
359 const char *p
, *q
= 0;
361 for (p
= str
; *p
!= LT_EOS_CHAR
; ++p
)
375 /* NOTE: Neither bcopy nor the memcpy implementation below can
376 reliably handle copying in overlapping areas of memory. Use
377 memmove (for which there is a fallback implmentation below)
378 if you need that behaviour. */
382 # define memcpy(dest, src, size) bcopy (src, dest, size)
384 # define memcpy rpl_memcpy
386 static lt_ptr memcpy
LT_PARAMS((lt_ptr dest
, const lt_ptr src
, size_t size
));
389 memcpy (dest
, src
, size
)
394 const char * s
= src
;
398 for (i
= 0; i
< size
; ++i
)
406 # endif /* !HAVE_BCOPY */
407 #endif /* !HAVE_MEMCPY */
410 # define memmove rpl_memmove
412 static lt_ptr memmove
LT_PARAMS((lt_ptr dest
, const lt_ptr src
, size_t size
));
415 memmove (dest
, src
, size
)
420 const char * s
= src
;
425 for (i
= 0; i
< size
; ++i
)
429 else if (d
> s
&& size
> 0)
430 for (i
= size
-1; ; --i
)
440 #endif /* !HAVE_MEMMOVE */
442 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
444 static void closedir
LT_PARAMS((DIR *entry
));
450 assert(entry
!= (DIR *) NULL
);
451 FindClose(entry
->hSearch
);
452 lt_dlfree((lt_ptr
)entry
);
456 static DIR * opendir
LT_PARAMS((const char *path
));
462 char file_specification
[LT_FILENAME_MAX
];
465 assert(path
!= (char *) NULL
);
466 /* allow space for: path + '\\' '\\' '*' '.' '*' + '\0' */
467 (void) strncpy (file_specification
, path
, LT_FILENAME_MAX
-6);
468 file_specification
[LT_FILENAME_MAX
-6] = LT_EOS_CHAR
;
469 (void) strcat(file_specification
,"\\");
470 entry
= LT_DLMALLOC (DIR,sizeof(DIR));
471 if (entry
!= (DIR *) 0)
473 entry
->firsttime
= TRUE
;
474 entry
->hSearch
= FindFirstFile(file_specification
,&entry
->Win32FindData
);
476 if (entry
->hSearch
== INVALID_HANDLE_VALUE
)
478 (void) strcat(file_specification
,"\\*.*");
479 entry
->hSearch
= FindFirstFile(file_specification
,&entry
->Win32FindData
);
480 if (entry
->hSearch
== INVALID_HANDLE_VALUE
)
490 static struct dirent
*readdir
LT_PARAMS((DIR *entry
));
492 static struct dirent
*readdir(entry
)
498 if (entry
== (DIR *) 0)
499 return((struct dirent
*) 0);
500 if (!entry
->firsttime
)
502 status
= FindNextFile(entry
->hSearch
,&entry
->Win32FindData
);
504 return((struct dirent
*) 0);
506 entry
->firsttime
= FALSE
;
507 (void) strncpy(entry
->file_info
.d_name
,entry
->Win32FindData
.cFileName
,
509 entry
->file_info
.d_name
[LT_FILENAME_MAX
- 1] = LT_EOS_CHAR
;
510 entry
->file_info
.d_namlen
= strlen(entry
->file_info
.d_name
);
511 return(&entry
->file_info
);
514 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
516 /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
517 ``realloc is not entirely portable''
518 In any case we want to use the allocator supplied by the user without
519 burdening them with an lt_dlrealloc function pointer to maintain.
520 Instead implement our own version (with known boundary conditions)
521 using lt_dlmalloc and lt_dlfree. */
524 #define realloc rpl_realloc
527 /* You can't (re)define realloc unless you also (re)define malloc.
528 Right now, this code uses the size of the *destination* to decide
529 how much to copy. That's not right, but you can't know the size
530 of the source unless you know enough about, or wrote malloc. So
531 this code is disabled... */
540 /* For zero or less bytes, free the original memory */
550 /* Allow reallocation of a NULL pointer. */
551 return lt_dlmalloc (size
);
555 /* Allocate a new block, copy and free the old block. */
556 lt_ptr mem
= lt_dlmalloc (size
);
560 memcpy (mem
, ptr
, size
);
564 /* Note that the contents of PTR are not damaged if there is
565 insufficient memory to realloc. */
572 #if ! HAVE_ARGZ_APPEND
573 # define argz_append rpl_argz_append
575 static error_t argz_append
LT_PARAMS((char **pargz
, size_t *pargz_len
,
576 const char *buf
, size_t buf_len
));
579 argz_append (pargz
, pargz_len
, buf
, buf_len
)
590 assert ((*pargz
&& *pargz_len
) || (!*pargz
&& !*pargz_len
));
592 /* If nothing needs to be appended, no more work is required. */
596 /* Ensure there is enough room to append BUF_LEN. */
597 argz_len
= *pargz_len
+ buf_len
;
598 argz
= LT_DLREALLOC (char, *pargz
, argz_len
);
602 /* Copy characters from BUF after terminating '\0' in ARGZ. */
603 memcpy (argz
+ *pargz_len
, buf
, buf_len
);
605 /* Assign new values. */
607 *pargz_len
= argz_len
;
611 #endif /* !HAVE_ARGZ_APPEND */
614 #if ! HAVE_ARGZ_CREATE_SEP
615 # define argz_create_sep rpl_argz_create_sep
617 static error_t argz_create_sep
LT_PARAMS((const char *str
, int delim
,
618 char **pargz
, size_t *pargz_len
));
621 argz_create_sep (str
, delim
, pargz
, pargz_len
)
634 /* Make a copy of STR, but replacing each occurrence of
636 argz_len
= 1+ LT_STRLEN (str
);
642 argz
= LT_DLMALLOC (char, argz_len
);
646 for (p
= str
, q
= argz
; *p
!= LT_EOS_CHAR
; ++p
)
650 /* Ignore leading delimiters, and fold consecutive
651 delimiters in STR into a single '\0' in ARGZ. */
652 if ((q
> argz
) && (q
[-1] != LT_EOS_CHAR
))
660 /* Copy terminating LT_EOS_CHAR. */
664 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
668 /* Assign new values. */
670 *pargz_len
= argz_len
;
674 #endif /* !HAVE_ARGZ_CREATE_SEP */
677 #if ! HAVE_ARGZ_INSERT
678 # define argz_insert rpl_argz_insert
680 static error_t argz_insert
LT_PARAMS((char **pargz
, size_t *pargz_len
,
681 char *before
, const char *entry
));
684 argz_insert (pargz
, pargz_len
, before
, entry
)
692 assert (entry
&& *entry
);
694 /* No BEFORE address indicates ENTRY should be inserted after the
695 current last element. */
697 return argz_append (pargz
, pargz_len
, entry
, 1+ LT_STRLEN (entry
));
699 /* This probably indicates a programmer error, but to preserve
700 semantics, scan back to the start of an entry if BEFORE points
701 into the middle of it. */
702 while ((before
> *pargz
) && (before
[-1] != LT_EOS_CHAR
))
706 size_t entry_len
= 1+ LT_STRLEN (entry
);
707 size_t argz_len
= *pargz_len
+ entry_len
;
708 size_t offset
= before
- *pargz
;
709 char *argz
= LT_DLREALLOC (char, *pargz
, argz_len
);
714 /* Make BEFORE point to the equivalent offset in ARGZ that it
715 used to have in *PARGZ incase realloc() moved the block. */
716 before
= argz
+ offset
;
718 /* Move the ARGZ entries starting at BEFORE up into the new
719 space at the end -- making room to copy ENTRY into the
721 memmove (before
+ entry_len
, before
, *pargz_len
- offset
);
722 memcpy (before
, entry
, entry_len
);
724 /* Assign new values. */
726 *pargz_len
= argz_len
;
731 #endif /* !HAVE_ARGZ_INSERT */
735 # define argz_next rpl_argz_next
737 static char *argz_next
LT_PARAMS((char *argz
, size_t argz_len
,
741 argz_next (argz
, argz_len
, entry
)
746 assert ((argz
&& argz_len
) || (!argz
&& !argz_len
));
750 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
751 within the ARGZ vector. */
752 assert ((!argz
&& !argz_len
)
753 || ((argz
<= entry
) && (entry
< (argz
+ argz_len
))));
755 /* Move to the char immediately after the terminating
757 entry
= 1+ strchr (entry
, LT_EOS_CHAR
);
759 /* Return either the new ENTRY, or else NULL if ARGZ is
761 return (entry
>= argz
+ argz_len
) ? 0 : (char *) entry
;
765 /* This should probably be flagged as a programmer error,
766 since starting an argz_next loop with the iterator set
767 to ARGZ is safer. To preserve semantics, handle the NULL
768 case by returning the start of ARGZ (if any). */
775 #endif /* !HAVE_ARGZ_NEXT */
779 #if ! HAVE_ARGZ_STRINGIFY
780 # define argz_stringify rpl_argz_stringify
782 static void argz_stringify
LT_PARAMS((char *argz
, size_t argz_len
,
786 argz_stringify (argz
, argz_len
, sep
)
791 assert ((argz
&& argz_len
) || (!argz
&& !argz_len
));
795 --argz_len
; /* don't stringify the terminating EOS */
796 while (--argz_len
> 0)
798 if (argz
[argz_len
] == LT_EOS_CHAR
)
799 argz
[argz_len
] = sep
;
803 #endif /* !HAVE_ARGZ_STRINGIFY */
808 /* --- TYPE DEFINITIONS -- */
811 /* This type is used for the array of caller data sets in each handler. */
820 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
823 /* Extract the diagnostic strings from the error table macro in the same
824 order as the enumerated indices in ltdl.h. */
826 static const char *lt_dlerror_strings
[] =
828 #define LT_ERROR(name, diagnostic) (diagnostic),
835 /* This structure is used for the list of registered loaders. */
837 struct lt_dlloader
*next
;
838 const char *loader_name
; /* identifying name for each loader */
839 const char *sym_prefix
; /* prefix for symbols */
840 lt_module_open
*module_open
;
841 lt_module_close
*module_close
;
842 lt_find_sym
*find_sym
;
843 lt_dlloader_exit
*dlloader_exit
;
844 lt_user_data dlloader_data
;
847 struct lt_dlhandle_struct
{
848 struct lt_dlhandle_struct
*next
;
849 lt_dlloader
*loader
; /* dlopening interface */
851 int depcount
; /* number of dependencies */
852 lt_dlhandle
*deplibs
; /* dependencies */
853 lt_module module
; /* system module handle */
854 lt_ptr system
; /* system specific data */
855 lt_caller_data
*caller_data
; /* per caller associated data */
856 int flags
; /* various boolean stats */
859 /* Various boolean flags can be stored in the flags field of an
860 lt_dlhandle_struct... */
861 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
862 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
864 #define LT_DLRESIDENT_FLAG (0x01 << 0)
865 /* ...add more flags here... */
867 #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
870 #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
872 static const char objdir
[] = LTDL_OBJDIR
;
873 static const char archive_ext
[] = LTDL_ARCHIVE_EXT
;
874 #ifdef LTDL_SHLIB_EXT
875 static const char shlib_ext
[] = LTDL_SHLIB_EXT
;
877 #ifdef LTDL_SYSSEARCHPATH
878 static const char sys_search_path
[] = LTDL_SYSSEARCHPATH
;
884 /* --- MUTEX LOCKING --- */
887 /* Macros to make it easier to run the lock functions only if they have
888 been registered. The reason for the complicated lock macro is to
889 ensure that the stored error message from the last error is not
890 accidentally erased if the current function doesn't generate an
892 #define LT_DLMUTEX_LOCK() LT_STMT_START { \
893 if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
895 #define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
896 if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
898 #define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
899 if (lt_dlmutex_seterror_func) \
900 (*lt_dlmutex_seterror_func) (errormsg); \
901 else lt_dllast_error = (errormsg); } LT_STMT_END
902 #define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
903 if (lt_dlmutex_geterror_func) \
904 (errormsg) = (*lt_dlmutex_geterror_func) (); \
905 else (errormsg) = lt_dllast_error; } LT_STMT_END
907 /* The mutex functions stored here are global, and are necessarily the
908 same for all threads that wish to share access to libltdl. */
909 static lt_dlmutex_lock
*lt_dlmutex_lock_func
= 0;
910 static lt_dlmutex_unlock
*lt_dlmutex_unlock_func
= 0;
911 static lt_dlmutex_seterror
*lt_dlmutex_seterror_func
= 0;
912 static lt_dlmutex_geterror
*lt_dlmutex_geterror_func
= 0;
913 static const char *lt_dllast_error
= 0;
916 /* Either set or reset the mutex functions. Either all the arguments must
917 be valid functions, or else all can be NULL to turn off locking entirely.
918 The registered functions should be manipulating a static global lock
919 from the lock() and unlock() callbacks, which needs to be reentrant. */
921 lt_dlmutex_register (lock
, unlock
, seterror
, geterror
)
922 lt_dlmutex_lock
*lock
;
923 lt_dlmutex_unlock
*unlock
;
924 lt_dlmutex_seterror
*seterror
;
925 lt_dlmutex_geterror
*geterror
;
927 lt_dlmutex_unlock
*old_unlock
= lt_dlmutex_unlock_func
;
930 /* Lock using the old lock() callback, if any. */
933 if ((lock
&& unlock
&& seterror
&& geterror
)
934 || !(lock
|| unlock
|| seterror
|| geterror
))
936 lt_dlmutex_lock_func
= lock
;
937 lt_dlmutex_unlock_func
= unlock
;
938 lt_dlmutex_seterror_func
= seterror
;
939 lt_dlmutex_geterror_func
= geterror
;
943 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS
));
947 /* Use the old unlock() callback we saved earlier, if any. Otherwise
948 record any errors using internal storage. */
952 /* Return the number of errors encountered during the execution of
960 /* --- ERROR HANDLING --- */
963 static const char **user_error_strings
= 0;
964 static int errorcount
= LT_ERROR_MAX
;
967 lt_dladderror (diagnostic
)
968 const char *diagnostic
;
972 const char **temp
= (const char **) 0;
978 errindex
= errorcount
- LT_ERROR_MAX
;
979 temp
= LT_EREALLOC (const char *, user_error_strings
, 1 + errindex
);
982 user_error_strings
= temp
;
983 user_error_strings
[errindex
] = diagnostic
;
984 result
= errorcount
++;
987 LT_DLMUTEX_UNLOCK ();
993 lt_dlseterror (errindex
)
1000 if (errindex
>= errorcount
|| errindex
< 0)
1002 /* Ack! Error setting the error message! */
1003 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE
));
1006 else if (errindex
< LT_ERROR_MAX
)
1008 /* No error setting the error message! */
1009 LT_DLMUTEX_SETERROR (lt_dlerror_strings
[errindex
]);
1013 /* No error setting the error message! */
1014 LT_DLMUTEX_SETERROR (user_error_strings
[errindex
- LT_ERROR_MAX
]);
1017 LT_DLMUTEX_UNLOCK ();
1026 lt_ptr mem
= lt_dlmalloc (size
);
1028 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
1033 lt_erealloc (addr
, size
)
1037 lt_ptr mem
= lt_dlrealloc (addr
, size
);
1039 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
1047 char *copy
= strdup (str
);
1048 if (LT_STRLEN (str
) && !copy
)
1049 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
1056 /* --- DLOPEN() INTERFACE LOADER --- */
1061 /* dynamic linking with dlopen/dlsym */
1068 # include <sys/dl.h>
1071 /* We may have to define LT_LAZY_OR_NOW in the command line if we
1072 find out it does not work in some platform. */
1073 #ifndef LT_LAZY_OR_NOW
1075 # define LT_LAZY_OR_NOW RTLD_LAZY
1078 # define LT_LAZY_OR_NOW DL_LAZY
1080 # endif /* !RTLD_LAZY */
1082 #ifndef LT_LAZY_OR_NOW
1084 # define LT_LAZY_OR_NOW RTLD_NOW
1087 # define LT_LAZY_OR_NOW DL_NOW
1089 # endif /* !RTLD_NOW */
1091 #ifndef LT_LAZY_OR_NOW
1092 # define LT_LAZY_OR_NOW 0
1093 #endif /* !LT_LAZY_OR_NOW */
1096 # define DLERROR(arg) dlerror ()
1098 # define DLERROR(arg) LT_DLSTRERROR (arg)
1102 sys_dl_open (loader_data
, filename
)
1103 lt_user_data loader_data
;
1104 const char *filename
;
1106 lt_module module
= dlopen (filename
, LT_LAZY_OR_NOW
);
1110 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN
));
1117 sys_dl_close (loader_data
, module
)
1118 lt_user_data loader_data
;
1123 if (dlclose (module
) != 0)
1125 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE
));
1133 sys_dl_sym (loader_data
, module
, symbol
)
1134 lt_user_data loader_data
;
1138 lt_ptr address
= dlsym (module
, symbol
);
1142 LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND
));
1148 static struct lt_user_dlloader sys_dl
=
1155 sys_dl_open
, sys_dl_close
, sys_dl_sym
, 0, 0 };
1158 #endif /* HAVE_LIBDL */
1162 /* --- SHL_LOAD() INTERFACE LOADER --- */
1166 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1172 /* some flags are missing on some systems, so we provide
1173 * harmless defaults.
1176 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1177 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1180 * BIND_FIRST - Place the library at the head of the symbol search
1182 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1183 * unsatisfied symbols as fatal. This flag allows
1184 * binding of unsatisfied code symbols to be deferred
1186 * [Perl: For certain libraries, like DCE, deferred
1187 * binding often causes run time problems. Adding
1188 * BIND_NONFATAL to BIND_IMMEDIATE still allows
1189 * unresolved references in situations like this.]
1190 * BIND_NOSTART - Do not call the initializer for the shared library
1191 * when the library is loaded, nor on a future call to
1193 * BIND_VERBOSE - Print verbose messages concerning possible
1194 * unsatisfied symbols.
1196 * hp9000s700/hp9000s800:
1197 * BIND_RESTRICTED - Restrict symbols visible by the library to those
1198 * present at library load time.
1199 * DYNAMIC_PATH - Allow the loader to dynamically search for the
1200 * library specified by the path argument.
1203 #ifndef DYNAMIC_PATH
1204 # define DYNAMIC_PATH 0
1206 #ifndef BIND_RESTRICTED
1207 # define BIND_RESTRICTED 0
1210 #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1213 sys_shl_open (loader_data
, filename
)
1214 lt_user_data loader_data
;
1215 const char *filename
;
1217 static shl_t self
= (shl_t
) 0;
1218 lt_module module
= shl_load (filename
, LT_BIND_FLAGS
, 0L);
1220 /* Since searching for a symbol against a NULL module handle will also
1221 look in everything else that was already loaded and exported with
1222 the -E compiler flag, we always cache a handle saved before any
1223 modules are loaded. */
1227 shl_findsym (&self
, "main", TYPE_UNDEFINED
, &address
);
1236 module
= shl_load (filename
, LT_BIND_FLAGS
, 0L);
1240 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1248 sys_shl_close (loader_data
, module
)
1249 lt_user_data loader_data
;
1254 if (module
&& (shl_unload ((shl_t
) (module
)) != 0))
1256 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1264 sys_shl_sym (loader_data
, module
, symbol
)
1265 lt_user_data loader_data
;
1271 /* sys_shl_open should never return a NULL module handle */
1272 if (module
== (lt_module
) 0)
1274 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
1276 else if (!shl_findsym((shl_t
*) &module
, symbol
, TYPE_UNDEFINED
, &address
))
1280 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1287 static struct lt_user_dlloader sys_shl
= {
1288 0, sys_shl_open
, sys_shl_close
, sys_shl_sym
, 0, 0
1291 #endif /* HAVE_SHL_LOAD */
1296 /* --- LOADLIBRARY() INTERFACE LOADER --- */
1300 /* dynamic linking for Win32 */
1302 #include <windows.h>
1304 /* Forward declaration; required to implement handle search below. */
1305 static lt_dlhandle handles
;
1308 sys_wll_open (loader_data
, filename
)
1309 lt_user_data loader_data
;
1310 const char *filename
;
1313 lt_module module
= 0;
1314 const char *errormsg
= 0;
1315 char *searchname
= 0;
1317 char self_name_buf
[MAX_PATH
];
1321 /* Get the name of main module */
1323 GetModuleFileName (NULL
, self_name_buf
, sizeof (self_name_buf
));
1324 filename
= ext
= self_name_buf
;
1328 ext
= strrchr (filename
, '.');
1333 /* FILENAME already has an extension. */
1334 searchname
= lt_estrdup (filename
);
1338 /* Append a `.' to stop Windows from adding an
1339 implicit `.dll' extension. */
1340 searchname
= LT_EMALLOC (char, 2+ LT_STRLEN (filename
));
1342 sprintf (searchname
, "%s.", filename
);
1348 /* Silence dialog from LoadLibrary on some failures.
1349 No way to get the error mode, but to set it,
1350 so set it twice to preserve any previous flags. */
1351 UINT errormode
= SetErrorMode(SEM_FAILCRITICALERRORS
);
1352 SetErrorMode(errormode
| SEM_FAILCRITICALERRORS
);
1354 #if defined(__CYGWIN__)
1356 char wpath
[MAX_PATH
];
1357 cygwin_conv_to_full_win32_path (searchname
, wpath
);
1358 module
= LoadLibrary (wpath
);
1361 module
= LoadLibrary (searchname
);
1364 /* Restore the error mode. */
1365 SetErrorMode(errormode
);
1368 LT_DLFREE (searchname
);
1370 /* libltdl expects this function to fail if it is unable
1371 to physically load the library. Sadly, LoadLibrary
1372 will search the loaded libraries for a match and return
1373 one of them if the path search load fails.
1375 We check whether LoadLibrary is returning a handle to
1376 an already loaded module, and simulate failure if we
1388 if (cur
->module
== module
)
1395 LT_DLMUTEX_UNLOCK ();
1399 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1407 sys_wll_close (loader_data
, module
)
1408 lt_user_data loader_data
;
1413 if (FreeLibrary(module
) == 0)
1415 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1423 sys_wll_sym (loader_data
, module
, symbol
)
1424 lt_user_data loader_data
;
1428 lt_ptr address
= GetProcAddress (module
, symbol
);
1432 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1438 static struct lt_user_dlloader sys_wll
= {
1439 0, sys_wll_open
, sys_wll_close
, sys_wll_sym
, 0, 0
1442 #endif /* __WINDOWS__ */
1447 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1452 /* dynamic linking for BeOS */
1454 #include <kernel/image.h>
1457 sys_bedl_open (loader_data
, filename
)
1458 lt_user_data loader_data
;
1459 const char *filename
;
1465 image
= load_add_on (filename
);
1471 if (get_next_image_info (0, &cookie
, &info
) == B_OK
)
1472 image
= load_add_on (info
.name
);
1477 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1481 return (lt_module
) image
;
1485 sys_bedl_close (loader_data
, module
)
1486 lt_user_data loader_data
;
1491 if (unload_add_on ((image_id
) module
) != B_OK
)
1493 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1501 sys_bedl_sym (loader_data
, module
, symbol
)
1502 lt_user_data loader_data
;
1507 image_id image
= (image_id
) module
;
1509 if (get_image_symbol (image
, symbol
, B_SYMBOL_TYPE_ANY
, address
) != B_OK
)
1511 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1518 static struct lt_user_dlloader sys_bedl
= {
1519 0, sys_bedl_open
, sys_bedl_close
, sys_bedl_sym
, 0, 0
1522 #endif /* __BEOS__ */
1527 /* --- DLD_LINK() INTERFACE LOADER --- */
1532 /* dynamic linking with dld */
1539 sys_dld_open (loader_data
, filename
)
1540 lt_user_data loader_data
;
1541 const char *filename
;
1543 lt_module module
= strdup (filename
);
1545 if (dld_link (filename
) != 0)
1547 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1556 sys_dld_close (loader_data
, module
)
1557 lt_user_data loader_data
;
1562 if (dld_unlink_by_file ((char*)(module
), 1) != 0)
1564 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1576 sys_dld_sym (loader_data
, module
, symbol
)
1577 lt_user_data loader_data
;
1581 lt_ptr address
= dld_get_func (symbol
);
1585 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1591 static struct lt_user_dlloader sys_dld
= {
1592 0, sys_dld_open
, sys_dld_close
, sys_dld_sym
, 0, 0
1595 #endif /* HAVE_DLD */
1597 /* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
1601 #if HAVE_MACH_O_DYLD_H
1602 #if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
1603 /* Is this correct? Does it still function properly? */
1604 #define __private_extern__ extern
1606 # include <mach-o/dyld.h>
1608 #include <mach-o/getsect.h>
1610 /* We have to put some stuff here that isn't in older dyld.h files */
1611 #ifndef ENUM_DYLD_BOOL
1612 # define ENUM_DYLD_BOOL
1621 # define LC_REQ_DYLD 0x80000000
1623 #ifndef LC_LOAD_WEAK_DYLIB
1624 # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
1626 static const struct mach_header
* (*ltdl_NSAddImage
)(const char *image_name
, unsigned long options
) = 0;
1627 static NSSymbol (*ltdl_NSLookupSymbolInImage
)(const struct mach_header
*image
,const char *symbolName
, unsigned long options
) = 0;
1628 static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage
)(const struct mach_header
*image
, const char *symbolName
) = 0;
1629 static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic
)(NSModule module
) = 0;
1631 #ifndef NSADDIMAGE_OPTION_NONE
1632 #define NSADDIMAGE_OPTION_NONE 0x0
1634 #ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
1635 #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
1637 #ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
1638 #define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
1640 #ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1641 #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
1643 #ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
1644 #define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
1646 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
1647 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
1649 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1650 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
1652 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
1653 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
1655 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1656 #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
1661 lt_int_dyld_error(othererror
)
1664 /* return the dyld error string, or the passed in error string if none */
1665 NSLinkEditErrors ler
;
1669 NSLinkEditError(&ler
,&lerno
,&file
,&errstr
);
1670 if (!errstr
|| !strlen(errstr
)) errstr
= othererror
;
1674 static const struct mach_header
*
1675 lt_int_dyld_get_mach_header_from_nsmodule(module
)
1678 /* There should probably be an apple dyld api for this */
1679 int i
=_dyld_image_count();
1681 const char *modname
=NSNameOfModule(module
);
1682 const struct mach_header
*mh
=NULL
;
1683 if (!modname
) return NULL
;
1684 for (j
= 0; j
< i
; j
++)
1686 if (!strcmp(_dyld_get_image_name(j
),modname
))
1688 mh
=_dyld_get_image_header(j
);
1695 static const char* lt_int_dyld_lib_install_name(mh
)
1696 const struct mach_header
*mh
;
1698 /* NSAddImage is also used to get the loaded image, but it only works if the lib
1699 is installed, for uninstalled libs we need to check the install_names against
1700 each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
1701 different lib was loaded as a result
1704 struct load_command
*lc
;
1705 unsigned long offset
= sizeof(struct mach_header
);
1706 const char* retStr
=NULL
;
1707 for (j
= 0; j
< mh
->ncmds
; j
++)
1709 lc
= (struct load_command
*)(((unsigned long)mh
) + offset
);
1710 if (LC_ID_DYLIB
== lc
->cmd
)
1712 retStr
=(char*)(((struct dylib_command
*)lc
)->dylib
.name
.offset
+
1715 offset
+= lc
->cmdsize
;
1720 static const struct mach_header
*
1721 lt_int_dyld_match_loaded_lib_by_install_name(const char *name
)
1723 int i
=_dyld_image_count();
1725 const struct mach_header
*mh
=NULL
;
1726 const char *id
=NULL
;
1727 for (j
= 0; j
< i
; j
++)
1729 id
=lt_int_dyld_lib_install_name(_dyld_get_image_header(j
));
1730 if ((id
) && (!strcmp(id
,name
)))
1732 mh
=_dyld_get_image_header(j
);
1740 lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol
,mh
)
1742 const struct mach_header
*mh
;
1744 /* Safe to assume our mh is good */
1746 struct load_command
*lc
;
1747 unsigned long offset
= sizeof(struct mach_header
);
1748 NSSymbol retSym
= 0;
1749 const struct mach_header
*mh1
;
1750 if ((ltdl_NSLookupSymbolInImage
) && NSIsSymbolNameDefined(symbol
) )
1752 for (j
= 0; j
< mh
->ncmds
; j
++)
1754 lc
= (struct load_command
*)(((unsigned long)mh
) + offset
);
1755 if ((LC_LOAD_DYLIB
== lc
->cmd
) || (LC_LOAD_WEAK_DYLIB
== lc
->cmd
))
1757 mh1
=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command
*)lc
)->dylib
.name
.offset
+
1758 (unsigned long)lc
));
1761 /* Maybe NSAddImage can find it */
1762 mh1
=ltdl_NSAddImage((char*)(((struct dylib_command
*)lc
)->dylib
.name
.offset
+
1764 NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
+
1765 NSADDIMAGE_OPTION_WITH_SEARCHING
+
1766 NSADDIMAGE_OPTION_RETURN_ON_ERROR
);
1770 retSym
= ltdl_NSLookupSymbolInImage(mh1
,
1772 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1773 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1778 offset
+= lc
->cmdsize
;
1789 if (!_dyld_present()) {
1793 err
= _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage
);
1794 err
= _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage
);
1795 err
= _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage
);
1796 err
= _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic
);
1802 sys_dyld_open (loader_data
, filename
)
1803 lt_user_data loader_data
;
1804 const char *filename
;
1806 lt_module module
= 0;
1807 NSObjectFileImage ofi
= 0;
1808 NSObjectFileImageReturnCode ofirc
;
1811 return (lt_module
)-1;
1812 ofirc
= NSCreateObjectFileImageFromFile(filename
, &ofi
);
1815 case NSObjectFileImageSuccess
:
1816 module
= NSLinkModule(ofi
, filename
,
1817 NSLINKMODULE_OPTION_RETURN_ON_ERROR
1818 | NSLINKMODULE_OPTION_PRIVATE
1819 | NSLINKMODULE_OPTION_BINDNOW
);
1820 NSDestroyObjectFileImage(ofi
);
1822 ltdl_NSMakePrivateModulePublic(module
);
1824 case NSObjectFileImageInappropriateFile
:
1825 if (ltdl_NSIsSymbolNameDefinedInImage
&& ltdl_NSLookupSymbolInImage
)
1827 module
= (lt_module
)ltdl_NSAddImage(filename
, NSADDIMAGE_OPTION_RETURN_ON_ERROR
);
1831 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN
)));
1834 if (!module
) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN
)));
1839 sys_dyld_close (loader_data
, module
)
1840 lt_user_data loader_data
;
1845 if (module
== (lt_module
)-1) return 0;
1846 #ifdef __BIG_ENDIAN__
1847 if (((struct mach_header
*)module
)->magic
== MH_MAGIC
)
1849 if (((struct mach_header
*)module
)->magic
== MH_CIGAM
)
1852 LT_DLMUTEX_SETERROR("Can not close a dylib");
1858 /* Currently, if a module contains c++ static destructors and it is unloaded, we
1859 get a segfault in atexit(), due to compiler and dynamic loader differences of
1860 opinion, this works around that.
1862 if ((const struct section
*)NULL
!=
1863 getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module
),
1864 "__DATA","__mod_term_func"))
1866 flags
+= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
;
1870 flags
+= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES
;
1872 if (!NSUnLinkModule(module
,flags
))
1875 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE
)));
1883 sys_dyld_sym (loader_data
, module
, symbol
)
1884 lt_user_data loader_data
;
1889 NSSymbol
*nssym
= 0;
1891 const struct mach_header
*mh
=NULL
;
1892 char saveError
[256] = "Symbol not found";
1893 if (module
== (lt_module
)-1)
1895 _dyld_lookup_and_bind(symbol
,(unsigned long*)&address
,&unused
);
1898 #ifdef __BIG_ENDIAN__
1899 if (((struct mach_header
*)module
)->magic
== MH_MAGIC
)
1901 if (((struct mach_header
*)module
)->magic
== MH_CIGAM
)
1904 if (ltdl_NSIsSymbolNameDefinedInImage
&& ltdl_NSLookupSymbolInImage
)
1907 if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header
*)module
,symbol
))
1909 nssym
= ltdl_NSLookupSymbolInImage((struct mach_header
*)module
,
1911 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1912 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1919 nssym
= NSLookupSymbolInModule(module
, symbol
);
1923 strncpy(saveError
, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND
)), 255);
1925 if (!mh
) mh
=lt_int_dyld_get_mach_header_from_nsmodule(module
);
1926 nssym
= lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol
,mh
);
1930 LT_DLMUTEX_SETERROR (saveError
);
1933 return NSAddressOfSymbol(nssym
);
1936 static struct lt_user_dlloader sys_dyld
=
1937 { "_", sys_dyld_open
, sys_dyld_close
, sys_dyld_sym
, 0, 0 };
1940 #endif /* HAVE_DYLD */
1943 /* --- DLPREOPEN() INTERFACE LOADER --- */
1946 /* emulate dynamic linking using preloaded_symbols */
1948 typedef struct lt_dlsymlists_t
1950 struct lt_dlsymlists_t
*next
;
1951 const lt_dlsymlist
*syms
;
1954 static const lt_dlsymlist
*default_preloaded_symbols
= 0;
1955 static lt_dlsymlists_t
*preloaded_symbols
= 0;
1958 presym_init (loader_data
)
1959 lt_user_data loader_data
;
1965 preloaded_symbols
= 0;
1966 if (default_preloaded_symbols
)
1968 errors
= lt_dlpreload (default_preloaded_symbols
);
1971 LT_DLMUTEX_UNLOCK ();
1977 presym_free_symlists ()
1979 lt_dlsymlists_t
*lists
;
1983 lists
= preloaded_symbols
;
1986 lt_dlsymlists_t
*tmp
= lists
;
1988 lists
= lists
->next
;
1991 preloaded_symbols
= 0;
1993 LT_DLMUTEX_UNLOCK ();
1999 presym_exit (loader_data
)
2000 lt_user_data loader_data
;
2002 presym_free_symlists ();
2007 presym_add_symlist (preloaded
)
2008 const lt_dlsymlist
*preloaded
;
2010 lt_dlsymlists_t
*tmp
;
2011 lt_dlsymlists_t
*lists
;
2016 lists
= preloaded_symbols
;
2019 if (lists
->syms
== preloaded
)
2023 lists
= lists
->next
;
2026 tmp
= LT_EMALLOC (lt_dlsymlists_t
, 1);
2029 memset (tmp
, 0, sizeof(lt_dlsymlists_t
));
2030 tmp
->syms
= preloaded
;
2031 tmp
->next
= preloaded_symbols
;
2032 preloaded_symbols
= tmp
;
2040 LT_DLMUTEX_UNLOCK ();
2045 presym_open (loader_data
, filename
)
2046 lt_user_data loader_data
;
2047 const char *filename
;
2049 lt_dlsymlists_t
*lists
;
2050 lt_module module
= (lt_module
) 0;
2053 lists
= preloaded_symbols
;
2057 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS
));
2061 /* Can't use NULL as the reflective symbol header, as NULL is
2062 used to mark the end of the entire symbol list. Self-dlpreopened
2063 symbols follow this magic number, chosen to be an unlikely
2064 clash with a real module name. */
2067 filename
= "@PROGRAM@";
2072 const lt_dlsymlist
*syms
= lists
->syms
;
2076 if (!syms
->address
&& strcmp(syms
->name
, filename
) == 0)
2078 module
= (lt_module
) syms
;
2084 lists
= lists
->next
;
2087 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
2090 LT_DLMUTEX_UNLOCK ();
2095 presym_close (loader_data
, module
)
2096 lt_user_data loader_data
;
2099 /* Just to silence gcc -Wall */
2105 presym_sym (loader_data
, module
, symbol
)
2106 lt_user_data loader_data
;
2110 lt_dlsymlist
*syms
= (lt_dlsymlist
*) module
;
2113 while (syms
->address
)
2115 if (strcmp(syms
->name
, symbol
) == 0)
2117 return syms
->address
;
2123 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
2128 static struct lt_user_dlloader presym
= {
2129 0, presym_open
, presym_close
, presym_sym
, presym_exit
, 0
2136 /* --- DYNAMIC MODULE LOADING --- */
2139 /* The type of a function used at each iteration of foreach_dirinpath(). */
2140 typedef int foreach_callback_func
LT_PARAMS((char *filename
, lt_ptr data1
,
2143 static int foreach_dirinpath
LT_PARAMS((const char *search_path
,
2144 const char *base_name
,
2145 foreach_callback_func
*func
,
2146 lt_ptr data1
, lt_ptr data2
));
2148 static int find_file_callback
LT_PARAMS((char *filename
, lt_ptr data
,
2150 static int find_handle_callback
LT_PARAMS((char *filename
, lt_ptr data
,
2152 static int foreachfile_callback
LT_PARAMS((char *filename
, lt_ptr data1
,
2156 static int canonicalize_path
LT_PARAMS((const char *path
,
2157 char **pcanonical
));
2158 static int argzize_path
LT_PARAMS((const char *path
,
2160 size_t *pargz_len
));
2161 static FILE *find_file
LT_PARAMS((const char *search_path
,
2162 const char *base_name
,
2164 static lt_dlhandle
*find_handle
LT_PARAMS((const char *search_path
,
2165 const char *base_name
,
2166 lt_dlhandle
*handle
));
2167 static int find_module
LT_PARAMS((lt_dlhandle
*handle
,
2171 const char *old_name
,
2173 static int free_vars
LT_PARAMS((char *dlname
, char *oldname
,
2174 char *libdir
, char *deplibs
));
2175 static int load_deplibs
LT_PARAMS((lt_dlhandle handle
,
2177 static int trim
LT_PARAMS((char **dest
,
2179 static int try_dlopen
LT_PARAMS((lt_dlhandle
*handle
,
2180 const char *filename
));
2181 static int tryall_dlopen
LT_PARAMS((lt_dlhandle
*handle
,
2182 const char *filename
));
2183 static int unload_deplibs
LT_PARAMS((lt_dlhandle handle
));
2184 static int lt_argz_insert
LT_PARAMS((char **pargz
,
2187 const char *entry
));
2188 static int lt_argz_insertinorder
LT_PARAMS((char **pargz
,
2190 const char *entry
));
2191 static int lt_argz_insertdir
LT_PARAMS((char **pargz
,
2194 struct dirent
*dp
));
2195 static int lt_dlpath_insertdir
LT_PARAMS((char **ppath
,
2198 static int list_files_by_dir
LT_PARAMS((const char *dirnam
,
2200 size_t *pargz_len
));
2201 static int file_not_found
LT_PARAMS((void));
2203 static char *user_search_path
= 0;
2204 static lt_dlloader
*loaders
= 0;
2205 static lt_dlhandle handles
= 0;
2206 static int initialized
= 0;
2208 /* Initialize libltdl. */
2216 /* Initialize only at first call. */
2217 if (++initialized
== 1)
2220 user_search_path
= 0; /* empty search path */
2223 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_dl
, "dlopen");
2226 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_shl
, "dlopen");
2229 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_wll
, "dlopen");
2232 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_bedl
, "dlopen");
2235 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_dld
, "dld");
2238 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_dyld
, "dyld");
2239 errors
+= sys_dyld_init();
2241 errors
+= lt_dlloader_add (lt_dlloader_next (0), &presym
, "dlpreload");
2243 if (presym_init (presym
.dlloader_data
))
2245 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER
));
2248 else if (errors
!= 0)
2250 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED
));
2255 LT_DLMUTEX_UNLOCK ();
2261 lt_dlpreload (preloaded
)
2262 const lt_dlsymlist
*preloaded
;
2268 errors
= presym_add_symlist (preloaded
);
2272 presym_free_symlists();
2275 if (default_preloaded_symbols
)
2277 errors
= lt_dlpreload (default_preloaded_symbols
);
2279 LT_DLMUTEX_UNLOCK ();
2286 lt_dlpreload_default (preloaded
)
2287 const lt_dlsymlist
*preloaded
;
2290 default_preloaded_symbols
= preloaded
;
2291 LT_DLMUTEX_UNLOCK ();
2298 /* shut down libltdl */
2299 lt_dlloader
*loader
;
2307 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN
));
2312 /* shut down only at last call. */
2313 if (--initialized
== 0)
2317 while (handles
&& LT_DLIS_RESIDENT (handles
))
2319 handles
= handles
->next
;
2322 /* close all modules */
2323 for (level
= 1; handles
; ++level
)
2325 lt_dlhandle cur
= handles
;
2326 int saw_nonresident
= 0;
2330 lt_dlhandle tmp
= cur
;
2332 if (!LT_DLIS_RESIDENT (tmp
))
2333 saw_nonresident
= 1;
2334 if (!LT_DLIS_RESIDENT (tmp
) && tmp
->info
.ref_count
<= level
)
2336 if (lt_dlclose (tmp
))
2340 /* Make sure that the handle pointed to by 'cur' still exists.
2341 lt_dlclose recursively closes dependent libraries which removes
2342 them from the linked list. One of these might be the one
2343 pointed to by 'cur'. */
2346 for (tmp
= handles
; tmp
; tmp
= tmp
->next
)
2354 /* done if only resident modules are left */
2355 if (!saw_nonresident
)
2359 /* close all loaders */
2362 lt_dlloader
*next
= loader
->next
;
2363 lt_user_data data
= loader
->dlloader_data
;
2364 if (loader
->dlloader_exit
&& loader
->dlloader_exit (data
))
2369 LT_DLMEM_REASSIGN (loader
, next
);
2375 LT_DLMUTEX_UNLOCK ();
2380 tryall_dlopen (handle
, filename
)
2381 lt_dlhandle
*handle
;
2382 const char *filename
;
2385 lt_dlloader
*loader
;
2386 const char *saved_error
;
2389 LT_DLMUTEX_GETERROR (saved_error
);
2395 /* check whether the module was already opened */
2398 /* try to dlopen the program itself? */
2399 if (!cur
->info
.filename
&& !filename
)
2404 if (cur
->info
.filename
&& filename
2405 && strcmp (cur
->info
.filename
, filename
) == 0)
2415 ++cur
->info
.ref_count
;
2423 /* Comment out the check of file permissions using access.
2424 This call seems to always return -1 with error EACCES.
2426 /* We need to catch missing file errors early so that
2427 file_not_found() can detect what happened.
2428 if (access (filename, R_OK) != 0)
2430 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2435 cur
->info
.filename
= lt_estrdup (filename
);
2436 if (!cur
->info
.filename
)
2444 cur
->info
.filename
= 0;
2449 lt_user_data data
= loader
->dlloader_data
;
2451 cur
->module
= loader
->module_open (data
, filename
);
2453 if (cur
->module
!= 0)
2457 loader
= loader
->next
;
2462 LT_DLFREE (cur
->info
.filename
);
2467 cur
->loader
= loader
;
2468 LT_DLMUTEX_SETERROR (saved_error
);
2471 LT_DLMUTEX_UNLOCK ();
2477 tryall_dlopen_module (handle
, prefix
, dirname
, dlname
)
2478 lt_dlhandle
*handle
;
2480 const char *dirname
;
2485 size_t filename_len
= 0;
2486 size_t dirname_len
= LT_STRLEN (dirname
);
2491 #ifdef LT_DIRSEP_CHAR
2492 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2493 should make it into this function: */
2494 assert (strchr (dirname
, LT_DIRSEP_CHAR
) == 0);
2497 if (dirname_len
> 0)
2498 if (dirname
[dirname_len
-1] == '/')
2500 filename_len
= dirname_len
+ 1 + LT_STRLEN (dlname
);
2502 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2503 The PREFIX (if any) is handled below. */
2504 filename
= LT_EMALLOC (char, dirname_len
+ 1 + filename_len
+ 1);
2508 sprintf (filename
, "%.*s/%s", (int) dirname_len
, dirname
, dlname
);
2510 /* Now that we have combined DIRNAME and MODULENAME, if there is
2511 also a PREFIX to contend with, simply recurse with the arguments
2512 shuffled. Otherwise, attempt to open FILENAME as a module. */
2515 error
+= tryall_dlopen_module (handle
,
2516 (const char *) 0, prefix
, filename
);
2518 else if (tryall_dlopen (handle
, filename
) != 0)
2523 LT_DLFREE (filename
);
2528 find_module (handle
, dir
, libdir
, dlname
, old_name
, installed
)
2529 lt_dlhandle
*handle
;
2533 const char *old_name
;
2536 /* Try to open the old library first; if it was dlpreopened,
2537 we want the preopened version of it, even if a dlopenable
2538 module is available. */
2539 if (old_name
&& tryall_dlopen (handle
, old_name
) == 0)
2544 /* Try to open the dynamic library. */
2547 /* try to open the installed module */
2548 if (installed
&& libdir
)
2550 if (tryall_dlopen_module (handle
,
2551 (const char *) 0, libdir
, dlname
) == 0)
2555 /* try to open the not-installed module */
2558 if (tryall_dlopen_module (handle
, dir
, objdir
, dlname
) == 0)
2562 /* maybe it was moved to another directory */
2564 if (dir
&& (tryall_dlopen_module (handle
,
2565 (const char *) 0, dir
, dlname
) == 0))
2575 canonicalize_path (path
, pcanonical
)
2579 char *canonical
= 0;
2581 assert (path
&& *path
);
2582 assert (pcanonical
);
2584 canonical
= LT_EMALLOC (char, 1+ LT_STRLEN (path
));
2591 for (src
= 0; path
[src
] != LT_EOS_CHAR
; ++src
)
2593 /* Path separators are not copied to the beginning or end of
2594 the destination, or if another separator would follow
2596 if (path
[src
] == LT_PATHSEP_CHAR
)
2599 || (path
[1+ src
] == LT_PATHSEP_CHAR
)
2600 || (path
[1+ src
] == LT_EOS_CHAR
))
2604 /* Anything other than a directory separator is copied verbatim. */
2605 if ((path
[src
] != '/')
2606 #ifdef LT_DIRSEP_CHAR
2607 && (path
[src
] != LT_DIRSEP_CHAR
)
2611 canonical
[dest
++] = path
[src
];
2613 /* Directory separators are converted and copied only if they are
2614 not at the end of a path -- i.e. before a path separator or
2616 else if ((path
[1+ src
] != LT_PATHSEP_CHAR
)
2617 && (path
[1+ src
] != LT_EOS_CHAR
)
2618 #ifdef LT_DIRSEP_CHAR
2619 && (path
[1+ src
] != LT_DIRSEP_CHAR
)
2621 && (path
[1+ src
] != '/'))
2623 canonical
[dest
++] = '/';
2627 /* Add an end-of-string marker at the end. */
2628 canonical
[dest
] = LT_EOS_CHAR
;
2631 /* Assign new value. */
2632 *pcanonical
= canonical
;
2638 argzize_path (path
, pargz
, pargz_len
)
2649 if ((error
= argz_create_sep (path
, LT_PATHSEP_CHAR
, pargz
, pargz_len
)))
2654 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
2657 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN
));
2667 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2668 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2669 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2670 it is appended to each SEARCH_PATH element before FUNC is called. */
2672 foreach_dirinpath (search_path
, base_name
, func
, data1
, data2
)
2673 const char *search_path
;
2674 const char *base_name
;
2675 foreach_callback_func
*func
;
2680 int filenamesize
= 0;
2681 size_t lenbase
= LT_STRLEN (base_name
);
2682 size_t argz_len
= 0;
2685 char *canonical
= 0;
2689 if (!search_path
|| !*search_path
)
2691 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
2695 if (canonicalize_path (search_path
, &canonical
) != 0)
2698 if (argzize_path (canonical
, &argz
, &argz_len
) != 0)
2703 while ((dir_name
= argz_next (argz
, argz_len
, dir_name
)))
2705 size_t lendir
= LT_STRLEN (dir_name
);
2707 if (lendir
+1 +lenbase
>= filenamesize
)
2709 LT_DLFREE (filename
);
2710 filenamesize
= lendir
+1 +lenbase
+1; /* "/d" + '/' + "f" + '\0' */
2711 filename
= LT_EMALLOC (char, filenamesize
);
2716 assert (filenamesize
> lendir
);
2717 strcpy (filename
, dir_name
);
2719 if (base_name
&& *base_name
)
2721 if (filename
[lendir
-1] != '/')
2722 filename
[lendir
++] = '/';
2723 strcpy (filename
+lendir
, base_name
);
2726 if ((result
= (*func
) (filename
, data1
, data2
)))
2735 LT_DLFREE (canonical
);
2736 LT_DLFREE (filename
);
2738 LT_DLMUTEX_UNLOCK ();
2743 /* If FILEPATH can be opened, store the name of the directory component
2744 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2745 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2747 find_file_callback (filename
, data1
, data2
)
2752 char **pdir
= (char **) data1
;
2753 FILE **pfile
= (FILE **) data2
;
2756 assert (filename
&& *filename
);
2760 if ((*pfile
= fopen (filename
, LT_READTEXT_MODE
)))
2762 char *dirend
= strrchr (filename
, '/');
2764 if (dirend
> filename
)
2765 *dirend
= LT_EOS_CHAR
;
2768 *pdir
= lt_estrdup (filename
);
2769 is_done
= (*pdir
== 0) ? -1 : 1;
2776 find_file (search_path
, base_name
, pdir
)
2777 const char *search_path
;
2778 const char *base_name
;
2783 foreach_dirinpath (search_path
, base_name
, find_file_callback
, pdir
, &file
);
2789 find_handle_callback (filename
, data
, ignored
)
2794 lt_dlhandle
*handle
= (lt_dlhandle
*) data
;
2795 int notfound
= access (filename
, R_OK
);
2797 /* Bail out if file cannot be read... */
2801 /* Try to dlopen the file, but do not continue searching in any
2803 if (tryall_dlopen (handle
, filename
) != 0)
2809 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2810 found but could not be opened, *HANDLE will be set to 0. */
2811 static lt_dlhandle
*
2812 find_handle (search_path
, base_name
, handle
)
2813 const char *search_path
;
2814 const char *base_name
;
2815 lt_dlhandle
*handle
;
2820 if (!foreach_dirinpath (search_path
, base_name
, find_handle_callback
,
2828 load_deplibs (handle
, deplibs
)
2832 #if LTDL_DLOPEN_DEPLIBS
2833 char *p
, *save_search_path
= 0;
2840 handle
->depcount
= 0;
2842 #if LTDL_DLOPEN_DEPLIBS
2850 if (user_search_path
)
2852 save_search_path
= lt_estrdup (user_search_path
);
2853 if (!save_search_path
)
2857 /* extract search paths and count deplibs */
2861 if (!isspace ((int) *p
))
2864 while (*end
&& !isspace((int) *end
))
2869 if (strncmp(p
, "-L", 2) == 0 || strncmp(p
, "-R", 2) == 0)
2872 *end
= 0; /* set a temporary string terminator */
2873 if (lt_dladdsearchdir(p
+2))
2898 names
= LT_EMALLOC (char *, depcount
* sizeof (char*));
2902 /* now only extract the actual deplibs */
2907 if (isspace ((int) *p
))
2914 while (*end
&& !isspace ((int) *end
))
2919 if (strncmp(p
, "-L", 2) != 0 && strncmp(p
, "-R", 2) != 0)
2923 *end
= 0; /* set a temporary string terminator */
2924 if (strncmp(p
, "-l", 2) == 0)
2926 size_t name_len
= 3+ /* "lib" */ LT_STRLEN (p
+ 2);
2927 name
= LT_EMALLOC (char, 1+ name_len
);
2929 sprintf (name
, "lib%s", p
+2);
2932 name
= lt_estrdup(p
);
2937 names
[depcount
++] = name
;
2944 /* load the deplibs (in reverse order)
2945 At this stage, don't worry if the deplibs do not load correctly,
2946 they may already be statically linked into the loading application
2947 for instance. There will be a more enlightening error message
2948 later on if the loaded module cannot resolve all of its symbols. */
2953 handle
->deplibs
= (lt_dlhandle
*) LT_EMALLOC (lt_dlhandle
*, depcount
);
2954 if (!handle
->deplibs
)
2957 for (i
= 0; i
< depcount
; ++i
)
2959 handle
->deplibs
[j
] = lt_dlopenext(names
[depcount
-1-i
]);
2960 if (handle
->deplibs
[j
])
2966 handle
->depcount
= j
; /* Number of successfully loaded deplibs */
2971 for (i
= 0; i
< depcount
; ++i
)
2973 LT_DLFREE (names
[i
]);
2978 /* restore the old search path */
2979 if (user_search_path
) {
2980 LT_DLFREE (user_search_path
);
2981 user_search_path
= save_search_path
;
2983 LT_DLMUTEX_UNLOCK ();
2991 unload_deplibs (handle
)
2997 if (handle
->depcount
)
2999 for (i
= 0; i
< handle
->depcount
; ++i
)
3001 if (!LT_DLIS_RESIDENT (handle
->deplibs
[i
]))
3003 errors
+= lt_dlclose (handle
->deplibs
[i
]);
3006 LT_DLFREE (handle
->deplibs
);
3017 /* remove the leading and trailing "'" from str
3018 and store the result in dest */
3019 const char *end
= strrchr (str
, '\'');
3020 size_t len
= LT_STRLEN (str
);
3028 if (len
> 3 && str
[0] == '\'')
3030 tmp
= LT_EMALLOC (char, end
- str
);
3034 strncpy(tmp
, &str
[1], (end
- str
) - 1);
3035 tmp
[len
-3] = LT_EOS_CHAR
;
3047 free_vars (dlname
, oldname
, libdir
, deplibs
)
3054 LT_DLFREE (oldname
);
3056 LT_DLFREE (deplibs
);
3062 try_dlopen (phandle
, filename
)
3063 lt_dlhandle
*phandle
;
3064 const char *filename
;
3066 const char * ext
= 0;
3067 const char * saved_error
= 0;
3068 char * canonical
= 0;
3069 char * base_name
= 0;
3073 lt_dlhandle newhandle
;
3076 assert (*phandle
== 0);
3078 LT_DLMUTEX_GETERROR (saved_error
);
3083 *phandle
= (lt_dlhandle
) LT_EMALLOC (struct lt_dlhandle_struct
, 1);
3087 memset (*phandle
, 0, sizeof(struct lt_dlhandle_struct
));
3088 newhandle
= *phandle
;
3090 /* lt_dlclose()ing yourself is very bad! Disallow it. */
3091 LT_DLSET_FLAG (*phandle
, LT_DLRESIDENT_FLAG
);
3093 if (tryall_dlopen (&newhandle
, 0) != 0)
3095 LT_DLFREE (*phandle
);
3099 goto register_handle
;
3102 assert (filename
&& *filename
);
3104 /* Doing this immediately allows internal functions to safely
3105 assume only canonicalized paths are passed. */
3106 if (canonicalize_path (filename
, &canonical
) != 0)
3112 /* If the canonical module name is a path (relative or absolute)
3113 then split it into a directory part and a name part. */
3114 base_name
= strrchr (canonical
, '/');
3117 size_t dirlen
= (1+ base_name
) - canonical
;
3119 dir
= LT_EMALLOC (char, 1+ dirlen
);
3126 strncpy (dir
, canonical
, dirlen
);
3127 dir
[dirlen
] = LT_EOS_CHAR
;
3132 base_name
= canonical
;
3134 assert (base_name
&& *base_name
);
3136 /* Check whether we are opening a libtool module (.la extension). */
3137 ext
= strrchr (base_name
, '.');
3138 if (ext
&& strcmp (ext
, archive_ext
) == 0)
3140 /* this seems to be a libtool module */
3143 char * old_name
= 0;
3149 /* if we can't find the installed flag, it is probably an
3150 installed libtool archive, produced with an old version
3154 /* extract the module name from the file name */
3155 name
= LT_EMALLOC (char, ext
- base_name
+ 1);
3162 /* canonicalize the module name */
3165 for (i
= 0; i
< ext
- base_name
; ++i
)
3167 if (isalnum ((int)(base_name
[i
])))
3169 name
[i
] = base_name
[i
];
3176 name
[ext
- base_name
] = LT_EOS_CHAR
;
3179 /* Now try to open the .la file. If there is no directory name
3180 component, try to find it first in user_search_path and then other
3181 prescribed paths. Otherwise (or in any case if the module was not
3182 yet found) try opening just the module name as passed. */
3185 const char *search_path
;
3188 search_path
= user_search_path
;
3190 file
= find_file (user_search_path
, base_name
, &dir
);
3191 LT_DLMUTEX_UNLOCK ();
3195 search_path
= getenv (LTDL_SEARCHPATH_VAR
);
3197 file
= find_file (search_path
, base_name
, &dir
);
3200 #ifdef LTDL_SHLIBPATH_VAR
3203 search_path
= getenv (LTDL_SHLIBPATH_VAR
);
3205 file
= find_file (search_path
, base_name
, &dir
);
3208 #ifdef LTDL_SYSSEARCHPATH
3209 if (!file
&& sys_search_path
)
3211 file
= find_file (sys_search_path
, base_name
, &dir
);
3217 file
= fopen (filename
, LT_READTEXT_MODE
);
3220 /* If we didn't find the file by now, it really isn't there. Set
3221 the status flag, and bail out. */
3224 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
3229 line_len
= LT_FILENAME_MAX
;
3230 line
= LT_EMALLOC (char, line_len
);
3238 /* read the .la file */
3239 while (!feof (file
))
3241 if (!fgets (line
, (int) line_len
, file
))
3246 /* Handle the case where we occasionally need to read a line
3247 that is longer than the initial buffer size. */
3248 while ((line
[LT_STRLEN(line
) -1] != '\n') && (!feof (file
)))
3250 line
= LT_DLREALLOC (char, line
, line_len
*2);
3251 if (!fgets (&line
[line_len
-1], (int) line_len
+1, file
))
3258 if (line
[0] == '\n' || line
[0] == '#')
3264 #define STR_DLNAME "dlname="
3265 if (strncmp (line
, STR_DLNAME
, sizeof (STR_DLNAME
) - 1) == 0)
3267 errors
+= trim (&dlname
, &line
[sizeof (STR_DLNAME
) - 1]);
3270 #undef STR_OLD_LIBRARY
3271 #define STR_OLD_LIBRARY "old_library="
3272 else if (strncmp (line
, STR_OLD_LIBRARY
,
3273 sizeof (STR_OLD_LIBRARY
) - 1) == 0)
3275 errors
+= trim (&old_name
, &line
[sizeof (STR_OLD_LIBRARY
) - 1]);
3278 #define STR_LIBDIR "libdir="
3279 else if (strncmp (line
, STR_LIBDIR
, sizeof (STR_LIBDIR
) - 1) == 0)
3281 errors
+= trim (&libdir
, &line
[sizeof(STR_LIBDIR
) - 1]);
3284 #undef STR_DL_DEPLIBS
3285 #define STR_DL_DEPLIBS "dependency_libs="
3286 else if (strncmp (line
, STR_DL_DEPLIBS
,
3287 sizeof (STR_DL_DEPLIBS
) - 1) == 0)
3289 errors
+= trim (&deplibs
, &line
[sizeof (STR_DL_DEPLIBS
) - 1]);
3291 else if (strcmp (line
, "installed=yes\n") == 0)
3295 else if (strcmp (line
, "installed=no\n") == 0)
3300 #undef STR_LIBRARY_NAMES
3301 #define STR_LIBRARY_NAMES "library_names="
3302 else if (! dlname
&& strncmp (line
, STR_LIBRARY_NAMES
,
3303 sizeof (STR_LIBRARY_NAMES
) - 1) == 0)
3306 errors
+= trim (&dlname
, &line
[sizeof (STR_LIBRARY_NAMES
) - 1]);
3309 && (last_libname
= strrchr (dlname
, ' ')) != 0)
3311 last_libname
= lt_estrdup (last_libname
+ 1);
3317 LT_DLMEM_REASSIGN (dlname
, last_libname
);
3328 /* allocate the handle */
3329 *phandle
= (lt_dlhandle
) LT_EMALLOC (struct lt_dlhandle_struct
, 1);
3335 free_vars (dlname
, old_name
, libdir
, deplibs
);
3336 LT_DLFREE (*phandle
);
3342 memset (*phandle
, 0, sizeof(struct lt_dlhandle_struct
));
3343 if (load_deplibs (*phandle
, deplibs
) == 0)
3345 newhandle
= *phandle
;
3346 /* find_module may replace newhandle */
3347 if (find_module (&newhandle
, dir
, libdir
, dlname
, old_name
, installed
))
3349 unload_deplibs (*phandle
);
3358 free_vars (dlname
, old_name
, libdir
, deplibs
);
3361 LT_DLFREE (*phandle
);
3365 if (*phandle
!= newhandle
)
3367 unload_deplibs (*phandle
);
3372 /* not a libtool module */
3373 *phandle
= (lt_dlhandle
) LT_EMALLOC (struct lt_dlhandle_struct
, 1);
3380 memset (*phandle
, 0, sizeof (struct lt_dlhandle_struct
));
3381 newhandle
= *phandle
;
3383 /* If the module has no directory name component, try to find it
3384 first in user_search_path and then other prescribed paths.
3385 Otherwise (or in any case if the module was not yet found) try
3386 opening just the module name as passed. */
3387 if ((dir
|| (!find_handle (user_search_path
, base_name
, &newhandle
)
3388 && !find_handle (getenv (LTDL_SEARCHPATH_VAR
), base_name
,
3390 #ifdef LTDL_SHLIBPATH_VAR
3391 && !find_handle (getenv (LTDL_SHLIBPATH_VAR
), base_name
,
3394 #ifdef LTDL_SYSSEARCHPATH
3395 && !find_handle (sys_search_path
, base_name
, &newhandle
)
3399 if (tryall_dlopen (&newhandle
, filename
) != 0)
3407 LT_DLFREE (*phandle
);
3414 LT_DLMEM_REASSIGN (*phandle
, newhandle
);
3416 if ((*phandle
)->info
.ref_count
== 0)
3418 (*phandle
)->info
.ref_count
= 1;
3419 LT_DLMEM_REASSIGN ((*phandle
)->info
.name
, name
);
3422 (*phandle
)->next
= handles
;
3424 LT_DLMUTEX_UNLOCK ();
3427 LT_DLMUTEX_SETERROR (saved_error
);
3432 LT_DLFREE (canonical
);
3438 lt_dlopen (filename
)
3439 const char *filename
;
3441 lt_dlhandle handle
= 0;
3443 /* Just incase we missed a code path in try_dlopen() that reports
3444 an error, but forgets to reset handle... */
3445 if (try_dlopen (&handle
, filename
) != 0)
3451 /* If the last error messge store was `FILE_NOT_FOUND', then return
3456 const char *error
= 0;
3458 LT_DLMUTEX_GETERROR (error
);
3459 if (error
== LT_DLSTRERROR (FILE_NOT_FOUND
))
3465 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3466 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3467 and if a file is still not found try again with SHLIB_EXT appended
3470 lt_dlopenext (filename
)
3471 const char *filename
;
3473 lt_dlhandle handle
= 0;
3481 return lt_dlopen (filename
);
3486 len
= LT_STRLEN (filename
);
3487 ext
= strrchr (filename
, '.');
3489 /* If FILENAME already bears a suitable extension, there is no need
3490 to try appending additional extensions. */
3491 if (ext
&& ((strcmp (ext
, archive_ext
) == 0)
3492 #ifdef LTDL_SHLIB_EXT
3493 || (strcmp (ext
, shlib_ext
) == 0)
3497 return lt_dlopen (filename
);
3500 /* First try appending ARCHIVE_EXT. */
3501 tmp
= LT_EMALLOC (char, len
+ LT_STRLEN (archive_ext
) + 1);
3505 strcpy (tmp
, filename
);
3506 strcat (tmp
, archive_ext
);
3507 errors
= try_dlopen (&handle
, tmp
);
3509 /* If we found FILENAME, stop searching -- whether we were able to
3510 load the file as a module or not. If the file exists but loading
3511 failed, it is better to return an error message here than to
3512 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3513 in the module search path. */
3514 if (handle
|| ((errors
> 0) && !file_not_found ()))
3520 #ifdef LTDL_SHLIB_EXT
3521 /* Try appending SHLIB_EXT. */
3522 if (LT_STRLEN (shlib_ext
) > LT_STRLEN (archive_ext
))
3525 tmp
= LT_EMALLOC (char, len
+ LT_STRLEN (shlib_ext
) + 1);
3529 strcpy (tmp
, filename
);
3533 tmp
[len
] = LT_EOS_CHAR
;
3536 strcat(tmp
, shlib_ext
);
3537 errors
= try_dlopen (&handle
, tmp
);
3539 /* As before, if the file was found but loading failed, return now
3540 with the current error message. */
3541 if (handle
|| ((errors
> 0) && !file_not_found ()))
3548 /* Still here? Then we really did fail to locate any of the file
3550 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
3557 lt_argz_insert (pargz
, pargz_len
, before
, entry
)
3565 /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
3566 pargz_len, NULL, entry) failed with EINVAL. */
3568 error
= argz_insert (pargz
, pargz_len
, before
, entry
);
3570 error
= argz_append (pargz
, pargz_len
, entry
, 1 + LT_STRLEN (entry
));
3577 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
3580 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN
));
3590 lt_argz_insertinorder (pargz
, pargz_len
, entry
)
3599 assert (entry
&& *entry
);
3602 while ((before
= argz_next (*pargz
, *pargz_len
, before
)))
3604 int cmp
= strcmp (entry
, before
);
3607 if (cmp
== 0) return 0; /* No duplicates! */
3610 return lt_argz_insert (pargz
, pargz_len
, before
, entry
);
3614 lt_argz_insertdir (pargz
, pargz_len
, dirnam
, dp
)
3623 size_t end_offset
= 0;
3631 dir_len
= LT_STRLEN (dirnam
);
3632 end
= dp
->d_name
+ LT_D_NAMLEN(dp
);
3634 /* Ignore version numbers. */
3637 for (p
= end
; p
-1 > dp
->d_name
; --p
)
3638 if (strchr (".0123456789", p
[-1]) == 0)
3645 /* Ignore filename extension. */
3648 for (p
= end
-1; p
> dp
->d_name
; --p
)
3656 /* Prepend the directory name. */
3657 end_offset
= end
- dp
->d_name
;
3658 buf_len
= dir_len
+ 1+ end_offset
;
3659 buf
= LT_EMALLOC (char, 1+ buf_len
);
3665 strcpy (buf
, dirnam
);
3667 strncat (buf
, dp
->d_name
, end_offset
);
3668 buf
[buf_len
] = LT_EOS_CHAR
;
3670 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3671 if (lt_argz_insertinorder (pargz
, pargz_len
, buf
) != 0)
3680 list_files_by_dir (dirnam
, pargz
, pargz_len
)
3688 assert (dirnam
&& *dirnam
);
3691 assert (dirnam
[LT_STRLEN(dirnam
) -1] != '/');
3693 dirp
= opendir (dirnam
);
3696 struct dirent
*dp
= 0;
3698 while ((dp
= readdir (dirp
)))
3699 if (dp
->d_name
[0] != '.')
3700 if (lt_argz_insertdir (pargz
, pargz_len
, dirnam
, dp
))
3715 /* If there are any files in DIRNAME, call the function passed in
3716 DATA1 (with the name of each file and DATA2 as arguments). */
3718 foreachfile_callback (dirname
, data1
, data2
)
3723 int (*func
) LT_PARAMS((const char *filename
, lt_ptr data
))
3724 = (int (*) LT_PARAMS((const char *filename
, lt_ptr data
))) data1
;
3728 size_t argz_len
= 0;
3730 if (list_files_by_dir (dirname
, &argz
, &argz_len
) != 0)
3737 while ((filename
= argz_next (argz
, argz_len
, filename
)))
3738 if ((is_done
= (*func
) (filename
, data2
)))
3749 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3750 with DATA. The filenames passed to FUNC would be suitable for
3751 passing to lt_dlopenext. The extensions are stripped so that
3752 individual modules do not generate several entries (e.g. libfoo.la,
3753 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3754 then the same directories that lt_dlopen would search are examined. */
3756 lt_dlforeachfile (search_path
, func
, data
)
3757 const char *search_path
;
3758 int (*func
) LT_PARAMS ((const char *filename
, lt_ptr data
));
3765 /* If a specific path was passed, search only the directories
3767 is_done
= foreach_dirinpath (search_path
, 0,
3768 foreachfile_callback
, func
, data
);
3772 /* Otherwise search the default paths. */
3773 is_done
= foreach_dirinpath (user_search_path
, 0,
3774 foreachfile_callback
, func
, data
);
3777 is_done
= foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3778 foreachfile_callback
, func
, data
);
3781 #ifdef LTDL_SHLIBPATH_VAR
3784 is_done
= foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR
), 0,
3785 foreachfile_callback
, func
, data
);
3788 #ifdef LTDL_SYSSEARCHPATH
3791 is_done
= foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH
), 0,
3792 foreachfile_callback
, func
, data
);
3804 lt_dlhandle cur
, last
;
3809 /* check whether the handle is valid */
3810 last
= cur
= handles
;
3811 while (cur
&& handle
!= cur
)
3819 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
3824 handle
->info
.ref_count
--;
3826 /* Note that even with resident modules, we must track the ref_count
3827 correctly incase the user decides to reset the residency flag
3828 later (even though the API makes no provision for that at the
3830 if (handle
->info
.ref_count
<= 0 && !LT_DLIS_RESIDENT (handle
))
3832 lt_user_data data
= handle
->loader
->dlloader_data
;
3834 if (handle
!= handles
)
3836 last
->next
= handle
->next
;
3840 handles
= handle
->next
;
3843 errors
+= handle
->loader
->module_close (data
, handle
->module
);
3844 errors
+= unload_deplibs(handle
);
3846 /* It is up to the callers to free the data itself. */
3847 LT_DLFREE (handle
->caller_data
);
3849 LT_DLFREE (handle
->info
.filename
);
3850 LT_DLFREE (handle
->info
.name
);
3856 if (LT_DLIS_RESIDENT (handle
))
3858 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE
));
3863 LT_DLMUTEX_UNLOCK ();
3869 lt_dlsym (handle
, symbol
)
3874 char lsym
[LT_SYMBOL_LENGTH
];
3881 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
3887 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
3891 lensym
= LT_STRLEN (symbol
) + LT_STRLEN (handle
->loader
->sym_prefix
)
3892 + LT_STRLEN (handle
->info
.name
);
3894 if (lensym
+ LT_SYMBOL_OVERHEAD
< LT_SYMBOL_LENGTH
)
3900 sym
= LT_EMALLOC (char, lensym
+ LT_SYMBOL_OVERHEAD
+ 1);
3903 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW
));
3908 data
= handle
->loader
->dlloader_data
;
3909 if (handle
->info
.name
)
3911 const char *saved_error
;
3913 LT_DLMUTEX_GETERROR (saved_error
);
3915 /* this is a libtool module */
3916 if (handle
->loader
->sym_prefix
)
3918 strcpy(sym
, handle
->loader
->sym_prefix
);
3919 strcat(sym
, handle
->info
.name
);
3923 strcpy(sym
, handle
->info
.name
);
3926 strcat(sym
, "_LTX_");
3927 strcat(sym
, symbol
);
3929 /* try "modulename_LTX_symbol" */
3930 address
= handle
->loader
->find_sym (data
, handle
->module
, sym
);
3939 LT_DLMUTEX_SETERROR (saved_error
);
3942 /* otherwise try "symbol" */
3943 if (handle
->loader
->sym_prefix
)
3945 strcpy(sym
, handle
->loader
->sym_prefix
);
3946 strcat(sym
, symbol
);
3950 strcpy(sym
, symbol
);
3953 address
= handle
->loader
->find_sym (data
, handle
->module
, sym
);
3967 LT_DLMUTEX_GETERROR (error
);
3968 LT_DLMUTEX_SETERROR (0);
3970 return error
? error
: NULL
;
3974 lt_dlpath_insertdir (ppath
, before
, dir
)
3980 char *canonical
= 0;
3982 size_t argz_len
= 0;
3985 assert (dir
&& *dir
);
3987 if (canonicalize_path (dir
, &canonical
) != 0)
3993 assert (canonical
&& *canonical
);
3995 /* If *PPATH is empty, set it to DIR. */
3998 assert (!before
); /* BEFORE cannot be set without PPATH. */
3999 assert (dir
); /* Without DIR, don't call this function! */
4001 *ppath
= lt_estrdup (dir
);
4008 assert (ppath
&& *ppath
);
4010 if (argzize_path (*ppath
, &argz
, &argz_len
) != 0)
4016 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
4017 if *PPATH is already canonicalized, and hence does not change length
4018 with respect to ARGZ. We canonicalize each entry as it is added to
4019 the search path, and don't call this function with (uncanonicalized)
4020 user paths, so this is a fair assumption. */
4023 assert (*ppath
<= before
);
4024 assert (before
- *ppath
<= strlen (*ppath
));
4026 before
= before
- *ppath
+ argz
;
4029 if (lt_argz_insert (&argz
, &argz_len
, before
, dir
) != 0)
4035 argz_stringify (argz
, argz_len
, LT_PATHSEP_CHAR
);
4036 LT_DLMEM_REASSIGN (*ppath
, argz
);
4039 LT_DLFREE (canonical
);
4046 lt_dladdsearchdir (search_dir
)
4047 const char *search_dir
;
4051 if (search_dir
&& *search_dir
)
4054 if (lt_dlpath_insertdir (&user_search_path
, 0, search_dir
) != 0)
4056 LT_DLMUTEX_UNLOCK ();
4063 lt_dlinsertsearchdir (before
, search_dir
)
4065 const char *search_dir
;
4072 if ((before
< user_search_path
)
4073 || (before
>= user_search_path
+ LT_STRLEN (user_search_path
)))
4075 LT_DLMUTEX_UNLOCK ();
4076 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION
));
4079 LT_DLMUTEX_UNLOCK ();
4082 if (search_dir
&& *search_dir
)
4085 if (lt_dlpath_insertdir (&user_search_path
,
4086 (char *) before
, search_dir
) != 0)
4090 LT_DLMUTEX_UNLOCK ();
4097 lt_dlsetsearchpath (search_path
)
4098 const char *search_path
;
4103 LT_DLFREE (user_search_path
);
4104 LT_DLMUTEX_UNLOCK ();
4106 if (!search_path
|| !LT_STRLEN (search_path
))
4112 if (canonicalize_path (search_path
, &user_search_path
) != 0)
4114 LT_DLMUTEX_UNLOCK ();
4120 lt_dlgetsearchpath ()
4122 const char *saved_path
;
4125 saved_path
= user_search_path
;
4126 LT_DLMUTEX_UNLOCK ();
4132 lt_dlmakeresident (handle
)
4139 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
4144 LT_DLSET_FLAG (handle
, LT_DLRESIDENT_FLAG
);
4151 lt_dlisresident (handle
)
4156 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
4160 return LT_DLIS_RESIDENT (handle
);
4166 /* --- MODULE INFORMATION --- */
4169 lt_dlgetinfo (handle
)
4174 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
4178 return &(handle
->info
);
4182 lt_dlhandle_next (place
)
4185 return place
? place
->next
: handles
;
4189 lt_dlforeach (func
, data
)
4190 int (*func
) LT_PARAMS((lt_dlhandle handle
, lt_ptr data
));
4201 lt_dlhandle tmp
= cur
;
4204 if ((*func
) (tmp
, data
))
4211 LT_DLMUTEX_UNLOCK ();
4217 lt_dlcaller_register ()
4219 static lt_dlcaller_id last_caller_id
= 0;
4223 result
= ++last_caller_id
;
4224 LT_DLMUTEX_UNLOCK ();
4230 lt_dlcaller_set_data (key
, handle
, data
)
4236 lt_ptr stale
= (lt_ptr
) 0;
4239 /* This needs to be locked so that the caller data can be updated
4240 simultaneously by different threads. */
4243 if (handle
->caller_data
)
4244 while (handle
->caller_data
[n_elements
].key
)
4247 for (i
= 0; i
< n_elements
; ++i
)
4249 if (handle
->caller_data
[i
].key
== key
)
4251 stale
= handle
->caller_data
[i
].data
;
4256 /* Ensure that there is enough room in this handle's caller_data
4257 array to accept a new element (and an empty end marker). */
4258 if (i
== n_elements
)
4260 lt_caller_data
*temp
4261 = LT_DLREALLOC (lt_caller_data
, handle
->caller_data
, 2+ n_elements
);
4269 handle
->caller_data
= temp
;
4271 /* We only need this if we needed to allocate a new caller_data. */
4272 handle
->caller_data
[i
].key
= key
;
4273 handle
->caller_data
[1+ i
].key
= 0;
4276 handle
->caller_data
[i
].data
= data
;
4279 LT_DLMUTEX_UNLOCK ();
4285 lt_dlcaller_get_data (key
, handle
)
4289 lt_ptr result
= (lt_ptr
) 0;
4291 /* This needs to be locked so that the caller data isn't updated by
4292 another thread part way through this function. */
4295 /* Locate the index of the element with a matching KEY. */
4298 for (i
= 0; handle
->caller_data
[i
].key
; ++i
)
4300 if (handle
->caller_data
[i
].key
== key
)
4302 result
= handle
->caller_data
[i
].data
;
4308 LT_DLMUTEX_UNLOCK ();
4315 /* --- USER MODULE LOADER API --- */
4319 lt_dlloader_add (place
, dlloader
, loader_name
)
4321 const struct lt_user_dlloader
*dlloader
;
4322 const char *loader_name
;
4325 lt_dlloader
*node
= 0, *ptr
= 0;
4327 if ((dlloader
== 0) /* diagnose null parameters */
4328 || (dlloader
->module_open
== 0)
4329 || (dlloader
->module_close
== 0)
4330 || (dlloader
->find_sym
== 0))
4332 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4336 /* Create a new dlloader node with copies of the user callbacks. */
4337 node
= LT_EMALLOC (lt_dlloader
, 1);
4342 node
->loader_name
= loader_name
;
4343 node
->sym_prefix
= dlloader
->sym_prefix
;
4344 node
->dlloader_exit
= dlloader
->dlloader_exit
;
4345 node
->module_open
= dlloader
->module_open
;
4346 node
->module_close
= dlloader
->module_close
;
4347 node
->find_sym
= dlloader
->find_sym
;
4348 node
->dlloader_data
= dlloader
->dlloader_data
;
4353 /* If there are no loaders, NODE becomes the list! */
4358 /* If PLACE is not set, add NODE to the end of the
4360 for (ptr
= loaders
; ptr
->next
; ptr
= ptr
->next
)
4367 else if (loaders
== place
)
4369 /* If PLACE is the first loader, NODE goes first. */
4375 /* Find the node immediately preceding PLACE. */
4376 for (ptr
= loaders
; ptr
->next
!= place
; ptr
= ptr
->next
)
4381 if (ptr
->next
!= place
)
4383 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4388 /* Insert NODE between PTR and PLACE. */
4394 LT_DLMUTEX_UNLOCK ();
4400 lt_dlloader_remove (loader_name
)
4401 const char *loader_name
;
4403 lt_dlloader
*place
= lt_dlloader_find (loader_name
);
4409 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4415 /* Fail if there are any open modules which use this loader. */
4416 for (handle
= handles
; handle
; handle
= handle
->next
)
4418 if (handle
->loader
== place
)
4420 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER
));
4426 if (place
== loaders
)
4428 /* PLACE is the first loader in the list. */
4429 loaders
= loaders
->next
;
4433 /* Find the loader before the one being removed. */
4435 for (prev
= loaders
; prev
->next
; prev
= prev
->next
)
4437 if (!strcmp (prev
->next
->loader_name
, loader_name
))
4444 prev
->next
= prev
->next
->next
;
4447 if (place
->dlloader_exit
)
4449 errors
= place
->dlloader_exit (place
->dlloader_data
);
4455 LT_DLMUTEX_UNLOCK ();
4461 lt_dlloader_next (place
)
4467 next
= place
? place
->next
: loaders
;
4468 LT_DLMUTEX_UNLOCK ();
4474 lt_dlloader_name (place
)
4477 const char *name
= 0;
4482 name
= place
? place
->loader_name
: 0;
4483 LT_DLMUTEX_UNLOCK ();
4487 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4494 lt_dlloader_data (place
)
4497 lt_user_data
*data
= 0;
4502 data
= place
? &(place
->dlloader_data
) : 0;
4503 LT_DLMUTEX_UNLOCK ();
4507 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4514 lt_dlloader_find (loader_name
)
4515 const char *loader_name
;
4517 lt_dlloader
*place
= 0;
4520 for (place
= loaders
; place
; place
= place
->next
)
4522 if (strcmp (place
->loader_name
, loader_name
) == 0)
4527 LT_DLMUTEX_UNLOCK ();