1 /////////////////////////////////////////////////////////////////////////
2 // $Id: ltdl.c,v 1.4 2002/11/01 13:02:15 bdenney Exp $
4 // NOTE: The ltdl library comes from the Libtool package. Bochs uses
5 // ltdl and libtool to build and load plugins. The libtool
6 // documentation describes how to copy ltdl.c and ltdl.h into your
7 // distribution, so it is clearly legal to do so.
8 /////////////////////////////////////////////////////////////////////////
10 /* ltdl.c -- system independent dlopen wrapper
11 Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
12 Originally by Thomas Tanner <tanner@ffii.org>
13 This file is part of GNU Libtool.
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 2 of the License, or (at your option) any later version.
20 As a special exception to the GNU Lesser General Public License,
21 if you distribute this file as part of a program or library that
22 is built using GNU libtool, you may include it under the same
23 distribution terms that you use for the rest of that program.
25 This library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 Lesser General Public License for more details.
30 You should have received a copy of the GNU Lesser General Public
31 License along with this library; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
37 // ltdlconf.h added for Bochs
82 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
84 # define dirent direct
85 # define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
87 # include <sys/ndir.h>
105 # warning using my own assert
107 # define assert(cond) while (!(cond)) { fprintf (stderr, "Assert failed at %s:%d: '%s'\n", __FILE__, __LINE__, #cond); abort(); }
110 #define LTDEBUG_PRINTF(x) /* debug output disabled */
111 //#define LTDEBUG_PRINTF(x) do{ printf("LT_DEBUG: "); printf x; } while (0)
118 /* --- WINDOWS SUPPORT --- */
122 # define LT_GLOBAL_DATA __declspec(dllexport)
124 # define LT_GLOBAL_DATA
127 /* fopen() mode flags for reading a text file */
128 #undef LT_READTEXT_MODE
130 # define LT_READTEXT_MODE "rt"
132 # define LT_READTEXT_MODE "r"
138 /* --- MANIFEST CONSTANTS --- */
141 /* Standard libltdl search path environment variable name */
142 #undef LTDL_SEARCHPATH_VAR
143 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
145 /* Standard libtool archive file extension. */
146 #undef LTDL_ARCHIVE_EXT
147 #define LTDL_ARCHIVE_EXT ".la"
149 /* max. filename length */
150 #ifndef LT_FILENAME_MAX
151 # define LT_FILENAME_MAX 1024
154 /* This is the maximum symbol size that won't require malloc/free */
155 #undef LT_SYMBOL_LENGTH
156 #define LT_SYMBOL_LENGTH 128
158 /* This accounts for the _LTX_ separator */
159 #undef LT_SYMBOL_OVERHEAD
160 #define LT_SYMBOL_OVERHEAD 5
165 /* --- MEMORY HANDLING --- */
168 /* These are the functions used internally. In addition to making
169 use of the associated function pointers above, they also perform
171 static char *lt_estrdup
LT_PARAMS((const char *str
));
172 static lt_ptr lt_emalloc
LT_PARAMS((size_t size
));
173 static lt_ptr lt_erealloc
LT_PARAMS((lt_ptr addr
, size_t size
));
175 static lt_ptr rpl_realloc
LT_PARAMS((lt_ptr ptr
, size_t size
));
177 /* These are the pointers that can be changed by the caller: */
178 LT_GLOBAL_DATA
lt_ptr (*lt_dlmalloc
) LT_PARAMS((size_t size
))
179 = (lt_ptr (*) LT_PARAMS((size_t))) malloc
;
180 LT_GLOBAL_DATA
lt_ptr (*lt_dlrealloc
) LT_PARAMS((lt_ptr ptr
, size_t size
))
181 = (lt_ptr (*) LT_PARAMS((lt_ptr
, size_t))) rpl_realloc
;
182 LT_GLOBAL_DATA
void (*lt_dlfree
) LT_PARAMS((lt_ptr ptr
))
183 = (void (*) LT_PARAMS((lt_ptr
))) free
;
185 /* The following macros reduce the amount of typing needed to cast
187 #define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
188 #define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
189 #define LT_DLFREE(p) \
190 LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
192 #define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
193 #define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
195 #define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
196 if ((p) != (q)) { lt_dlfree (p); (p) = (q); (q) = 0; } \
200 /* --- REPLACEMENT FUNCTIONS --- */
204 #define strdup rpl_strdup
206 static char *strdup
LT_PARAMS((const char *str
));
216 tmp
= LT_DLMALLOC (char, 1+ strlen (str
));
230 #define strcmp rpl_strcmp
232 static int strcmp
LT_PARAMS((const char *str1
, const char *str2
));
246 for (;*str1
&& *str2
; ++str1
, ++str2
)
252 return (int)(*str1
- *str2
);
260 # define strchr index
262 # define strchr rpl_strchr
264 static const char *strchr
LT_PARAMS((const char *str
, int ch
));
273 for (p
= str
; *p
!= (char)ch
&& *p
!= LT_EOS_CHAR
; ++p
)
276 return (*p
== (char)ch
) ? p
: 0;
280 #endif /* !HAVE_STRCHR */
286 # define strrchr rindex
288 # define strrchr rpl_strrchr
290 static const char *strrchr
LT_PARAMS((const char *str
, int ch
));
297 const char *p
, *q
= 0;
299 for (p
= str
; *p
!= LT_EOS_CHAR
; ++p
)
313 /* NOTE: Neither bcopy nor the memcpy implementation below can
314 reliably handle copying in overlapping areas of memory. Use
315 memmove (for which there is a fallback implmentation below)
316 if you need that behaviour. */
320 # define memcpy(dest, src, size) bcopy (src, dest, size)
322 # define memcpy rpl_memcpy
324 static lt_ptr memcpy
LT_PARAMS((lt_ptr dest
, const lt_ptr src
, size_t size
));
327 memcpy (dest
, src
, size
)
334 for (i
= 0; i
< size
; ++i
)
342 # endif /* !HAVE_BCOPY */
343 #endif /* !HAVE_MEMCPY */
346 # define memmove rpl_memmove
348 static lt_ptr memmove
LT_PARAMS((lt_ptr dest
, const lt_ptr src
, size_t size
));
351 memmove (dest
, src
, size
)
359 for (i
= 0; i
< size
; ++i
)
364 for (i
= size
-1; i
>= 0; --i
)
372 #endif /* !HAVE_MEMMOVE */
375 /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
376 ``realloc is not entirely portable''
377 In any case we want to use the allocator supplied by the user without
378 burdening them with an lt_dlrealloc function pointer to maintain.
379 Instead implement our own version (with known boundary conditions)
380 using lt_dlmalloc and lt_dlfree. */
383 #define realloc rpl_realloc
392 /* For zero or less bytes, free the original memory */
402 /* Allow reallocation of a NULL pointer. */
403 return lt_dlmalloc (size
);
407 /* Allocate a new block, copy and free the old block. */
408 lt_ptr mem
= lt_dlmalloc (size
);
412 memcpy (mem
, ptr
, size
);
416 /* Note that the contents of PTR are not damaged if there is
417 insufficient memory to realloc. */
423 #if ! HAVE_ARGZ_APPEND
424 # define argz_append rpl_argz_append
426 static error_t argz_append
LT_PARAMS((char **pargz
, size_t *pargz_len
,
427 const char *buf
, size_t buf_len
));
430 argz_append (pargz
, pargz_len
, buf
, buf_len
)
441 assert ((*pargz
&& *pargz_len
) || (!*pargz
&& !*pargz_len
));
443 /* If nothing needs to be appended, no more work is required. */
447 /* Ensure there is enough room to append BUF_LEN. */
448 argz_len
= *pargz_len
+ buf_len
;
449 argz
= LT_DLREALLOC (char, *pargz
, argz_len
);
453 /* Copy characters from BUF after terminating '\0' in ARGZ. */
454 memcpy (argz
+ *pargz_len
, buf
, buf_len
);
456 /* Assign new values. */
458 *pargz_len
= argz_len
;
462 #endif /* !HAVE_ARGZ_APPEND */
465 #if ! HAVE_ARGZ_CREATE_SEP
466 # define argz_create_sep rpl_argz_create_sep
468 static error_t argz_create_sep
LT_PARAMS((const char *str
, int delim
,
469 char **pargz
, size_t *pargz_len
));
472 argz_create_sep (str
, delim
, pargz
, pargz_len
)
485 /* Make a copy of STR, but replacing each occurence of
487 argz_len
= 1+ LT_STRLEN (str
);
493 argz
= LT_DLMALLOC (char, argz_len
);
497 for (p
= str
, q
= argz
; *p
!= LT_EOS_CHAR
; ++p
)
501 /* Ignore leading delimiters, and fold consecutive
502 delimiters in STR into a single '\0' in ARGZ. */
503 if ((q
> argz
) && (q
[-1] != LT_EOS_CHAR
))
511 /* Copy terminating LT_EOS_CHAR. */
515 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
519 /* Assign new values. */
521 *pargz_len
= argz_len
;
525 #endif /* !HAVE_ARGZ_CREATE_SEP */
528 #if ! HAVE_ARGZ_INSERT
529 # define argz_insert rpl_argz_insert
531 static error_t argz_insert
LT_PARAMS((char **pargz
, size_t *pargz_len
,
532 char *before
, const char *entry
));
535 argz_insert (pargz
, pargz_len
, before
, entry
)
543 assert (entry
&& *entry
);
545 /* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL,
546 or BEFORE points into an address within the ARGZ vector. */
547 assert ((!*pargz
&& !*pargz_len
&& !before
)
548 || ((*pargz
<= before
) && (before
< (*pargz
+ *pargz_len
))));
550 /* No BEFORE address indicates ENTRY should be inserted after the
551 current last element. */
553 return argz_append (pargz
, pargz_len
, entry
, 1+ LT_STRLEN (entry
));
555 /* This probably indicates a programmer error, but to preserve
556 semantics, scan back to the start of an entry if BEFORE points
557 into the middle of it. */
558 while ((before
>= *pargz
) && (before
[-1] != LT_EOS_CHAR
))
562 size_t entry_len
= 1+ LT_STRLEN (entry
);
563 size_t argz_len
= *pargz_len
+ entry_len
;
564 size_t offset
= before
- *pargz
;
565 char *argz
= LT_DLREALLOC (char, *pargz
, argz_len
);
570 /* Make BEFORE point to the equivalent offset in ARGZ that it
571 used to have in *PARGZ incase realloc() moved the block. */
572 before
= argz
+ offset
;
574 /* Move the ARGZ entries starting at BEFORE up into the new
575 space at the end -- making room to copy ENTRY into the
577 memmove (before
+ entry_len
, before
, *pargz_len
- offset
);
578 memcpy (before
, entry
, entry_len
);
580 /* Assign new values. */
582 *pargz_len
= argz_len
;
587 #endif /* !HAVE_ARGZ_INSERT */
591 # define argz_next rpl_argz_next
593 static char *argz_next
LT_PARAMS((char *argz
, size_t argz_len
,
597 argz_next (argz
, argz_len
, entry
)
602 assert ((argz
&& argz_len
) || (!argz
&& !argz_len
));
606 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
607 within the ARGZ vector. */
608 assert ((!argz
&& !argz_len
)
609 || ((argz
<= entry
) && (entry
< (argz
+ argz_len
))));
611 /* Move to the char immediately after the terminating
613 entry
= 1+ strchr (entry
, LT_EOS_CHAR
);
615 /* Return either the new ENTRY, or else NULL if ARGZ is
617 return (entry
>= argz
+ argz_len
) ? 0 : (char *) entry
;
621 /* This should probably be flagged as a programmer error,
622 since starting an argz_next loop with the iterator set
623 to ARGZ is safer. To preserve semantics, handle the NULL
624 case by returning the start of ARGZ (if any). */
631 #endif /* !HAVE_ARGZ_NEXT */
635 #if ! HAVE_ARGZ_STRINGIFY
636 # define argz_stringify rpl_argz_stringify
638 static void argz_stringify
LT_PARAMS((char *argz
, size_t argz_len
,
642 argz_stringify (argz
, argz_len
, sep
)
647 assert ((argz
&& argz_len
) || (!argz
&& !argz_len
));
651 --argz_len
; /* don't stringify the terminating EOS */
652 while (--argz_len
> 0)
654 if (argz
[argz_len
] == LT_EOS_CHAR
)
655 argz
[argz_len
] = sep
;
659 #endif /* !HAVE_ARGZ_STRINGIFY */
664 /* --- TYPE DEFINITIONS -- */
667 /* This type is used for the array of caller data sets in each handler. */
676 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
679 /* Extract the diagnostic strings from the error table macro in the same
680 order as the enumerated indices in ltdl.h. */
682 static const char *lt_dlerror_strings
[] =
684 lt_dlerror_names_list
688 /* This structure is used for the list of registered loaders. */
690 struct lt_dlloader
*next
;
691 const char *loader_name
; /* identifying name for each loader */
692 const char *sym_prefix
; /* prefix for symbols */
693 lt_module_open
*module_open
;
694 lt_module_close
*module_close
;
695 lt_find_sym
*find_sym
;
696 lt_dlloader_exit
*dlloader_exit
;
697 lt_user_data dlloader_data
;
700 struct lt_dlhandle_struct
{
701 struct lt_dlhandle_struct
*next
;
702 lt_dlloader
*loader
; /* dlopening interface */
704 int depcount
; /* number of dependencies */
705 lt_dlhandle
*deplibs
; /* dependencies */
706 lt_module module
; /* system module handle */
707 lt_ptr system
; /* system specific data */
708 lt_caller_data
*caller_data
; /* per caller associated data */
709 int flags
; /* various boolean stats */
712 /* Various boolean flags can be stored in the flags field of an
713 lt_dlhandle_struct... */
714 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
715 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
717 #define LT_DLRESIDENT_FLAG (0x01 << 0)
718 /* ...add more flags here... */
720 #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
723 #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
725 static const char objdir
[] = LTDL_OBJDIR
;
726 static const char archive_ext
[] = LTDL_ARCHIVE_EXT
;
727 #ifdef LTDL_SHLIB_EXT
728 static const char shlib_ext
[] = LTDL_SHLIB_EXT
;
730 #ifdef LTDL_SYSSEARCHPATH
731 static const char sys_search_path
[] = LTDL_SYSSEARCHPATH
;
737 /* --- MUTEX LOCKING --- */
740 /* Macros to make it easier to run the lock functions only if they have
741 been registered. The reason for the complicated lock macro is to
742 ensure that the stored error message from the last error is not
743 accidentally erased if the current function doesn't generate an
745 #define LT_DLMUTEX_LOCK() LT_STMT_START { \
746 if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
748 #define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
749 if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
751 #define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
752 if (lt_dlmutex_seterror_func) \
753 (*lt_dlmutex_seterror_func) (errormsg); \
754 else lt_dllast_error = (errormsg); } LT_STMT_END
755 #define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
756 if (lt_dlmutex_seterror_func) \
757 (errormsg) = (*lt_dlmutex_geterror_func) (); \
758 else (errormsg) = lt_dllast_error; } LT_STMT_END
760 /* The mutex functions stored here are global, and are necessarily the
761 same for all threads that wish to share access to libltdl. */
762 static lt_dlmutex_lock
*lt_dlmutex_lock_func
= 0;
763 static lt_dlmutex_unlock
*lt_dlmutex_unlock_func
= 0;
764 static lt_dlmutex_seterror
*lt_dlmutex_seterror_func
= 0;
765 static lt_dlmutex_geterror
*lt_dlmutex_geterror_func
= 0;
766 static const char *lt_dllast_error
= 0;
769 /* Either set or reset the mutex functions. Either all the arguments must
770 be valid functions, or else all can be NULL to turn off locking entirely.
771 The registered functions should be manipulating a static global lock
772 from the lock() and unlock() callbacks, which needs to be reentrant. */
774 lt_dlmutex_register (lock
, unlock
, seterror
, geterror
)
775 lt_dlmutex_lock
*lock
;
776 lt_dlmutex_unlock
*unlock
;
777 lt_dlmutex_seterror
*seterror
;
778 lt_dlmutex_geterror
*geterror
;
780 lt_dlmutex_unlock
*old_unlock
= unlock
;
783 /* Lock using the old lock() callback, if any. */
786 if ((lock
&& unlock
&& seterror
&& geterror
)
787 || !(lock
|| unlock
|| seterror
|| geterror
))
789 lt_dlmutex_lock_func
= lock
;
790 lt_dlmutex_unlock_func
= unlock
;
791 lt_dlmutex_geterror_func
= geterror
;
795 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS
));
799 /* Use the old unlock() callback we saved earlier, if any. Otherwise
800 record any errors using internal storage. */
804 /* Return the number of errors encountered during the execution of
812 /* --- ERROR HANDLING --- */
815 static const char **user_error_strings
= 0;
816 static int errorcount
= LT_ERROR_MAX
;
819 lt_dladderror (diagnostic
)
820 const char *diagnostic
;
824 const char **temp
= (const char **) 0;
830 errindex
= errorcount
- LT_ERROR_MAX
;
831 temp
= LT_EREALLOC (const char *, user_error_strings
, 1 + errindex
);
834 user_error_strings
= temp
;
835 user_error_strings
[errindex
] = diagnostic
;
836 result
= errorcount
++;
839 LT_DLMUTEX_UNLOCK ();
845 lt_dlseterror (errindex
)
852 if (errindex
>= errorcount
|| errindex
< 0)
854 /* Ack! Error setting the error message! */
855 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE
));
858 else if (errindex
< LT_ERROR_MAX
)
860 /* No error setting the error message! */
861 LT_DLMUTEX_SETERROR (lt_dlerror_strings
[errindex
]);
865 /* No error setting the error message! */
866 LT_DLMUTEX_SETERROR (user_error_strings
[errindex
- LT_ERROR_MAX
]);
869 LT_DLMUTEX_UNLOCK ();
878 lt_ptr mem
= lt_dlmalloc (size
);
880 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
885 lt_erealloc (addr
, size
)
889 lt_ptr mem
= realloc (addr
, size
);
891 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
899 char *dup
= strdup (str
);
900 if (LT_STRLEN (str
) && !dup
)
901 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
908 /* --- DLOPEN() INTERFACE LOADER --- */
911 /* The Cygwin dlopen implementation prints a spurious error message to
912 stderr if its call to LoadLibrary() fails for any reason. We can
913 mitigate this by not using the Cygwin implementation, and falling
914 back to our own LoadLibrary() wrapper. */
915 #if HAVE_LIBDL && !defined(__CYGWIN__)
917 /* dynamic linking with dlopen/dlsym */
928 # define LT_GLOBAL RTLD_GLOBAL
931 # define LT_GLOBAL DL_GLOBAL
933 #endif /* !RTLD_GLOBAL */
936 #endif /* !LT_GLOBAL */
938 /* We may have to define LT_LAZY_OR_NOW in the command line if we
939 find out it does not work in some platform. */
940 #ifndef LT_LAZY_OR_NOW
942 # define LT_LAZY_OR_NOW RTLD_LAZY
945 # define LT_LAZY_OR_NOW DL_LAZY
947 # endif /* !RTLD_LAZY */
949 #ifndef LT_LAZY_OR_NOW
951 # define LT_LAZY_OR_NOW RTLD_NOW
954 # define LT_LAZY_OR_NOW DL_NOW
956 # endif /* !RTLD_NOW */
958 #ifndef LT_LAZY_OR_NOW
959 # define LT_LAZY_OR_NOW 0
960 #endif /* !LT_LAZY_OR_NOW */
963 # define DLERROR(arg) dlerror ()
965 # define DLERROR(arg) LT_DLSTRERROR (arg)
969 sys_dl_open (loader_data
, filename
)
970 lt_user_data loader_data
;
971 const char *filename
;
973 lt_module module
= dlopen (filename
, LT_GLOBAL
| LT_LAZY_OR_NOW
);
977 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN
));
984 sys_dl_close (loader_data
, module
)
985 lt_user_data loader_data
;
990 if (dlclose (module
) != 0)
992 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE
));
1000 sys_dl_sym (loader_data
, module
, symbol
)
1001 lt_user_data loader_data
;
1005 lt_ptr address
= dlsym (module
, symbol
);
1009 LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND
));
1015 static struct lt_user_dlloader sys_dl
=
1022 sys_dl_open
, sys_dl_close
, sys_dl_sym
, 0, 0 };
1025 #endif /* HAVE_LIBDL */
1029 /* --- SHL_LOAD() INTERFACE LOADER --- */
1033 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1039 /* some flags are missing on some systems, so we provide
1040 * harmless defaults.
1043 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1044 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1047 * BIND_FIRST - Place the library at the head of the symbol search
1049 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1050 * unsatisfied symbols as fatal. This flag allows
1051 * binding of unsatisfied code symbols to be deferred
1053 * [Perl: For certain libraries, like DCE, deferred
1054 * binding often causes run time problems. Adding
1055 * BIND_NONFATAL to BIND_IMMEDIATE still allows
1056 * unresolved references in situations like this.]
1057 * BIND_NOSTART - Do not call the initializer for the shared library
1058 * when the library is loaded, nor on a future call to
1060 * BIND_VERBOSE - Print verbose messages concerning possible
1061 * unsatisfied symbols.
1063 * hp9000s700/hp9000s800:
1064 * BIND_RESTRICTED - Restrict symbols visible by the library to those
1065 * present at library load time.
1066 * DYNAMIC_PATH - Allow the loader to dynamically search for the
1067 * library specified by the path argument.
1070 #ifndef DYNAMIC_PATH
1071 # define DYNAMIC_PATH 0
1073 #ifndef BIND_RESTRICTED
1074 # define BIND_RESTRICTED 0
1077 #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1080 sys_shl_open (loader_data
, filename
)
1081 lt_user_data loader_data
;
1082 const char *filename
;
1084 static shl_t self
= (shl_t
) 0;
1085 lt_module module
= shl_load (filename
, LT_BIND_FLAGS
, 0L);
1087 /* Since searching for a symbol against a NULL module handle will also
1088 look in everything else that was already loaded and exported with
1089 the -E compiler flag, we always cache a handle saved before any
1090 modules are loaded. */
1094 shl_findsym (&self
, "main", TYPE_UNDEFINED
, &address
);
1103 module
= shl_load (filename
, LT_BIND_FLAGS
, 0L);
1107 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1115 sys_shl_close (loader_data
, module
)
1116 lt_user_data loader_data
;
1121 if (module
&& (shl_unload ((shl_t
) (module
)) != 0))
1123 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1131 sys_shl_sym (loader_data
, module
, symbol
)
1132 lt_user_data loader_data
;
1138 /* sys_shl_open should never return a NULL module handle */
1139 if (module
== (lt_module
) 0)
1141 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
1143 else if (!shl_findsym((shl_t
*) &module
, symbol
, TYPE_UNDEFINED
, &address
))
1147 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1154 static struct lt_user_dlloader sys_shl
= {
1155 0, sys_shl_open
, sys_shl_close
, sys_shl_sym
, 0, 0
1158 #endif /* HAVE_SHL_LOAD */
1163 /* --- LOADLIBRARY() INTERFACE LOADER --- */
1167 /* dynamic linking for Win32 */
1169 #include <windows.h>
1171 void win32_print_last_error (char *fmtstring
)
1175 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1176 FORMAT_MESSAGE_FROM_SYSTEM
|
1177 FORMAT_MESSAGE_IGNORE_INSERTS
,
1180 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), // Default language
1185 printf (fmtstring
, (char*)lpMsgBuf
);
1186 LocalFree (lpMsgBuf
);
1189 /* Forward declaration; required to implement handle search below. */
1190 static lt_dlhandle handles
;
1193 sys_wll_open (loader_data
, filename
)
1194 lt_user_data loader_data
;
1195 const char *filename
;
1198 lt_module module
= 0;
1199 const char *errormsg
= 0;
1200 char *searchname
= 0;
1202 char self_name_buf
[MAX_PATH
];
1206 /* Get the name of main module */
1208 GetModuleFileName (NULL
, self_name_buf
, sizeof (self_name_buf
));
1209 filename
= ext
= self_name_buf
;
1213 ext
= strrchr (filename
, '.');
1218 /* FILENAME already has an extension. */
1219 searchname
= lt_estrdup (filename
);
1223 /* Append a `.' to stop Windows from adding an
1224 implicit `.dll' extension. */
1225 searchname
= LT_EMALLOC (char, 2+ LT_STRLEN (filename
));
1227 sprintf (searchname
, "%s.", filename
);
1234 char wpath
[MAX_PATH
];
1235 cygwin_conv_to_full_win32_path(searchname
, wpath
);
1236 module
= LoadLibrary(wpath
);
1239 module
= LoadLibrary (searchname
);
1241 win32_print_last_error ("LoadLibrary failed: %s\n");
1244 LT_DLFREE (searchname
);
1246 /* libltdl expects this function to fail if it is unable
1247 to physically load the library. Sadly, LoadLibrary
1248 will search the loaded libraries for a match and return
1249 one of them if the path search load fails.
1251 We check whether LoadLibrary is returning a handle to
1252 an already loaded module, and simulate failure if we
1264 if (cur
->module
== module
)
1271 LT_DLMUTEX_UNLOCK ();
1275 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1283 sys_wll_close (loader_data
, module
)
1284 lt_user_data loader_data
;
1289 if (FreeLibrary(module
) == 0)
1291 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1299 sys_wll_sym (loader_data
, module
, symbol
)
1300 lt_user_data loader_data
;
1304 lt_ptr address
= GetProcAddress (module
, symbol
);
1308 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1314 static struct lt_user_dlloader sys_wll
= {
1315 0, sys_wll_open
, sys_wll_close
, sys_wll_sym
, 0, 0
1318 #endif /* __WINDOWS__ */
1323 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1328 /* dynamic linking for BeOS */
1330 #include <kernel/image.h>
1333 sys_bedl_open (loader_data
, filename
)
1334 lt_user_data loader_data
;
1335 const char *filename
;
1341 image
= load_add_on (filename
);
1347 if (get_next_image_info (0, &cookie
, &info
) == B_OK
)
1348 image
= load_add_on (info
.name
);
1353 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1357 return (lt_module
) image
;
1361 sys_bedl_close (loader_data
, module
)
1362 lt_user_data loader_data
;
1367 if (unload_add_on ((image_id
) module
) != B_OK
)
1369 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1377 sys_bedl_sym (loader_data
, module
, symbol
)
1378 lt_user_data loader_data
;
1383 image_id image
= (image_id
) module
;
1385 if (get_image_symbol (image
, symbol
, B_SYMBOL_TYPE_ANY
, address
) != B_OK
)
1387 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1394 static struct lt_user_dlloader sys_bedl
= {
1395 0, sys_bedl_open
, sys_bedl_close
, sys_bedl_sym
, 0, 0
1398 #endif /* __BEOS__ */
1403 /* --- DLD_LINK() INTERFACE LOADER --- */
1408 /* dynamic linking with dld */
1415 sys_dld_open (loader_data
, filename
)
1416 lt_user_data loader_data
;
1417 const char *filename
;
1419 lt_module module
= strdup (filename
);
1421 if (dld_link (filename
) != 0)
1423 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN
));
1432 sys_dld_close (loader_data
, module
)
1433 lt_user_data loader_data
;
1438 if (dld_unlink_by_file ((char*)(module
), 1) != 0)
1440 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE
));
1452 sys_dld_sym (loader_data
, module
, symbol
)
1453 lt_user_data loader_data
;
1457 lt_ptr address
= dld_get_func (symbol
);
1461 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1467 static struct lt_user_dlloader sys_dld
= {
1468 0, sys_dld_open
, sys_dld_close
, sys_dld_sym
, 0, 0
1471 #endif /* HAVE_DLD */
1476 /* --- DLPREOPEN() INTERFACE LOADER --- */
1479 /* emulate dynamic linking using preloaded_symbols */
1481 typedef struct lt_dlsymlists_t
1483 struct lt_dlsymlists_t
*next
;
1484 const lt_dlsymlist
*syms
;
1487 static const lt_dlsymlist
*default_preloaded_symbols
= 0;
1488 static lt_dlsymlists_t
*preloaded_symbols
= 0;
1491 presym_init (loader_data
)
1492 lt_user_data loader_data
;
1498 preloaded_symbols
= 0;
1499 if (default_preloaded_symbols
)
1501 errors
= lt_dlpreload (default_preloaded_symbols
);
1504 LT_DLMUTEX_UNLOCK ();
1510 presym_free_symlists ()
1512 lt_dlsymlists_t
*lists
;
1516 lists
= preloaded_symbols
;
1519 lt_dlsymlists_t
*tmp
= lists
;
1521 lists
= lists
->next
;
1524 preloaded_symbols
= 0;
1526 LT_DLMUTEX_UNLOCK ();
1532 presym_exit (loader_data
)
1533 lt_user_data loader_data
;
1535 presym_free_symlists ();
1540 presym_add_symlist (preloaded
)
1541 const lt_dlsymlist
*preloaded
;
1543 lt_dlsymlists_t
*tmp
;
1544 lt_dlsymlists_t
*lists
;
1549 lists
= preloaded_symbols
;
1552 if (lists
->syms
== preloaded
)
1556 lists
= lists
->next
;
1559 tmp
= LT_EMALLOC (lt_dlsymlists_t
, 1);
1562 memset (tmp
, 0, sizeof(lt_dlsymlists_t
));
1563 tmp
->syms
= preloaded
;
1564 tmp
->next
= preloaded_symbols
;
1565 preloaded_symbols
= tmp
;
1573 LT_DLMUTEX_UNLOCK ();
1578 presym_open (loader_data
, filename
)
1579 lt_user_data loader_data
;
1580 const char *filename
;
1582 lt_dlsymlists_t
*lists
;
1583 lt_module module
= (lt_module
) 0;
1586 lists
= preloaded_symbols
;
1590 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS
));
1594 /* Can't use NULL as the reflective symbol header, as NULL is
1595 used to mark the end of the entire symbol list. Self-dlpreopened
1596 symbols follow this magic number, chosen to be an unlikely
1597 clash with a real module name. */
1600 filename
= "@PROGRAM@";
1605 const lt_dlsymlist
*syms
= lists
->syms
;
1609 if (!syms
->address
&& strcmp(syms
->name
, filename
) == 0)
1611 module
= (lt_module
) syms
;
1617 lists
= lists
->next
;
1620 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
1623 LT_DLMUTEX_UNLOCK ();
1628 presym_close (loader_data
, module
)
1629 lt_user_data loader_data
;
1632 /* Just to silence gcc -Wall */
1638 presym_sym (loader_data
, module
, symbol
)
1639 lt_user_data loader_data
;
1643 lt_dlsymlist
*syms
= (lt_dlsymlist
*) module
;
1646 while (syms
->address
)
1648 if (strcmp(syms
->name
, symbol
) == 0)
1650 return syms
->address
;
1656 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
1661 static struct lt_user_dlloader presym
= {
1662 0, presym_open
, presym_close
, presym_sym
, presym_exit
, 0
1669 /* --- DYNAMIC MODULE LOADING --- */
1672 /* The type of a function used at each iteration of foreach_dirinpath(). */
1673 typedef int foreach_callback_func
LT_PARAMS((char *filename
, lt_ptr data1
,
1676 static int foreach_dirinpath
LT_PARAMS((const char *search_path
,
1677 const char *base_name
,
1678 foreach_callback_func
*func
,
1679 lt_ptr data1
, lt_ptr data2
));
1681 static int find_file_callback
LT_PARAMS((char *filename
, lt_ptr data
,
1683 static int find_handle_callback
LT_PARAMS((char *filename
, lt_ptr data
,
1685 static int foreachfile_callback
LT_PARAMS((char *filename
, lt_ptr data1
,
1689 static int canonicalize_path
LT_PARAMS((const char *path
,
1690 char **pcanonical
));
1691 static int argzize_path
LT_PARAMS((const char *path
,
1693 size_t *pargz_len
));
1694 static FILE *find_file
LT_PARAMS((const char *search_path
,
1695 const char *base_name
,
1697 static lt_dlhandle
*find_handle
LT_PARAMS((const char *search_path
,
1698 const char *base_name
,
1699 lt_dlhandle
*handle
));
1700 static int find_module
LT_PARAMS((lt_dlhandle
*handle
,
1704 const char *old_name
,
1706 static int free_vars
LT_PARAMS((char *dlname
, char *oldname
,
1707 char *libdir
, char *deplibs
));
1708 static int load_deplibs
LT_PARAMS((lt_dlhandle handle
,
1710 static int trim
LT_PARAMS((char **dest
,
1712 static int try_dlopen
LT_PARAMS((lt_dlhandle
*handle
,
1713 const char *filename
));
1714 static int tryall_dlopen
LT_PARAMS((lt_dlhandle
*handle
,
1715 const char *filename
));
1716 static int unload_deplibs
LT_PARAMS((lt_dlhandle handle
));
1717 static int lt_argz_insert
LT_PARAMS((char **pargz
,
1720 const char *entry
));
1721 static int lt_argz_insertinorder
LT_PARAMS((char **pargz
,
1723 const char *entry
));
1724 static int lt_dlpath_insertdir
LT_PARAMS((char **ppath
,
1728 static char *user_search_path
= 0;
1729 static lt_dlloader
*loaders
= 0;
1730 static lt_dlhandle handles
= 0;
1731 static int initialized
= 0;
1733 /* Initialize libltdl. */
1741 /* Initialize only at first call. */
1742 if (++initialized
== 1)
1745 user_search_path
= 0; /* empty search path */
1747 #if HAVE_LIBDL && !defined(__CYGWIN__)
1748 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_dl
, "dlopen");
1751 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_shl
, "dlopen");
1754 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_wll
, "dlopen");
1757 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_bedl
, "dlopen");
1760 errors
+= lt_dlloader_add (lt_dlloader_next (0), &sys_dld
, "dld");
1762 errors
+= lt_dlloader_add (lt_dlloader_next (0), &presym
, "dlpreload");
1764 if (presym_init (presym
.dlloader_data
))
1766 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER
));
1769 else if (errors
!= 0)
1771 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED
));
1776 LT_DLMUTEX_UNLOCK ();
1782 lt_dlpreload (preloaded
)
1783 const lt_dlsymlist
*preloaded
;
1789 errors
= presym_add_symlist (preloaded
);
1793 presym_free_symlists();
1796 if (default_preloaded_symbols
)
1798 errors
= lt_dlpreload (default_preloaded_symbols
);
1800 LT_DLMUTEX_UNLOCK ();
1807 lt_dlpreload_default (preloaded
)
1808 const lt_dlsymlist
*preloaded
;
1811 default_preloaded_symbols
= preloaded
;
1812 LT_DLMUTEX_UNLOCK ();
1819 /* shut down libltdl */
1820 lt_dlloader
*loader
;
1828 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN
));
1833 /* shut down only at last call. */
1834 if (--initialized
== 0)
1838 while (handles
&& LT_DLIS_RESIDENT (handles
))
1840 handles
= handles
->next
;
1843 /* close all modules */
1844 for (level
= 1; handles
; ++level
)
1846 lt_dlhandle cur
= handles
;
1847 int saw_nonresident
= 0;
1851 lt_dlhandle tmp
= cur
;
1853 if (!LT_DLIS_RESIDENT (tmp
))
1854 saw_nonresident
= 1;
1855 if (!LT_DLIS_RESIDENT (tmp
) && tmp
->info
.ref_count
<= level
)
1857 if (lt_dlclose (tmp
))
1863 /* done if only resident modules are left */
1864 if (!saw_nonresident
)
1868 /* close all loaders */
1871 lt_dlloader
*next
= loader
->next
;
1872 lt_user_data data
= loader
->dlloader_data
;
1873 if (loader
->dlloader_exit
&& loader
->dlloader_exit (data
))
1878 LT_DLMEM_REASSIGN (loader
, next
);
1884 LT_DLMUTEX_UNLOCK ();
1888 // returns number of errors, so 0=success
1889 // returns handle in *handle, if one is found.
1891 tryall_dlopen (handle
, filename
)
1892 lt_dlhandle
*handle
;
1893 const char *filename
;
1896 lt_dlloader
*loader
;
1897 const char *saved_error
;
1900 LT_DLMUTEX_GETERROR (saved_error
);
1906 /* check whether the module was already opened */
1909 /* try to dlopen the program itself? */
1910 if (!cur
->info
.filename
&& !filename
)
1915 if (cur
->info
.filename
&& filename
1916 && strcmp (cur
->info
.filename
, filename
) == 0)
1926 ++cur
->info
.ref_count
;
1934 cur
->info
.filename
= lt_estrdup (filename
);
1935 if (!cur
->info
.filename
)
1943 cur
->info
.filename
= 0;
1946 // Call access() to see if it exists first. If not return FILE_NOT_FOUND
1947 // instead of CANNOT_OPEN.
1948 if (access (cur
->info
.filename
, R_OK
) != 0) {
1949 LT_DLFREE (cur
->info
.filename
);
1950 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
1957 lt_user_data data
= loader
->dlloader_data
;
1958 LTDEBUG_PRINTF(("Trying to open '%s' using loader '%s'\n", filename
, loader
->loader_name
));
1959 cur
->module
= loader
->module_open (data
, filename
);
1961 if (cur
->module
!= 0)
1963 LTDEBUG_PRINTF(("Load '%s' succeeded.\n", filename
));
1966 loader
= loader
->next
;
1971 LT_DLFREE (cur
->info
.filename
);
1976 cur
->loader
= loader
;
1977 LT_DLMUTEX_SETERROR (saved_error
);
1980 LT_DLMUTEX_UNLOCK ();
1986 tryall_dlopen_module (handle
, prefix
, dirname
, dlname
)
1987 lt_dlhandle
*handle
;
1989 const char *dirname
;
1994 size_t filename_len
= 0;
1996 #warning dirname could be null
1998 size_t dirname_len
= LT_STRLEN (dirname
);
2000 if (dirname
== NULL
) {
2001 LTDEBUG_PRINTF(("leaving tryall_dlopen_module early because dirname is NULL\n"));
2008 #ifdef LT_DIRSEP_CHAR
2009 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2010 should make it into this function: */
2011 assert (strchr (dirname
, LT_DIRSEP_CHAR
) == 0);
2014 if (dirname
[dirname_len
-1] == '/')
2016 filename_len
= dirname_len
+ 1 + LT_STRLEN (dlname
);
2018 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2019 The PREFIX (if any) is handled below. */
2020 filename
= LT_EMALLOC (char, dirname_len
+ 1 + filename_len
+ 1);
2024 sprintf (filename
, "%.*s/%s", (int) dirname_len
, dirname
, dlname
);
2026 /* Now that we have combined DIRNAME and MODULENAME, if there is
2027 also a PREFIX to contend with, simply recurse with the arguments
2028 shuffled. Otherwise, attempt to open FILENAME as a module. */
2031 error
+= tryall_dlopen_module (handle
,
2032 (const char *) 0, prefix
, filename
);
2034 else if (tryall_dlopen (handle
, filename
) != 0)
2039 LT_DLFREE (filename
);
2044 find_module (handle
, dir
, libdir
, dlname
, old_name
, installed
)
2045 lt_dlhandle
*handle
;
2049 const char *old_name
;
2052 /* Try to open the old library first; if it was dlpreopened,
2053 we want the preopened version of it, even if a dlopenable
2054 module is available. */
2055 if (old_name
&& tryall_dlopen (handle
, old_name
) == 0)
2060 /* Try to open the dynamic library. */
2063 /* try to open the installed module */
2064 if (installed
&& libdir
)
2066 if (tryall_dlopen_module (handle
,
2067 (const char *) 0, libdir
, dlname
) == 0)
2071 /* try to open the not-installed module */
2074 if (tryall_dlopen_module (handle
, dir
, objdir
, dlname
) == 0)
2078 /* maybe it was moved to another directory */
2080 if (tryall_dlopen_module (handle
,
2081 (const char *) 0, dir
, dlname
) == 0)
2091 canonicalize_path (path
, pcanonical
)
2095 char *canonical
= 0;
2097 assert (path
&& *path
);
2098 assert (pcanonical
);
2100 canonical
= LT_EMALLOC (char, 1+ LT_STRLEN (path
));
2107 for (src
= 0; path
[src
] != LT_EOS_CHAR
; ++src
)
2109 /* Path separators are not copied to the beginning or end of
2110 the destination, or if another separator would follow
2112 if (path
[src
] == LT_PATHSEP_CHAR
)
2115 || (path
[1+ src
] == LT_PATHSEP_CHAR
)
2116 || (path
[1+ src
] == LT_EOS_CHAR
))
2120 /* Anything other than a directory separator is copied verbatim. */
2121 if ((path
[src
] != '/')
2122 #ifdef LT_DIRSEP_CHAR
2123 && (path
[src
] != LT_DIRSEP_CHAR
)
2127 canonical
[dest
++] = path
[src
];
2129 /* Directory separators are converted and copied only if they are
2130 not at the end of a path -- i.e. before a path separator or
2132 else if ((path
[1+ src
] != LT_PATHSEP_CHAR
)
2133 && (path
[1+ src
] != LT_EOS_CHAR
)
2134 #ifdef LT_DIRSEP_CHAR
2135 && (path
[1+ src
] != LT_DIRSEP_CHAR
)
2137 && (path
[1+ src
] != '/'))
2139 canonical
[dest
++] = '/';
2143 /* Add an end-of-string marker at the end. */
2144 canonical
[dest
] = LT_EOS_CHAR
;
2147 /* Assign new value. */
2148 *pcanonical
= canonical
;
2154 argzize_path (path
, pargz
, pargz_len
)
2165 if ((error
= argz_create_sep (path
, LT_PATHSEP_CHAR
, pargz
, pargz_len
)))
2170 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
2173 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN
));
2183 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2184 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2185 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2186 it is appended to each SEARCH_PATH element before FUNC is called. */
2188 foreach_dirinpath (search_path
, base_name
, func
, data1
, data2
)
2189 const char *search_path
;
2190 const char *base_name
;
2191 foreach_callback_func
*func
;
2196 int filenamesize
= 0;
2197 int lenbase
= LT_STRLEN (base_name
);
2198 size_t argz_len
= 0;
2200 char * filename
= 0;
2201 char * canonical
= 0;
2205 if (!search_path
|| !*search_path
)
2207 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
2211 if (canonicalize_path (search_path
, &canonical
) != 0)
2214 if (argzize_path (canonical
, &argz
, &argz_len
) != 0)
2219 while ((dir_name
= argz_next (argz
, argz_len
, dir_name
)))
2221 int lendir
= LT_STRLEN (dir_name
);
2223 if (lendir
+1 +lenbase
>= filenamesize
)
2225 LT_DLFREE (filename
);
2226 filenamesize
= lendir
+1 +lenbase
+1; /* "/d" + '/' + "f" + '\0' */
2227 filename
= LT_EMALLOC (char, filenamesize
);
2232 strncpy (filename
, dir_name
, lendir
);
2233 if (base_name
&& *base_name
)
2235 if (filename
[lendir
-1] != '/')
2236 filename
[lendir
++] = '/';
2237 strcpy (filename
+lendir
, base_name
);
2240 if ((result
= (*func
) (filename
, data1
, data2
)))
2249 LT_DLFREE (canonical
);
2250 LT_DLFREE (filename
);
2252 LT_DLMUTEX_UNLOCK ();
2257 /* If FILEPATH can be opened, store the name of the directory component
2258 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2259 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2261 find_file_callback (filename
, data1
, data2
)
2266 char **pdir
= (char **) data1
;
2267 FILE **pfile
= (FILE **) data2
;
2270 assert (filename
&& *filename
);
2274 if ((*pfile
= fopen (filename
, LT_READTEXT_MODE
)))
2276 char *dirend
= strrchr (filename
, '/');
2277 LTDEBUG_PRINTF(("find_file_callback opening file '%s'...ok\n", filename
));
2279 if (dirend
> filename
)
2280 *dirend
= LT_EOS_CHAR
;
2283 *pdir
= lt_estrdup (filename
);
2284 is_done
= (*pdir
== 0) ? -1 : 1;
2288 LTDEBUG_PRINTF(("find_file_callback opening file '%s'...failed\n", filename
));
2295 find_file (search_path
, base_name
, pdir
)
2296 const char *search_path
;
2297 const char *base_name
;
2302 foreach_dirinpath (search_path
, base_name
, find_file_callback
, pdir
, &file
);
2308 find_handle_callback (filename
, data
, ignored
)
2313 lt_dlhandle
*handle
= (lt_dlhandle
*) data
;
2314 int found
= (0 == access (filename
, R_OK
));
2315 LTDEBUG_PRINTF(("find_handle_callback searching for '%s'...%s\n", filename
, found
?"found":"not found"));
2317 /* Bail out if file cannot be read... */
2321 /* Try to dlopen the file, but do not continue searching in any
2323 if (tryall_dlopen (handle
, filename
) != 0)
2329 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2330 found but could not be opened, *HANDLE will be set to 0. */
2331 static lt_dlhandle
*
2332 find_handle (search_path
, base_name
, handle
)
2333 const char *search_path
;
2334 const char *base_name
;
2335 lt_dlhandle
*handle
;
2340 if (!foreach_dirinpath (search_path
, base_name
, find_handle_callback
,
2348 load_deplibs (handle
, deplibs
)
2352 #if LTDL_DLOPEN_DEPLIBS
2353 char *p
, *save_search_path
= 0;
2360 handle
->depcount
= 0;
2362 #if LTDL_DLOPEN_DEPLIBS
2370 if (user_search_path
)
2372 save_search_path
= lt_estrdup (user_search_path
);
2373 if (!save_search_path
)
2377 /* extract search paths and count deplibs */
2381 if (!isspace ((int) *p
))
2384 while (*end
&& !isspace((int) *end
))
2389 if (strncmp(p
, "-L", 2) == 0 || strncmp(p
, "-R", 2) == 0)
2392 *end
= 0; /* set a temporary string terminator */
2393 if (lt_dladdsearchdir(p
+2))
2412 /* restore the old search path */
2413 LT_DLFREE (user_search_path
);
2414 user_search_path
= save_search_path
;
2416 LT_DLMUTEX_UNLOCK ();
2424 names
= LT_EMALLOC (char *, depcount
* sizeof (char*));
2428 /* now only extract the actual deplibs */
2433 if (isspace ((int) *p
))
2440 while (*end
&& !isspace ((int) *end
))
2445 if (strncmp(p
, "-L", 2) != 0 && strncmp(p
, "-R", 2) != 0)
2449 *end
= 0; /* set a temporary string terminator */
2450 if (strncmp(p
, "-l", 2) == 0)
2452 size_t name_len
= 3+ /* "lib" */ LT_STRLEN (p
+ 2);
2453 name
= LT_EMALLOC (char, 1+ name_len
);
2455 sprintf (name
, "lib%s", p
+2);
2458 name
= lt_estrdup(p
);
2463 names
[depcount
++] = name
;
2470 /* load the deplibs (in reverse order)
2471 At this stage, don't worry if the deplibs do not load correctly,
2472 they may already be statically linked into the loading application
2473 for instance. There will be a more enlightening error message
2474 later on if the loaded module cannot resolve all of its symbols. */
2479 handle
->deplibs
= (lt_dlhandle
*) LT_EMALLOC (lt_dlhandle
*, depcount
);
2480 if (!handle
->deplibs
)
2483 for (i
= 0; i
< depcount
; ++i
)
2485 handle
->deplibs
[j
] = lt_dlopenext(names
[depcount
-1-i
]);
2486 if (handle
->deplibs
[j
])
2492 handle
->depcount
= j
; /* Number of successfully loaded deplibs */
2497 for (i
= 0; i
< depcount
; ++i
)
2499 LT_DLFREE (names
[i
]);
2510 unload_deplibs (handle
)
2516 if (handle
->depcount
)
2518 for (i
= 0; i
< handle
->depcount
; ++i
)
2520 if (!LT_DLIS_RESIDENT (handle
->deplibs
[i
]))
2522 errors
+= lt_dlclose (handle
->deplibs
[i
]);
2535 /* remove the leading and trailing "'" from str
2536 and store the result in dest */
2537 const char *end
= strrchr (str
, '\'');
2538 int len
= LT_STRLEN (str
);
2543 if (len
> 3 && str
[0] == '\'')
2545 tmp
= LT_EMALLOC (char, end
- str
);
2549 strncpy(tmp
, &str
[1], (end
- str
) - 1);
2550 tmp
[len
-3] = LT_EOS_CHAR
;
2562 free_vars (dlname
, oldname
, libdir
, deplibs
)
2569 LT_DLFREE (oldname
);
2571 LT_DLFREE (deplibs
);
2576 // returns number of errors, so 0=success.
2577 // phandle is a pointer to an lt_dlhandle, which must initially be NULL.
2578 // On success (return value=0), *phandle is changed to point to the new
2581 try_dlopen (phandle
, filename
)
2582 lt_dlhandle
*phandle
;
2583 const char *filename
;
2585 const char * ext
= 0;
2586 const char * saved_error
= 0;
2587 char * canonical
= 0;
2588 char * base_name
= 0;
2592 lt_dlhandle newhandle
;
2595 assert (*phandle
== 0);
2597 LT_DLMUTEX_GETERROR (saved_error
);
2602 *phandle
= (lt_dlhandle
) LT_EMALLOC (struct lt_dlhandle_struct
, 1);
2606 memset (*phandle
, 0, sizeof(struct lt_dlhandle_struct
));
2607 newhandle
= *phandle
;
2609 /* lt_dlclose()ing yourself is very bad! Disallow it. */
2610 LT_DLSET_FLAG (*phandle
, LT_DLRESIDENT_FLAG
);
2612 if (tryall_dlopen (&newhandle
, 0) != 0)
2614 LT_DLFREE (*phandle
); // this sets *phandle=NULL
2618 goto register_handle
;
2621 assert (filename
&& *filename
);
2623 /* Doing this immediately allows internal functions to safely
2624 assume only canonicalized paths are passed. */
2625 if (canonicalize_path (filename
, &canonical
) != 0)
2631 /* If the canonical module name is a path (relative or absolute)
2632 then split it into a directory part and a name part. */
2633 base_name
= strrchr (canonical
, '/');
2636 size_t dirlen
= (1+ base_name
) - canonical
;
2638 dir
= LT_EMALLOC (char, 1+ dirlen
);
2645 strncpy (dir
, canonical
, dirlen
);
2646 dir
[dirlen
] = LT_EOS_CHAR
;
2649 LTDEBUG_PRINTF(("in base_name not NULL section. dir='%s', base_name='%s', canonical='%s'\n", dir
, base_name
, canonical
));
2652 LT_DLMEM_REASSIGN (base_name
, canonical
);
2653 LTDEBUG_PRINTF(("in base_name=NULL section. dir=NULL, base_name='%s', canonical='%s'\n", base_name
, canonical
));
2656 assert (base_name
&& *base_name
);
2658 /* Check whether we are opening a libtool module (.la extension). */
2659 ext
= strrchr (base_name
, '.');
2660 if (ext
&& strcmp (ext
, archive_ext
) == 0)
2662 /* this seems to be a libtool module */
2665 char * old_name
= 0;
2672 /* if we can't find the installed flag, it is probably an
2673 installed libtool archive, produced with an old version
2677 /* extract the module name from the file name */
2678 name
= LT_EMALLOC (char, ext
- base_name
+ 1);
2685 /* canonicalize the module name */
2686 for (i
= 0; i
< ext
- base_name
; ++i
)
2688 if (isalnum ((int)(base_name
[i
])))
2690 name
[i
] = base_name
[i
];
2697 name
[ext
- base_name
] = LT_EOS_CHAR
;
2699 /* Now try to open the .la file. If there is no directory name
2700 component, try to find it first in user_search_path and then other
2701 prescribed paths. Otherwise (or in any case if the module was not
2702 yet found) try opening just the module name as passed. */
2705 const char *search_path
;
2708 search_path
= user_search_path
;
2710 file
= find_file (user_search_path
, base_name
, &dir
);
2711 LT_DLMUTEX_UNLOCK ();
2715 search_path
= getenv (LTDL_SEARCHPATH_VAR
);
2717 file
= find_file (search_path
, base_name
, &dir
);
2720 #ifdef LTDL_SHLIBPATH_VAR
2723 search_path
= getenv (LTDL_SHLIBPATH_VAR
);
2725 file
= find_file (search_path
, base_name
, &dir
);
2728 #ifdef LTDL_SYSSEARCHPATH
2729 if (!file
&& sys_search_path
)
2731 file
= find_file (sys_search_path
, base_name
, &dir
);
2737 LTDEBUG_PRINTF(("try_dlopen opening file '%s'\n", filename
));
2738 file
= fopen (filename
, LT_READTEXT_MODE
);
2740 #warning dir is still NULL
2744 /* If we didn't find the file by now, it really isn't there. Set
2745 the status flag, and bail out. */
2748 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
2753 line_len
= LT_FILENAME_MAX
;
2754 line
= LT_EMALLOC (char, line_len
);
2762 /* read the .la file */
2763 while (!feof (file
))
2765 if (!fgets (line
, line_len
, file
))
2770 /* Handle the case where we occasionally need to read a line
2771 that is longer than the initial buffer size. */
2772 while (line
[LT_STRLEN(line
) -1] != '\n')
2774 line
= LT_DLREALLOC (char, line
, line_len
*2);
2775 if (!fgets (&line
[line_len
-1], line_len
+1, file
))
2782 if (line
[0] == '\n' || line
[0] == '#')
2788 #define STR_DLNAME "dlname="
2789 if (strncmp (line
, STR_DLNAME
, sizeof (STR_DLNAME
) - 1) == 0)
2791 errors
+= trim (&dlname
, &line
[sizeof (STR_DLNAME
) - 1]);
2794 #undef STR_OLD_LIBRARY
2795 #define STR_OLD_LIBRARY "old_library="
2796 else if (strncmp (line
, STR_OLD_LIBRARY
,
2797 sizeof (STR_OLD_LIBRARY
) - 1) == 0)
2799 errors
+= trim (&old_name
, &line
[sizeof (STR_OLD_LIBRARY
) - 1]);
2802 #define STR_LIBDIR "libdir="
2803 else if (strncmp (line
, STR_LIBDIR
, sizeof (STR_LIBDIR
) - 1) == 0)
2805 errors
+= trim (&libdir
, &line
[sizeof(STR_LIBDIR
) - 1]);
2808 #undef STR_DL_DEPLIBS
2809 #define STR_DL_DEPLIBS "dependency_libs="
2810 else if (strncmp (line
, STR_DL_DEPLIBS
,
2811 sizeof (STR_DL_DEPLIBS
) - 1) == 0)
2813 errors
+= trim (&deplibs
, &line
[sizeof (STR_DL_DEPLIBS
) - 1]);
2815 else if (strcmp (line
, "installed=yes\n") == 0)
2819 else if (strcmp (line
, "installed=no\n") == 0)
2824 #undef STR_LIBRARY_NAMES
2825 #define STR_LIBRARY_NAMES "library_names="
2826 else if (! dlname
&& strncmp (line
, STR_LIBRARY_NAMES
,
2827 sizeof (STR_LIBRARY_NAMES
) - 1) == 0)
2830 errors
+= trim (&dlname
, &line
[sizeof (STR_LIBRARY_NAMES
) - 1]);
2833 && (last_libname
= strrchr (dlname
, ' ')) != 0)
2835 last_libname
= lt_estrdup (last_libname
+ 1);
2841 LT_DLMEM_REASSIGN (dlname
, last_libname
);
2852 /* allocate the handle */
2853 *phandle
= (lt_dlhandle
) LT_EMALLOC (struct lt_dlhandle_struct
, 1);
2859 free_vars (dlname
, old_name
, libdir
, deplibs
);
2860 LT_DLFREE (*phandle
);
2866 memset (*phandle
, 0, sizeof(struct lt_dlhandle_struct
));
2867 if (load_deplibs (*phandle
, deplibs
) == 0)
2869 newhandle
= *phandle
;
2870 /* find_module may replace newhandle */
2871 if (find_module (&newhandle
, dir
, libdir
, dlname
, old_name
, installed
))
2873 unload_deplibs (*phandle
);
2882 free_vars (dlname
, old_name
, libdir
, deplibs
);
2885 LT_DLFREE (*phandle
); // sets *phandle=NULL
2889 if (*phandle
!= newhandle
)
2891 unload_deplibs (*phandle
);
2896 /* not a libtool module */
2897 *phandle
= (lt_dlhandle
) LT_EMALLOC (struct lt_dlhandle_struct
, 1);
2904 memset (*phandle
, 0, sizeof (struct lt_dlhandle_struct
));
2905 newhandle
= *phandle
;
2907 /* If the module has no directory name component, try to find it
2908 first in user_search_path and then other prescribed paths.
2909 Otherwise (or in any case if the module was not yet found) try
2910 opening just the module name as passed. */
2911 if ((dir
|| (!find_handle (user_search_path
, base_name
, &newhandle
)
2912 && !find_handle (getenv (LTDL_SEARCHPATH_VAR
), base_name
,
2914 #ifdef LTDL_SHLIBPATH_VAR
2915 && !find_handle (getenv (LTDL_SHLIBPATH_VAR
), base_name
,
2918 #ifdef LTDL_SYSSEARCHPATH
2919 && !find_handle (sys_search_path
, base_name
, &newhandle
)
2923 // Directory component was specified, or all find_handle() calls
2924 // failed to find the lib. This is our last try.
2925 errors
= tryall_dlopen (&newhandle
, filename
);
2928 if (!newhandle
|| errors
>0)
2930 LT_DLFREE (*phandle
);
2937 LT_DLMEM_REASSIGN (*phandle
, newhandle
);
2939 if ((*phandle
)->info
.ref_count
== 0)
2941 (*phandle
)->info
.ref_count
= 1;
2942 LT_DLMEM_REASSIGN ((*phandle
)->info
.name
, name
);
2945 (*phandle
)->next
= handles
;
2947 LT_DLMUTEX_UNLOCK ();
2950 LT_DLMUTEX_SETERROR (saved_error
);
2955 LT_DLFREE (canonical
);
2961 lt_dlopen (filename
)
2962 const char *filename
;
2964 lt_dlhandle handle
= 0;
2966 /* Just incase we missed a code path in try_dlopen() that reports
2967 an error, but forgets to reset handle... */
2968 if (try_dlopen (&handle
, filename
) != 0)
2971 // If we're going to return a handle, be sure that has its loader
2972 // field filled in. This is in response to some bugs in which dlopen()
2973 // would return valid-looking handle with NULL loader, causing crashes
2975 if (handle
) assert (handle
->loader
!= NULL
);
2980 /* If the last error messge store was `FILE_NOT_FOUND', then return
2985 const char *error
= 0;
2987 LT_DLMUTEX_GETERROR (error
);
2988 if (error
== LT_DLSTRERROR (FILE_NOT_FOUND
))
2994 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
2995 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
2996 and if a file is still not found try again with SHLIB_EXT appended
2999 lt_dlopenext (filename
)
3000 const char *filename
;
3002 lt_dlhandle handle
= 0;
3007 int file_found
= 1; /* until proven otherwise */
3011 return lt_dlopen (filename
);
3016 len
= LT_STRLEN (filename
);
3017 ext
= strrchr (filename
, '.');
3019 /* If FILENAME already bears a suitable extension, there is no need
3020 to try appending additional extensions. */
3021 if (ext
&& ((strcmp (ext
, archive_ext
) == 0)
3022 #ifdef LTDL_SHLIB_EXT
3023 || (strcmp (ext
, shlib_ext
) == 0)
3027 return lt_dlopen (filename
);
3030 /* First try appending ARCHIVE_EXT. */
3031 tmp
= LT_EMALLOC (char, len
+ LT_STRLEN (archive_ext
) + 1);
3035 strcpy (tmp
, filename
);
3036 strcat (tmp
, archive_ext
);
3037 errors
= try_dlopen (&handle
, tmp
);
3039 /* If we found FILENAME, stop searching -- whether we were able to
3040 load the file as a module or not. If the file exists but loading
3041 failed, it is better to return an error message here than to
3042 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3043 in the module search path. */
3044 if (handle
|| ((errors
> 0) && !file_not_found ()))
3048 // If we're going to return a handle, be sure that has its loader
3049 // field filled in. This is in response to some bugs in which dlopen()
3050 // would return valid-looking handle with NULL loader, causing crashes
3052 if (handle
) assert (handle
->loader
!= NULL
);
3057 #ifdef LTDL_SHLIB_EXT
3058 /* Try appending SHLIB_EXT. */
3059 if (LT_STRLEN (shlib_ext
) > LT_STRLEN (archive_ext
))
3062 tmp
= LT_EMALLOC (char, len
+ LT_STRLEN (shlib_ext
) + 1);
3066 strcpy (tmp
, filename
);
3070 tmp
[len
] = LT_EOS_CHAR
;
3073 strcat(tmp
, shlib_ext
);
3074 errors
= try_dlopen (&handle
, tmp
);
3076 /* As before, if the file was found but loading failed, return now
3077 with the current error message. */
3078 if (handle
|| ((errors
> 0) && !file_not_found ()))
3081 // If we're going to return a handle, be sure that has its loader
3082 // field filled in. This is in response to some bugs in which dlopen()
3083 // would return valid-looking handle with NULL loader, causing crashes
3085 if (handle
) assert (handle
->loader
!= NULL
);
3090 /* Still here? Then we really did fail to locate any of the file
3092 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND
));
3099 lt_argz_insert (pargz
, pargz_len
, before
, entry
)
3107 if ((error
= argz_insert (pargz
, pargz_len
, before
, entry
)))
3112 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY
));
3115 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN
));
3125 lt_argz_insertinorder (pargz
, pargz_len
, entry
)
3134 assert (entry
&& *entry
);
3137 while ((before
= argz_next (*pargz
, *pargz_len
, before
)))
3139 int cmp
= strcmp (entry
, before
);
3142 if (cmp
== 0) return 0; /* No duplicates! */
3145 return lt_argz_insert (pargz
, pargz_len
, before
, entry
);
3149 lt_argz_insertdir (pargz
, pargz_len
, dirnam
, dp
)
3158 size_t end_offset
= 0;
3166 dir_len
= LT_STRLEN (dirnam
);
3167 end
= dp
->d_name
+ LT_D_NAMLEN(dp
);
3169 /* Ignore version numbers. */
3172 for (p
= end
; p
-1 > dp
->d_name
; --p
)
3173 if (strchr (".0123456789", p
[-1]) == 0)
3180 /* Ignore filename extension. */
3183 for (p
= end
-1; p
> dp
->d_name
; --p
)
3191 /* Prepend the directory name. */
3192 end_offset
= end
- dp
->d_name
;
3193 buf_len
= dir_len
+ 1+ end_offset
;
3194 buf
= LT_EMALLOC (char, 1+ buf_len
);
3200 strcpy (buf
, dirnam
);
3202 strncat (buf
, dp
->d_name
, end_offset
);
3203 buf
[buf_len
] = LT_EOS_CHAR
;
3205 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3206 if (lt_argz_insertinorder (pargz
, pargz_len
, buf
) != 0)
3215 list_files_by_dir (dirnam
, pargz
, pargz_len
)
3223 assert (dirnam
&& *dirnam
);
3226 assert (dirnam
[LT_STRLEN(dirnam
) -1] != '/');
3228 dirp
= opendir (dirnam
);
3231 struct dirent
*dp
= 0;
3233 while ((dp
= readdir (dirp
)))
3234 if (dp
->d_name
[0] != '.')
3235 if (lt_argz_insertdir (pargz
, pargz_len
, dirnam
, dp
))
3250 /* If there are any files in DIRNAME, call the function passed in
3251 DATA1 (with the name of each file and DATA2 as arguments). */
3253 foreachfile_callback (dirname
, data1
, data2
)
3258 int (*func
) LT_PARAMS((const char *filename
, lt_ptr data
))
3259 = (int (*) LT_PARAMS((const char *filename
, lt_ptr data
))) data1
;
3263 size_t argz_len
= 0;
3265 if (list_files_by_dir (dirname
, &argz
, &argz_len
) != 0)
3272 while ((filename
= argz_next (argz
, argz_len
, filename
)))
3273 if ((is_done
= (*func
) (filename
, data2
)))
3284 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3285 with DATA. The filenames passed to FUNC would be suitable for
3286 passing to lt_dlopenext. The extensions are stripped so that
3287 individual modules do not generate several entries (e.g. libfoo.la,
3288 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3289 then the same directories that lt_dlopen would search are examined. */
3291 lt_dlforeachfile (search_path
, func
, data
)
3292 const char *search_path
;
3293 int (*func
) LT_PARAMS ((const char *filename
, lt_ptr data
));
3300 /* If a specific path was passed, search only the directories
3302 is_done
= foreach_dirinpath (search_path
, 0,
3303 foreachfile_callback
, func
, data
);
3307 /* Otherwise search the default paths. */
3308 is_done
= foreach_dirinpath (user_search_path
, 0,
3309 foreachfile_callback
, func
, data
);
3312 is_done
= foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3313 foreachfile_callback
, func
, data
);
3316 #ifdef LTDL_SHLIBPATH_VAR
3319 is_done
= foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR
), 0,
3320 foreachfile_callback
, func
, data
);
3323 #ifdef LTDL_SYSSEARCHPATH
3326 is_done
= foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH
), 0,
3327 foreachfile_callback
, func
, data
);
3339 lt_dlhandle cur
, last
;
3344 /* check whether the handle is valid */
3345 last
= cur
= handles
;
3346 while (cur
&& handle
!= cur
)
3354 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
3359 handle
->info
.ref_count
--;
3361 /* Note that even with resident modules, we must track the ref_count
3362 correctly incase the user decides to reset the residency flag
3363 later (even though the API makes no provision for that at the
3365 if (handle
->info
.ref_count
<= 0 && !LT_DLIS_RESIDENT (handle
))
3367 lt_user_data data
= handle
->loader
->dlloader_data
;
3369 if (handle
!= handles
)
3371 last
->next
= handle
->next
;
3375 handles
= handle
->next
;
3378 errors
+= handle
->loader
->module_close (data
, handle
->module
);
3379 errors
+= unload_deplibs(handle
);
3381 LT_DLFREE (handle
->info
.filename
);
3382 LT_DLFREE (handle
->info
.name
);
3388 if (LT_DLIS_RESIDENT (handle
))
3390 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE
));
3395 LT_DLMUTEX_UNLOCK ();
3401 lt_dlsym (handle
, symbol
)
3406 char lsym
[LT_SYMBOL_LENGTH
];
3413 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
3419 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND
));
3423 // Due to bugs in lt_dlopen*, some handles were being returned that have a
3424 // NULL loader field. Check for this.
3425 assert (handle
->loader
);
3427 lensym
= LT_STRLEN (symbol
) + LT_STRLEN (handle
->loader
->sym_prefix
)
3428 + LT_STRLEN (handle
->info
.name
);
3430 if (lensym
+ LT_SYMBOL_OVERHEAD
< LT_SYMBOL_LENGTH
)
3436 sym
= LT_EMALLOC (char, lensym
+ LT_SYMBOL_OVERHEAD
+ 1);
3439 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW
));
3444 data
= handle
->loader
->dlloader_data
;
3445 if (handle
->info
.name
)
3447 const char *saved_error
;
3449 LT_DLMUTEX_GETERROR (saved_error
);
3451 /* this is a libtool module */
3452 if (handle
->loader
->sym_prefix
)
3454 strcpy(sym
, handle
->loader
->sym_prefix
);
3455 strcat(sym
, handle
->info
.name
);
3459 strcpy(sym
, handle
->info
.name
);
3462 strcat(sym
, "_LTX_");
3463 strcat(sym
, symbol
);
3465 /* try "modulename_LTX_symbol" */
3466 LTDEBUG_PRINTF(("dlsym looking for '%s'\n", sym
));
3467 address
= handle
->loader
->find_sym (data
, handle
->module
, sym
);
3476 LT_DLMUTEX_SETERROR (saved_error
);
3479 /* otherwise try "symbol" */
3480 if (handle
->loader
->sym_prefix
)
3482 strcpy(sym
, handle
->loader
->sym_prefix
);
3483 strcat(sym
, symbol
);
3487 strcpy(sym
, symbol
);
3490 LTDEBUG_PRINTF(("dlsym looking for '%s'\n", sym
));
3491 address
= handle
->loader
->find_sym (data
, handle
->module
, sym
);
3505 LT_DLMUTEX_GETERROR (error
);
3506 LT_DLMUTEX_SETERROR (0);
3508 return error
? error
: LT_DLSTRERROR (UNKNOWN
);
3512 lt_dlpath_insertdir (ppath
, before
, dir
)
3518 char *canonical
= 0;
3520 size_t argz_len
= 0;
3523 assert (dir
&& *dir
);
3525 if (canonicalize_path (dir
, &canonical
) != 0)
3531 assert (canonical
&& *canonical
);
3533 /* If *PPATH is empty, set it to DIR. */
3536 assert (!before
); /* BEFORE cannot be set without PPATH. */
3537 assert (dir
); /* Without DIR, don't call this function! */
3539 *ppath
= lt_estrdup (dir
);
3546 assert (ppath
&& *ppath
);
3548 if (argzize_path (*ppath
, &argz
, &argz_len
) != 0)
3554 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
3555 if *PPATH is already canonicalized, and hence does not change length
3556 with respect to ARGZ. We canonicalize each entry as it is added to
3557 the search path, and don't call this function with (uncanonicalized)
3558 user paths, so this is a fair assumption. */
3561 assert (*ppath
<= before
);
3562 assert (before
- *ppath
<= strlen (*ppath
));
3564 before
= before
- *ppath
+ argz
;
3567 if (lt_argz_insert (&argz
, &argz_len
, before
, dir
) != 0)
3573 argz_stringify (argz
, argz_len
, LT_PATHSEP_CHAR
);
3574 LT_DLMEM_REASSIGN (*ppath
, argz
);
3577 LT_DLFREE (canonical
);
3584 lt_dladdsearchdir (search_dir
)
3585 const char *search_dir
;
3589 if (search_dir
&& *search_dir
)
3592 if (lt_dlpath_insertdir (&user_search_path
, 0, search_dir
) != 0)
3594 LT_DLMUTEX_UNLOCK ();
3601 lt_dlinsertsearchdir (before
, search_dir
)
3603 const char *search_dir
;
3610 if ((before
< user_search_path
)
3611 || (before
>= user_search_path
+ LT_STRLEN (user_search_path
)))
3613 LT_DLMUTEX_UNLOCK ();
3614 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION
));
3617 LT_DLMUTEX_UNLOCK ();
3620 if (search_dir
&& *search_dir
)
3623 if (lt_dlpath_insertdir (&user_search_path
,
3624 (char *) before
, search_dir
) != 0)
3628 LT_DLMUTEX_UNLOCK ();
3635 lt_dlsetsearchpath (search_path
)
3636 const char *search_path
;
3641 LT_DLFREE (user_search_path
);
3642 LT_DLMUTEX_UNLOCK ();
3644 if (!search_path
|| !LT_STRLEN (search_path
))
3650 if (canonicalize_path (search_path
, &user_search_path
) != 0)
3652 LT_DLMUTEX_UNLOCK ();
3658 lt_dlgetsearchpath ()
3660 const char *saved_path
;
3663 saved_path
= user_search_path
;
3664 LT_DLMUTEX_UNLOCK ();
3670 lt_dlmakeresident (handle
)
3677 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
3682 LT_DLSET_FLAG (handle
, LT_DLRESIDENT_FLAG
);
3689 lt_dlisresident (handle
)
3694 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
3698 return LT_DLIS_RESIDENT (handle
);
3704 /* --- MODULE INFORMATION --- */
3707 lt_dlgetinfo (handle
)
3712 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE
));
3716 return &(handle
->info
);
3720 lt_dlhandle_next (place
)
3723 return place
? place
->next
: handles
;
3727 lt_dlforeach (func
, data
)
3728 int (*func
) LT_PARAMS((lt_dlhandle handle
, lt_ptr data
));
3739 lt_dlhandle tmp
= cur
;
3742 if ((*func
) (tmp
, data
))
3749 LT_DLMUTEX_UNLOCK ();
3755 lt_dlcaller_register ()
3757 static lt_dlcaller_id last_caller_id
= 0;
3761 result
= ++last_caller_id
;
3762 LT_DLMUTEX_UNLOCK ();
3768 lt_dlcaller_set_data (key
, handle
, data
)
3774 lt_ptr stale
= (lt_ptr
) 0;
3777 /* This needs to be locked so that the caller data can be updated
3778 simultaneously by different threads. */
3781 if (handle
->caller_data
)
3782 while (handle
->caller_data
[n_elements
].key
)
3785 for (i
= 0; i
< n_elements
; ++i
)
3787 if (handle
->caller_data
[i
].key
== key
)
3789 stale
= handle
->caller_data
[i
].data
;
3794 /* Ensure that there is enough room in this handle's caller_data
3795 array to accept a new element (and an empty end marker). */
3796 if (i
== n_elements
)
3798 lt_caller_data
*temp
3799 = LT_DLREALLOC (lt_caller_data
, handle
->caller_data
, 2+ n_elements
);
3807 handle
->caller_data
= temp
;
3809 /* We only need this if we needed to allocate a new caller_data. */
3810 handle
->caller_data
[i
].key
= key
;
3811 handle
->caller_data
[1+ i
].key
= 0;
3814 handle
->caller_data
[i
].data
= data
;
3817 LT_DLMUTEX_UNLOCK ();
3823 lt_dlcaller_get_data (key
, handle
)
3827 lt_ptr result
= (lt_ptr
) 0;
3829 /* This needs to be locked so that the caller data isn't updated by
3830 another thread part way through this function. */
3833 /* Locate the index of the element with a matching KEY. */
3836 for (i
= 0; handle
->caller_data
[i
].key
; ++i
)
3838 if (handle
->caller_data
[i
].key
== key
)
3840 result
= handle
->caller_data
[i
].data
;
3846 LT_DLMUTEX_UNLOCK ();
3853 /* --- USER MODULE LOADER API --- */
3857 lt_dlloader_add (place
, dlloader
, loader_name
)
3859 const struct lt_user_dlloader
*dlloader
;
3860 const char *loader_name
;
3863 lt_dlloader
*node
= 0, *ptr
= 0;
3865 if ((dlloader
== 0) /* diagnose null parameters */
3866 || (dlloader
->module_open
== 0)
3867 || (dlloader
->module_close
== 0)
3868 || (dlloader
->find_sym
== 0))
3870 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
3874 /* Create a new dlloader node with copies of the user callbacks. */
3875 node
= LT_EMALLOC (lt_dlloader
, 1);
3880 node
->loader_name
= loader_name
;
3881 node
->sym_prefix
= dlloader
->sym_prefix
;
3882 node
->dlloader_exit
= dlloader
->dlloader_exit
;
3883 node
->module_open
= dlloader
->module_open
;
3884 node
->module_close
= dlloader
->module_close
;
3885 node
->find_sym
= dlloader
->find_sym
;
3886 node
->dlloader_data
= dlloader
->dlloader_data
;
3891 /* If there are no loaders, NODE becomes the list! */
3896 /* If PLACE is not set, add NODE to the end of the
3898 for (ptr
= loaders
; ptr
->next
; ptr
= ptr
->next
)
3905 else if (loaders
== place
)
3907 /* If PLACE is the first loader, NODE goes first. */
3913 /* Find the node immediately preceding PLACE. */
3914 for (ptr
= loaders
; ptr
->next
!= place
; ptr
= ptr
->next
)
3919 if (ptr
->next
!= place
)
3921 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
3926 /* Insert NODE between PTR and PLACE. */
3932 LT_DLMUTEX_UNLOCK ();
3938 lt_dlloader_remove (loader_name
)
3939 const char *loader_name
;
3941 lt_dlloader
*place
= lt_dlloader_find (loader_name
);
3947 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
3953 /* Fail if there are any open modules which use this loader. */
3954 for (handle
= handles
; handle
; handle
= handle
->next
)
3956 if (handle
->loader
== place
)
3958 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER
));
3964 if (place
== loaders
)
3966 /* PLACE is the first loader in the list. */
3967 loaders
= loaders
->next
;
3971 /* Find the loader before the one being removed. */
3973 for (prev
= loaders
; prev
->next
; prev
= prev
->next
)
3975 if (!strcmp (prev
->next
->loader_name
, loader_name
))
3982 prev
->next
= prev
->next
->next
;
3985 if (place
->dlloader_exit
)
3987 errors
= place
->dlloader_exit (place
->dlloader_data
);
3993 LT_DLMUTEX_UNLOCK ();
3999 lt_dlloader_next (place
)
4005 next
= place
? place
->next
: loaders
;
4006 LT_DLMUTEX_UNLOCK ();
4012 lt_dlloader_name (place
)
4015 const char *name
= 0;
4020 name
= place
? place
->loader_name
: 0;
4021 LT_DLMUTEX_UNLOCK ();
4025 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4032 lt_dlloader_data (place
)
4035 lt_user_data
*data
= 0;
4040 data
= place
? &(place
->dlloader_data
) : 0;
4041 LT_DLMUTEX_UNLOCK ();
4045 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER
));
4052 lt_dlloader_find (loader_name
)
4053 const char *loader_name
;
4055 lt_dlloader
*place
= 0;
4058 for (place
= loaders
; place
; place
= place
->next
)
4060 if (strcmp (place
->loader_name
, loader_name
) == 0)
4065 LT_DLMUTEX_UNLOCK ();