1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3 Originally by Thomas Tanner <tanner@ffii.org>
4 This file is part of GNU Libtool.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 As a special exception to the GNU Lesser General Public License,
12 if you distribute this file as part of a program or library that
13 is built using GNU libtool, you may include it under the same
14 distribution terms that you use for the rest of that program.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
80 #undef LT_USE_POSIX_DIRENT
85 # define LT_USE_POSIX_DIRENT
86 # endif /* HAVE_DIRENT_H */
87 # endif /* HAVE_READDIR */
88 # endif /* HAVE_OPENDIR */
89 #endif /* HAVE_CLOSEDIR */
92 #undef LT_USE_WINDOWS_DIRENT_EMULATION
93 #ifndef LT_USE_POSIX_DIRENT
95 # define LT_USE_WINDOWS_DIRENT_EMULATION
96 # endif /* __WINDOWS__ */
97 #endif /* LT_USE_POSIX_DIRENT */
100 #ifdef LT_USE_POSIX_DIRENT
102 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
104 # ifdef LT_USE_WINDOWS_DIRENT_EMULATION
105 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
107 # define dirent direct
108 # define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
110 # include <sys/ndir.h>
113 # include <sys/dir.h>
128 # define assert(arg) ((void) 0)
134 # include <dmalloc.h>
140 /* --- WINDOWS SUPPORT --- */
144 # define LT_GLOBAL_DATA __declspec(dllexport)
146 # define LT_GLOBAL_DATA
149 /* fopen() mode flags for reading a text file */
150 #undef LT_READTEXT_MODE
152 # define LT_READTEXT_MODE "rt"
154 # define LT_READTEXT_MODE "r"
157 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
161 #define dirent lt_dirent
173 WIN32_FIND_DATA Win32FindData
;
175 struct dirent file_info
;
178 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
181 /* --- MANIFEST CONSTANTS --- */
184 /* Standard libltdl search path environment variable name */
185 #undef LTDL_SEARCHPATH_VAR
186 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
188 /* Standard libtool archive file extension. */
189 #undef LTDL_ARCHIVE_EXT
190 #define LTDL_ARCHIVE_EXT ".la"
192 /* max. filename length */
193 #ifndef LT_FILENAME_MAX
194 # define LT_FILENAME_MAX 1024
197 /* This is the maximum symbol size that won't require malloc/free */
198 #undef LT_SYMBOL_LENGTH
199 #define LT_SYMBOL_LENGTH 128
201 /* This accounts for the _LTX_ separator */
202 #undef LT_SYMBOL_OVERHEAD
203 #define LT_SYMBOL_OVERHEAD 5
208 /* --- MEMORY HANDLING --- */
211 /* These are the functions used internally. In addition to making
212 use of the associated function pointers above, they also perform
214 static char *lt_estrdup
LT_PARAMS((const char *str
));
215 static lt_ptr lt_emalloc
LT_PARAMS((size_t size
));
216 static lt_ptr lt_erealloc
LT_PARAMS((lt_ptr addr
, size_t size
));
218 /* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */
219 #define rpl_realloc realloc
221 /* These are the pointers that can be changed by the caller: */
222 LT_GLOBAL_DATA
lt_ptr (*lt_dlmalloc
) LT_PARAMS((size_t size
))
223 = (lt_ptr (*) LT_PARAMS((size_t))) malloc
;
224 LT_GLOBAL_DATA
lt_ptr (*lt_dlrealloc
) LT_PARAMS((lt_ptr ptr
, size_t size
))
225 = (lt_ptr (*) LT_PARAMS((lt_ptr
, size_t))) rpl_realloc
;
226 LT_GLOBAL_DATA
void (*lt_dlfree
) LT_PARAMS((lt_ptr ptr
))
227 = (void (*) LT_PARAMS((lt_ptr
))) free
;
229 /* The following macros reduce the amount of typing needed to cast
233 #define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
234 #define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
235 #define LT_DLFREE(p) \
236 LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
238 #define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
239 #define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
243 #define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
244 #define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
245 #define LT_DLFREE(p) \
246 LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
248 #define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
249 #define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
253 #define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
254 if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \
258 /* --- REPLACEMENT FUNCTIONS --- */
262 #define strdup rpl_strdup
264 static char *strdup
LT_PARAMS((const char *str
));
274 tmp
= LT_DLMALLOC (char, 1+ strlen (str
));
288 #define strcmp rpl_strcmp
290 static int strcmp
LT_PARAMS((const char *str1
, const char *str2
));
304 for (;*str1
&& *str2
; ++str1
, ++str2
)
310 return (int)(*str1
- *str2
);
318 # define strchr index
320 # define strchr rpl_strchr
322 static const char *strchr
LT_PARAMS((const char *str
, int ch
));
331 for (p
= str
; *p
!= (char)ch
&& *p
!= LT_EOS_CHAR
; ++p
)
334 return (*p
== (char)ch
) ? p
: 0;
338 #endif /* !HAVE_STRCHR */
344 # define strrchr rindex
346 # define strrchr rpl_strrchr
348 static const char *strrchr
LT_PARAMS((const char *str
, int ch
));
355 const char *p
, *q
= 0;
357 for (p
= str
; *p
!= LT_EOS_CHAR
; ++p
)
371 /* NOTE: Neither bcopy nor the memcpy implementation below can
372 reliably handle copying in overlapping areas of memory. Use
373 memmove (for which there is a fallback implmentation below)
374 if you need that behaviour. */
378 # define memcpy(dest, src, size) bcopy (src, dest, size)
380 # define memcpy rpl_memcpy
382 static lt_ptr memcpy
LT_PARAMS((lt_ptr dest
, const lt_ptr src
, size_t size
));
385 memcpy (dest
, src
, size
)
392 for (i
= 0; i
< size
; ++i
)
400 # endif /* !HAVE_BCOPY */
401 #endif /* !HAVE_MEMCPY */
404 # define memmove rpl_memmove
406 static lt_ptr memmove
LT_PARAMS((lt_ptr dest
, const lt_ptr src
, size_t size
));
409 memmove (dest
, src
, size
)
417 for (i
= 0; i
< size
; ++i
)
422 for (i
= size
-1; i
>= 0; --i
)
430 #endif /* !HAVE_MEMMOVE */
432 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
434 static void closedir
LT_PARAMS((DIR *entry
));
440 assert(entry
!= (DIR *) NULL
);
441 FindClose(entry
->hSearch
);
442 lt_dlfree((lt_ptr
)entry
);
446 static DIR * opendir
LT_PARAMS((const char *path
));
452 char file_specification
[LT_FILENAME_MAX
];
455 assert(path
!= (char *) NULL
);
456 (void) strncpy(file_specification
,path
,LT_FILENAME_MAX
-1);
457 (void) strcat(file_specification
,"\\");
458 entry
= LT_DLMALLOC (DIR,sizeof(DIR));
459 if (entry
!= (DIR *) 0)
461 entry
->firsttime
= TRUE
;
462 entry
->hSearch
= FindFirstFile(file_specification
,&entry
->Win32FindData
);
464 if (entry
->hSearch
== INVALID_HANDLE_VALUE
)
466 (void) strcat(file_specification
,"\\*.*");
467 entry
->hSearch
= FindFirstFile(file_specification
,&entry
->Win32FindData
);
468 if (entry
->hSearch
== INVALID_HANDLE_VALUE
)
478 static struct dirent
*readdir
LT_PARAMS((DIR *entry
));
480 static struct dirent
*readdir(entry
)
486 if (entry
== (DIR *) 0)
487 return((struct dirent
*) 0);
488 if (!entry
->firsttime
)
490 status
= FindNextFile(entry
->hSearch
,&entry
->Win32FindData
);
492 return((struct dirent
*) 0);
494 entry
->firsttime
= FALSE
;
495 (void) strncpy(entry
->file_info
.d_name
,entry
->Win32FindData
.cFileName
,
497 entry
->file_info
.d_namlen
= strlen(entry
->file_info
.d_name
);
498 return(&entry
->file_info
);
501 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
503 /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
504 ``realloc is not entirely portable''
505 In any case we want to use the allocator supplied by the user without
506 burdening them with an lt_dlrealloc function pointer to maintain.
507 Instead implement our own version (with known boundary conditions)
508 using lt_dlmalloc and lt_dlfree. */
511 #define realloc rpl_realloc
514 /* You can't (re)define realloc unless you also (re)define malloc.
515 Right now, this code uses the size of the *destination* to decide
516 how much to copy. That's not right, but you can't know the size
517 of the source unless you know enough about, or wrote malloc. So
518 this code is disabled... */
527 /* For zero or less bytes, free the original memory */
537 /* Allow reallocation of a NULL pointer. */
538 return lt_dlmalloc (size
);
542 /* Allocate a new block, copy and free the old block. */
543 lt_ptr mem
= lt_dlmalloc (size
);
547 memcpy (mem
, ptr
, size
);
551 /* Note that the contents of PTR are not damaged if there is
552 insufficient memory to realloc. */
559 #if ! HAVE_ARGZ_APPEND
560 # define argz_append rpl_argz_append
562 static error_t argz_append
LT_PARAMS((char **pargz
, size_t *pargz_len
,
563 const char *buf
, size_t buf_len
));
566 argz_append (pargz
, pargz_len
, buf
, buf_len
)
577 assert ((*pargz
&& *pargz_len
) || (!*pargz
&& !*pargz_len
));
579 /* If nothing needs to be appended, no more work is required. */
583 /* Ensure there is enough room to append BUF_LEN. */
584 argz_len
= *pargz_len
+ buf_len
;
585 argz
= LT_DLREALLOC (char, *pargz
, argz_len
);
589 /* Copy characters from BUF after terminating '\0' in ARGZ. */
590 memcpy (argz
+ *pargz_len
, buf
, buf_len
);
592 /* Assign new values. */
594 *pargz_len
= argz_len
;
598 #endif /* !HAVE_ARGZ_APPEND */
601 #if ! HAVE_ARGZ_CREATE_SEP
602 # define argz_create_sep rpl_argz_create_sep
604 static error_t argz_create_sep
LT_PARAMS((const char *str
, int delim
,
605 char **pargz
, size_t *pargz_len
));
608 argz_create_sep (str
, delim
, pargz
, pargz_len
)
621 /* Make a copy of STR, but replacing each occurence of
623 argz_len
= 1+ LT_STRLEN (str
);
629 argz
= LT_DLMALLOC (char, argz_len
);
633 for (p
= str
, q
= argz
; *p
!= LT_EOS_CHAR
; ++p
)
637 /* Ignore leading delimiters, and fold consecutive
638 delimiters in STR into a single '\0' in ARGZ. */
639 if ((q
> argz
) && (q
[-1] != LT_EOS_CHAR
))
647 /* Copy terminating LT_EOS_CHAR. */
651 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
655 /* Assign new values. */
657 *pargz_len
= argz_len
;
661 #endif /* !HAVE_ARGZ_CREATE_SEP */
664 #if ! HAVE_ARGZ_INSERT
665 # define argz_insert rpl_argz_insert
667 static error_t argz_insert
LT_PARAMS((char **pargz
, size_t *pargz_len
,
668 char *before
, const char *entry
));
671 argz_insert (pargz
, pargz_len
, before
, entry
)
679 assert (entry
&& *entry
);
681 /* No BEFORE address indicates ENTRY should be inserted after the
682 current last element. */
684 return argz_append (pargz
, pargz_len
, entry
, 1+ LT_STRLEN (entry
));
686 /* This probably indicates a programmer error, but to preserve
687 semantics, scan back to the start of an entry if BEFORE points
688 into the middle of it. */
689 while ((before
>= *pargz
) && (before
[-1] != LT_EOS_CHAR
))
693 size_t entry_len
= 1+ LT_STRLEN (entry
);
694 size_t argz_len
= *pargz_len
+ entry_len
;
695 size_t offset
= before
- *pargz
;
696 char *argz
= LT_DLREALLOC (char, *pargz
, argz_len
);
701 /* Make BEFORE point to the equivalent offset in ARGZ that it
702 used to have in *PARGZ incase realloc() moved the block. */
703 before
= argz
+ offset
;
705 /* Move the ARGZ entries starting at BEFORE up into the new
706 space at the end -- making room to copy ENTRY into the
708 memmove (before
+ entry_len
, before
, *pargz_len
- offset
);
709 memcpy (before
, entry
, entry_len
);
711 /* Assign new values. */
713 *pargz_len
= argz_len
;
718 #endif /* !HAVE_ARGZ_INSERT */
722 # define argz_next rpl_argz_next
724 static char *argz_next
LT_PARAMS((char *argz
, size_t argz_len
,
728 argz_next (argz
, argz_len
, entry
)
733 assert ((argz
&& argz_len
) || (!argz
&& !argz_len
));
737 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
738 within the ARGZ vector. */
739 assert ((!argz
&& !argz_len
)
740 || ((argz
<= entry
) && (entry
< (argz
+ argz_len
))));
742 /* Move to the char immediately after the terminating
744 entry
= 1+ strchr (entry
, LT_EOS_CHAR
);
746 /* Return either the new ENTRY, or else NULL if ARGZ is
748 return (entry
>= argz
+ argz_len
) ? 0 : (char *) entry
;
752 /* This should probably be flagged as a programmer error,
753 since starting an argz_next loop with the iterator set
754 to ARGZ is safer. To preserve semantics, handle the NULL
755 case by returning the start of ARGZ (if any). */
762 #endif /* !HAVE_ARGZ_NEXT */
766 #if ! HAVE_ARGZ_STRINGIFY
767 # define argz_stringify rpl_argz_stringify
769 static void argz_stringify
LT_PARAMS((char *argz
, size_t argz_len
,
773 argz_stringify (argz
, argz_len
, sep
)
778 assert ((argz
&& argz_len
) || (!argz
&& !argz_len
));
782 --argz_len
; /* don't stringify the terminating EOS */
783 while (--argz_len
> 0)
785 if (argz
[argz_len
] == LT_EOS_CHAR
)
786 argz
[argz_len
] = sep
;
790 #endif /* !HAVE_ARGZ_STRINGIFY */
795 /* --- TYPE DEFINITIONS -- */
798 /* This type is used for the array of caller data sets in each handler. */
807 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
810 /* Extract the diagnostic strings from the error table macro in the same
811 order as the enumerated indices in ltdl.h. */
813 static const char *lt_dlerror_strings
[] =
815 #define LT_ERROR(name, diagnostic) (diagnostic),
822 /* This structure is used for the list of registered loaders. */
824 struct lt_dlloader
*next
;
825 const char *loader_name
; /* identifying name for each loader */
826 const char *sym_prefix
; /* prefix for symbols */
827 lt_module_open
*module_open
;
828 lt_module_close
*module_close
;
829 lt_find_sym
*find_sym
;
830 lt_dlloader_exit
*dlloader_exit
;
831 lt_user_data dlloader_data
;
834 struct lt_dlhandle_struct
{
835 struct lt_dlhandle_struct
*next
;
836 lt_dlloader
*loader
; /* dlopening interface */
838 int depcount
; /* number of dependencies */
839 lt_dlhandle
*deplibs
; /* dependencies */
840 lt_module module
; /* system module handle */
841 lt_ptr system
; /* system specific data */
842 lt_caller_data
*caller_data
; /* per caller associated data */
843 int flags
; /* various boolean stats */
846 /* Various boolean flags can be stored in the flags field of an
847 lt_dlhandle_struct... */
848 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
849 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
851 #define LT_DLRESIDENT_FLAG (0x01 << 0)
852 /* ...add more flags here... */
854 #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
857 #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
859 static const char objdir
[] = LTDL_OBJDIR
;
860 static const char archive_ext
[] = LTDL_ARCHIVE_EXT
;
861 #ifdef LTDL_SHLIB_EXT
862 static const char shlib_ext
[] = LTDL_SHLIB_EXT
;
864 #ifdef LTDL_SYSSEARCHPATH
865 static const char sys_search_path
[] = LTDL_SYSSEARCHPATH
;
871 /* --- MUTEX LOCKING --- */
874 /* Macros to make it easier to run the lock functions only if they have
875 been registered. The reason for the complicated lock macro is to
876 ensure that the stored error message from the last error is not
877 accidentally erased if the current function doesn't generate an
879 #define LT_DLMUTEX_LOCK() LT_STMT_START { \
880 if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
882 #define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
883 if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
885 #define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
886 if (lt_dlmutex_seterror_func) \
887 (*lt_dlmutex_seterror_func) (errormsg); \
888 else lt_dllast_error = (errormsg); } LT_STMT_END
889 #define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
890 if (lt_dlmutex_seterror_func) \
891 (errormsg) = (*lt_dlmutex_geterror_func) (); \
892 else (errormsg) = lt_dllast_error; } LT_STMT_END
894 /* The mutex functions stored here are global, and are necessarily the
895 same for all threads that wish to share access to libltdl. */
896 static lt_dlmutex_lock
*lt_dlmutex_lock_func
= 0;
897 static lt_dlmutex_unlock
*lt_dlmutex_unlock_func
= 0;
898 static lt_dlmutex_seterror
*lt_dlmutex_seterror_func
= 0;
899 static lt_dlmutex_geterror
*lt_dlmutex_geterror_func
= 0;
900 static const char *lt_dllast_error
= 0;
903 /* Either set or reset the mutex functions. Either all the arguments must
904 be valid functions, or else all can be NULL to turn off locking entirely.
905 The registered functions should be manipulating a static global lock
906 from the lock() and unlock() callbacks, which needs to be reentrant. */
908 lt_dlmutex_register (lock
, unlock
, seterror
, geterror
)
909 lt_dlmutex_lock
*lock
;
910 lt_dlmutex_unlock
*unlock
;
911 lt_dlmutex_seterror
*seterror
;
912 lt_dlmutex_geterror
*geterror
;
914 lt_dlmutex_unlock
*old_unlock
= unlock
;
917 /* Lock using the old lock() callback, if any. */
920 if ((lock
&& unlock
&& seterror
&& geterror
)
921 || !(lock
|| unlock
|| seterror
|| geterror
))
923 lt_dlmutex_lock_func
= lock
;
924 lt_dlmutex_unlock_func
= unlock
;
925 lt_dlmutex_geterror_func
= geterror
;
929 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS
));
933 /* Use the old unlock() callback we saved earlier, if any. Otherwise
934 record any errors using internal storage. */
938 /* Return the number of errors encountered during the execution of
946 /* --- ERROR HANDLING --- */
949 static const char **user_error_strings
= 0;
950 static int errorcount
= LT_ERROR_MAX
;
953 lt_dladderror (diagnostic
)
954 const char *diagnostic
;
958 const char **temp
= (const char **) 0;
964 errindex
= errorcount
- LT_ERROR_MAX
;
965 temp
= LT_EREALLOC (const char *, user_error_strings
, 1 + errindex
);
968 user_error_strings
= temp
;
969 user_error_strings
[errindex
] = diagnostic
;
970 result
= errorcount
++;
973 LT_DLMUTEX_UNLOCK ();
979 lt_dlseterror (errindex
)
986 if (errindex
>= errorcount
|| errindex
< 0)
988 /* Ack! Error setting the error message! */
989 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE
));
992 else if (errindex
< LT_ERROR_MAX
)
994 /* No error setting the error message! */
995 LT_DLMUTEX_SETERROR (lt_dlerror_strings
[errindex
]);
999 /* No error setting the error message! */
1000 LT_DLMUTEX_SETERROR (user_error_strings
[errindex
- LT_ERROR_MAX
]);
1003 LT_DLMUTEX_UNLOCK ();
1012 lt_ptr mem
= lt_dlmalloc (size
);
1014 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
1019 lt_erealloc (addr
, size
)
1023 lt_ptr mem
= realloc (addr
, size
);
1025 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
1033 char *copy
= strdup (str
);
1034 if (LT_STRLEN (str
) && !copy
)
1035 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
1042 /* --- DLOPEN() INTERFACE LOADER --- */
1047 /* dynamic linking with dlopen/dlsym */
1054 # include <sys/dl.h>
1058 # define LT_GLOBAL RTLD_GLOBAL
1061 # define LT_GLOBAL DL_GLOBAL
1063 #endif /* !RTLD_GLOBAL */
1065 # define LT_GLOBAL 0
1066 #endif /* !LT_GLOBAL */
1068 /* We may have to define LT_LAZY_OR_NOW in the command line if we
1069 find out it does not work in some platform. */
1070 #ifndef LT_LAZY_OR_NOW
1072 # define LT_LAZY_OR_NOW RTLD_LAZY
1075 # define LT_LAZY_OR_NOW DL_LAZY
1077 # endif /* !RTLD_LAZY */
1079 #ifndef LT_LAZY_OR_NOW
1081 # define LT_LAZY_OR_NOW RTLD_NOW
1084 # define LT_LAZY_OR_NOW DL_NOW
1086 # endif /* !RTLD_NOW */
1088 #ifndef LT_LAZY_OR_NOW
1089 # define LT_LAZY_OR_NOW 0
1090 #endif /* !LT_LAZY_OR_NOW */
1093 # define DLERROR(arg) dlerror ()
1095 # define DLERROR(arg) LT_DLSTRERROR (arg)
1099 sys_dl_open (loader_data
, filename
)
1100 lt_user_data loader_data
;
1101 const char *filename
;
1103 lt_module module
= dlopen (filename
, LT_GLOBAL
| LT_LAZY_OR_NOW
);
1107 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN
));
1114 sys_dl_close (loader_data
, module
)
1115 lt_user_data loader_data
;
1120 if (dlclose (module
) != 0)
1122 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE
));
1130 sys_dl_sym (loader_data
, module
, symbol
)
1131 lt_user_data loader_data
;
1135 lt_ptr address
= dlsym (module
, symbol
);
1139 LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND
));
1145 static struct lt_user_dlloader sys_dl
=
1152 sys_dl_open
, sys_dl_close
, sys_dl_sym
, 0, 0 };
1155 #endif /* HAVE_LIBDL */
1159 /* --- SHL_LOAD() INTERFACE LOADER --- */
1163 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1169 /* some flags are missing on some systems, so we provide
1170 * harmless defaults.
1173 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1174 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1177 * BIND_FIRST - Place the library at the head of the symbol search
1179 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1180 * unsatisfied symbols as fatal. This flag allows
1181 * binding of unsatisfied code symbols to be deferred
1183 * [Perl: For certain libraries, like DCE, deferred
1184 * binding often causes run time problems. Adding
1185 * BIND_NONFATAL to BIND_IMMEDIATE still allows
1186 * unresolved references in situations like this.]
1187 * BIND_NOSTART - Do not call the initializer for the shared library
1188 * when the library is loaded, nor on a future call to
1190 * BIND_VERBOSE - Print verbose messages concerning possible
1191 * unsatisfied symbols.
1193 * hp9000s700/hp9000s800:
1194 * BIND_RESTRICTED - Restrict symbols visible by the library to those
1195 * present at library load time.
1196 * DYNAMIC_PATH - Allow the loader to dynamically search for the
1197 * library specified by the path argument.
1200 #ifndef DYNAMIC_PATH
1201 # define DYNAMIC_PATH 0
1203 #ifndef BIND_RESTRICTED
1204 # define BIND_RESTRICTED 0
1207 #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1210 sys_shl_open (loader_data
, filename
)
1211 lt_user_data loader_data
;
1212 const char *filename
;
1214 static shl_t self
= (shl_t
) 0;
1215 lt_module module
= shl_load (filename
, LT_BIND_FLAGS
, 0L);
1217 /* Since searching for a symbol against a NULL module handle will also
1218 look in everything else that was already loaded and exported with
1219 the -E compiler flag, we always cache a handle saved before any
1220 modules are loaded. */
1224 shl_findsym (&self
, "main", TYPE_UNDEFINED
, &address
);
1233 module
= shl_load (filename
, LT_BIND_FLAGS
, 0L);
1237 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1245 sys_shl_close (loader_data
, module
)
1246 lt_user_data loader_data
;
1251 if (module
&& (shl_unload ((shl_t
) (module
)) != 0))
1253 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1261 sys_shl_sym (loader_data
, module
, symbol
)
1262 lt_user_data loader_data
;
1268 /* sys_shl_open should never return a NULL module handle */
1269 if (module
== (lt_module
) 0)
1271 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
1273 else if (!shl_findsym((shl_t
*) &module
, symbol
, TYPE_UNDEFINED
, &address
))
1277 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1284 static struct lt_user_dlloader sys_shl
= {
1285 0, sys_shl_open
, sys_shl_close
, sys_shl_sym
, 0, 0
1288 #endif /* HAVE_SHL_LOAD */
1293 /* --- LOADLIBRARY() INTERFACE LOADER --- */
1297 /* dynamic linking for Win32 */
1299 #include <windows.h>
1301 /* Forward declaration; required to implement handle search below. */
1302 static lt_dlhandle handles
;
1305 sys_wll_open (loader_data
, filename
)
1306 lt_user_data loader_data
;
1307 const char *filename
;
1310 lt_module module
= 0;
1311 const char *errormsg
= 0;
1312 char *searchname
= 0;
1314 char self_name_buf
[MAX_PATH
];
1318 /* Get the name of main module */
1320 GetModuleFileName (NULL
, self_name_buf
, sizeof (self_name_buf
));
1321 filename
= ext
= self_name_buf
;
1325 ext
= strrchr (filename
, '.');
1330 /* FILENAME already has an extension. */
1331 searchname
= lt_estrdup (filename
);
1335 /* Append a `.' to stop Windows from adding an
1336 implicit `.dll' extension. */
1337 searchname
= LT_EMALLOC (char, 2+ LT_STRLEN (filename
));
1339 sprintf (searchname
, "%s.", filename
);
1346 char wpath
[MAX_PATH
];
1347 cygwin_conv_to_full_win32_path(searchname
, wpath
);
1348 module
= LoadLibrary(wpath
);
1351 module
= LoadLibrary (searchname
);
1353 LT_DLFREE (searchname
);
1355 /* libltdl expects this function to fail if it is unable
1356 to physically load the library. Sadly, LoadLibrary
1357 will search the loaded libraries for a match and return
1358 one of them if the path search load fails.
1360 We check whether LoadLibrary is returning a handle to
1361 an already loaded module, and simulate failure if we
1373 if (cur
->module
== module
)
1380 LT_DLMUTEX_UNLOCK ();
1384 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1392 sys_wll_close (loader_data
, module
)
1393 lt_user_data loader_data
;
1398 if (FreeLibrary(module
) == 0)
1400 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1408 sys_wll_sym (loader_data
, module
, symbol
)
1409 lt_user_data loader_data
;
1413 lt_ptr address
= GetProcAddress (module
, symbol
);
1417 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1423 static struct lt_user_dlloader sys_wll
= {
1424 0, sys_wll_open
, sys_wll_close
, sys_wll_sym
, 0, 0
1427 #endif /* __WINDOWS__ */
1432 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1437 /* dynamic linking for BeOS */
1439 #include <kernel/image.h>
1442 sys_bedl_open (loader_data
, filename
)
1443 lt_user_data loader_data
;
1444 const char *filename
;
1450 image
= load_add_on (filename
);
1456 if (get_next_image_info (0, &cookie
, &info
) == B_OK
)
1457 image
= load_add_on (info
.name
);
1462 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1466 return (lt_module
) image
;
1470 sys_bedl_close (loader_data
, module
)
1471 lt_user_data loader_data
;
1476 if (unload_add_on ((image_id
) module
) != B_OK
)
1478 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1486 sys_bedl_sym (loader_data
, module
, symbol
)
1487 lt_user_data loader_data
;
1492 image_id image
= (image_id
) module
;
1494 if (get_image_symbol (image
, symbol
, B_SYMBOL_TYPE_ANY
, address
) != B_OK
)
1496 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1503 static struct lt_user_dlloader sys_bedl
= {
1504 0, sys_bedl_open
, sys_bedl_close
, sys_bedl_sym
, 0, 0
1507 #endif /* __BEOS__ */
1512 /* --- DLD_LINK() INTERFACE LOADER --- */
1517 /* dynamic linking with dld */
1524 sys_dld_open (loader_data
, filename
)
1525 lt_user_data loader_data
;
1526 const char *filename
;
1528 lt_module module
= strdup (filename
);
1530 if (dld_link (filename
) != 0)
1532 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1541 sys_dld_close (loader_data
, module
)
1542 lt_user_data loader_data
;
1547 if (dld_unlink_by_file ((char*)(module
), 1) != 0)
1549 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1561 sys_dld_sym (loader_data
, module
, symbol
)
1562 lt_user_data loader_data
;
1566 lt_ptr address
= dld_get_func (symbol
);
1570 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1576 static struct lt_user_dlloader sys_dld
= {
1577 0, sys_dld_open
, sys_dld_close
, sys_dld_sym
, 0, 0
1580 #endif /* HAVE_DLD */
1582 /* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
1586 #if HAVE_MACH_O_DYLD_H
1587 # include <mach-o/dyld.h>
1589 #include <mach-o/getsect.h>
1591 /* We have to put some stuff here that isn't in older dyld.h files */
1592 #ifndef ENUM_DYLD_BOOL
1593 # define ENUM_DYLD_BOOL
1602 # define LC_REQ_DYLD 0x80000000
1604 #ifndef LC_LOAD_WEAK_DYLIB
1605 # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
1607 static const struct mach_header
* (*ltdl_NSAddImage
)(const char *image_name
, unsigned long options
) = 0;
1608 static NSSymbol (*ltdl_NSLookupSymbolInImage
)(const struct mach_header
*image
,const char *symbolName
, unsigned long options
) = 0;
1609 static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage
)(const struct mach_header
*image
, const char *symbolName
) = 0;
1610 static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic
)(NSModule module
) = 0;
1612 #ifndef NSADDIMAGE_OPTION_NONE
1613 #define NSADDIMAGE_OPTION_NONE 0x0
1615 #ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
1616 #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
1618 #ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
1619 #define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
1621 #ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1622 #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
1624 #ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
1625 #define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
1627 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
1628 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
1630 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1631 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
1633 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
1634 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
1636 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1637 #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
1642 lt_int_dyld_error(othererror
)
1645 /* return the dyld error string, or the passed in error string if none */
1646 NSLinkEditErrors ler
;
1650 NSLinkEditError(&ler
,&lerno
,&file
,&errstr
);
1651 if (!errstr
|| !strlen(errstr
)) errstr
= othererror
;
1655 static const struct mach_header
*
1656 lt_int_dyld_get_mach_header_from_nsmodule(module
)
1659 /* There should probably be an apple dyld api for this */
1660 int i
=_dyld_image_count();
1662 const char *modname
=NSNameOfModule(module
);
1663 const struct mach_header
*mh
=NULL
;
1664 if (!modname
) return NULL
;
1665 for (j
= 0; j
< i
; j
++)
1667 if (!strcmp(_dyld_get_image_name(j
),modname
))
1669 mh
=_dyld_get_image_header(j
);
1676 static const char* lt_int_dyld_lib_install_name(mh
)
1677 const struct mach_header
*mh
;
1679 /* NSAddImage is also used to get the loaded image, but it only works if the lib
1680 is installed, for uninstalled libs we need to check the install_names against
1681 each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
1682 different lib was loaded as a result
1685 struct load_command
*lc
;
1686 unsigned long offset
= sizeof(struct mach_header
);
1687 const struct mach_header
*mh1
;
1688 const char* retStr
=NULL
;
1689 for (j
= 0; j
< mh
->ncmds
; j
++)
1691 lc
= (struct load_command
*)(((unsigned long)mh
) + offset
);
1692 if (LC_ID_DYLIB
== lc
->cmd
)
1694 retStr
=(char*)(((struct dylib_command
*)lc
)->dylib
.name
.offset
+
1697 offset
+= lc
->cmdsize
;
1702 static const struct mach_header
*
1703 lt_int_dyld_match_loaded_lib_by_install_name(const char *name
)
1705 int i
=_dyld_image_count();
1707 const struct mach_header
*mh
=NULL
;
1708 const char *id
=NULL
;
1709 for (j
= 0; j
< i
; j
++)
1711 id
=lt_int_dyld_lib_install_name(_dyld_get_image_header(j
));
1712 if ((id
) && (!strcmp(id
,name
)))
1714 mh
=_dyld_get_image_header(j
);
1722 lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol
,mh
)
1724 const struct mach_header
*mh
;
1726 /* Safe to assume our mh is good */
1728 struct load_command
*lc
;
1729 unsigned long offset
= sizeof(struct mach_header
);
1730 NSSymbol retSym
= 0;
1731 const struct mach_header
*mh1
;
1732 if ((ltdl_NSLookupSymbolInImage
) && NSIsSymbolNameDefined(symbol
) )
1734 for (j
= 0; j
< mh
->ncmds
; j
++)
1736 lc
= (struct load_command
*)(((unsigned long)mh
) + offset
);
1737 if ((LC_LOAD_DYLIB
== lc
->cmd
) || (LC_LOAD_WEAK_DYLIB
== lc
->cmd
))
1739 mh1
=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command
*)lc
)->dylib
.name
.offset
+
1740 (unsigned long)lc
));
1743 /* Maybe NSAddImage can find it */
1744 mh1
=ltdl_NSAddImage((char*)(((struct dylib_command
*)lc
)->dylib
.name
.offset
+
1746 NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
+
1747 NSADDIMAGE_OPTION_WITH_SEARCHING
+
1748 NSADDIMAGE_OPTION_RETURN_ON_ERROR
);
1752 retSym
= ltdl_NSLookupSymbolInImage(mh1
,
1754 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1755 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1760 offset
+= lc
->cmdsize
;
1771 if (!_dyld_present()) {
1775 err
= _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage
);
1776 err
= _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage
);
1777 err
= _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage
);
1778 err
= _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic
);
1784 sys_dyld_open (loader_data
, filename
)
1785 lt_user_data loader_data
;
1786 const char *filename
;
1788 lt_module module
= 0;
1789 NSObjectFileImage ofi
= 0;
1790 NSObjectFileImageReturnCode ofirc
;
1793 return (lt_module
)-1;
1794 ofirc
= NSCreateObjectFileImageFromFile(filename
, &ofi
);
1797 case NSObjectFileImageSuccess
:
1798 module
= NSLinkModule(ofi
, filename
,
1799 NSLINKMODULE_OPTION_RETURN_ON_ERROR
1800 | NSLINKMODULE_OPTION_PRIVATE
1801 | NSLINKMODULE_OPTION_BINDNOW
);
1802 NSDestroyObjectFileImage(ofi
);
1804 ltdl_NSMakePrivateModulePublic(module
);
1806 case NSObjectFileImageInappropriateFile
:
1807 if (ltdl_NSIsSymbolNameDefinedInImage
&& ltdl_NSLookupSymbolInImage
)
1809 module
= (lt_module
)ltdl_NSAddImage(filename
, NSADDIMAGE_OPTION_RETURN_ON_ERROR
);
1813 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN
)));
1816 if (!module
) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN
)));
1821 sys_dyld_close (loader_data
, module
)
1822 lt_user_data loader_data
;
1827 unsigned long size
=0;
1828 if (module
== (lt_module
)-1) return 0;
1829 #ifdef __BIG_ENDIAN__
1830 if (((struct mach_header
*)module
)->magic
== MH_MAGIC
)
1832 if (((struct mach_header
*)module
)->magic
== MH_CIGAM
)
1835 LT_DLMUTEX_SETERROR("Can not close a dylib");
1841 /* Currently, if a module contains c++ static destructors and it is unloaded, we
1842 get a segfault in atexit(), due to compiler and dynamic loader differences of
1843 opinion, this works around that.
1845 if ((const struct section
*)NULL
!=
1846 getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module
),
1847 "__DATA","__mod_term_func"))
1849 flags
+= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
;
1853 flags
+= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES
;
1855 if (!NSUnLinkModule(module
,flags
))
1858 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE
)));
1866 sys_dyld_sym (loader_data
, module
, symbol
)
1867 lt_user_data loader_data
;
1872 NSSymbol
*nssym
= 0;
1874 const struct mach_header
*mh
=NULL
;
1875 if (module
== (lt_module
)-1)
1877 _dyld_lookup_and_bind(symbol
,(unsigned long*)&address
,&unused
);
1880 #ifdef __BIG_ENDIAN__
1881 if (((struct mach_header
*)module
)->magic
== MH_MAGIC
)
1883 if (((struct mach_header
*)module
)->magic
== MH_CIGAM
)
1886 if (ltdl_NSIsSymbolNameDefinedInImage
&& ltdl_NSLookupSymbolInImage
)
1889 if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header
*)module
,symbol
))
1891 nssym
= ltdl_NSLookupSymbolInImage((struct mach_header
*)module
,
1893 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1894 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1901 nssym
= NSLookupSymbolInModule(module
, symbol
);
1905 if (!mh
) mh
=lt_int_dyld_get_mach_header_from_nsmodule(module
);
1906 nssym
= lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol
,mh
);
1910 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND
)));
1913 return NSAddressOfSymbol(nssym
);
1916 static struct lt_user_dlloader sys_dyld
=
1917 { "_", sys_dyld_open
, sys_dyld_close
, sys_dyld_sym
, 0, 0 };
1920 #endif /* HAVE_DYLD */
1923 /* --- DLPREOPEN() INTERFACE LOADER --- */
1926 /* emulate dynamic linking using preloaded_symbols */
1928 typedef struct lt_dlsymlists_t
1930 struct lt_dlsymlists_t
*next
;
1931 const lt_dlsymlist
*syms
;
1934 static const lt_dlsymlist
*default_preloaded_symbols
= 0;
1935 static lt_dlsymlists_t
*preloaded_symbols
= 0;
1938 presym_init (loader_data
)
1939 lt_user_data loader_data
;
1945 preloaded_symbols
= 0;
1946 if (default_preloaded_symbols
)
1948 errors
= lt_dlpreload (default_preloaded_symbols
);
1951 LT_DLMUTEX_UNLOCK ();
1957 presym_free_symlists ()
1959 lt_dlsymlists_t
*lists
;
1963 lists
= preloaded_symbols
;
1966 lt_dlsymlists_t
*tmp
= lists
;
1968 lists
= lists
->next
;
1971 preloaded_symbols
= 0;
1973 LT_DLMUTEX_UNLOCK ();
1979 presym_exit (loader_data
)
1980 lt_user_data loader_data
;
1982 presym_free_symlists ();
1987 presym_add_symlist (preloaded
)
1988 const lt_dlsymlist
*preloaded
;
1990 lt_dlsymlists_t
*tmp
;
1991 lt_dlsymlists_t
*lists
;
1996 lists
= preloaded_symbols
;
1999 if (lists
->syms
== preloaded
)
2003 lists
= lists
->next
;
2006 tmp
= LT_EMALLOC (lt_dlsymlists_t
, 1);
2009 memset (tmp
, 0, sizeof(lt_dlsymlists_t
));
2010 tmp
->syms
= preloaded
;
2011 tmp
->next
= preloaded_symbols
;
2012 preloaded_symbols
= tmp
;
2020 LT_DLMUTEX_UNLOCK ();
2025 presym_open (loader_data
, filename
)
2026 lt_user_data loader_data
;
2027 const char *filename
;
2029 lt_dlsymlists_t
*lists
;
2030 lt_module module
= (lt_module
) 0;
2033 lists
= preloaded_symbols
;
2037 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS
));
2041 /* Can't use NULL as the reflective symbol header, as NULL is
2042 used to mark the end of the entire symbol list. Self-dlpreopened
2043 symbols follow this magic number, chosen to be an unlikely
2044 clash with a real module name. */
2047 filename
= "@PROGRAM@";
2052 const lt_dlsymlist
*syms
= lists
->syms
;
2056 if (!syms
->address
&& strcmp(syms
->name
, filename
) == 0)
2058 module
= (lt_module
) syms
;
2064 lists
= lists
->next
;
2067 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
2070 LT_DLMUTEX_UNLOCK ();
2075 presym_close (loader_data
, module
)
2076 lt_user_data loader_data
;
2079 /* Just to silence gcc -Wall */
2085 presym_sym (loader_data
, module
, symbol
)
2086 lt_user_data loader_data
;
2090 lt_dlsymlist
*syms
= (lt_dlsymlist
*) module
;
2093 while (syms
->address
)
2095 if (strcmp(syms
->name
, symbol
) == 0)
2097 return syms
->address
;
2103 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
2108 static struct lt_user_dlloader presym
= {
2109 0, presym_open
, presym_close
, presym_sym
, presym_exit
, 0
2116 /* --- DYNAMIC MODULE LOADING --- */
2119 /* The type of a function used at each iteration of foreach_dirinpath(). */
2120 typedef int foreach_callback_func
LT_PARAMS((char *filename
, lt_ptr data1
,
2123 static int foreach_dirinpath
LT_PARAMS((const char *search_path
,
2124 const char *base_name
,
2125 foreach_callback_func
*func
,
2126 lt_ptr data1
, lt_ptr data2
));
2128 static int find_file_callback
LT_PARAMS((char *filename
, lt_ptr data
,
2130 static int find_handle_callback
LT_PARAMS((char *filename
, lt_ptr data
,
2132 static int foreachfile_callback
LT_PARAMS((char *filename
, lt_ptr data1
,
2136 static int canonicalize_path
LT_PARAMS((const char *path
,
2137 char **pcanonical
));
2138 static int argzize_path
LT_PARAMS((const char *path
,
2140 size_t *pargz_len
));
2141 static FILE *find_file
LT_PARAMS((const char *search_path
,
2142 const char *base_name
,
2144 static lt_dlhandle
*find_handle
LT_PARAMS((const char *search_path
,
2145 const char *base_name
,
2146 lt_dlhandle
*handle
));
2147 static int find_module
LT_PARAMS((lt_dlhandle
*handle
,
2151 const char *old_name
,
2153 static int free_vars
LT_PARAMS((char *dlname
, char *oldname
,
2154 char *libdir
, char *deplibs
));
2155 static int load_deplibs
LT_PARAMS((lt_dlhandle handle
,
2157 static int trim
LT_PARAMS((char **dest
,
2159 static int try_dlopen
LT_PARAMS((lt_dlhandle
*handle
,
2160 const char *filename
));
2161 static int tryall_dlopen
LT_PARAMS((lt_dlhandle
*handle
,
2162 const char *filename
));
2163 static int unload_deplibs
LT_PARAMS((lt_dlhandle handle
));
2164 static int lt_argz_insert
LT_PARAMS((char **pargz
,
2167 const char *entry
));
2168 static int lt_argz_insertinorder
LT_PARAMS((char **pargz
,
2170 const char *entry
));
2171 static int lt_argz_insertdir
LT_PARAMS((char **pargz
,
2174 struct dirent
*dp
));
2175 static int lt_dlpath_insertdir
LT_PARAMS((char **ppath
,
2178 static int list_files_by_dir
LT_PARAMS((const char *dirnam
,
2180 size_t *pargz_len
));
2181 static int file_not_found
LT_PARAMS((void));
2183 static char *user_search_path
= 0;
2184 static lt_dlloader
*loaders
= 0;
2185 static lt_dlhandle handles
= 0;
2186 static int initialized
= 0;
2188 /* Initialize libltdl. */
2196 /* Initialize only at first call. */
2197 if (++initialized
== 1)
2200 user_search_path
= 0; /* empty search path */
2203 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_dl
, "dlopen");
2206 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_shl
, "dlopen");
2209 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_wll
, "dlopen");
2212 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_bedl
, "dlopen");
2215 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_dld
, "dld");
2218 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_dyld
, "dyld");
2219 errors
+= sys_dyld_init();
2221 errors
+= lt_dlloader_add (lt_dlloader_next (0), &presym
, "dlpreload");
2223 if (presym_init (presym
.dlloader_data
))
2225 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER
));
2228 else if (errors
!= 0)
2230 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED
));
2235 LT_DLMUTEX_UNLOCK ();
2241 lt_dlpreload (preloaded
)
2242 const lt_dlsymlist
*preloaded
;
2248 errors
= presym_add_symlist (preloaded
);
2252 presym_free_symlists();
2255 if (default_preloaded_symbols
)
2257 errors
= lt_dlpreload (default_preloaded_symbols
);
2259 LT_DLMUTEX_UNLOCK ();
2266 lt_dlpreload_default (preloaded
)
2267 const lt_dlsymlist
*preloaded
;
2270 default_preloaded_symbols
= preloaded
;
2271 LT_DLMUTEX_UNLOCK ();
2278 /* shut down libltdl */
2279 lt_dlloader
*loader
;
2287 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN
));
2292 /* shut down only at last call. */
2293 if (--initialized
== 0)
2297 while (handles
&& LT_DLIS_RESIDENT (handles
))
2299 handles
= handles
->next
;
2302 /* close all modules */
2303 for (level
= 1; handles
; ++level
)
2305 lt_dlhandle cur
= handles
;
2306 int saw_nonresident
= 0;
2310 lt_dlhandle tmp
= cur
;
2312 if (!LT_DLIS_RESIDENT (tmp
))
2313 saw_nonresident
= 1;
2314 if (!LT_DLIS_RESIDENT (tmp
) && tmp
->info
.ref_count
<= level
)
2316 if (lt_dlclose (tmp
))
2322 /* done if only resident modules are left */
2323 if (!saw_nonresident
)
2327 /* close all loaders */
2330 lt_dlloader
*next
= loader
->next
;
2331 lt_user_data data
= loader
->dlloader_data
;
2332 if (loader
->dlloader_exit
&& loader
->dlloader_exit (data
))
2337 LT_DLMEM_REASSIGN (loader
, next
);
2343 LT_DLMUTEX_UNLOCK ();
2348 tryall_dlopen (handle
, filename
)
2349 lt_dlhandle
*handle
;
2350 const char *filename
;
2353 lt_dlloader
*loader
;
2354 const char *saved_error
;
2357 LT_DLMUTEX_GETERROR (saved_error
);
2363 /* check whether the module was already opened */
2366 /* try to dlopen the program itself? */
2367 if (!cur
->info
.filename
&& !filename
)
2372 if (cur
->info
.filename
&& filename
2373 && strcmp (cur
->info
.filename
, filename
) == 0)
2383 ++cur
->info
.ref_count
;
2391 /* Comment out the check of file permissions using access.
2392 This call seems to always return -1 with error EACCES.
2394 /* We need to catch missing file errors early so that
2395 file_not_found() can detect what happened.
2396 if (access (filename, R_OK) != 0)
2398 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2403 cur
->info
.filename
= lt_estrdup (filename
);
2404 if (!cur
->info
.filename
)
2412 cur
->info
.filename
= 0;
2417 lt_user_data data
= loader
->dlloader_data
;
2419 cur
->module
= loader
->module_open (data
, filename
);
2421 if (cur
->module
!= 0)
2425 loader
= loader
->next
;
2430 LT_DLFREE (cur
->info
.filename
);
2435 cur
->loader
= loader
;
2436 LT_DLMUTEX_SETERROR (saved_error
);
2439 LT_DLMUTEX_UNLOCK ();
2445 tryall_dlopen_module (handle
, prefix
, dirname
, dlname
)
2446 lt_dlhandle
*handle
;
2448 const char *dirname
;
2453 size_t filename_len
= 0;
2454 size_t dirname_len
= LT_STRLEN (dirname
);
2459 #ifdef LT_DIRSEP_CHAR
2460 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2461 should make it into this function: */
2462 assert (strchr (dirname
, LT_DIRSEP_CHAR
) == 0);
2465 if (dirname_len
> 0)
2466 if (dirname
[dirname_len
-1] == '/')
2468 filename_len
= dirname_len
+ 1 + LT_STRLEN (dlname
);
2470 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2471 The PREFIX (if any) is handled below. */
2472 filename
= LT_EMALLOC (char, dirname_len
+ 1 + filename_len
+ 1);
2476 sprintf (filename
, "%.*s/%s", (int) dirname_len
, dirname
, dlname
);
2478 /* Now that we have combined DIRNAME and MODULENAME, if there is
2479 also a PREFIX to contend with, simply recurse with the arguments
2480 shuffled. Otherwise, attempt to open FILENAME as a module. */
2483 error
+= tryall_dlopen_module (handle
,
2484 (const char *) 0, prefix
, filename
);
2486 else if (tryall_dlopen (handle
, filename
) != 0)
2491 LT_DLFREE (filename
);
2496 find_module (handle
, dir
, libdir
, dlname
, old_name
, installed
)
2497 lt_dlhandle
*handle
;
2501 const char *old_name
;
2504 /* Try to open the old library first; if it was dlpreopened,
2505 we want the preopened version of it, even if a dlopenable
2506 module is available. */
2507 if (old_name
&& tryall_dlopen (handle
, old_name
) == 0)
2512 /* Try to open the dynamic library. */
2515 /* try to open the installed module */
2516 if (installed
&& libdir
)
2518 if (tryall_dlopen_module (handle
,
2519 (const char *) 0, libdir
, dlname
) == 0)
2523 /* try to open the not-installed module */
2526 if (tryall_dlopen_module (handle
, dir
, objdir
, dlname
) == 0)
2530 /* maybe it was moved to another directory */
2532 if (tryall_dlopen_module (handle
,
2533 (const char *) 0, dir
, dlname
) == 0)
2543 canonicalize_path (path
, pcanonical
)
2547 char *canonical
= 0;
2549 assert (path
&& *path
);
2550 assert (pcanonical
);
2552 canonical
= LT_EMALLOC (char, 1+ LT_STRLEN (path
));
2559 for (src
= 0; path
[src
] != LT_EOS_CHAR
; ++src
)
2561 /* Path separators are not copied to the beginning or end of
2562 the destination, or if another separator would follow
2564 if (path
[src
] == LT_PATHSEP_CHAR
)
2567 || (path
[1+ src
] == LT_PATHSEP_CHAR
)
2568 || (path
[1+ src
] == LT_EOS_CHAR
))
2572 /* Anything other than a directory separator is copied verbatim. */
2573 if ((path
[src
] != '/')
2574 #ifdef LT_DIRSEP_CHAR
2575 && (path
[src
] != LT_DIRSEP_CHAR
)
2579 canonical
[dest
++] = path
[src
];
2581 /* Directory separators are converted and copied only if they are
2582 not at the end of a path -- i.e. before a path separator or
2584 else if ((path
[1+ src
] != LT_PATHSEP_CHAR
)
2585 && (path
[1+ src
] != LT_EOS_CHAR
)
2586 #ifdef LT_DIRSEP_CHAR
2587 && (path
[1+ src
] != LT_DIRSEP_CHAR
)
2589 && (path
[1+ src
] != '/'))
2591 canonical
[dest
++] = '/';
2595 /* Add an end-of-string marker at the end. */
2596 canonical
[dest
] = LT_EOS_CHAR
;
2599 /* Assign new value. */
2600 *pcanonical
= canonical
;
2606 argzize_path (path
, pargz
, pargz_len
)
2617 if ((error
= argz_create_sep (path
, LT_PATHSEP_CHAR
, pargz
, pargz_len
)))
2622 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
2625 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN
));
2635 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2636 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2637 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2638 it is appended to each SEARCH_PATH element before FUNC is called. */
2640 foreach_dirinpath (search_path
, base_name
, func
, data1
, data2
)
2641 const char *search_path
;
2642 const char *base_name
;
2643 foreach_callback_func
*func
;
2648 int filenamesize
= 0;
2649 size_t lenbase
= LT_STRLEN (base_name
);
2650 size_t argz_len
= 0;
2653 char *canonical
= 0;
2657 if (!search_path
|| !*search_path
)
2659 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
2663 if (canonicalize_path (search_path
, &canonical
) != 0)
2666 if (argzize_path (canonical
, &argz
, &argz_len
) != 0)
2671 while ((dir_name
= argz_next (argz
, argz_len
, dir_name
)))
2673 size_t lendir
= LT_STRLEN (dir_name
);
2675 if (lendir
+1 +lenbase
>= filenamesize
)
2677 LT_DLFREE (filename
);
2678 filenamesize
= lendir
+1 +lenbase
+1; /* "/d" + '/' + "f" + '\0' */
2679 filename
= LT_EMALLOC (char, filenamesize
);
2684 assert (filenamesize
> lendir
);
2685 strcpy (filename
, dir_name
);
2687 if (base_name
&& *base_name
)
2689 if (filename
[lendir
-1] != '/')
2690 filename
[lendir
++] = '/';
2691 strcpy (filename
+lendir
, base_name
);
2694 if ((result
= (*func
) (filename
, data1
, data2
)))
2703 LT_DLFREE (canonical
);
2704 LT_DLFREE (filename
);
2706 LT_DLMUTEX_UNLOCK ();
2711 /* If FILEPATH can be opened, store the name of the directory component
2712 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2713 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2715 find_file_callback (filename
, data1
, data2
)
2720 char **pdir
= (char **) data1
;
2721 FILE **pfile
= (FILE **) data2
;
2724 assert (filename
&& *filename
);
2728 if ((*pfile
= fopen (filename
, LT_READTEXT_MODE
)))
2730 char *dirend
= strrchr (filename
, '/');
2732 if (dirend
> filename
)
2733 *dirend
= LT_EOS_CHAR
;
2736 *pdir
= lt_estrdup (filename
);
2737 is_done
= (*pdir
== 0) ? -1 : 1;
2744 find_file (search_path
, base_name
, pdir
)
2745 const char *search_path
;
2746 const char *base_name
;
2751 foreach_dirinpath (search_path
, base_name
, find_file_callback
, pdir
, &file
);
2757 find_handle_callback (filename
, data
, ignored
)
2762 lt_dlhandle
*handle
= (lt_dlhandle
*) data
;
2763 int notfound
= access (filename
, R_OK
);
2765 /* Bail out if file cannot be read... */
2769 /* Try to dlopen the file, but do not continue searching in any
2771 if (tryall_dlopen (handle
, filename
) != 0)
2777 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2778 found but could not be opened, *HANDLE will be set to 0. */
2779 static lt_dlhandle
*
2780 find_handle (search_path
, base_name
, handle
)
2781 const char *search_path
;
2782 const char *base_name
;
2783 lt_dlhandle
*handle
;
2788 if (!foreach_dirinpath (search_path
, base_name
, find_handle_callback
,
2796 load_deplibs (handle
, deplibs
)
2800 #if LTDL_DLOPEN_DEPLIBS
2801 char *p
, *save_search_path
= 0;
2808 handle
->depcount
= 0;
2810 #if LTDL_DLOPEN_DEPLIBS
2818 if (user_search_path
)
2820 save_search_path
= lt_estrdup (user_search_path
);
2821 if (!save_search_path
)
2825 /* extract search paths and count deplibs */
2829 if (!isspace ((int) *p
))
2832 while (*end
&& !isspace((int) *end
))
2837 if (strncmp(p
, "-L", 2) == 0 || strncmp(p
, "-R", 2) == 0)
2840 *end
= 0; /* set a temporary string terminator */
2841 if (lt_dladdsearchdir(p
+2))
2860 /* restore the old search path */
2861 LT_DLFREE (user_search_path
);
2862 user_search_path
= save_search_path
;
2864 LT_DLMUTEX_UNLOCK ();
2872 names
= LT_EMALLOC (char *, depcount
* sizeof (char*));
2876 /* now only extract the actual deplibs */
2881 if (isspace ((int) *p
))
2888 while (*end
&& !isspace ((int) *end
))
2893 if (strncmp(p
, "-L", 2) != 0 && strncmp(p
, "-R", 2) != 0)
2897 *end
= 0; /* set a temporary string terminator */
2898 if (strncmp(p
, "-l", 2) == 0)
2900 size_t name_len
= 3+ /* "lib" */ LT_STRLEN (p
+ 2);
2901 name
= LT_EMALLOC (char, 1+ name_len
);
2903 sprintf (name
, "lib%s", p
+2);
2906 name
= lt_estrdup(p
);
2911 names
[depcount
++] = name
;
2918 /* load the deplibs (in reverse order)
2919 At this stage, don't worry if the deplibs do not load correctly,
2920 they may already be statically linked into the loading application
2921 for instance. There will be a more enlightening error message
2922 later on if the loaded module cannot resolve all of its symbols. */
2927 handle
->deplibs
= (lt_dlhandle
*) LT_EMALLOC (lt_dlhandle
*, depcount
);
2928 if (!handle
->deplibs
)
2931 for (i
= 0; i
< depcount
; ++i
)
2933 handle
->deplibs
[j
] = lt_dlopenext(names
[depcount
-1-i
]);
2934 if (handle
->deplibs
[j
])
2940 handle
->depcount
= j
; /* Number of successfully loaded deplibs */
2945 for (i
= 0; i
< depcount
; ++i
)
2947 LT_DLFREE (names
[i
]);
2958 unload_deplibs (handle
)
2964 if (handle
->depcount
)
2966 for (i
= 0; i
< handle
->depcount
; ++i
)
2968 if (!LT_DLIS_RESIDENT (handle
->deplibs
[i
]))
2970 errors
+= lt_dlclose (handle
->deplibs
[i
]);
2983 /* remove the leading and trailing "'" from str
2984 and store the result in dest */
2985 const char *end
= strrchr (str
, '\'');
2986 size_t len
= LT_STRLEN (str
);
2991 if (len
> 3 && str
[0] == '\'')
2993 tmp
= LT_EMALLOC (char, end
- str
);
2997 strncpy(tmp
, &str
[1], (end
- str
) - 1);
2998 tmp
[len
-3] = LT_EOS_CHAR
;
3010 free_vars (dlname
, oldname
, libdir
, deplibs
)
3017 LT_DLFREE (oldname
);
3019 LT_DLFREE (deplibs
);
3025 try_dlopen (phandle
, filename
)
3026 lt_dlhandle
*phandle
;
3027 const char *filename
;
3029 const char * ext
= 0;
3030 const char * saved_error
= 0;
3031 char * canonical
= 0;
3032 char * base_name
= 0;
3036 lt_dlhandle newhandle
;
3039 assert (*phandle
== 0);
3041 LT_DLMUTEX_GETERROR (saved_error
);
3046 *phandle
= (lt_dlhandle
) LT_EMALLOC (struct lt_dlhandle_struct
, 1);
3050 memset (*phandle
, 0, sizeof(struct lt_dlhandle_struct
));
3051 newhandle
= *phandle
;
3053 /* lt_dlclose()ing yourself is very bad! Disallow it. */
3054 LT_DLSET_FLAG (*phandle
, LT_DLRESIDENT_FLAG
);
3056 if (tryall_dlopen (&newhandle
, 0) != 0)
3058 LT_DLFREE (*phandle
);
3062 goto register_handle
;
3065 assert (filename
&& *filename
);
3067 /* Doing this immediately allows internal functions to safely
3068 assume only canonicalized paths are passed. */
3069 if (canonicalize_path (filename
, &canonical
) != 0)
3075 /* If the canonical module name is a path (relative or absolute)
3076 then split it into a directory part and a name part. */
3077 base_name
= strrchr (canonical
, '/');
3080 size_t dirlen
= (1+ base_name
) - canonical
;
3082 dir
= LT_EMALLOC (char, 1+ dirlen
);
3089 strncpy (dir
, canonical
, dirlen
);
3090 dir
[dirlen
] = LT_EOS_CHAR
;
3095 LT_DLMEM_REASSIGN (base_name
, canonical
);
3097 assert (base_name
&& *base_name
);
3099 /* Check whether we are opening a libtool module (.la extension). */
3100 ext
= strrchr (base_name
, '.');
3101 if (ext
&& strcmp (ext
, archive_ext
) == 0)
3103 /* this seems to be a libtool module */
3106 char * old_name
= 0;
3112 /* if we can't find the installed flag, it is probably an
3113 installed libtool archive, produced with an old version
3117 /* extract the module name from the file name */
3118 name
= LT_EMALLOC (char, ext
- base_name
+ 1);
3125 /* canonicalize the module name */
3128 for (i
= 0; i
< ext
- base_name
; ++i
)
3130 if (isalnum ((int)(base_name
[i
])))
3132 name
[i
] = base_name
[i
];
3139 name
[ext
- base_name
] = LT_EOS_CHAR
;
3142 /* Now try to open the .la file. If there is no directory name
3143 component, try to find it first in user_search_path and then other
3144 prescribed paths. Otherwise (or in any case if the module was not
3145 yet found) try opening just the module name as passed. */
3148 const char *search_path
;
3151 search_path
= user_search_path
;
3153 file
= find_file (user_search_path
, base_name
, &dir
);
3154 LT_DLMUTEX_UNLOCK ();
3158 search_path
= getenv (LTDL_SEARCHPATH_VAR
);
3160 file
= find_file (search_path
, base_name
, &dir
);
3163 #ifdef LTDL_SHLIBPATH_VAR
3166 search_path
= getenv (LTDL_SHLIBPATH_VAR
);
3168 file
= find_file (search_path
, base_name
, &dir
);
3171 #ifdef LTDL_SYSSEARCHPATH
3172 if (!file
&& sys_search_path
)
3174 file
= find_file (sys_search_path
, base_name
, &dir
);
3180 file
= fopen (filename
, LT_READTEXT_MODE
);
3183 /* If we didn't find the file by now, it really isn't there. Set
3184 the status flag, and bail out. */
3187 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
3192 line_len
= LT_FILENAME_MAX
;
3193 line
= LT_EMALLOC (char, line_len
);
3201 /* read the .la file */
3202 while (!feof (file
))
3204 if (!fgets (line
, (int) line_len
, file
))
3209 /* Handle the case where we occasionally need to read a line
3210 that is longer than the initial buffer size. */
3211 while ((line
[LT_STRLEN(line
) -1] != '\n') && (!feof (file
)))
3213 line
= LT_DLREALLOC (char, line
, line_len
*2);
3214 if (!fgets (&line
[line_len
-1], (int) line_len
+1, file
))
3221 if (line
[0] == '\n' || line
[0] == '#')
3227 #define STR_DLNAME "dlname="
3228 if (strncmp (line
, STR_DLNAME
, sizeof (STR_DLNAME
) - 1) == 0)
3230 errors
+= trim (&dlname
, &line
[sizeof (STR_DLNAME
) - 1]);
3233 #undef STR_OLD_LIBRARY
3234 #define STR_OLD_LIBRARY "old_library="
3235 else if (strncmp (line
, STR_OLD_LIBRARY
,
3236 sizeof (STR_OLD_LIBRARY
) - 1) == 0)
3238 errors
+= trim (&old_name
, &line
[sizeof (STR_OLD_LIBRARY
) - 1]);
3241 #define STR_LIBDIR "libdir="
3242 else if (strncmp (line
, STR_LIBDIR
, sizeof (STR_LIBDIR
) - 1) == 0)
3244 errors
+= trim (&libdir
, &line
[sizeof(STR_LIBDIR
) - 1]);
3247 #undef STR_DL_DEPLIBS
3248 #define STR_DL_DEPLIBS "dependency_libs="
3249 else if (strncmp (line
, STR_DL_DEPLIBS
,
3250 sizeof (STR_DL_DEPLIBS
) - 1) == 0)
3252 errors
+= trim (&deplibs
, &line
[sizeof (STR_DL_DEPLIBS
) - 1]);
3254 else if (strcmp (line
, "installed=yes\n") == 0)
3258 else if (strcmp (line
, "installed=no\n") == 0)
3263 #undef STR_LIBRARY_NAMES
3264 #define STR_LIBRARY_NAMES "library_names="
3265 else if (! dlname
&& strncmp (line
, STR_LIBRARY_NAMES
,
3266 sizeof (STR_LIBRARY_NAMES
) - 1) == 0)
3269 errors
+= trim (&dlname
, &line
[sizeof (STR_LIBRARY_NAMES
) - 1]);
3272 && (last_libname
= strrchr (dlname
, ' ')) != 0)
3274 last_libname
= lt_estrdup (last_libname
+ 1);
3280 LT_DLMEM_REASSIGN (dlname
, last_libname
);
3291 /* allocate the handle */
3292 *phandle
= (lt_dlhandle
) LT_EMALLOC (struct lt_dlhandle_struct
, 1);
3298 free_vars (dlname
, old_name
, libdir
, deplibs
);
3299 LT_DLFREE (*phandle
);
3305 memset (*phandle
, 0, sizeof(struct lt_dlhandle_struct
));
3306 if (load_deplibs (*phandle
, deplibs
) == 0)
3308 newhandle
= *phandle
;
3309 /* find_module may replace newhandle */
3310 if (find_module (&newhandle
, dir
, libdir
, dlname
, old_name
, installed
))
3312 unload_deplibs (*phandle
);
3321 free_vars (dlname
, old_name
, libdir
, deplibs
);
3324 LT_DLFREE (*phandle
);
3328 if (*phandle
!= newhandle
)
3330 unload_deplibs (*phandle
);
3335 /* not a libtool module */
3336 *phandle
= (lt_dlhandle
) LT_EMALLOC (struct lt_dlhandle_struct
, 1);
3343 memset (*phandle
, 0, sizeof (struct lt_dlhandle_struct
));
3344 newhandle
= *phandle
;
3346 /* If the module has no directory name component, try to find it
3347 first in user_search_path and then other prescribed paths.
3348 Otherwise (or in any case if the module was not yet found) try
3349 opening just the module name as passed. */
3350 if ((dir
|| (!find_handle (user_search_path
, base_name
, &newhandle
)
3351 && !find_handle (getenv (LTDL_SEARCHPATH_VAR
), base_name
,
3353 #ifdef LTDL_SHLIBPATH_VAR
3354 && !find_handle (getenv (LTDL_SHLIBPATH_VAR
), base_name
,
3357 #ifdef LTDL_SYSSEARCHPATH
3358 && !find_handle (sys_search_path
, base_name
, &newhandle
)
3362 if (tryall_dlopen (&newhandle
, filename
) != 0)
3370 LT_DLFREE (*phandle
);
3377 LT_DLMEM_REASSIGN (*phandle
, newhandle
);
3379 if ((*phandle
)->info
.ref_count
== 0)
3381 (*phandle
)->info
.ref_count
= 1;
3382 LT_DLMEM_REASSIGN ((*phandle
)->info
.name
, name
);
3385 (*phandle
)->next
= handles
;
3387 LT_DLMUTEX_UNLOCK ();
3390 LT_DLMUTEX_SETERROR (saved_error
);
3395 LT_DLFREE (canonical
);
3401 lt_dlopen (filename
)
3402 const char *filename
;
3404 lt_dlhandle handle
= 0;
3406 /* Just incase we missed a code path in try_dlopen() that reports
3407 an error, but forgets to reset handle... */
3408 if (try_dlopen (&handle
, filename
) != 0)
3414 /* If the last error messge store was `FILE_NOT_FOUND', then return
3419 const char *error
= 0;
3421 LT_DLMUTEX_GETERROR (error
);
3422 if (error
== LT_DLSTRERROR (FILE_NOT_FOUND
))
3428 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3429 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3430 and if a file is still not found try again with SHLIB_EXT appended
3433 lt_dlopenext (filename
)
3434 const char *filename
;
3436 lt_dlhandle handle
= 0;
3444 return lt_dlopen (filename
);
3449 len
= LT_STRLEN (filename
);
3450 ext
= strrchr (filename
, '.');
3452 /* If FILENAME already bears a suitable extension, there is no need
3453 to try appending additional extensions. */
3454 if (ext
&& ((strcmp (ext
, archive_ext
) == 0)
3455 #ifdef LTDL_SHLIB_EXT
3456 || (strcmp (ext
, shlib_ext
) == 0)
3460 return lt_dlopen (filename
);
3463 /* First try appending ARCHIVE_EXT. */
3464 tmp
= LT_EMALLOC (char, len
+ LT_STRLEN (archive_ext
) + 1);
3468 strcpy (tmp
, filename
);
3469 strcat (tmp
, archive_ext
);
3470 errors
= try_dlopen (&handle
, tmp
);
3472 /* If we found FILENAME, stop searching -- whether we were able to
3473 load the file as a module or not. If the file exists but loading
3474 failed, it is better to return an error message here than to
3475 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3476 in the module search path. */
3477 if (handle
|| ((errors
> 0) && !file_not_found ()))
3483 #ifdef LTDL_SHLIB_EXT
3484 /* Try appending SHLIB_EXT. */
3485 if (LT_STRLEN (shlib_ext
) > LT_STRLEN (archive_ext
))
3488 tmp
= LT_EMALLOC (char, len
+ LT_STRLEN (shlib_ext
) + 1);
3492 strcpy (tmp
, filename
);
3496 tmp
[len
] = LT_EOS_CHAR
;
3499 strcat(tmp
, shlib_ext
);
3500 errors
= try_dlopen (&handle
, tmp
);
3502 /* As before, if the file was found but loading failed, return now
3503 with the current error message. */
3504 if (handle
|| ((errors
> 0) && !file_not_found ()))
3511 /* Still here? Then we really did fail to locate any of the file
3513 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
3520 lt_argz_insert (pargz
, pargz_len
, before
, entry
)
3528 if ((error
= argz_insert (pargz
, pargz_len
, before
, entry
)))
3533 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
3536 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN
));
3546 lt_argz_insertinorder (pargz
, pargz_len
, entry
)
3555 assert (entry
&& *entry
);
3558 while ((before
= argz_next (*pargz
, *pargz_len
, before
)))
3560 int cmp
= strcmp (entry
, before
);
3563 if (cmp
== 0) return 0; /* No duplicates! */
3566 return lt_argz_insert (pargz
, pargz_len
, before
, entry
);
3570 lt_argz_insertdir (pargz
, pargz_len
, dirnam
, dp
)
3579 size_t end_offset
= 0;
3587 dir_len
= LT_STRLEN (dirnam
);
3588 end
= dp
->d_name
+ LT_D_NAMLEN(dp
);
3590 /* Ignore version numbers. */
3593 for (p
= end
; p
-1 > dp
->d_name
; --p
)
3594 if (strchr (".0123456789", p
[-1]) == 0)
3601 /* Ignore filename extension. */
3604 for (p
= end
-1; p
> dp
->d_name
; --p
)
3612 /* Prepend the directory name. */
3613 end_offset
= end
- dp
->d_name
;
3614 buf_len
= dir_len
+ 1+ end_offset
;
3615 buf
= LT_EMALLOC (char, 1+ buf_len
);
3621 strcpy (buf
, dirnam
);
3623 strncat (buf
, dp
->d_name
, end_offset
);
3624 buf
[buf_len
] = LT_EOS_CHAR
;
3626 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3627 if (lt_argz_insertinorder (pargz
, pargz_len
, buf
) != 0)
3636 list_files_by_dir (dirnam
, pargz
, pargz_len
)
3644 assert (dirnam
&& *dirnam
);
3647 assert (dirnam
[LT_STRLEN(dirnam
) -1] != '/');
3649 dirp
= opendir (dirnam
);
3652 struct dirent
*dp
= 0;
3654 while ((dp
= readdir (dirp
)))
3655 if (dp
->d_name
[0] != '.')
3656 if (lt_argz_insertdir (pargz
, pargz_len
, dirnam
, dp
))
3671 /* If there are any files in DIRNAME, call the function passed in
3672 DATA1 (with the name of each file and DATA2 as arguments). */
3674 foreachfile_callback (dirname
, data1
, data2
)
3679 int (*func
) LT_PARAMS((const char *filename
, lt_ptr data
))
3680 = (int (*) LT_PARAMS((const char *filename
, lt_ptr data
))) data1
;
3684 size_t argz_len
= 0;
3686 if (list_files_by_dir (dirname
, &argz
, &argz_len
) != 0)
3693 while ((filename
= argz_next (argz
, argz_len
, filename
)))
3694 if ((is_done
= (*func
) (filename
, data2
)))
3705 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3706 with DATA. The filenames passed to FUNC would be suitable for
3707 passing to lt_dlopenext. The extensions are stripped so that
3708 individual modules do not generate several entries (e.g. libfoo.la,
3709 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3710 then the same directories that lt_dlopen would search are examined. */
3712 lt_dlforeachfile (search_path
, func
, data
)
3713 const char *search_path
;
3714 int (*func
) LT_PARAMS ((const char *filename
, lt_ptr data
));
3721 /* If a specific path was passed, search only the directories
3723 is_done
= foreach_dirinpath (search_path
, 0,
3724 foreachfile_callback
, func
, data
);
3728 /* Otherwise search the default paths. */
3729 is_done
= foreach_dirinpath (user_search_path
, 0,
3730 foreachfile_callback
, func
, data
);
3733 is_done
= foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3734 foreachfile_callback
, func
, data
);
3737 #ifdef LTDL_SHLIBPATH_VAR
3740 is_done
= foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR
), 0,
3741 foreachfile_callback
, func
, data
);
3744 #ifdef LTDL_SYSSEARCHPATH
3747 is_done
= foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH
), 0,
3748 foreachfile_callback
, func
, data
);
3760 lt_dlhandle cur
, last
;
3765 /* check whether the handle is valid */
3766 last
= cur
= handles
;
3767 while (cur
&& handle
!= cur
)
3775 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
3780 handle
->info
.ref_count
--;
3782 /* Note that even with resident modules, we must track the ref_count
3783 correctly incase the user decides to reset the residency flag
3784 later (even though the API makes no provision for that at the
3786 if (handle
->info
.ref_count
<= 0 && !LT_DLIS_RESIDENT (handle
))
3788 lt_user_data data
= handle
->loader
->dlloader_data
;
3790 if (handle
!= handles
)
3792 last
->next
= handle
->next
;
3796 handles
= handle
->next
;
3799 errors
+= handle
->loader
->module_close (data
, handle
->module
);
3800 errors
+= unload_deplibs(handle
);
3802 /* It is up to the callers to free the data itself. */
3803 LT_DLFREE (handle
->caller_data
);
3805 LT_DLFREE (handle
->info
.filename
);
3806 LT_DLFREE (handle
->info
.name
);
3812 if (LT_DLIS_RESIDENT (handle
))
3814 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE
));
3819 LT_DLMUTEX_UNLOCK ();
3825 lt_dlsym (handle
, symbol
)
3830 char lsym
[LT_SYMBOL_LENGTH
];
3837 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
3843 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
3847 lensym
= LT_STRLEN (symbol
) + LT_STRLEN (handle
->loader
->sym_prefix
)
3848 + LT_STRLEN (handle
->info
.name
);
3850 if (lensym
+ LT_SYMBOL_OVERHEAD
< LT_SYMBOL_LENGTH
)
3856 sym
= LT_EMALLOC (char, lensym
+ LT_SYMBOL_OVERHEAD
+ 1);
3859 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW
));
3864 data
= handle
->loader
->dlloader_data
;
3865 if (handle
->info
.name
)
3867 const char *saved_error
;
3869 LT_DLMUTEX_GETERROR (saved_error
);
3871 /* this is a libtool module */
3872 if (handle
->loader
->sym_prefix
)
3874 strcpy(sym
, handle
->loader
->sym_prefix
);
3875 strcat(sym
, handle
->info
.name
);
3879 strcpy(sym
, handle
->info
.name
);
3882 strcat(sym
, "_LTX_");
3883 strcat(sym
, symbol
);
3885 /* try "modulename_LTX_symbol" */
3886 address
= handle
->loader
->find_sym (data
, handle
->module
, sym
);
3895 LT_DLMUTEX_SETERROR (saved_error
);
3898 /* otherwise try "symbol" */
3899 if (handle
->loader
->sym_prefix
)
3901 strcpy(sym
, handle
->loader
->sym_prefix
);
3902 strcat(sym
, symbol
);
3906 strcpy(sym
, symbol
);
3909 address
= handle
->loader
->find_sym (data
, handle
->module
, sym
);
3923 LT_DLMUTEX_GETERROR (error
);
3924 LT_DLMUTEX_SETERROR (0);
3926 return error
? error
: LT_DLSTRERROR (UNKNOWN
);
3930 lt_dlpath_insertdir (ppath
, before
, dir
)
3936 char *canonical
= 0;
3938 size_t argz_len
= 0;
3941 assert (dir
&& *dir
);
3943 if (canonicalize_path (dir
, &canonical
) != 0)
3949 assert (canonical
&& *canonical
);
3951 /* If *PPATH is empty, set it to DIR. */
3954 assert (!before
); /* BEFORE cannot be set without PPATH. */
3955 assert (dir
); /* Without DIR, don't call this function! */
3957 *ppath
= lt_estrdup (dir
);
3964 assert (ppath
&& *ppath
);
3966 if (argzize_path (*ppath
, &argz
, &argz_len
) != 0)
3972 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
3973 if *PPATH is already canonicalized, and hence does not change length
3974 with respect to ARGZ. We canonicalize each entry as it is added to
3975 the search path, and don't call this function with (uncanonicalized)
3976 user paths, so this is a fair assumption. */
3979 assert (*ppath
<= before
);
3980 assert (before
- *ppath
<= strlen (*ppath
));
3982 before
= before
- *ppath
+ argz
;
3985 if (lt_argz_insert (&argz
, &argz_len
, before
, dir
) != 0)
3991 argz_stringify (argz
, argz_len
, LT_PATHSEP_CHAR
);
3992 LT_DLMEM_REASSIGN (*ppath
, argz
);
3995 LT_DLFREE (canonical
);
4002 lt_dladdsearchdir (search_dir
)
4003 const char *search_dir
;
4007 if (search_dir
&& *search_dir
)
4010 if (lt_dlpath_insertdir (&user_search_path
, 0, search_dir
) != 0)
4012 LT_DLMUTEX_UNLOCK ();
4019 lt_dlinsertsearchdir (before
, search_dir
)
4021 const char *search_dir
;
4028 if ((before
< user_search_path
)
4029 || (before
>= user_search_path
+ LT_STRLEN (user_search_path
)))
4031 LT_DLMUTEX_UNLOCK ();
4032 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION
));
4035 LT_DLMUTEX_UNLOCK ();
4038 if (search_dir
&& *search_dir
)
4041 if (lt_dlpath_insertdir (&user_search_path
,
4042 (char *) before
, search_dir
) != 0)
4046 LT_DLMUTEX_UNLOCK ();
4053 lt_dlsetsearchpath (search_path
)
4054 const char *search_path
;
4059 LT_DLFREE (user_search_path
);
4060 LT_DLMUTEX_UNLOCK ();
4062 if (!search_path
|| !LT_STRLEN (search_path
))
4068 if (canonicalize_path (search_path
, &user_search_path
) != 0)
4070 LT_DLMUTEX_UNLOCK ();
4076 lt_dlgetsearchpath ()
4078 const char *saved_path
;
4081 saved_path
= user_search_path
;
4082 LT_DLMUTEX_UNLOCK ();
4088 lt_dlmakeresident (handle
)
4095 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
4100 LT_DLSET_FLAG (handle
, LT_DLRESIDENT_FLAG
);
4107 lt_dlisresident (handle
)
4112 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
4116 return LT_DLIS_RESIDENT (handle
);
4122 /* --- MODULE INFORMATION --- */
4125 lt_dlgetinfo (handle
)
4130 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
4134 return &(handle
->info
);
4138 lt_dlhandle_next (place
)
4141 return place
? place
->next
: handles
;
4145 lt_dlforeach (func
, data
)
4146 int (*func
) LT_PARAMS((lt_dlhandle handle
, lt_ptr data
));
4157 lt_dlhandle tmp
= cur
;
4160 if ((*func
) (tmp
, data
))
4167 LT_DLMUTEX_UNLOCK ();
4173 lt_dlcaller_register ()
4175 static lt_dlcaller_id last_caller_id
= 0;
4179 result
= ++last_caller_id
;
4180 LT_DLMUTEX_UNLOCK ();
4186 lt_dlcaller_set_data (key
, handle
, data
)
4192 lt_ptr stale
= (lt_ptr
) 0;
4195 /* This needs to be locked so that the caller data can be updated
4196 simultaneously by different threads. */
4199 if (handle
->caller_data
)
4200 while (handle
->caller_data
[n_elements
].key
)
4203 for (i
= 0; i
< n_elements
; ++i
)
4205 if (handle
->caller_data
[i
].key
== key
)
4207 stale
= handle
->caller_data
[i
].data
;
4212 /* Ensure that there is enough room in this handle's caller_data
4213 array to accept a new element (and an empty end marker). */
4214 if (i
== n_elements
)
4216 lt_caller_data
*temp
4217 = LT_DLREALLOC (lt_caller_data
, handle
->caller_data
, 2+ n_elements
);
4225 handle
->caller_data
= temp
;
4227 /* We only need this if we needed to allocate a new caller_data. */
4228 handle
->caller_data
[i
].key
= key
;
4229 handle
->caller_data
[1+ i
].key
= 0;
4232 handle
->caller_data
[i
].data
= data
;
4235 LT_DLMUTEX_UNLOCK ();
4241 lt_dlcaller_get_data (key
, handle
)
4245 lt_ptr result
= (lt_ptr
) 0;
4247 /* This needs to be locked so that the caller data isn't updated by
4248 another thread part way through this function. */
4251 /* Locate the index of the element with a matching KEY. */
4254 for (i
= 0; handle
->caller_data
[i
].key
; ++i
)
4256 if (handle
->caller_data
[i
].key
== key
)
4258 result
= handle
->caller_data
[i
].data
;
4264 LT_DLMUTEX_UNLOCK ();
4271 /* --- USER MODULE LOADER API --- */
4275 lt_dlloader_add (place
, dlloader
, loader_name
)
4277 const struct lt_user_dlloader
*dlloader
;
4278 const char *loader_name
;
4281 lt_dlloader
*node
= 0, *ptr
= 0;
4283 if ((dlloader
== 0) /* diagnose null parameters */
4284 || (dlloader
->module_open
== 0)
4285 || (dlloader
->module_close
== 0)
4286 || (dlloader
->find_sym
== 0))
4288 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4292 /* Create a new dlloader node with copies of the user callbacks. */
4293 node
= LT_EMALLOC (lt_dlloader
, 1);
4298 node
->loader_name
= loader_name
;
4299 node
->sym_prefix
= dlloader
->sym_prefix
;
4300 node
->dlloader_exit
= dlloader
->dlloader_exit
;
4301 node
->module_open
= dlloader
->module_open
;
4302 node
->module_close
= dlloader
->module_close
;
4303 node
->find_sym
= dlloader
->find_sym
;
4304 node
->dlloader_data
= dlloader
->dlloader_data
;
4309 /* If there are no loaders, NODE becomes the list! */
4314 /* If PLACE is not set, add NODE to the end of the
4316 for (ptr
= loaders
; ptr
->next
; ptr
= ptr
->next
)
4323 else if (loaders
== place
)
4325 /* If PLACE is the first loader, NODE goes first. */
4331 /* Find the node immediately preceding PLACE. */
4332 for (ptr
= loaders
; ptr
->next
!= place
; ptr
= ptr
->next
)
4337 if (ptr
->next
!= place
)
4339 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4344 /* Insert NODE between PTR and PLACE. */
4350 LT_DLMUTEX_UNLOCK ();
4356 lt_dlloader_remove (loader_name
)
4357 const char *loader_name
;
4359 lt_dlloader
*place
= lt_dlloader_find (loader_name
);
4365 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4371 /* Fail if there are any open modules which use this loader. */
4372 for (handle
= handles
; handle
; handle
= handle
->next
)
4374 if (handle
->loader
== place
)
4376 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER
));
4382 if (place
== loaders
)
4384 /* PLACE is the first loader in the list. */
4385 loaders
= loaders
->next
;
4389 /* Find the loader before the one being removed. */
4391 for (prev
= loaders
; prev
->next
; prev
= prev
->next
)
4393 if (!strcmp (prev
->next
->loader_name
, loader_name
))
4400 prev
->next
= prev
->next
->next
;
4403 if (place
->dlloader_exit
)
4405 errors
= place
->dlloader_exit (place
->dlloader_data
);
4411 LT_DLMUTEX_UNLOCK ();
4417 lt_dlloader_next (place
)
4423 next
= place
? place
->next
: loaders
;
4424 LT_DLMUTEX_UNLOCK ();
4430 lt_dlloader_name (place
)
4433 const char *name
= 0;
4438 name
= place
? place
->loader_name
: 0;
4439 LT_DLMUTEX_UNLOCK ();
4443 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4450 lt_dlloader_data (place
)
4453 lt_user_data
*data
= 0;
4458 data
= place
? &(place
->dlloader_data
) : 0;
4459 LT_DLMUTEX_UNLOCK ();
4463 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4470 lt_dlloader_find (loader_name
)
4471 const char *loader_name
;
4473 lt_dlloader
*place
= 0;
4476 for (place
= loaders
; place
; place
= place
->next
)
4478 if (strcmp (place
->loader_name
, loader_name
) == 0)
4483 LT_DLMUTEX_UNLOCK ();