1
/* ltdl.c -- system independent dlopen wrapper
2
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3
Originally by Thomas Tanner <tanner@ffii.org>
4
This file is part of GNU Libtool.
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Lesser General Public
8
License as published by the Free Software Foundation; either
9
version 2 of the License, or (at your option) any later version.
11
As a special exception to the GNU Lesser General Public License,
12
if you distribute this file as part of a program or library that
13
is built using GNU libtool, you may include it under the same
14
distribution terms that you use for the rest of that program.
16
This library is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
Lesser General Public License for more details.
21
You should have received a copy of the GNU Lesser General Public
22
License along with this library; if not, write to the Free Software
23
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
40
/* Include the header defining malloc. On K&R C compilers,
41
that's <malloc.h>, on ANSI C and ISO C compilers, that's <stdlib.h>. */
78
#undef LT_USE_POSIX_DIRENT
83
# define LT_USE_POSIX_DIRENT
84
# endif /* HAVE_DIRENT_H */
85
# endif /* HAVE_READDIR */
86
# endif /* HAVE_OPENDIR */
87
#endif /* HAVE_CLOSEDIR */
90
#undef LT_USE_WINDOWS_DIRENT_EMULATION
91
#ifndef LT_USE_POSIX_DIRENT
93
# define LT_USE_WINDOWS_DIRENT_EMULATION
94
# endif /* __WINDOWS__ */
95
#endif /* LT_USE_POSIX_DIRENT */
98
#ifdef LT_USE_POSIX_DIRENT
100
# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
102
# ifdef LT_USE_WINDOWS_DIRENT_EMULATION
103
# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
105
# define dirent direct
106
# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
108
# include <sys/ndir.h>
111
# include <sys/dir.h>
126
# define assert(arg) ((void) 0)
132
# include <dmalloc.h>
138
/* --- WINDOWS SUPPORT --- */
142
# define LT_GLOBAL_DATA __declspec(dllexport)
144
# define LT_GLOBAL_DATA
147
/* fopen() mode flags for reading a text file */
148
#undef LT_READTEXT_MODE
150
# define LT_READTEXT_MODE "rt"
152
# define LT_READTEXT_MODE "r"
155
#ifdef LT_USE_WINDOWS_DIRENT_EMULATION
159
#define dirent lt_dirent
171
WIN32_FIND_DATA Win32FindData;
173
struct dirent file_info;
176
#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
181
/* --- MANIFEST CONSTANTS --- */
184
/* Standard libltdl search path environment variable name */
185
#undef LTDL_SEARCHPATH_VAR
186
#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
188
/* Standard libtool archive file extension. */
189
#undef LTDL_ARCHIVE_EXT
190
#define LTDL_ARCHIVE_EXT ".la"
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) { xfree (p); (p) = 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 *) lt_dlrealloc ((p), (n) * sizeof(tp)))
245
#define LT_DLFREE(p) \
246
LT_STMT_START { if (p) { lt_dlfree (p); (p) = 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));
267
strdup(const char *str)
273
tmp = LT_DLMALLOC (char, 1+ strlen (str));
287
#define strcmp rpl_strcmp
289
static int strcmp LT_PARAMS((const char *str1, const char *str2));
292
strcmp (const char *str1, const char *str2)
301
for (;*str1 && *str2; ++str1, ++str2)
307
return (int)(*str1 - *str2);
315
# define strchr index
317
# define strchr rpl_strchr
319
static const char *strchr LT_PARAMS((const char *str, int ch));
322
strchr(const char *str, int ch)
326
for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
329
return (*p == (char)ch) ? p : 0;
333
#endif /* !HAVE_STRCHR */
339
# define strrchr rindex
341
# define strrchr rpl_strrchr
343
static const char *strrchr LT_PARAMS((const char *str, int ch));
346
strrchr(const char *str, int ch)
348
const char *p, *q = 0;
350
for (p = str; *p != LT_EOS_CHAR; ++p)
364
/* NOTE: Neither bcopy nor the memcpy implementation below can
365
reliably handle copying in overlapping areas of memory. Use
366
memmove (for which there is a fallback implmentation below)
367
if you need that behaviour. */
371
# define memcpy(dest, src, size) bcopy (src, dest, size)
373
# define memcpy rpl_memcpy
375
static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
378
memcpy (lt_ptr dest, const lt_ptr src, size_t size)
382
for (i = 0; i < size; ++i)
390
# endif /* !HAVE_BCOPY */
391
#endif /* !HAVE_MEMCPY */
394
# define memmove rpl_memmove
396
static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
399
memmove (lt_ptr dest, const lt_ptr src, size_t size)
404
for (i = 0; i < size; ++i)
409
for (i = size -1; i >= 0; --i)
417
#endif /* !HAVE_MEMMOVE */
419
#ifdef LT_USE_WINDOWS_DIRENT_EMULATION
421
static void closedir LT_PARAMS((DIR *entry));
426
assert(entry != (DIR *) NULL);
427
FindClose(entry->hSearch);
428
lt_dlfree((lt_ptr)entry);
432
static DIR * opendir LT_PARAMS((const char *path));
435
opendir (const char *path)
437
char file_specification[LT_FILENAME_MAX];
440
assert(path != (char *) NULL);
441
(void) strncpy(file_specification,path,LT_FILENAME_MAX-1);
442
(void) strcat(file_specification,"\\");
443
entry = LT_DLMALLOC (DIR,sizeof(DIR));
444
if (entry != (DIR *) 0)
446
entry->firsttime = TRUE;
447
entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
449
if (entry->hSearch == INVALID_HANDLE_VALUE)
451
(void) strcat(file_specification,"\\*.*");
452
entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
453
if (entry->hSearch == INVALID_HANDLE_VALUE)
463
static struct dirent *readdir LT_PARAMS((DIR *entry));
465
static struct dirent *readdir(DIR *entry)
470
if (entry == (DIR *) 0)
471
return((struct dirent *) 0);
472
if (!entry->firsttime)
474
status = FindNextFile(entry->hSearch,&entry->Win32FindData);
476
return((struct dirent *) 0);
478
entry->firsttime = FALSE;
479
(void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
481
entry->file_info.d_namlen = strlen(entry->file_info.d_name);
482
return(&entry->file_info);
485
#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
487
/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
488
``realloc is not entirely portable''
489
In any case we want to use the allocator supplied by the user without
490
burdening them with an lt_dlrealloc function pointer to maintain.
491
Instead implement our own version (with known boundary conditions)
492
using lt_dlmalloc and lt_dlfree. */
495
#define realloc rpl_realloc
498
/* You can't (re)define realloc unless you also (re)define malloc.
499
Right now, this code uses the size of the *destination* to decide
500
how much to copy. That's not right, but you can't know the size
501
of the source unless you know enough about, or wrote malloc. So
502
this code is disabled... */
511
/* For zero or less bytes, free the original memory */
521
/* Allow reallocation of a NULL pointer. */
522
return lt_dlmalloc (size);
526
/* Allocate a new block, copy and free the old block. */
527
lt_ptr mem = lt_dlmalloc (size);
531
memcpy (mem, ptr, size);
535
/* Note that the contents of PTR are not damaged if there is
536
insufficient memory to realloc. */
543
#if ! HAVE_ARGZ_APPEND
544
# define argz_append rpl_argz_append
546
static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
547
const char *buf, size_t buf_len));
550
argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len)
557
assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
559
/* If nothing needs to be appended, no more work is required. */
563
/* Ensure there is enough room to append BUF_LEN. */
564
argz_len = *pargz_len + buf_len;
565
argz = LT_DLREALLOC (char, *pargz, argz_len);
569
/* Copy characters from BUF after terminating '\0' in ARGZ. */
570
memcpy (argz + *pargz_len, buf, buf_len);
572
/* Assign new values. */
574
*pargz_len = argz_len;
578
#endif /* !HAVE_ARGZ_APPEND */
581
#if ! HAVE_ARGZ_CREATE_SEP
582
# define argz_create_sep rpl_argz_create_sep
584
static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
585
char **pargz, size_t *pargz_len));
588
argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len)
597
/* Make a copy of STR, but replacing each occurence of
599
argz_len = 1+ LT_STRLEN (str);
605
argz = LT_DLMALLOC (char, argz_len);
609
for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
613
/* Ignore leading delimiters, and fold consecutive
614
delimiters in STR into a single '\0' in ARGZ. */
615
if ((q > argz) && (q[-1] != LT_EOS_CHAR))
623
/* Copy terminating LT_EOS_CHAR. */
627
/* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
631
/* Assign new values. */
633
*pargz_len = argz_len;
637
#endif /* !HAVE_ARGZ_CREATE_SEP */
640
#if ! HAVE_ARGZ_INSERT
641
# define argz_insert rpl_argz_insert
643
static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
644
char *before, const char *entry));
647
argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry)
651
assert (entry && *entry);
653
/* No BEFORE address indicates ENTRY should be inserted after the
654
current last element. */
656
return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
658
/* This probably indicates a programmer error, but to preserve
659
semantics, scan back to the start of an entry if BEFORE points
660
into the middle of it. */
661
while ((before > *pargz) && (before[-1] != LT_EOS_CHAR))
665
size_t entry_len = 1+ LT_STRLEN (entry);
666
size_t argz_len = *pargz_len + entry_len;
667
size_t offset = before - *pargz;
668
char *argz = LT_DLREALLOC (char, *pargz, argz_len);
673
/* Make BEFORE point to the equivalent offset in ARGZ that it
674
used to have in *PARGZ incase realloc() moved the block. */
675
before = argz + offset;
677
/* Move the ARGZ entries starting at BEFORE up into the new
678
space at the end -- making room to copy ENTRY into the
680
memmove (before + entry_len, before, *pargz_len - offset);
681
memcpy (before, entry, entry_len);
683
/* Assign new values. */
685
*pargz_len = argz_len;
690
#endif /* !HAVE_ARGZ_INSERT */
694
# define argz_next rpl_argz_next
696
static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
700
argz_next (char *argz, size_t argz_len, const char *entry)
702
assert ((argz && argz_len) || (!argz && !argz_len));
706
/* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
707
within the ARGZ vector. */
708
assert ((!argz && !argz_len)
709
|| ((argz <= entry) && (entry < (argz + argz_len))));
711
/* Move to the char immediately after the terminating
713
entry = 1+ strchr (entry, LT_EOS_CHAR);
715
/* Return either the new ENTRY, or else NULL if ARGZ is
717
return (entry >= argz + argz_len) ? 0 : (char *) entry;
721
/* This should probably be flagged as a programmer error,
722
since starting an argz_next loop with the iterator set
723
to ARGZ is safer. To preserve semantics, handle the NULL
724
case by returning the start of ARGZ (if any). */
731
#endif /* !HAVE_ARGZ_NEXT */
735
#if ! HAVE_ARGZ_STRINGIFY
736
# define argz_stringify rpl_argz_stringify
738
static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
742
argz_stringify (char *argz, size_t argz_len, int sep)
744
assert ((argz && argz_len) || (!argz && !argz_len));
748
--argz_len; /* don't stringify the terminating EOS */
749
while (--argz_len > 0)
751
if (argz[argz_len] == LT_EOS_CHAR)
752
argz[argz_len] = sep;
756
#endif /* !HAVE_ARGZ_STRINGIFY */
761
/* --- TYPE DEFINITIONS -- */
764
/* This type is used for the array of caller data sets in each handler. */
773
/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
776
/* Extract the diagnostic strings from the error table macro in the same
777
order as the enumerated indices in ltdl.h. */
779
static const char *lt_dlerror_strings[] =
781
#define LT_ERROR(name, diagnostic) (diagnostic),
788
/* This structure is used for the list of registered loaders. */
790
struct lt_dlloader *next;
791
const char *loader_name; /* identifying name for each loader */
792
const char *sym_prefix; /* prefix for symbols */
793
lt_module_open *module_open;
794
lt_module_close *module_close;
795
lt_find_sym *find_sym;
796
lt_dlloader_exit *dlloader_exit;
797
lt_user_data dlloader_data;
800
struct lt_dlhandle_struct {
801
struct lt_dlhandle_struct *next;
802
lt_dlloader *loader; /* dlopening interface */
804
int depcount; /* number of dependencies */
805
lt_dlhandle *deplibs; /* dependencies */
806
lt_module module; /* system module handle */
807
lt_ptr system; /* system specific data */
808
lt_caller_data *caller_data; /* per caller associated data */
809
int flags; /* various boolean stats */
812
/* Various boolean flags can be stored in the flags field of an
813
lt_dlhandle_struct... */
814
#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
815
#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
817
#define LT_DLRESIDENT_FLAG (0x01 << 0)
818
/* ...add more flags here... */
820
#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
823
#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
825
static const char objdir[] = LTDL_OBJDIR;
826
static const char archive_ext[] = LTDL_ARCHIVE_EXT;
827
#ifdef LTDL_SHLIB_EXT
828
static const char shlib_ext[] = LTDL_SHLIB_EXT;
830
#ifdef LTDL_SYSSEARCHPATH
831
static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
837
/* --- MUTEX LOCKING --- */
840
/* Macros to make it easier to run the lock functions only if they have
841
been registered. The reason for the complicated lock macro is to
842
ensure that the stored error message from the last error is not
843
accidentally erased if the current function doesn't generate an
845
#define LT_DLMUTEX_LOCK() LT_STMT_START { \
846
if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
848
#define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
849
if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
851
#define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
852
if (lt_dlmutex_seterror_func) \
853
(*lt_dlmutex_seterror_func) (errormsg); \
854
else lt_dllast_error = (errormsg); } LT_STMT_END
855
#define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
856
if (lt_dlmutex_seterror_func) \
857
(errormsg) = (*lt_dlmutex_geterror_func) (); \
858
else (errormsg) = lt_dllast_error; } LT_STMT_END
860
/* The mutex functions stored here are global, and are necessarily the
861
same for all threads that wish to share access to libltdl. */
862
static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
863
static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
864
static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
865
static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
866
static const char *lt_dllast_error = 0;
869
/* Either set or reset the mutex functions. Either all the arguments must
870
be valid functions, or else all can be NULL to turn off locking entirely.
871
The registered functions should be manipulating a static global lock
872
from the lock() and unlock() callbacks, which needs to be reentrant. */
874
lt_dlmutex_register (
875
lt_dlmutex_lock *lock,
876
lt_dlmutex_unlock *unlock,
877
lt_dlmutex_seterror *seterror,
878
lt_dlmutex_geterror *geterror)
880
lt_dlmutex_unlock *old_unlock = unlock;
883
/* Lock using the old lock() callback, if any. */
886
if ((lock && unlock && seterror && geterror)
887
|| !(lock || unlock || seterror || geterror))
889
lt_dlmutex_lock_func = lock;
890
lt_dlmutex_unlock_func = unlock;
891
lt_dlmutex_geterror_func = geterror;
895
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
899
/* Use the old unlock() callback we saved earlier, if any. Otherwise
900
record any errors using internal storage. */
904
/* Return the number of errors encountered during the execution of
912
/* --- ERROR HANDLING --- */
915
static const char **user_error_strings = 0;
916
static int errorcount = LT_ERROR_MAX;
919
lt_dladderror (const char *diagnostic)
923
const char **temp = (const char **) 0;
929
errindex = errorcount - LT_ERROR_MAX;
930
temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
933
user_error_strings = temp;
934
user_error_strings[errindex] = diagnostic;
935
result = errorcount++;
938
LT_DLMUTEX_UNLOCK ();
944
lt_dlseterror (int errindex)
950
if (errindex >= errorcount || errindex < 0)
952
/* Ack! Error setting the error message! */
953
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
956
else if (errindex < LT_ERROR_MAX)
958
/* No error setting the error message! */
959
LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
963
/* No error setting the error message! */
964
LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
967
LT_DLMUTEX_UNLOCK ();
973
lt_emalloc (size_t size)
975
lt_ptr mem = lt_dlmalloc (size);
977
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
982
lt_erealloc (lt_ptr addr, size_t size)
984
lt_ptr mem = lt_dlrealloc (addr, size);
986
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
991
lt_estrdup (const char *str)
993
char *copy = strdup (str);
994
if (LT_STRLEN (str) && !copy)
995
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1002
/* --- DLOPEN() INTERFACE LOADER --- */
1007
/* dynamic linking with dlopen/dlsym */
1014
# include <sys/dl.h>
1018
# define LT_GLOBAL RTLD_GLOBAL
1021
# define LT_GLOBAL DL_GLOBAL
1023
#endif /* !RTLD_GLOBAL */
1025
# define LT_GLOBAL 0
1026
#endif /* !LT_GLOBAL */
1028
/* We may have to define LT_LAZY_OR_NOW in the command line if we
1029
find out it does not work in some platform. */
1030
#ifndef LT_LAZY_OR_NOW
1032
# define LT_LAZY_OR_NOW RTLD_LAZY
1035
# define LT_LAZY_OR_NOW DL_LAZY
1037
# endif /* !RTLD_LAZY */
1039
#ifndef LT_LAZY_OR_NOW
1041
# define LT_LAZY_OR_NOW RTLD_NOW
1044
# define LT_LAZY_OR_NOW DL_NOW
1046
# endif /* !RTLD_NOW */
1048
#ifndef LT_LAZY_OR_NOW
1049
# define LT_LAZY_OR_NOW 0
1050
#endif /* !LT_LAZY_OR_NOW */
1053
# define DLERROR(arg) dlerror ()
1055
# define DLERROR(arg) LT_DLSTRERROR (arg)
1059
sys_dl_open (lt_user_data loader_data, const char *filename)
1061
// XXX Need to investigate why .a files are asked to be open by this routine ???
1062
lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
1066
LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
1073
sys_dl_close (lt_user_data loader_data, lt_module module)
1077
if (dlclose (module) != 0)
1079
LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
1088
lt_user_data loader_data,
1092
lt_ptr address = dlsym (module, symbol);
1096
LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
1102
static struct lt_user_dlloader sys_dl =
1109
sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
1112
#endif /* HAVE_LIBDL */
1116
/* --- SHL_LOAD() INTERFACE LOADER --- */
1120
/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1126
/* some flags are missing on some systems, so we provide
1127
* harmless defaults.
1130
* BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1131
* BIND_DEFERRED - Delay code symbol resolution until actual reference.
1134
* BIND_FIRST - Place the library at the head of the symbol search
1136
* BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1137
* unsatisfied symbols as fatal. This flag allows
1138
* binding of unsatisfied code symbols to be deferred
1140
* [Perl: For certain libraries, like DCE, deferred
1141
* binding often causes run time problems. Adding
1142
* BIND_NONFATAL to BIND_IMMEDIATE still allows
1143
* unresolved references in situations like this.]
1144
* BIND_NOSTART - Do not call the initializer for the shared library
1145
* when the library is loaded, nor on a future call to
1147
* BIND_VERBOSE - Print verbose messages concerning possible
1148
* unsatisfied symbols.
1150
* hp9000s700/hp9000s800:
1151
* BIND_RESTRICTED - Restrict symbols visible by the library to those
1152
* present at library load time.
1153
* DYNAMIC_PATH - Allow the loader to dynamically search for the
1154
* library specified by the path argument.
1157
#ifndef DYNAMIC_PATH
1158
# define DYNAMIC_PATH 0
1160
#ifndef BIND_RESTRICTED
1161
# define BIND_RESTRICTED 0
1164
#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1167
sys_shl_open (lt_user_data loader_data, const char *filename)
1169
static shl_t self = (shl_t) 0;
1170
lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1172
/* Since searching for a symbol against a NULL module handle will also
1173
look in everything else that was already loaded and exported with
1174
the -E compiler flag, we always cache a handle saved before any
1175
modules are loaded. */
1179
shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1188
module = shl_load (filename, LT_BIND_FLAGS, 0L);
1192
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1200
sys_shl_close (lt_user_data loader_data, lt_module module)
1204
if (module && (shl_unload ((shl_t) (module)) != 0))
1206
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1215
lt_user_data loader_data,
1221
/* sys_shl_open should never return a NULL module handle */
1222
if (module == (lt_module) 0)
1224
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1226
else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
1230
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1237
static struct lt_user_dlloader sys_shl = {
1238
0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
1241
#endif /* HAVE_SHL_LOAD */
1246
/* --- LOADLIBRARY() INTERFACE LOADER --- */
1250
/* dynamic linking for Win32 */
1252
#include <windows.h>
1254
/* Forward declaration; required to implement handle search below. */
1255
static lt_dlhandle handles;
1258
sys_wll_open (lt_user_data loader_data, const char *filename)
1261
lt_module module = 0;
1262
const char *errormsg = 0;
1263
char *searchname = 0;
1265
char self_name_buf[MAX_PATH];
1269
/* Get the name of main module */
1271
GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
1272
filename = ext = self_name_buf;
1276
ext = strrchr (filename, '.');
1281
/* FILENAME already has an extension. */
1282
searchname = lt_estrdup (filename);
1286
/* Append a `.' to stop Windows from adding an
1287
implicit `.dll' extension. */
1288
searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
1290
sprintf (searchname, "%s.", filename);
1297
char wpath[MAX_PATH];
1298
cygwin_conv_to_full_win32_path(searchname, wpath);
1299
module = LoadLibrary(wpath);
1302
module = LoadLibrary (searchname);
1304
LT_DLFREE (searchname);
1306
/* libltdl expects this function to fail if it is unable
1307
to physically load the library. Sadly, LoadLibrary
1308
will search the loaded libraries for a match and return
1309
one of them if the path search load fails.
1311
We check whether LoadLibrary is returning a handle to
1312
an already loaded module, and simulate failure if we
1324
if (cur->module == module)
1331
LT_DLMUTEX_UNLOCK ();
1335
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1343
sys_wll_close (lt_user_data loader_data, lt_module module)
1347
if (FreeLibrary(module) == 0)
1349
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1358
lt_user_data loader_data,
1362
lt_ptr address = GetProcAddress (module, symbol);
1366
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1372
static struct lt_user_dlloader sys_wll = {
1373
0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1376
#endif /* __WINDOWS__ */
1381
/* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1386
/* dynamic linking for BeOS */
1388
#include <kernel/image.h>
1391
sys_bedl_open (lt_user_data loader_data, const char *filename)
1397
image = load_add_on (filename);
1403
if (get_next_image_info (0, &cookie, &info) == B_OK)
1404
image = load_add_on (info.name);
1409
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1413
return (lt_module) image;
1417
sys_bedl_close (lt_user_data loader_data, lt_module module)
1421
if (unload_add_on ((image_id) module) != B_OK)
1423
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1432
lt_user_data loader_data,
1437
image_id image = (image_id) module;
1439
if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1441
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1448
static struct lt_user_dlloader sys_bedl = {
1449
0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1452
#endif /* __BEOS__ */
1457
/* --- DLD_LINK() INTERFACE LOADER --- */
1462
/* dynamic linking with dld */
1469
sys_dld_open (lt_user_data loader_data, const char *filename)
1471
lt_module module = strdup (filename);
1473
if (dld_link (filename) != 0)
1475
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1484
sys_dld_close (lt_user_data loader_data, lt_module module)
1488
if (dld_unlink_by_file ((char*)(module), 1) != 0)
1490
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1503
lt_user_data loader_data,
1507
lt_ptr address = dld_get_func (symbol);
1511
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1517
static struct lt_user_dlloader sys_dld = {
1518
0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1521
#endif /* HAVE_DLD */
1523
/* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
1527
#if HAVE_MACH_O_DYLD_H
1528
#if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
1529
/* Is this correct? Does it still function properly? */
1530
#define __private_extern__ extern
1532
# include <mach-o/dyld.h>
1534
#include <mach-o/getsect.h>
1536
/* We have to put some stuff here that isn't in older dyld.h files */
1537
#ifndef ENUM_DYLD_BOOL
1538
# define ENUM_DYLD_BOOL
1547
# define LC_REQ_DYLD 0x80000000
1549
#ifndef LC_LOAD_WEAK_DYLIB
1550
# define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
1552
static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0;
1553
static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0;
1554
static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0;
1555
static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0;
1557
#ifndef NSADDIMAGE_OPTION_NONE
1558
#define NSADDIMAGE_OPTION_NONE 0x0
1560
#ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
1561
#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
1563
#ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
1564
#define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
1566
#ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1567
#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
1569
#ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
1570
#define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
1572
#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
1573
#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
1575
#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1576
#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
1578
#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
1579
#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
1581
#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1582
#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
1587
lt_int_dyld_error(char* othererror)
1589
/* return the dyld error string, or the passed in error string if none */
1590
NSLinkEditErrors ler;
1594
NSLinkEditError(&ler,&lerno,&file,&errstr);
1595
if (!errstr || !strlen(errstr)) errstr = othererror;
1599
static const struct mach_header *
1600
lt_int_dyld_get_mach_header_from_nsmodule(NSModule module)
1602
/* There should probably be an apple dyld api for this */
1603
int i=_dyld_image_count();
1605
const char *modname=NSNameOfModule(module);
1606
const struct mach_header *mh=NULL;
1607
if (!modname) return NULL;
1608
for (j = 0; j < i; j++)
1610
if (!strcmp(_dyld_get_image_name(j),modname))
1612
mh=_dyld_get_image_header(j);
1619
static const char* lt_int_dyld_lib_install_name(const struct mach_header *mh)
1621
/* NSAddImage is also used to get the loaded image, but it only works if the lib
1622
is installed, for uninstalled libs we need to check the install_names against
1623
each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
1624
different lib was loaded as a result
1627
struct load_command *lc;
1628
unsigned long offset = sizeof(struct mach_header);
1629
const char* retStr=NULL;
1630
for (j = 0; j < mh->ncmds; j++)
1632
lc = (struct load_command*)(((unsigned long)mh) + offset);
1633
if (LC_ID_DYLIB == lc->cmd)
1635
retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset +
1638
offset += lc->cmdsize;
1643
static const struct mach_header *
1644
lt_int_dyld_match_loaded_lib_by_install_name(const char *name)
1646
int i=_dyld_image_count();
1648
const struct mach_header *mh=NULL;
1649
const char *id=NULL;
1650
for (j = 0; j < i; j++)
1652
id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j));
1653
if ((id) && (!strcmp(id,name)))
1655
mh=_dyld_get_image_header(j);
1663
lt_int_dyld_NSlookupSymbolInLinkedLibs(const char *symbol, const struct mach_header *mh)
1665
/* Safe to assume our mh is good */
1667
struct load_command *lc;
1668
unsigned long offset = sizeof(struct mach_header);
1669
NSSymbol retSym = 0;
1670
const struct mach_header *mh1;
1671
if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) )
1673
for (j = 0; j < mh->ncmds; j++)
1675
lc = (struct load_command*)(((unsigned long)mh) + offset);
1676
if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
1678
mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1679
(unsigned long)lc));
1682
/* Maybe NSAddImage can find it */
1683
mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1685
NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +
1686
NSADDIMAGE_OPTION_WITH_SEARCHING +
1687
NSADDIMAGE_OPTION_RETURN_ON_ERROR );
1691
retSym = ltdl_NSLookupSymbolInImage(mh1,
1693
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1694
| NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1699
offset += lc->cmdsize;
1710
if (!_dyld_present()) {
1714
err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage);
1715
err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage);
1716
err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage);
1717
err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic);
1723
sys_dyld_open (lt_user_data loader_data, const char *filename)
1725
lt_module module = 0;
1726
NSObjectFileImage ofi = 0;
1727
NSObjectFileImageReturnCode ofirc;
1730
return (lt_module)-1;
1731
ofirc = NSCreateObjectFileImageFromFile(filename, &ofi);
1734
case NSObjectFileImageSuccess:
1735
module = NSLinkModule(ofi, filename,
1736
NSLINKMODULE_OPTION_RETURN_ON_ERROR
1737
| NSLINKMODULE_OPTION_PRIVATE
1738
| NSLINKMODULE_OPTION_BINDNOW);
1739
NSDestroyObjectFileImage(ofi);
1741
ltdl_NSMakePrivateModulePublic(module);
1743
case NSObjectFileImageInappropriateFile:
1744
if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1746
module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
1750
LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1753
if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1758
sys_dyld_close (lt_user_data loader_data, lt_module module)
1762
if (module == (lt_module)-1) return 0;
1763
#ifdef __BIG_ENDIAN__
1764
if (((struct mach_header *)module)->magic == MH_MAGIC)
1766
if (((struct mach_header *)module)->magic == MH_CIGAM)
1769
LT_DLMUTEX_SETERROR("Can not close a dylib");
1775
/* Currently, if a module contains c++ static destructors and it is unloaded, we
1776
get a segfault in atexit(), due to compiler and dynamic loader differences of
1777
opinion, this works around that.
1779
if ((const struct section *)NULL !=
1780
getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module),
1781
"__DATA","__mod_term_func"))
1783
flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
1787
flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
1789
if (!NSUnLinkModule(module,flags))
1792
LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE)));
1801
lt_user_data loader_data,
1806
NSSymbol *nssym = 0;
1808
const struct mach_header *mh=NULL;
1809
char saveError[256] = "Symbol not found";
1810
if (module == (lt_module)-1)
1812
_dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused);
1815
#ifdef __BIG_ENDIAN__
1816
if (((struct mach_header *)module)->magic == MH_MAGIC)
1818
if (((struct mach_header *)module)->magic == MH_CIGAM)
1821
if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1824
if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol))
1826
nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module,
1828
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1829
| NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1836
nssym = NSLookupSymbolInModule(module, symbol);
1840
strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255);
1842
if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module);
1843
nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh);
1847
LT_DLMUTEX_SETERROR (saveError);
1850
return NSAddressOfSymbol(nssym);
1853
static struct lt_user_dlloader sys_dyld =
1854
{ "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
1857
#endif /* HAVE_DYLD */
1860
/* --- DLPREOPEN() INTERFACE LOADER --- */
1863
/* emulate dynamic linking using preloaded_symbols */
1865
typedef struct lt_dlsymlists_t
1867
struct lt_dlsymlists_t *next;
1868
const lt_dlsymlist *syms;
1871
static const lt_dlsymlist *default_preloaded_symbols = 0;
1872
static lt_dlsymlists_t *preloaded_symbols = 0;
1875
presym_init (lt_user_data loader_data)
1881
preloaded_symbols = 0;
1882
if (default_preloaded_symbols)
1884
errors = lt_dlpreload (default_preloaded_symbols);
1887
LT_DLMUTEX_UNLOCK ();
1893
presym_free_symlists ()
1895
lt_dlsymlists_t *lists;
1899
lists = preloaded_symbols;
1902
lt_dlsymlists_t *tmp = lists;
1904
lists = lists->next;
1907
preloaded_symbols = 0;
1909
LT_DLMUTEX_UNLOCK ();
1915
presym_exit (lt_user_data loader_data)
1917
presym_free_symlists ();
1922
presym_add_symlist (const lt_dlsymlist *preloaded)
1924
lt_dlsymlists_t *tmp;
1925
lt_dlsymlists_t *lists;
1930
lists = preloaded_symbols;
1933
if (lists->syms == preloaded)
1937
lists = lists->next;
1940
tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
1943
memset (tmp, 0, sizeof(lt_dlsymlists_t));
1944
tmp->syms = preloaded;
1945
tmp->next = preloaded_symbols;
1946
preloaded_symbols = tmp;
1954
LT_DLMUTEX_UNLOCK ();
1959
presym_open (lt_user_data loader_data, const char *filename)
1961
lt_dlsymlists_t *lists;
1962
lt_module module = (lt_module) 0;
1965
lists = preloaded_symbols;
1969
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
1973
/* Can't use NULL as the reflective symbol header, as NULL is
1974
used to mark the end of the entire symbol list. Self-dlpreopened
1975
symbols follow this magic number, chosen to be an unlikely
1976
clash with a real module name. */
1979
filename = "@PROGRAM@";
1984
const lt_dlsymlist *syms = lists->syms;
1988
if (!syms->address && strcmp(syms->name, filename) == 0)
1990
module = (lt_module) syms;
1996
lists = lists->next;
1999
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2002
LT_DLMUTEX_UNLOCK ();
2007
presym_close (lt_user_data loader_data, lt_module module)
2009
/* Just to silence gcc -Wall */
2016
lt_user_data loader_data,
2020
lt_dlsymlist *syms = (lt_dlsymlist*) module;
2023
while (syms->address)
2025
if (strcmp(syms->name, symbol) == 0)
2027
return syms->address;
2033
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
2038
static struct lt_user_dlloader presym = {
2039
0, presym_open, presym_close, presym_sym, presym_exit, 0
2046
/* --- DYNAMIC MODULE LOADING --- */
2049
/* The type of a function used at each iteration of foreach_dirinpath(). */
2050
typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
2053
static int foreach_dirinpath LT_PARAMS((const char *search_path,
2054
const char *base_name,
2055
foreach_callback_func *func,
2056
lt_ptr data1, lt_ptr data2));
2058
static int find_file_callback LT_PARAMS((char *filename, lt_ptr data,
2060
static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data,
2062
static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1,
2066
static int canonicalize_path LT_PARAMS((const char *path,
2067
char **pcanonical));
2068
static int argzize_path LT_PARAMS((const char *path,
2070
size_t *pargz_len));
2071
static FILE *find_file LT_PARAMS((const char *search_path,
2072
const char *base_name,
2074
static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
2075
const char *base_name,
2076
lt_dlhandle *handle));
2077
static int find_module LT_PARAMS((lt_dlhandle *handle,
2081
const char *old_name,
2083
static int free_vars LT_PARAMS((char *dlname, char *oldname,
2084
char *libdir, char *deplibs));
2085
static int load_deplibs LT_PARAMS((lt_dlhandle handle,
2087
static int trim LT_PARAMS((char **dest,
2089
static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
2090
const char *filename));
2091
static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
2092
const char *filename));
2093
static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
2094
static int lt_argz_insert LT_PARAMS((char **pargz,
2097
const char *entry));
2098
static int lt_argz_insertinorder LT_PARAMS((char **pargz,
2100
const char *entry));
2101
static int lt_argz_insertdir LT_PARAMS((char **pargz,
2104
struct dirent *dp));
2105
static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
2108
static int list_files_by_dir LT_PARAMS((const char *dirnam,
2110
size_t *pargz_len));
2111
static int file_not_found LT_PARAMS((void));
2113
static char *user_search_path= 0;
2114
static lt_dlloader *loaders = 0;
2115
static lt_dlhandle handles = 0;
2116
static int initialized = 0;
2118
/* Initialize libltdl. */
2126
/* Initialize only at first call. */
2127
if (++initialized == 1)
2130
user_search_path = 0; /* empty search path */
2133
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
2136
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
2139
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
2142
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
2145
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
2148
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld");
2149
errors += sys_dyld_init();
2151
errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
2153
if (presym_init (presym.dlloader_data))
2155
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
2158
else if (errors != 0)
2160
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
2165
LT_DLMUTEX_UNLOCK ();
2171
lt_dlpreload (const lt_dlsymlist *preloaded)
2177
errors = presym_add_symlist (preloaded);
2181
presym_free_symlists();
2184
if (default_preloaded_symbols)
2186
errors = lt_dlpreload (default_preloaded_symbols);
2188
LT_DLMUTEX_UNLOCK ();
2195
lt_dlpreload_default (const lt_dlsymlist *preloaded)
2198
default_preloaded_symbols = preloaded;
2199
LT_DLMUTEX_UNLOCK ();
2206
/* shut down libltdl */
2207
lt_dlloader *loader;
2215
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
2220
/* shut down only at last call. */
2221
if (--initialized == 0)
2225
while (handles && LT_DLIS_RESIDENT (handles))
2227
handles = handles->next;
2230
/* close all modules */
2231
for (level = 1; handles; ++level)
2233
lt_dlhandle cur = handles;
2234
int saw_nonresident = 0;
2238
lt_dlhandle tmp = cur;
2240
if (!LT_DLIS_RESIDENT (tmp))
2241
saw_nonresident = 1;
2242
if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
2244
if (lt_dlclose (tmp))
2250
/* done if only resident modules are left */
2251
if (!saw_nonresident)
2255
/* close all loaders */
2258
lt_dlloader *next = loader->next;
2259
lt_user_data data = loader->dlloader_data;
2260
if (loader->dlloader_exit && loader->dlloader_exit (data))
2265
LT_DLMEM_REASSIGN (loader, next);
2271
LT_DLMUTEX_UNLOCK ();
2276
tryall_dlopen (lt_dlhandle *handle, const char *filename)
2279
lt_dlloader *loader;
2280
const char *saved_error;
2283
LT_DLMUTEX_GETERROR (saved_error);
2289
/* check whether the module was already opened */
2292
/* try to dlopen the program itself? */
2293
if (!cur->info.filename && !filename)
2298
if (cur->info.filename && filename
2299
&& strcmp (cur->info.filename, filename) == 0)
2309
++cur->info.ref_count;
2317
/* Comment out the check of file permissions using access.
2318
This call seems to always return -1 with error EACCES.
2320
/* We need to catch missing file errors early so that
2321
file_not_found() can detect what happened.
2322
if (access (filename, R_OK) != 0)
2324
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2329
cur->info.filename = lt_estrdup (filename);
2330
if (!cur->info.filename)
2338
cur->info.filename = 0;
2343
lt_user_data data = loader->dlloader_data;
2345
cur->module = loader->module_open (data, filename);
2347
if (cur->module != 0)
2351
loader = loader->next;
2356
LT_DLFREE (cur->info.filename);
2361
cur->loader = loader;
2362
LT_DLMUTEX_SETERROR (saved_error);
2365
LT_DLMUTEX_UNLOCK ();
2371
tryall_dlopen_module (
2372
lt_dlhandle *handle,
2374
const char *dirname,
2379
size_t filename_len = 0;
2380
size_t dirname_len = LT_STRLEN (dirname);
2385
#ifdef LT_DIRSEP_CHAR
2386
/* Only canonicalized names (i.e. with DIRSEP chars already converted)
2387
should make it into this function: */
2388
assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
2391
if (dirname_len > 0)
2392
if (dirname[dirname_len -1] == '/')
2394
filename_len = dirname_len + 1 + LT_STRLEN (dlname);
2396
/* Allocate memory, and combine DIRNAME and MODULENAME into it.
2397
The PREFIX (if any) is handled below. */
2398
filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
2402
sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
2404
/* Now that we have combined DIRNAME and MODULENAME, if there is
2405
also a PREFIX to contend with, simply recurse with the arguments
2406
shuffled. Otherwise, attempt to open FILENAME as a module. */
2409
error += tryall_dlopen_module (handle,
2410
(const char *) 0, prefix, filename);
2412
else if (tryall_dlopen (handle, filename) != 0)
2417
LT_DLFREE (filename);
2423
lt_dlhandle *handle,
2427
const char *old_name,
2430
/* Try to open the old library first; if it was dlpreopened,
2431
we want the preopened version of it, even if a dlopenable
2432
module is available. */
2433
if (old_name && tryall_dlopen (handle, old_name) == 0)
2438
/* Try to open the dynamic library. */
2441
/* try to open the installed module */
2442
if (installed && libdir)
2444
if (tryall_dlopen_module (handle,
2445
(const char *) 0, libdir, dlname) == 0)
2449
/* try to open the not-installed module */
2452
if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2456
/* maybe it was moved to another directory */
2458
if (tryall_dlopen_module (handle,
2459
(const char *) 0, dir, dlname) == 0)
2473
char *canonical = 0;
2475
assert (path && *path);
2476
assert (pcanonical);
2478
canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2485
for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2487
/* Path separators are not copied to the beginning or end of
2488
the destination, or if another separator would follow
2490
if (path[src] == LT_PATHSEP_CHAR)
2493
|| (path[1+ src] == LT_PATHSEP_CHAR)
2494
|| (path[1+ src] == LT_EOS_CHAR))
2498
/* Anything other than a directory separator is copied verbatim. */
2499
if ((path[src] != '/')
2500
#ifdef LT_DIRSEP_CHAR
2501
&& (path[src] != LT_DIRSEP_CHAR)
2505
canonical[dest++] = path[src];
2507
/* Directory separators are converted and copied only if they are
2508
not at the end of a path -- i.e. before a path separator or
2510
else if ((path[1+ src] != LT_PATHSEP_CHAR)
2511
&& (path[1+ src] != LT_EOS_CHAR)
2512
#ifdef LT_DIRSEP_CHAR
2513
&& (path[1+ src] != LT_DIRSEP_CHAR)
2515
&& (path[1+ src] != '/'))
2517
canonical[dest++] = '/';
2521
/* Add an end-of-string marker at the end. */
2522
canonical[dest] = LT_EOS_CHAR;
2525
/* Assign new value. */
2526
*pcanonical = canonical;
2543
if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2548
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2551
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2561
/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2562
of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2563
non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2564
it is appended to each SEARCH_PATH element before FUNC is called. */
2567
const char *search_path,
2568
const char *base_name,
2569
foreach_callback_func *func,
2574
int filenamesize = 0;
2575
size_t lenbase = LT_STRLEN (base_name);
2576
size_t argz_len = 0;
2579
char *canonical = 0;
2583
if (!search_path || !*search_path)
2585
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2589
if (canonicalize_path (search_path, &canonical) != 0)
2592
if (argzize_path (canonical, &argz, &argz_len) != 0)
2597
while ((dir_name = argz_next (argz, argz_len, dir_name)))
2599
size_t lendir = LT_STRLEN (dir_name);
2601
if (lendir +1 +lenbase >= filenamesize)
2603
LT_DLFREE (filename);
2604
filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2605
filename = LT_EMALLOC (char, filenamesize);
2610
assert (filenamesize > lendir);
2611
strcpy (filename, dir_name);
2613
if (base_name && *base_name)
2615
if (filename[lendir -1] != '/')
2616
filename[lendir++] = '/';
2617
strcpy (filename +lendir, base_name);
2620
if ((result = (*func) (filename, data1, data2)))
2629
LT_DLFREE (canonical);
2630
LT_DLFREE (filename);
2632
LT_DLMUTEX_UNLOCK ();
2637
/* If FILEPATH can be opened, store the name of the directory component
2638
in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2639
DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2641
find_file_callback (
2646
char **pdir = (char **) data1;
2647
FILE **pfile = (FILE **) data2;
2650
assert (filename && *filename);
2654
if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
2656
char *dirend = strrchr (filename, '/');
2658
if (dirend > filename)
2659
*dirend = LT_EOS_CHAR;
2662
*pdir = lt_estrdup (filename);
2663
is_done = (*pdir == 0) ? -1 : 1;
2671
const char *search_path,
2672
const char *base_name,
2677
foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
2683
find_handle_callback (
2688
lt_dlhandle *handle = (lt_dlhandle *) data;
2689
int notfound = access (filename, R_OK);
2691
/* Bail out if file cannot be read... */
2695
/* Try to dlopen the file, but do not continue searching in any
2697
if (tryall_dlopen (handle, filename) != 0)
2703
/* If HANDLE was found return it, otherwise return 0. If HANDLE was
2704
found but could not be opened, *HANDLE will be set to 0. */
2705
static lt_dlhandle *
2707
const char *search_path,
2708
const char *base_name,
2709
lt_dlhandle *handle)
2714
if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2726
#if LTDL_DLOPEN_DEPLIBS
2727
char *p, *save_search_path = 0;
2734
handle->depcount = 0;
2736
#if LTDL_DLOPEN_DEPLIBS
2744
if (user_search_path)
2746
save_search_path = lt_estrdup (user_search_path);
2747
if (!save_search_path)
2751
/* extract search paths and count deplibs */
2755
if (!isspace ((int) *p))
2758
while (*end && !isspace((int) *end))
2763
if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2766
*end = 0; /* set a temporary string terminator */
2767
if (lt_dladdsearchdir(p+2))
2786
/* restore the old search path */
2787
LT_DLFREE (user_search_path);
2788
user_search_path = save_search_path;
2790
LT_DLMUTEX_UNLOCK ();
2798
names = LT_EMALLOC (char *, depcount * sizeof (char*));
2802
/* now only extract the actual deplibs */
2807
if (isspace ((int) *p))
2814
while (*end && !isspace ((int) *end))
2819
if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2823
*end = 0; /* set a temporary string terminator */
2824
if (strncmp(p, "-l", 2) == 0)
2826
size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2827
name = LT_EMALLOC (char, 1+ name_len);
2829
sprintf (name, "lib%s", p+2);
2832
name = lt_estrdup(p);
2837
names[depcount++] = name;
2844
/* load the deplibs (in reverse order)
2845
At this stage, don't worry if the deplibs do not load correctly,
2846
they may already be statically linked into the loading application
2847
for instance. There will be a more enlightening error message
2848
later on if the loaded module cannot resolve all of its symbols. */
2853
handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2854
if (!handle->deplibs)
2857
for (i = 0; i < depcount; ++i)
2859
handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
2860
if (handle->deplibs[j])
2866
handle->depcount = j; /* Number of successfully loaded deplibs */
2871
for (i = 0; i < depcount; ++i)
2873
LT_DLFREE (names[i]);
2890
if (handle->depcount)
2892
for (i = 0; i < handle->depcount; ++i)
2894
if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
2896
errors += lt_dlclose (handle->deplibs[i]);
2909
/* remove the leading and trailing "'" from str
2910
and store the result in dest */
2911
const char *end = strrchr (str, '\'');
2912
size_t len = LT_STRLEN (str);
2917
if (len > 3 && str[0] == '\'')
2919
tmp = LT_EMALLOC (char, end - str);
2923
strncpy(tmp, &str[1], (end - str) - 1);
2924
tmp[len-3] = LT_EOS_CHAR;
2943
LT_DLFREE (oldname);
2945
LT_DLFREE (deplibs);
2952
lt_dlhandle *phandle,
2953
const char *filename)
2955
const char * ext = 0;
2956
const char * saved_error = 0;
2957
char * canonical = 0;
2958
char * base_name = 0;
2962
lt_dlhandle newhandle;
2965
assert (*phandle == 0);
2967
LT_DLMUTEX_GETERROR (saved_error);
2972
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
2976
memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
2977
newhandle = *phandle;
2979
/* lt_dlclose()ing yourself is very bad! Disallow it. */
2980
LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
2982
if (tryall_dlopen (&newhandle, 0) != 0)
2984
LT_DLFREE (*phandle);
2988
goto register_handle;
2991
assert (filename && *filename);
2993
/* Doing this immediately allows internal functions to safely
2994
assume only canonicalized paths are passed. */
2995
if (canonicalize_path (filename, &canonical) != 0)
3001
/* If the canonical module name is a path (relative or absolute)
3002
then split it into a directory part and a name part. */
3003
base_name = strrchr (canonical, '/');
3006
size_t dirlen = (1+ base_name) - canonical;
3008
dir = LT_EMALLOC (char, 1+ dirlen);
3015
strncpy (dir, canonical, dirlen);
3016
dir[dirlen] = LT_EOS_CHAR;
3021
LT_DLMEM_REASSIGN (base_name, canonical);
3023
assert (base_name && *base_name);
3025
/* Check whether we are opening a libtool module (.la extension). */
3026
ext = strrchr (base_name, '.');
3027
if (ext && strcmp (ext, archive_ext) == 0)
3029
/* this seems to be a libtool module */
3032
char * old_name = 0;
3038
/* if we can't find the installed flag, it is probably an
3039
installed libtool archive, produced with an old version
3043
/* extract the module name from the file name */
3044
name = LT_EMALLOC (char, ext - base_name + 1);
3051
/* canonicalize the module name */
3054
for (i = 0; i < ext - base_name; ++i)
3056
if (isalnum ((int)(base_name[i])))
3058
name[i] = base_name[i];
3065
name[ext - base_name] = LT_EOS_CHAR;
3068
/* Now try to open the .la file. If there is no directory name
3069
component, try to find it first in user_search_path and then other
3070
prescribed paths. Otherwise (or in any case if the module was not
3071
yet found) try opening just the module name as passed. */
3074
const char *search_path;
3077
search_path = user_search_path;
3079
file = find_file (user_search_path, base_name, &dir);
3080
LT_DLMUTEX_UNLOCK ();
3084
search_path = getenv (LTDL_SEARCHPATH_VAR);
3086
file = find_file (search_path, base_name, &dir);
3089
#ifdef LTDL_SHLIBPATH_VAR
3092
search_path = getenv (LTDL_SHLIBPATH_VAR);
3094
file = find_file (search_path, base_name, &dir);
3097
#ifdef LTDL_SYSSEARCHPATH
3098
if (!file && sys_search_path)
3100
file = find_file (sys_search_path, base_name, &dir);
3106
file = fopen (filename, LT_READTEXT_MODE);
3109
/* If we didn't find the file by now, it really isn't there. Set
3110
the status flag, and bail out. */
3113
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3118
line_len = LT_FILENAME_MAX;
3119
line = LT_EMALLOC (char, line_len);
3127
/* read the .la file */
3128
while (!feof (file))
3130
if (!fgets (line, (int) line_len, file))
3135
/* Handle the case where we occasionally need to read a line
3136
that is longer than the initial buffer size. */
3137
while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file)))
3139
line = LT_DLREALLOC (char, line, line_len *2);
3140
if (!fgets (&line[line_len -1], (int) line_len +1, file))
3147
if (line[0] == '\n' || line[0] == '#')
3153
#define STR_DLNAME "dlname="
3154
if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3156
errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
3159
#undef STR_OLD_LIBRARY
3160
#define STR_OLD_LIBRARY "old_library="
3161
else if (strncmp (line, STR_OLD_LIBRARY,
3162
sizeof (STR_OLD_LIBRARY) - 1) == 0)
3164
errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3167
#define STR_LIBDIR "libdir="
3168
else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3170
errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
3173
#undef STR_DL_DEPLIBS
3174
#define STR_DL_DEPLIBS "dependency_libs="
3175
else if (strncmp (line, STR_DL_DEPLIBS,
3176
sizeof (STR_DL_DEPLIBS) - 1) == 0)
3178
errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3180
else if (strcmp (line, "installed=yes\n") == 0)
3184
else if (strcmp (line, "installed=no\n") == 0)
3189
#undef STR_LIBRARY_NAMES
3190
#define STR_LIBRARY_NAMES "library_names="
3191
else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
3192
sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3195
errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3198
&& (last_libname = strrchr (dlname, ' ')) != 0)
3200
last_libname = lt_estrdup (last_libname + 1);
3206
LT_DLMEM_REASSIGN (dlname, last_libname);
3217
/* allocate the handle */
3218
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3224
free_vars (dlname, old_name, libdir, deplibs);
3225
LT_DLFREE (*phandle);
3231
memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3232
if (load_deplibs (*phandle, deplibs) == 0)
3234
newhandle = *phandle;
3235
/* find_module may replace newhandle */
3236
if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
3238
unload_deplibs (*phandle);
3247
free_vars (dlname, old_name, libdir, deplibs);
3250
LT_DLFREE (*phandle);
3254
if (*phandle != newhandle)
3256
unload_deplibs (*phandle);
3261
/* not a libtool module */
3262
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3269
memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3270
newhandle = *phandle;
3272
/* If the module has no directory name component, try to find it
3273
first in user_search_path and then other prescribed paths.
3274
Otherwise (or in any case if the module was not yet found) try
3275
opening just the module name as passed. */
3276
if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
3277
&& !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3279
#ifdef LTDL_SHLIBPATH_VAR
3280
&& !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
3283
#ifdef LTDL_SYSSEARCHPATH
3284
&& !find_handle (sys_search_path, base_name, &newhandle)
3288
if (tryall_dlopen (&newhandle, filename) != 0)
3296
LT_DLFREE (*phandle);
3303
LT_DLMEM_REASSIGN (*phandle, newhandle);
3305
if ((*phandle)->info.ref_count == 0)
3307
(*phandle)->info.ref_count = 1;
3308
LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
3311
(*phandle)->next = handles;
3313
LT_DLMUTEX_UNLOCK ();
3316
LT_DLMUTEX_SETERROR (saved_error);
3321
LT_DLFREE (canonical);
3328
const char *filename)
3330
lt_dlhandle handle = 0;
3332
/* Just incase we missed a code path in try_dlopen() that reports
3333
an error, but forgets to reset handle... */
3334
if (try_dlopen (&handle, filename) != 0)
3340
/* If the last error messge store was `FILE_NOT_FOUND', then return
3345
const char *error = 0;
3347
LT_DLMUTEX_GETERROR (error);
3348
if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
3354
/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3355
open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3356
and if a file is still not found try again with SHLIB_EXT appended
3360
const char *filename)
3362
lt_dlhandle handle = 0;
3370
return lt_dlopen (filename);
3375
len = LT_STRLEN (filename);
3376
ext = strrchr (filename, '.');
3378
/* If FILENAME already bears a suitable extension, there is no need
3379
to try appending additional extensions. */
3380
if (ext && ((strcmp (ext, archive_ext) == 0)
3381
#ifdef LTDL_SHLIB_EXT
3382
|| (strcmp (ext, shlib_ext) == 0)
3386
return lt_dlopen (filename);
3389
/* First try appending ARCHIVE_EXT. */
3390
tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
3394
strcpy (tmp, filename);
3395
strcat (tmp, archive_ext);
3396
errors = try_dlopen (&handle, tmp);
3398
/* If we found FILENAME, stop searching -- whether we were able to
3399
load the file as a module or not. If the file exists but loading
3400
failed, it is better to return an error message here than to
3401
report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3402
in the module search path. */
3403
if (handle || ((errors > 0) && !file_not_found ()))
3409
#ifdef LTDL_SHLIB_EXT
3410
/* Try appending SHLIB_EXT. */
3411
if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
3414
tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
3418
strcpy (tmp, filename);
3422
tmp[len] = LT_EOS_CHAR;
3425
strcat(tmp, shlib_ext);
3426
errors = try_dlopen (&handle, tmp);
3428
/* As before, if the file was found but loading failed, return now
3429
with the current error message. */
3430
if (handle || ((errors > 0) && !file_not_found ()))
3437
/* Still here? Then we really did fail to locate any of the file
3439
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3454
if ((error = argz_insert (pargz, pargz_len, before, entry)))
3459
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3462
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3472
lt_argz_insertinorder (
3481
assert (entry && *entry);
3484
while ((before = argz_next (*pargz, *pargz_len, before)))
3486
int cmp = strcmp (entry, before);
3489
if (cmp == 0) return 0; /* No duplicates! */
3492
return lt_argz_insert (pargz, pargz_len, before, entry);
3505
size_t end_offset = 0;
3513
dir_len = LT_STRLEN (dirnam);
3514
end = dp->d_name + LT_D_NAMLEN(dp);
3516
/* Ignore version numbers. */
3519
for (p = end; p -1 > dp->d_name; --p)
3520
if (strchr (".0123456789", p[-1]) == 0)
3527
/* Ignore filename extension. */
3530
for (p = end -1; p > dp->d_name; --p)
3538
/* Prepend the directory name. */
3539
end_offset = end - dp->d_name;
3540
buf_len = dir_len + 1+ end_offset;
3541
buf = LT_EMALLOC (char, 1+ buf_len);
3547
strcpy (buf, dirnam);
3549
strncat (buf, dp->d_name, end_offset);
3550
buf[buf_len] = LT_EOS_CHAR;
3552
/* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3553
if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3570
assert (dirnam && *dirnam);
3573
assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
3575
dirp = opendir (dirnam);
3578
struct dirent *dp = 0;
3580
while ((dp = readdir (dirp)))
3581
if (dp->d_name[0] != '.')
3582
if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3597
/* If there are any files in DIRNAME, call the function passed in
3598
DATA1 (with the name of each file and DATA2 as arguments). */
3600
foreachfile_callback (
3605
int (*func) LT_PARAMS((const char *filename, lt_ptr data))
3606
= (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
3610
size_t argz_len = 0;
3612
if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3619
while ((filename = argz_next (argz, argz_len, filename)))
3620
if ((is_done = (*func) (filename, data2)))
3631
/* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3632
with DATA. The filenames passed to FUNC would be suitable for
3633
passing to lt_dlopenext. The extensions are stripped so that
3634
individual modules do not generate several entries (e.g. libfoo.la,
3635
libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3636
then the same directories that lt_dlopen would search are examined. */
3639
const char *search_path,
3640
int (*func) LT_PARAMS ((const char *filename, lt_ptr data)),
3647
/* If a specific path was passed, search only the directories
3649
is_done = foreach_dirinpath (search_path, 0,
3650
foreachfile_callback, (void*)func, data);
3654
/* Otherwise search the default paths. */
3655
is_done = foreach_dirinpath (user_search_path, 0,
3656
foreachfile_callback, (void*)func, data);
3659
is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3660
foreachfile_callback, (void*)func, data);
3663
#ifdef LTDL_SHLIBPATH_VAR
3666
is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
3667
foreachfile_callback, (void*)func, data);
3670
#ifdef LTDL_SYSSEARCHPATH
3673
is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
3674
foreachfile_callback, (void*)func, data);
3686
lt_dlhandle cur, last;
3691
/* check whether the handle is valid */
3692
last = cur = handles;
3693
while (cur && handle != cur)
3701
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3706
handle->info.ref_count--;
3708
/* Note that even with resident modules, we must track the ref_count
3709
correctly incase the user decides to reset the residency flag
3710
later (even though the API makes no provision for that at the
3712
if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
3714
lt_user_data data = handle->loader->dlloader_data;
3716
if (handle != handles)
3718
last->next = handle->next;
3722
handles = handle->next;
3725
errors += handle->loader->module_close (data, handle->module);
3726
errors += unload_deplibs(handle);
3728
/* It is up to the callers to free the data itself. */
3729
LT_DLFREE (handle->caller_data);
3731
LT_DLFREE (handle->info.filename);
3732
LT_DLFREE (handle->info.name);
3738
if (LT_DLIS_RESIDENT (handle))
3740
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3745
LT_DLMUTEX_UNLOCK ();
3756
char lsym[LT_SYMBOL_LENGTH];
3763
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3769
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3773
lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3774
+ LT_STRLEN (handle->info.name);
3776
if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3782
sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3785
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3790
data = handle->loader->dlloader_data;
3791
if (handle->info.name)
3793
const char *saved_error;
3795
LT_DLMUTEX_GETERROR (saved_error);
3797
/* this is a libtool module */
3798
if (handle->loader->sym_prefix)
3800
strcpy(sym, handle->loader->sym_prefix);
3801
strcat(sym, handle->info.name);
3805
strcpy(sym, handle->info.name);
3808
strcat(sym, "_LTX_");
3809
strcat(sym, symbol);
3811
/* try "modulename_LTX_symbol" */
3812
address = handle->loader->find_sym (data, handle->module, sym);
3821
LT_DLMUTEX_SETERROR (saved_error);
3824
/* otherwise try "symbol" */
3825
if (handle->loader->sym_prefix)
3827
strcpy(sym, handle->loader->sym_prefix);
3828
strcat(sym, symbol);
3832
strcpy(sym, symbol);
3835
address = handle->loader->find_sym (data, handle->module, sym);
3849
LT_DLMUTEX_GETERROR (error);
3850
LT_DLMUTEX_SETERROR (0);
3852
return error ? error : NULL;
3856
lt_dlpath_insertdir (
3862
char *canonical = 0;
3864
size_t argz_len = 0;
3867
assert (dir && *dir);
3869
if (canonicalize_path (dir, &canonical) != 0)
3875
assert (canonical && *canonical);
3877
/* If *PPATH is empty, set it to DIR. */
3880
assert (!before); /* BEFORE cannot be set without PPATH. */
3881
assert (dir); /* Without DIR, don't call this function! */
3883
*ppath = lt_estrdup (dir);
3890
assert (ppath && *ppath);
3892
if (argzize_path (*ppath, &argz, &argz_len) != 0)
3898
/* Convert BEFORE into an equivalent offset into ARGZ. This only works
3899
if *PPATH is already canonicalized, and hence does not change length
3900
with respect to ARGZ. We canonicalize each entry as it is added to
3901
the search path, and don't call this function with (uncanonicalized)
3902
user paths, so this is a fair assumption. */
3905
assert (*ppath <= before);
3906
assert (before - *ppath <= strlen (*ppath));
3908
before = before - *ppath + argz;
3911
if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
3917
argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
3918
LT_DLMEM_REASSIGN (*ppath, argz);
3921
LT_DLFREE (canonical);
3929
const char *search_dir)
3933
if (search_dir && *search_dir)
3936
if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
3938
LT_DLMUTEX_UNLOCK ();
3945
lt_dlinsertsearchdir (
3947
const char *search_dir)
3954
if ((before < user_search_path)
3955
|| (before >= user_search_path + LT_STRLEN (user_search_path)))
3957
LT_DLMUTEX_UNLOCK ();
3958
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
3961
LT_DLMUTEX_UNLOCK ();
3964
if (search_dir && *search_dir)
3967
if (lt_dlpath_insertdir (&user_search_path,
3968
(char *) before, search_dir) != 0)
3972
LT_DLMUTEX_UNLOCK ();
3979
lt_dlsetsearchpath (
3980
const char *search_path)
3985
LT_DLFREE (user_search_path);
3986
LT_DLMUTEX_UNLOCK ();
3988
if (!search_path || !LT_STRLEN (search_path))
3994
if (canonicalize_path (search_path, &user_search_path) != 0)
3996
LT_DLMUTEX_UNLOCK ();
4002
lt_dlgetsearchpath ()
4004
const char *saved_path;
4007
saved_path = user_search_path;
4008
LT_DLMUTEX_UNLOCK ();
4021
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4026
LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4038
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4042
return LT_DLIS_RESIDENT (handle);
4048
/* --- MODULE INFORMATION --- */
4056
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4060
return &(handle->info);
4067
return place ? place->next : handles;
4072
int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data)),
4083
lt_dlhandle tmp = cur;
4086
if ((*func) (tmp, data))
4093
LT_DLMUTEX_UNLOCK ();
4099
lt_dlcaller_register ()
4101
static lt_dlcaller_id last_caller_id = 0;
4105
result = ++last_caller_id;
4106
LT_DLMUTEX_UNLOCK ();
4112
lt_dlcaller_set_data (
4118
lt_ptr stale = (lt_ptr) 0;
4121
/* This needs to be locked so that the caller data can be updated
4122
simultaneously by different threads. */
4125
if (handle->caller_data)
4126
while (handle->caller_data[n_elements].key)
4129
for (i = 0; i < n_elements; ++i)
4131
if (handle->caller_data[i].key == key)
4133
stale = handle->caller_data[i].data;
4138
/* Ensure that there is enough room in this handle's caller_data
4139
array to accept a new element (and an empty end marker). */
4140
if (i == n_elements)
4142
lt_caller_data *temp
4143
= LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
4151
handle->caller_data = temp;
4153
/* We only need this if we needed to allocate a new caller_data. */
4154
handle->caller_data[i].key = key;
4155
handle->caller_data[1+ i].key = 0;
4158
handle->caller_data[i].data = data;
4161
LT_DLMUTEX_UNLOCK ();
4167
lt_dlcaller_get_data (
4171
lt_ptr result = (lt_ptr) 0;
4173
/* This needs to be locked so that the caller data isn't updated by
4174
another thread part way through this function. */
4177
/* Locate the index of the element with a matching KEY. */
4180
for (i = 0; handle->caller_data[i].key; ++i)
4182
if (handle->caller_data[i].key == key)
4184
result = handle->caller_data[i].data;
4190
LT_DLMUTEX_UNLOCK ();
4197
/* --- USER MODULE LOADER API --- */
4203
const struct lt_user_dlloader *dlloader,
4204
const char *loader_name)
4207
lt_dlloader *node = 0, *ptr = 0;
4209
if ((dlloader == 0) /* diagnose null parameters */
4210
|| (dlloader->module_open == 0)
4211
|| (dlloader->module_close == 0)
4212
|| (dlloader->find_sym == 0))
4214
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4218
/* Create a new dlloader node with copies of the user callbacks. */
4219
node = LT_EMALLOC (lt_dlloader, 1);
4224
node->loader_name = loader_name;
4225
node->sym_prefix = dlloader->sym_prefix;
4226
node->dlloader_exit = dlloader->dlloader_exit;
4227
node->module_open = dlloader->module_open;
4228
node->module_close = dlloader->module_close;
4229
node->find_sym = dlloader->find_sym;
4230
node->dlloader_data = dlloader->dlloader_data;
4235
/* If there are no loaders, NODE becomes the list! */
4240
/* If PLACE is not set, add NODE to the end of the
4242
for (ptr = loaders; ptr->next; ptr = ptr->next)
4249
else if (loaders == place)
4251
/* If PLACE is the first loader, NODE goes first. */
4257
/* Find the node immediately preceding PLACE. */
4258
for (ptr = loaders; ptr->next != place; ptr = ptr->next)
4263
if (ptr->next != place)
4265
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4270
/* Insert NODE between PTR and PLACE. */
4276
LT_DLMUTEX_UNLOCK ();
4282
lt_dlloader_remove (
4283
const char *loader_name)
4285
lt_dlloader *place = lt_dlloader_find (loader_name);
4291
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4297
/* Fail if there are any open modules which use this loader. */
4298
for (handle = handles; handle; handle = handle->next)
4300
if (handle->loader == place)
4302
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
4308
if (place == loaders)
4310
/* PLACE is the first loader in the list. */
4311
loaders = loaders->next;
4315
/* Find the loader before the one being removed. */
4317
for (prev = loaders; prev->next; prev = prev->next)
4319
if (!strcmp (prev->next->loader_name, loader_name))
4326
prev->next = prev->next->next;
4329
if (place->dlloader_exit)
4331
errors = place->dlloader_exit (place->dlloader_data);
4337
LT_DLMUTEX_UNLOCK ();
4349
next = place ? place->next : loaders;
4350
LT_DLMUTEX_UNLOCK ();
4359
const char *name = 0;
4364
name = place ? place->loader_name : 0;
4365
LT_DLMUTEX_UNLOCK ();
4369
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4379
lt_user_data *data = 0;
4384
data = place ? &(place->dlloader_data) : 0;
4385
LT_DLMUTEX_UNLOCK ();
4389
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4397
const char *loader_name)
4399
lt_dlloader *place = 0;
4402
for (place = loaders; place; place = place->next)
4404
if (strcmp (place->loader_name, loader_name) == 0)
4409
LT_DLMUTEX_UNLOCK ();