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., 51 Franklin Street, Fifth Floor, Boston, MA
68
/* Bah. We don't want inline. Needs autoconf check, which we don't want. */
76
/* --- WINDOWS SUPPORT --- */
80
# define LT_GLOBAL_DATA __declspec(dllexport)
82
# define LT_GLOBAL_DATA
85
/* fopen() mode flags for reading a text file */
86
#undef LT_READTEXT_MODE
88
# define LT_READTEXT_MODE "rt"
90
# define LT_READTEXT_MODE "r"
93
#if defined(_WIN32) && !defined(__CYGWIN__)
94
# include "ltdl_win.h"
99
/* --- MANIFEST CONSTANTS --- */
102
/* max. filename length */
103
#ifndef LT_FILENAME_MAX
104
# define LT_FILENAME_MAX 1024
107
/* This is the maximum symbol size that won't require malloc/free */
108
#undef LT_SYMBOL_LENGTH
109
#define LT_SYMBOL_LENGTH 128
111
/* This accounts for the _LTX_ separator */
112
#undef LT_SYMBOL_OVERHEAD
113
#define LT_SYMBOL_OVERHEAD 5
118
/* --- TYPE DEFINITIONS -- */
121
/* This type is used for the array of caller data sets in each handler. */
130
/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
133
/* Extract the diagnostic strings from the error table macro in the same
134
order as the enumberated indices in ltdl.h. */
136
static const char *lt_dlerror_strings[] =
138
#define LT_ERROR(name, diagnostic) (diagnostic),
145
/* This structure is used for the list of registered loaders. */
147
struct lt_dlloader *next;
148
const char *loader_name; /* identifying name for each loader */
149
const char *sym_prefix; /* prefix for symbols */
150
lt_module_open *module_open;
151
lt_module_close *module_close;
152
lt_find_sym *find_sym;
153
lt_dlloader_exit *dlloader_exit;
154
lt_user_data dlloader_data;
157
struct lt_dlhandle_struct {
158
struct lt_dlhandle_struct *next;
159
lt_dlloader *loader; /* dlopening interface */
161
int depcount; /* number of dependencies */
162
lt_dlhandle *deplibs; /* dependencies */
163
lt_module module; /* system module handle */
164
lt_ptr system; /* system specific data */
165
lt_caller_data *caller_data; /* per caller associated data */
166
int flags; /* various boolean stats */
169
/* Various boolean flags can be stored in the flags field of an
170
lt_dlhandle_struct... */
171
#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
172
#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
174
#define LT_DLRESIDENT_FLAG (0x01 << 0)
176
#define LT_DLNOTFOUND_FLAG (0x01 << 1) /* may be linked statically */
177
#define LT_DLMEMBER_FLAG RTLD_MEMBER
179
/* ...add more flags here... */
181
#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
184
#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
186
static const char objdir[] = LTDL_OBJDIR;
187
#ifdef LTDL_SHLIB_EXT
188
static const char shlib_ext[] = LTDL_SHLIB_EXT;
190
#ifdef LTDL_SYSSEARCHPATH
191
static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
197
/* --- MUTEX LOCKING --- */
200
/* Macros to make it easier to run the lock functions only if they have
201
been registered. The reason for the complicated lock macro is to
202
ensure that the stored error message from the last error is not
203
accidentally erased if the current function doesn't generate an
205
#define MUTEX_LOCK() LT_STMT_START { \
206
if (mutex_lock) (*mutex_lock)(); } LT_STMT_END
207
#define MUTEX_UNLOCK() LT_STMT_START { \
208
if (mutex_unlock) (*mutex_unlock)(); } LT_STMT_END
209
#define MUTEX_SETERROR(errormsg) LT_STMT_START { \
210
if (mutex_seterror) (*mutex_seterror) (errormsg); \
211
else last_error = (errormsg); } LT_STMT_END
212
#define MUTEX_GETERROR(errormsg) LT_STMT_START { \
213
if (mutex_seterror) errormsg = (*mutex_geterror)(); \
214
else (errormsg) = last_error; } LT_STMT_END
216
/* The mutex functions stored here are global, and are necessarily the
217
same for all threads that wish to share access to libltdl. */
218
static lt_dlmutex_lock *mutex_lock = 0;
219
static lt_dlmutex_unlock *mutex_unlock = 0;
220
static lt_dlmutex_seterror *mutex_seterror = 0;
221
static lt_dlmutex_geterror *mutex_geterror = 0;
222
static const char *last_error = 0;
225
/* Either set or reset the mutex functions. Either all the arguments must
226
be valid functions, or else all can be NULL to turn off locking entirely.
227
The registered functions should be manipulating a static global lock
228
from the lock() and unlock() callbacks, which needs to be reentrant. */
230
lt_dlmutex_register (lock, unlock, seterror, geterror)
231
lt_dlmutex_lock *lock;
232
lt_dlmutex_unlock *unlock;
233
lt_dlmutex_seterror *seterror;
234
lt_dlmutex_geterror *geterror;
236
lt_dlmutex_unlock *old_unlock = unlock;
239
/* Lock using the old lock() callback, if any. */
242
if ((lock && unlock && seterror && geterror)
243
|| !(lock || unlock || seterror || geterror))
246
mutex_unlock = unlock;
247
mutex_geterror = geterror;
251
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
255
/* Use the old unlock() callback we saved earlier, if any. Otherwise
256
record any errors using internal storage. */
260
/* Return the number of errors encountered during the execution of
268
/* --- MEMORY HANDLING --- */
271
LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
272
= (lt_ptr (*) LT_PARAMS((size_t))) malloc;
273
LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
274
= (void (*) LT_PARAMS((lt_ptr))) free;
276
static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr,
279
#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
280
#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
281
#define LT_DLFREE(p) \
282
LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
284
#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
285
if ((p) != (q)) { lt_dlfree (p); (p) = (q); } \
290
/* --- ERROR MESSAGES --- */
293
static const char **user_error_strings = 0;
294
static int errorcount = LT_ERROR_MAX;
297
lt_dladderror (diagnostic)
298
const char *diagnostic;
302
const char **temp = (const char **) 0;
306
_index = errorcount - LT_ERROR_MAX;
307
temp = LT_DLREALLOC (const char *, user_error_strings, 1 + _index);
310
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
314
user_error_strings = temp;
315
user_error_strings[_index] = diagnostic;
316
result = errorcount++;
325
lt_dlseterror (_index)
332
if (_index >= errorcount || _index < 0)
334
/* Ack! Error setting the error message! */
335
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
338
else if (_index < LT_ERROR_MAX)
340
/* No error setting the error message! */
341
MUTEX_SETERROR (lt_dlerror_strings[errorcount]);
345
/* No error setting the error message! */
346
MUTEX_SETERROR (user_error_strings[errorcount - LT_ERROR_MAX]);
357
/* --- REPLACEMENT FUNCTIONS --- */
361
#define strdup rpl_strdup
371
tmp = LT_DLMALLOC (char, 1+ strlen (str));
385
#define strcmp rpl_strcmp
399
for (;*str1 && *str2; ++str1, ++str2)
405
return (int)(*str1 - *str2);
413
# define strchr index
415
# define strchr rpl_strchr
417
static inline const char*
424
for (p = str; *p != (char)ch && *p != '\0'; ++p)
427
return (*p == (char)ch) ? p : 0;
431
#endif /* !HAVE_STRCHR */
436
# define strrchr rindex
438
# define strrchr rpl_strrchr
440
static inline const char*
445
const char *p, *q = 0;
447
for (p = str; *p != '\0'; ++p)
461
/* NOTE: Neither bcopy nor the memcpy implementation below can
462
reliably handle copying in overlapping areas of memory, so
463
do not rely on this behavior when invoking memcpy later. */
467
# define memcpy(dest, src, size) bcopy (src, dest, size)
469
# define memcpy rpl_memcpy
472
memcpy (dest, src, size)
479
for (i = 0; i < size; ++i)
490
/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
491
``realloc is not entirely portable''
492
In any case we want to use the allocator supplied by the user without
493
burdening them with an lt_dlrealloc function pointer to maintain.
494
Instead implement our own version (with known boundary conditions)
495
using lt_dlmalloc and lt_dlfree. */
497
rpl_realloc (ptr, size)
503
/* For zero or less bytes, free the original memory */
513
/* Allow reallocation of a NULL pointer. */
514
return lt_dlmalloc (size);
518
/* Allocate a new block, copy and free the old block. */
519
lt_ptr mem = (lt_ptr) realloc (ptr, size);
521
/* Note that the contents of PTR are not damaged if there is
522
insufficient memory to realloc. */
530
/* --- DLOPEN() INTERFACE LOADER --- */
532
/* The Cygwin dlopen implementation prints a spurious error message to
533
stderr if its call to LoadLibrary() fails for any reason. We can
534
mitigate this by not using the Cygwin implementation, and falling
535
back to our own LoadLibrary() wrapper. */
536
#if HAVE_LIBDL && !defined(__CYGWIN__)
538
/* dynamic linking with dlopen/dlsym */
545
# define LT_GLOBAL RTLD_GLOBAL
548
# define LT_GLOBAL DL_GLOBAL
550
#endif /* !RTLD_GLOBAL */
553
#endif /* !LT_GLOBAL */
555
/* We may have to define LT_LAZY_OR_NOW in the command line if we
556
find out it does not work in some platform. */
557
#ifndef LT_LAZY_OR_NOW
559
# define LT_LAZY_OR_NOW RTLD_LAZY
562
# define LT_LAZY_OR_NOW DL_LAZY
564
# endif /* !RTLD_LAZY */
566
#ifndef LT_LAZY_OR_NOW
568
# define LT_LAZY_OR_NOW RTLD_NOW
571
# define LT_LAZY_OR_NOW DL_NOW
573
# endif /* !RTLD_NOW */
575
#ifndef LT_LAZY_OR_NOW
576
# define LT_LAZY_OR_NOW 0
577
#endif /* !LT_LAZY_OR_NOW */
580
# define DLERROR(arg) dlerror ()
582
# define DLERROR(arg) LT_DLSTRERROR (arg)
585
int lt_dlopen_flag = LT_LAZY_OR_NOW;
588
/*------------------------------------------------------------------*/
589
/* implementations found at the end */
590
/*------------------------------------------------------------------*/
596
sys_dl_search_by_name( const char* name );
599
sys_dl_not_found_entry( const char* tmp );
603
sys_dl_open (loader_data, filename)
604
lt_user_data loader_data;
605
const char *filename;
609
/* If the basename is of the form "libname.a(member)",
610
set the appropriate flag. */
611
if (strrchr(filename, '('))
612
lt_dlopen_flag |= LT_DLMEMBER_FLAG;
614
module = dlopen (filename, lt_dlopen_flag);
618
MUTEX_SETERROR (DLERROR (CANNOT_OPEN));
625
sys_dl_close (loader_data, module)
626
lt_user_data loader_data;
631
if (dlclose (module) != 0)
633
MUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
641
sys_dl_sym (loader_data, module, symbol)
642
lt_user_data loader_data;
646
lt_ptr address = dlsym (module, symbol);
650
MUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
656
static struct lt_user_dlloader sys_dl =
663
sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
666
int lt_dlopen_flag = 0;
667
#endif /* HAVE_LIBDL */
671
/* --- SHL_LOAD() INTERFACE LOADER --- */
675
/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
681
/* some flags are missing on some systems, so we provide
685
* BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
686
* BIND_DEFERRED - Delay code symbol resolution until actual reference.
689
* BIND_FIRST - Place the library at the head of the symbol search
691
* BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
692
* unsatisfied symbols as fatal. This flag allows
693
* binding of unsatisfied code symbols to be deferred
695
* [Perl: For certain libraries, like DCE, deferred
696
* binding often causes run time problems. Adding
697
* BIND_NONFATAL to BIND_IMMEDIATE still allows
698
* unresolved references in situations like this.]
699
* BIND_NOSTART - Do not call the initializer for the shared library
700
* when the library is loaded, nor on a future call to
702
* BIND_VERBOSE - Print verbose messages concerning possible
703
* unsatisfied symbols.
705
* hp9000s700/hp9000s800:
706
* BIND_RESTRICTED - Restrict symbols visible by the library to those
707
* present at library load time.
708
* DYNAMIC_PATH - Allow the loader to dynamically search for the
709
* library specified by the path argument.
713
# define DYNAMIC_PATH 0
715
#ifndef BIND_RESTRICTED
716
# define BIND_RESTRICTED 0
719
#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
722
sys_shl_open (loader_data, filename)
723
lt_user_data loader_data;
724
const char *filename;
726
/* A NULL handle is used to get symbols from self and everything
727
else already loaded that was exported with -E compiler flag. */
728
lt_module module = (lt_module) 0;
732
module = shl_load (filename, LT_BIND_FLAGS, 0L);
736
MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
744
sys_shl_close (loader_data, module)
745
lt_user_data loader_data;
750
if (module && (shl_unload ((shl_t) (module)) != 0))
752
MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
760
sys_shl_sym (loader_data, module, symbol)
761
lt_user_data loader_data;
765
int is_module_self = (module == (lt_module) 0);
768
/* shl_findsym considers zero valued MODULE as an indicator to search
769
for a symbol among all loaded (and exported) symbols including those
770
in the main executable. However, it sets MODULE to a valid module
771
address which breaks the semantics of libltdl's module management. */
772
if (shl_findsym ((shl_t*) &module, symbol, TYPE_UNDEFINED, &address) == 0)
776
MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
781
module = (lt_module) 0;
786
static struct lt_user_dlloader sys_shl = {
787
0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
790
#endif /* HAVE_SHL_LOAD */
795
/* --- LOADLIBRARY() INTERFACE LOADER --- */
797
#if defined(__WINDOWS__) || defined(__CYGWIN__)
799
/* dynamic linking for Win32 */
803
/* Forward declaration; required to implement handle search below. */
804
static lt_dlhandle handles;
807
sys_wll_open (loader_data, filename)
808
lt_user_data loader_data;
809
const char *filename;
812
lt_module module = 0;
813
const char *errormsg = 0;
814
char *searchname = 0;
816
char self_name_buf[MAX_PATH];
820
/* Get the name of main module */
822
GetModuleFileName (NULL, (unsigned short*)self_name_buf, sizeof (self_name_buf));
823
filename = ext = self_name_buf;
827
ext = (char *)strrchr (filename, '.');
832
/* FILENAME already has an extension. */
833
searchname = strdup (filename);
837
/* Append a `.' to stop Windows from adding an
838
implicit `.dll' extension. */
839
searchname = LT_DLMALLOC (char, 2+ strlen (filename));
842
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
845
strcpy (searchname, filename);
846
strcat (searchname, ".");
851
char wpath[MAX_PATH];
852
cygwin_conv_to_full_win32_path(searchname, wpath);
853
module = LoadLibrary(wpath);
855
#elif defined(_WIN32)
857
char wpath[MAX_PATH];
858
strncpy(wpath, searchname, MAX_PATH);
859
win32_backslashify( wpath );
860
win32_mapSo2Dll( wpath );
861
//fprintf (stderr, "LoadLibraryA(\"%s\")\n", wpath);
862
module = LoadLibraryA( wpath );
865
module = LoadLibrary (searchname);
867
LT_DLFREE (searchname);
869
/* libltdl expects this function to fail if it is unable
870
to physically load the library. Sadly, LoadLibrary
871
will search the loaded libraries for a match and return
872
one of them if the path search load fails.
874
We check whether LoadLibrary is returning a handle to
875
an already loaded module, and simulate failure if we
887
if (cur->module == module)
898
MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
906
sys_wll_close (loader_data, module)
907
lt_user_data loader_data;
912
if (FreeLibrary(module) == 0)
914
MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
922
sys_wll_sym (loader_data, module, symbol)
923
lt_user_data loader_data;
927
lt_ptr address = GetProcAddress (module, symbol);
931
MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
937
static struct lt_user_dlloader sys_wll = {
938
0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
941
#endif /* __WINDOWS__ */
946
/* --- LOAD_ADD_ON() INTERFACE LOADER --- */
951
/* dynamic linking for BeOS */
953
#include <kernel/image.h>
956
sys_bedl_open (loader_data, filename)
957
lt_user_data loader_data;
958
const char *filename;
964
image = load_add_on (filename);
970
if (get_next_image_info (0, &cookie, &info) == B_OK)
971
image = load_add_on (info.name);
976
MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
980
return (lt_module) image;
984
sys_bedl_close (loader_data, module)
985
lt_user_data loader_data;
990
if (unload_add_on ((image_id) module) != B_OK)
992
MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1000
sys_bedl_sym (loader_data, module, symbol)
1001
lt_user_data loader_data;
1006
image_id image = (image_id) module;
1008
if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1010
MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1017
static struct lt_user_dlloader sys_bedl = {
1018
0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1021
#endif /* __BEOS__ */
1026
/* --- DLD_LINK() INTERFACE LOADER --- */
1031
/* dynamic linking with dld */
1038
sys_dld_open (loader_data, filename)
1039
lt_user_data loader_data;
1040
const char *filename;
1042
lt_module module = strdup (filename);
1046
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1049
else if (dld_link (filename) != 0)
1051
MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1060
sys_dld_close (loader_data, module)
1061
lt_user_data loader_data;
1066
if (dld_unlink_by_file ((char*)(module), 1) != 0)
1068
MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1080
sys_dld_sym (loader_data, module, symbol)
1081
lt_user_data loader_data;
1085
lt_ptr address = dld_get_func (symbol);
1089
MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1095
static struct lt_user_dlloader sys_dld = {
1096
0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1099
#endif /* HAVE_DLD */
1104
/* --- DLPREOPEN() INTERFACE LOADER --- */
1107
/* emulate dynamic linking using preloaded_symbols */
1109
typedef struct lt_dlsymlists_t
1111
struct lt_dlsymlists_t *next;
1112
const lt_dlsymlist *syms;
1115
static const lt_dlsymlist *default_preloaded_symbols = 0;
1116
static lt_dlsymlists_t *preloaded_symbols = 0;
1119
presym_init (loader_data)
1120
lt_user_data loader_data;
1126
preloaded_symbols = 0;
1127
if (default_preloaded_symbols)
1129
errors = lt_dlpreload (default_preloaded_symbols);
1138
presym_free_symlists ()
1140
lt_dlsymlists_t *lists;
1144
lists = preloaded_symbols;
1147
lt_dlsymlists_t *tmp = lists;
1149
lists = lists->next;
1152
preloaded_symbols = 0;
1160
presym_exit (loader_data)
1161
lt_user_data loader_data;
1163
presym_free_symlists ();
1168
presym_add_symlist (preloaded)
1169
const lt_dlsymlist *preloaded;
1171
lt_dlsymlists_t *tmp;
1172
lt_dlsymlists_t *lists;
1177
lists = preloaded_symbols;
1180
if (lists->syms == preloaded)
1184
lists = lists->next;
1187
tmp = LT_DLMALLOC (lt_dlsymlists_t, 1);
1190
tmp->syms = preloaded;
1191
tmp->next = preloaded_symbols;
1192
preloaded_symbols = tmp;
1196
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1206
presym_open (loader_data, filename)
1207
lt_user_data loader_data;
1208
const char *filename;
1210
lt_dlsymlists_t *lists;
1211
lt_module module = (lt_module) 0;
1214
lists = preloaded_symbols;
1218
MUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
1224
filename = "@PROGRAM@";
1229
const lt_dlsymlist *syms = lists->syms;
1233
if (!syms->address && strcmp(syms->name, filename) == 0)
1235
module = (lt_module) syms;
1241
lists = lists->next;
1244
MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
1252
presym_close (loader_data, module)
1253
lt_user_data loader_data;
1256
/* Just to silence gcc -Wall */
1262
presym_sym (loader_data, module, symbol)
1263
lt_user_data loader_data;
1267
lt_dlsymlist *syms = (lt_dlsymlist*) module;
1270
while (syms->address)
1272
if (strcmp(syms->name, symbol) == 0)
1274
return syms->address;
1280
MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1285
static struct lt_user_dlloader presym = {
1286
0, presym_open, presym_close, presym_sym, presym_exit, 0
1293
/* --- DYNAMIC MODULE LOADING --- */
1296
static char *user_search_path= 0;
1297
static lt_dlloader *loaders = 0;
1298
static lt_dlhandle handles = 0;
1299
static int initialized = 0;
1301
/* Initialize libltdl. */
1309
/* Initialize only at first call. */
1310
if (++initialized == 1)
1313
user_search_path = 0; /* empty search path */
1315
#if HAVE_LIBDL && !defined(__CYGWIN__)
1316
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
1322
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
1324
#if defined(__WINDOWS__) || defined(__CYGWIN__)
1325
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
1328
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
1331
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
1333
errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
1335
if (presym_init (presym.dlloader_data))
1337
MUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
1340
else if (errors != 0)
1342
MUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
1353
lt_dlpreload (preloaded)
1354
const lt_dlsymlist *preloaded;
1360
errors = presym_add_symlist (preloaded);
1364
const char *errormsg = 0;
1366
presym_free_symlists();
1369
if (default_preloaded_symbols)
1371
errors = lt_dlpreload (default_preloaded_symbols);
1380
lt_dlpreload_default (preloaded)
1381
const lt_dlsymlist *preloaded;
1384
default_preloaded_symbols = preloaded;
1392
/* shut down libltdl */
1393
lt_dlloader *loader;
1394
const char *errormsg;
1402
MUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
1407
/* shut down only at last call. */
1408
if (--initialized == 0)
1412
while (handles && LT_DLIS_RESIDENT (handles))
1414
handles = handles->next;
1417
/* close all modules */
1418
for (level = 1; handles; ++level)
1420
lt_dlhandle cur = handles;
1424
lt_dlhandle tmp = cur;
1426
if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
1428
if (lt_dlclose (tmp))
1436
/* close all loaders */
1439
lt_dlloader *next = loader->next;
1440
lt_user_data data = loader->dlloader_data;
1441
if (loader->dlloader_exit && loader->dlloader_exit (data))
1446
LT_DLMEM_REASSIGN (loader, next);
1457
tryall_dlopen (handle, filename)
1458
lt_dlhandle *handle;
1459
const char *filename;
1462
lt_dlloader *loader;
1463
const char *saved_error;
1466
MUTEX_GETERROR (saved_error);
1472
/* check whether the module was already opened */
1475
/* try to dlopen the program itself? */
1476
if (!cur->info.filename && !filename)
1481
if (cur->info.filename && filename
1482
&& strcmp (cur->info.filename, filename) == 0)
1492
++cur->info.ref_count;
1500
LT_DLFREE( cur->info.filename );
1501
cur->info.filename = strdup (filename);
1502
if (!cur->info.filename)
1504
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1511
LT_DLFREE( cur->info.filename );
1512
cur->info.filename = 0;
1517
lt_user_data data = loader->dlloader_data;
1519
cur->module = loader->module_open (data, filename);
1521
if (cur->module != 0)
1525
loader = loader->next;
1530
LT_DLFREE (cur->info.filename);
1535
cur->loader = loader;
1536
last_error = saved_error;
1545
find_module (handle, dir, libdir, dlname, old_name, installed)
1546
lt_dlhandle *handle;
1550
const char *old_name;
1556
/* try to open the old library first; if it was dlpreopened,
1557
we want the preopened version of it, even if a dlopenable
1558
module is available */
1559
if (old_name && tryall_dlopen(handle, old_name) == 0)
1564
/* try to open the dynamic library */
1569
/* try to open the installed module */
1570
if (installed && libdir)
1572
len = strlen (libdir) + 1 + strlen (dlname);
1573
filename = LT_DLMALLOC (char, 1+ len);
1577
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1581
sprintf (filename, "%s/%s", libdir, dlname);
1582
error = (tryall_dlopen (handle, filename) != 0);
1583
LT_DLFREE (filename);
1591
/* try to open the not-installed module */
1594
len = (dir ? strlen (dir) : 0) + strlen (objdir) + strlen (dlname);
1595
filename = LT_DLMALLOC (char, 1+ len);
1599
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1605
strcpy (filename, dir);
1611
strcat(filename, objdir);
1612
strcat(filename, dlname);
1614
error = tryall_dlopen (handle, filename) != 0;
1615
LT_DLFREE (filename);
1622
/* maybe it was moved to another directory */
1624
len = (dir ? strlen (dir) : 0) + strlen (dlname);
1625
filename = LT_DLMALLOC (char, 1+ len);
1629
strcpy (filename, dir);
1635
strcat(filename, dlname);
1637
error = (tryall_dlopen (handle, filename) != 0);
1638
LT_DLFREE (filename);
1650
canonicalize_path (path)
1653
char *canonical = 0;
1657
char *ptr = strdup (path);
1660
#ifdef LT_DIRSEP_CHAR
1661
/* Avoid this overhead where '/' is the only separator. */
1662
while (ptr = (char*)strchr (ptr, LT_DIRSEP_CHAR))
1673
find_file (basename, search_path, pdir, handle)
1674
const char *basename;
1675
const char *search_path;
1677
lt_dlhandle *handle;
1679
/* When handle != NULL search a library, otherwise a file
1680
return NULL on failure, otherwise the file/handle. */
1684
int filenamesize= 0;
1685
int lenbase = strlen (basename);
1686
char *canonical = 0;
1691
if (!search_path || !*search_path)
1693
MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
1697
canonical = canonicalize_path (search_path);
1700
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1710
next = (char*)strchr (cur, LT_PATHSEP_CHAR);
1713
next = cur + strlen (cur);
1716
lendir = next - cur;
1717
if (*next == LT_PATHSEP_CHAR)
1731
if (lendir + 1 + lenbase >= filenamesize)
1733
LT_DLFREE (filename);
1734
filenamesize = lendir + 1 + lenbase + 1;
1735
filename = LT_DLMALLOC (char, filenamesize);
1739
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1744
strncpy(filename, cur, lendir);
1745
if (filename[lendir-1] != '/')
1747
filename[lendir++] = '/';
1749
strcpy(filename+lendir, basename);
1752
if (tryall_dlopen (handle, filename) == 0)
1754
result = (lt_ptr) handle;
1760
FILE *file = fopen (filename, LT_READTEXT_MODE);
1765
filename[lendir] = '\0';
1766
*pdir = strdup(filename);
1769
/* We could have even avoided the strdup,
1770
but there would be some memory overhead. */
1775
result = (lt_ptr) file;
1781
MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
1784
LT_DLFREE (filename);
1785
LT_DLFREE (canonical);
1793
load_deplibs(handle, deplibs)
1797
#if LTDL_DLOPEN_DEPLIBS
1798
char *p, *save_search_path;
1805
handle->depcount = 0;
1807
#if LTDL_DLOPEN_DEPLIBS
1815
save_search_path = strdup (user_search_path);
1816
if (user_search_path && !save_search_path)
1818
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1822
/* extract search paths and count deplibs */
1826
if (!isspace ((int) *p))
1829
while (*end && !isspace((int) *end))
1834
if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
1837
*end = 0; /* set a temporary string terminator */
1838
if (lt_dladdsearchdir(p+2))
1857
/* restore the old search path */
1858
LT_DLFREE (user_search_path);
1859
user_search_path = save_search_path;
1869
names = LT_DLMALLOC (char *, depcount * sizeof (char*));
1875
/* now only extract the actual deplibs */
1880
if (isspace ((int) *p))
1887
while (*end && !isspace ((int) *end))
1892
if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
1896
*end = 0; /* set a temporary string terminator */
1897
if (strncmp(p, "-l", 2) == 0)
1899
name = LT_DLMALLOC (char, 3+ /* "lib" */ strlen (p+2) + 1);
1902
sprintf (name, "lib%s", p+2);
1912
names[depcount++] = name;
1924
/* load the deplibs (in reverse order)
1925
At this stage, don't worry if the deplibs do not load correctly,
1926
they may already be statically linked into the loading application
1927
for instance. There will be a more enlightening error message
1928
later on if the loaded module cannot resolve all of its symbols. */
1933
handle->deplibs = (lt_dlhandle*) LT_DLMALLOC (lt_dlhandle *, depcount);
1934
if (!handle->deplibs)
1939
for (i = 0; i < depcount; ++i)
1941
handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
1942
if (handle->deplibs[j])
1948
handle->depcount = j; /* Number of successfully loaded deplibs */
1953
for (i = 0; i < depcount; ++i)
1955
LT_DLFREE (names[i]);
1966
unload_deplibs(handle)
1972
if (handle->depcount)
1974
for (i = 0; i < handle->depcount; ++i)
1976
if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
1978
errors += lt_dlclose (handle->deplibs[i]);
1991
/* remove the leading and trailing "'" from str
1992
and store the result in dest */
1993
const char *end = strrchr (str, '\'');
1994
int len = strlen (str);
1999
if (len > 3 && str[0] == '\'')
2001
tmp = LT_DLMALLOC (char, end - str);
2004
last_error = LT_DLSTRERROR (NO_MEMORY);
2008
strncpy(tmp, &str[1], (end - str) - 1);
2009
tmp[end-str-1] = '\0';
2021
free_vars( dlname, oldname, libdir, deplibs)
2028
LT_DLFREE (oldname);
2030
LT_DLFREE (deplibs);
2036
lt_dlopen (filename)
2037
const char *filename;
2039
lt_dlhandle handle = 0, newhandle;
2041
const char *saved_error;
2042
char *canonical = 0, *basename = 0, *dir = 0, *name = 0;
2044
MUTEX_GETERROR (saved_error);
2049
handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
2052
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2055
memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
2057
handle->info.ref_count = 0;
2058
handle->depcount = 0;
2059
handle->deplibs = 0;
2060
handle->caller_data = 0;
2063
/* lt_dlclose()ing yourself is very bad! Disallow it. */
2064
LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
2066
if (tryall_dlopen (&newhandle, 0) != 0)
2071
goto register_handle;
2074
canonical = canonicalize_path (filename);
2077
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2082
/* If the canonical module name is a path (relative or absolute)
2083
then split it into a directory part and a name part. */
2084
basename = (char*)strrchr (canonical, '/');
2088
dir = LT_DLMALLOC (char, basename - canonical + 1);
2091
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2096
strncpy (dir, canonical, basename - canonical);
2097
dir[basename - canonical] = '\0';
2101
basename = canonical;
2104
/* Check whether we are opening a libtool module (.la extension). */
2105
ext = strrchr(basename, '.');
2106
if (ext && strcmp(ext, ".la") == 0)
2108
/* this seems to be a libtool module */
2111
char *dlname = 0, *old_name = 0;
2112
char *libdir = 0, *deplibs = 0;
2117
/* if we can't find the installed flag, it is probably an
2118
installed libtool archive, produced with an old version
2122
/* extract the module name from the file name */
2123
name = LT_DLMALLOC (char, ext - basename + 1);
2126
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2131
/* canonicalize the module name */
2132
for (i = 0; i < ext - basename; ++i)
2134
if (isalnum ((int)(basename[i])))
2136
name[i] = basename[i];
2144
name[ext - basename] = '\0';
2146
/* Now try to open the .la file. If there is no directory name
2147
component, try to find it first in user_search_path and then other
2148
prescribed paths. Otherwise (or in any case if the module was not
2149
yet found) try opening just the module name as passed. */
2152
file = (FILE*) find_file(basename, user_search_path, &dir, 0);
2155
file = (FILE*) find_file(basename, getenv("LTDL_LIBRARY_PATH"),
2159
#ifdef LTDL_SHLIBPATH_VAR
2162
file = (FILE*) find_file(basename, getenv(LTDL_SHLIBPATH_VAR),
2166
#ifdef LTDL_SYSSEARCHPATH
2169
file = (FILE*) find_file(basename, sys_search_path, &dir, 0);
2175
file = fopen (filename, LT_READTEXT_MODE);
2179
MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2188
line_len = LT_FILENAME_MAX;
2189
line = LT_DLMALLOC (char, line_len);
2193
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2198
/* read the .la file */
2201
line[line_len-2] = '\0';
2202
if (!fgets (line, line_len, file))
2207
/* Handle the case where we occasionally need to read a line
2208
that is longer than the initial buffer size. */
2209
while (line[line_len-2] && (!feof (file)))
2211
line = LT_DLREALLOC (char, line, line_len *2);
2212
line[line_len*2-2] = '\0';
2213
if (!line || !fgets (&line[line_len -1], (int) line_len +1, file))
2223
if (line[0] == '\n' || line[0] == '#')
2230
#define STR_DLNAME "dlname="
2231
if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
2233
error = trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
2236
#undef STR_OLD_LIBRARY
2237
#define STR_OLD_LIBRARY "old_library="
2238
else if (strncmp (line, STR_OLD_LIBRARY,
2239
sizeof (STR_OLD_LIBRARY) - 1) == 0)
2241
error = trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
2244
#define STR_LIBDIR "libdir="
2245
else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
2247
error = trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
2248
#if defined(_WIN32) && !defined(__CYGWIN__)
2249
win32_mapDir(&libdir);
2253
#undef STR_DL_DEPLIBS
2254
#define STR_DL_DEPLIBS "dependency_libs="
2255
else if (strncmp (line, STR_DL_DEPLIBS,
2256
sizeof (STR_DL_DEPLIBS) - 1) == 0)
2258
error = trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
2260
else if (strcmp (line, "installed=yes\n") == 0)
2264
else if (strcmp (line, "installed=no\n") == 0)
2269
#undef STR_LIBRARY_NAMES
2270
#define STR_LIBRARY_NAMES "library_names="
2271
else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
2272
sizeof (STR_LIBRARY_NAMES) - 1) == 0)
2275
error = trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
2276
if (! error && dlname &&
2277
(last_libname = (char*)strrchr (dlname, ' ')) != NULL)
2279
last_libname = strdup (last_libname + 1);
2280
LT_DLMEM_REASSIGN (dlname, last_libname);
2293
/* allocate the handle */
2294
handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
2295
if (!handle || error)
2300
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2303
free_vars (dlname, old_name, libdir, deplibs);
2304
/* handle is already set to 0 */
2307
memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
2309
handle->info.ref_count = 0;
2310
if (load_deplibs (handle, deplibs) == 0)
2313
/* find_module may replace newhandle */
2314
if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
2316
unload_deplibs (handle);
2325
free_vars (dlname, old_name, libdir, deplibs);
2332
if (handle != newhandle)
2334
unload_deplibs (handle);
2336
LT_DLFREE( handle->info.filename );
2337
handle->info.filename = strdup( filename );
2342
/* not a libtool module */
2343
handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
2346
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2347
/* handle is already set to 0 */
2350
memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
2351
handle->info.ref_count = 0;
2352
/* non-libtool modules don't have dependencies */
2353
handle->depcount = 0;
2354
handle->deplibs = 0;
2357
/* If the module has no directory name component, try to find it
2358
first in user_search_path and then other prescribed paths.
2359
Otherwise (or in any case if the module was not yet found) try
2360
opening just the module name as passed. */
2361
if ((dir || (!find_file (basename, user_search_path, 0, &newhandle)
2362
&& !find_file (basename, getenv ("LTDL_LIBRARY_PATH"),
2364
#ifdef LTDL_SHLIBPATH_VAR
2365
&& !find_file (basename, getenv (LTDL_SHLIBPATH_VAR),
2368
#ifdef LTDL_SYSSEARCHPATH
2369
&& !find_file (basename, sys_search_path, 0, &newhandle)
2371
)) && tryall_dlopen (&newhandle, filename))
2379
LT_DLMEM_REASSIGN (handle, newhandle);
2381
if (handle->info.ref_count == 0)
2383
handle->info.ref_count = 1;
2384
handle->info.name = name;
2385
handle->next = handles;
2391
name = 0; /* don't free this during `cleanup' */
2394
MUTEX_SETERROR (saved_error);
2399
LT_DLFREE (canonical);
2405
lt_dlopenext (filename)
2406
const char *filename;
2411
const char *saved_error;
2413
MUTEX_GETERROR (saved_error);
2417
return lt_dlopen (filename);
2420
len = strlen (filename);
2423
MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2427
tmp = LT_DLMALLOC (char, len+4);
2430
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2433
strcpy (tmp, filename);
2438
/* find by info.name in the list */
2439
handle = sys_dl_search_by_name( tmp );
2442
if( LT_DLGET_FLAG (handle, LT_DLNOTFOUND_FLAG) )
2444
/* don't search libm and libstdc++ over and over again,
2445
* they are hardlinked and symbols are exported by the
2447
MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2451
MUTEX_SETERROR (saved_error);
2457
/* try "filename.la" */
2458
strcat (tmp, ".la");
2459
handle = lt_dlopen (tmp);
2462
MUTEX_SETERROR (saved_error);
2469
tmp[len] = '\0'; /* delete the ".la" again. */
2471
/* versioned shared objects can be in .a's */
2473
handle = lt_dlopen (tmp);
2476
MUTEX_SETERROR (saved_error);
2482
#ifdef LTDL_SHLIB_EXT
2483
/* try "filename.EXT" */
2484
if (strlen(shlib_ext) > 3)
2487
tmp = LT_DLMALLOC (char, len + strlen (shlib_ext) + 1);
2490
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2493
strcpy (tmp, filename);
2500
strcat(tmp, shlib_ext);
2501
handle = lt_dlopen (tmp);
2504
MUTEX_SETERROR (saved_error);
2510
/* try the normal file name */
2511
handle = lt_dlopen (filename);
2518
/* put into the can't be found list */
2520
sys_dl_not_found_entry( tmp );
2523
MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2532
lt_dlhandle cur, last;
2537
/* check whether the handle is valid */
2538
last = cur = handles;
2539
while (cur && handle != cur)
2547
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
2552
handle->info.ref_count--;
2554
/* Note that even with resident modules, we must track the ref_count
2555
correctly incase the user decides to reset the residency flag
2556
later (even though the API makes no provision for that at the
2558
if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
2560
lt_user_data data = handle->loader->dlloader_data;
2562
if (handle != handles)
2564
last->next = handle->next;
2568
handles = handle->next;
2571
errors += handle->loader->module_close (data, handle->module);
2572
errors += unload_deplibs(handle);
2574
LT_DLFREE (handle->info.filename);
2575
LT_DLFREE (handle->info.name);
2581
if (LT_DLIS_RESIDENT (handle))
2583
MUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
2594
lt_dlsym (handle, symbol)
2599
char lsym[LT_SYMBOL_LENGTH];
2606
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
2612
MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
2616
lensym = strlen(symbol);
2617
if (handle->loader->sym_prefix)
2619
lensym += strlen(handle->loader->sym_prefix);
2622
if (handle->info.name)
2624
lensym += strlen(handle->info.name);
2627
if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
2633
sym = LT_DLMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
2638
MUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
2642
data = handle->loader->dlloader_data;
2643
if (handle->info.name)
2645
const char *saved_error;
2647
MUTEX_GETERROR (saved_error);
2649
/* this is a libtool module */
2650
if (handle->loader->sym_prefix)
2652
strcpy(sym, handle->loader->sym_prefix);
2653
strcat(sym, handle->info.name);
2657
strcpy(sym, handle->info.name);
2660
strcat(sym, "_LTX_");
2661
strcat(sym, symbol);
2663
/* try "modulename_LTX_symbol" */
2664
address = handle->loader->find_sym (data, handle->module, sym);
2673
MUTEX_SETERROR (saved_error);
2676
/* otherwise try "symbol" */
2677
if (handle->loader->sym_prefix)
2679
strcpy(sym, handle->loader->sym_prefix);
2680
strcat(sym, symbol);
2684
strcpy(sym, symbol);
2687
address = handle->loader->find_sym (data, handle->module, sym);
2701
MUTEX_GETERROR (error);
2708
lt_dladdsearchdir (search_dir)
2709
const char *search_dir;
2713
if (!search_dir || !strlen(search_dir))
2719
if (!user_search_path)
2721
user_search_path = strdup (search_dir);
2722
if (!user_search_path)
2724
last_error = LT_DLSTRERROR (NO_MEMORY);
2730
size_t len = strlen (user_search_path) + 1 + strlen (search_dir);
2731
char *new_search_path = LT_DLMALLOC (char, 1+ len);
2733
if (!new_search_path)
2735
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2740
sprintf (new_search_path, "%s%c%s", user_search_path,
2741
LT_PATHSEP_CHAR, search_dir);
2743
LT_DLMEM_REASSIGN (user_search_path, new_search_path);
2752
lt_dlsetsearchpath (search_path)
2753
const char *search_path;
2758
LT_DLFREE (user_search_path);
2761
if (!search_path || !strlen (search_path))
2767
user_search_path = strdup (search_path);
2768
if (!user_search_path)
2778
lt_dlgetsearchpath ()
2780
const char *saved_path;
2783
saved_path = user_search_path;
2790
lt_dlmakeresident (handle)
2797
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
2802
LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
2809
lt_dlisresident (handle)
2814
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
2818
return LT_DLIS_RESIDENT (handle);
2824
/* --- MODULE INFORMATION --- */
2827
lt_dlgetinfo (handle)
2832
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
2836
return &(handle->info);
2840
lt_dlhandle_next (place)
2843
return place ? place->next : (lt_dlhandle) 0;
2847
lt_dlforeach (func, data)
2848
int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
2859
lt_dlhandle tmp = cur;
2862
if ((*func) (tmp, data))
2875
lt_dlcaller_register ()
2877
static int last_caller_id = -1;
2881
result = ++last_caller_id;
2887
#define N_ELEMENTS(a) (sizeof(a) / sizeof(*(a)))
2890
lt_dlcaller_set_data (key, handle, data)
2896
lt_ptr stale = (lt_ptr) 0;
2899
/* This needs to be locked so that the caller data can be updated
2900
simultaneously by different threads. */
2903
if (handle->caller_data)
2904
n_elements = N_ELEMENTS (handle->caller_data);
2906
for (i = 0; i < n_elements; ++i)
2908
if (handle->caller_data[i].key == key)
2910
stale = handle->caller_data[i].data;
2915
/* Ensure that there is enough room in this handle's caller_data
2916
array to accept a new element. */
2917
if (i == n_elements)
2919
lt_caller_data *temp
2920
= LT_DLREALLOC (lt_caller_data, handle->caller_data, 1+ n_elements);
2924
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2930
handle->caller_data = temp;
2933
/* We only need this if we needed to allocate a new caller_data. */
2934
handle->caller_data[i].key = key;
2937
handle->caller_data[i].data = data;
2946
lt_dlcaller_get_data (key, handle)
2950
lt_ptr result = (lt_ptr) 0;
2953
/* This needs to be locked so that the caller data isn't updated by
2954
another thread part way through this function. */
2957
if (handle->caller_data)
2958
n_elements = N_ELEMENTS (handle->caller_data);
2960
/* Locate the index of the element with a matching KEY. */
2963
for (i = 0; i < n_elements; ++i)
2965
if (handle->caller_data[i].key == key)
2967
result = handle->caller_data[i].data;
2980
/* --- USER MODULE LOADER API --- */
2984
lt_dlloader_add (place, dlloader, loader_name)
2986
const struct lt_user_dlloader *dlloader;
2987
const char *loader_name;
2990
lt_dlloader *node = 0, *ptr = 0;
2992
if ((dlloader == 0) /* diagnose null parameters */
2993
|| (dlloader->module_open == 0)
2994
|| (dlloader->module_close == 0)
2995
|| (dlloader->find_sym == 0))
2997
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3001
/* Create a new dlloader node with copies of the user callbacks. */
3002
node = LT_DLMALLOC (lt_dlloader, 1);
3005
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3010
node->loader_name = loader_name;
3011
node->sym_prefix = dlloader->sym_prefix;
3012
node->dlloader_exit = dlloader->dlloader_exit;
3013
node->module_open = dlloader->module_open;
3014
node->module_close = dlloader->module_close;
3015
node->find_sym = dlloader->find_sym;
3016
node->dlloader_data = dlloader->dlloader_data;
3021
/* If there are no loaders, NODE becomes the list! */
3026
/* If PLACE is not set, add NODE to the end of the
3028
for (ptr = loaders; ptr->next; ptr = ptr->next)
3035
else if (loaders == place)
3037
/* If PLACE is the first loader, NODE goes first. */
3043
/* Find the node immediately preceding PLACE. */
3044
for (ptr = loaders; ptr->next != place; ptr = ptr->next)
3049
if (ptr->next != place)
3051
last_error = LT_DLSTRERROR (INVALID_LOADER);
3056
/* Insert NODE between PTR and PLACE. */
3068
lt_dlloader_remove (loader_name)
3069
const char *loader_name;
3071
lt_dlloader *place = lt_dlloader_find (loader_name);
3077
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3083
/* Fail if there are any open modules which use this loader. */
3084
for (handle = handles; handle; handle = handle->next)
3086
if (handle->loader == place)
3088
MUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
3094
if (place == loaders)
3096
/* PLACE is the first loader in the list. */
3097
loaders = loaders->next;
3101
/* Find the loader before the one being removed. */
3103
for (prev = loaders; prev->next; prev = prev->next)
3105
if (!strcmp (prev->next->loader_name, loader_name))
3112
prev->next = prev->next->next;
3115
if (place->dlloader_exit)
3117
errors = place->dlloader_exit (place->dlloader_data);
3129
lt_dlloader_next (place)
3135
next = place ? place->next : loaders;
3142
lt_dlloader_name (place)
3145
const char *name = 0;
3150
name = place ? place->loader_name : 0;
3155
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3162
lt_dlloader_data (place)
3165
lt_user_data *data = 0;
3170
data = place ? &(place->dlloader_data) : 0;
3175
MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3182
lt_dlloader_find (loader_name)
3183
const char *loader_name;
3185
lt_dlloader *place = 0;
3188
for (place = loaders; place; place = place->next)
3190
if (strcmp (place->loader_name, loader_name) == 0)
3202
/* #define DBG_PRNT(a) fprintf a ; */
3206
sys_dl_debug_print_loaded( const char* filename )
3209
static unsigned char buffer[1024*1024];
3210
struct ld_info* info;
3212
ret = loadquery( L_GETINFO, buffer, 1024*1024 );
3215
DBG_PRNT((stderr, "%d: Successfully loaded %s\n",
3216
__LINE__, filename ))
3217
info = (struct ld_info*)buffer;
3222
c = info->ldinfo_filename;
3225
DBG_PRNT((stderr, "%d: path name %s, member name %s\n",
3228
info = (struct ld_info*)(((char*)info)+info->ldinfo_next);
3230
while( info->ldinfo_next != 0 );
3232
else if( errno == ENOMEM )
3234
DBG_PRNT((stderr, "%d: Successfully loaded %s, loadquery needs larger buffer\n",
3235
__LINE__, filename ))
3239
DBG_PRNT((stderr, "Loadquery failure\n"))
3244
sys_dl_debug_print_handle( lt_dlhandle handle )
3246
DBG_PRNT((stderr," > next = %ld\n", (long)handle->next ))
3247
DBG_PRNT((stderr," > loader = %ld\n", (long)handle->loader ))
3248
DBG_PRNT((stderr," > info.filename = %s\n", handle->info.filename ))
3249
DBG_PRNT((stderr," > info.name = %s\n", handle->info.name ))
3250
DBG_PRNT((stderr," > info.ref_count= %d\n", handle->info.ref_count ))
3251
DBG_PRNT((stderr," > depcount = %d\n", handle->depcount ))
3252
DBG_PRNT((stderr," > resident flags %s\n",
3253
(LT_DLGET_FLAG (handle, LT_DLRESIDENT_FLAG)?"yes":"no")))
3254
DBG_PRNT((stderr," > not found flags %s\n",
3255
(LT_DLGET_FLAG (handle, LT_DLNOTFOUND_FLAG)?"yes":"no")))
3261
char* buffer = NULL;
3262
size_t buf_size = 512;
3264
const char* libname;
3265
const char* modname;
3266
struct ld_info* info;
3270
const char* last_slash;
3271
const char* last_dot;
3276
if( buffer != NULL ) LT_DLFREE( buffer );
3277
buffer = LT_DLMALLOC( char, buf_size );
3278
ret = loadquery( L_GETINFO, buffer, buf_size );
3280
while( ret==-1 && errno==ENOMEM );
3284
info = (struct ld_info*)buffer;
3287
libname = info->ldinfo_filename;
3288
modname = &libname[strlen(libname)];
3295
if( cur->info.filename &&
3296
!strcmp( cur->info.filename, libname ) )
3304
if( already_listed == 0 )
3306
handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
3309
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3310
LT_DLFREE( buffer );
3313
memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
3315
last_slash = strrchr( libname, '/' );
3316
if( last_slash == NULL )
3318
last_slash = libname;
3324
last_dot = strrchr( last_slash, '.' );
3325
if( last_dot == NULL )
3327
last_dot = &last_slash[strlen(last_slash)];
3330
handle->info.name = LT_DLMALLOC( char, last_dot-last_slash+1 );
3331
strncpy( handle->info.name, last_slash, last_dot-last_slash );
3332
handle->info.name[last_dot-last_slash] = '\0';
3334
handle->loader = lt_dlloader_find ("dlopen");
3335
handle->info.filename = strdup( libname );
3336
handle->info.ref_count = 1;
3337
handle->depcount = 0;
3338
handle->deplibs = 0;
3339
handle->module = dlopen( libname, lt_dlopen_flag );
3341
handle->caller_data = 0;
3342
LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
3345
handle->next = handles;
3350
info = (struct ld_info*)(((char*)info)+info->ldinfo_next);
3352
while( info->ldinfo_next != 0 );
3355
if( buffer != NULL ) LT_DLFREE( buffer );
3359
sys_dl_search_by_name( const char* name )
3369
if( cur->info.name && name )
3371
if( !strcmp( cur->info.name, name ) )
3373
if( cur->info.filename )
3375
la = strrchr( cur->info.filename, '.' );
3376
if( !la || strcmp(la,".la") )
3383
if( cur->info.filename && name )
3385
if( !strcmp( cur->info.filename, name ) )
3396
sys_dl_not_found_entry( const char* tmp )
3400
handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
3403
MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3406
memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
3408
handle->loader = NULL;
3410
handle->info.filename = strdup( tmp );
3411
handle->info.name = strdup( tmp );
3412
handle->info.ref_count = 0;
3413
handle->depcount = 0;
3414
handle->deplibs = 0;
3417
handle->caller_data = 0;
3419
LT_DLSET_FLAG (handle, LT_DLNOTFOUND_FLAG);
3422
handle->next = handles;