blob: be1e4c093b01b73aa82bcad774a260fd3ee7acf6 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/* ltdl.c -- system independent dlopen wrapper
2
3 Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
4 2007, 2008 Free Software Foundation, Inc.
5 Written by Thomas Tanner, 1998
6
7 NOTE: The canonical source of this file is maintained with the
8 GNU Libtool package. Report bugs to bug-libtool@gnu.org.
9
10GNU Libltdl is free software; you can redistribute it and/or
11modify it under the terms of the GNU Lesser General Public
12License as published by the Free Software Foundation; either
13version 2 of the License, or (at your option) any later version.
14
15As a special exception to the GNU Lesser General Public License,
16if you distribute this file as part of a program or library that
17is built using GNU Libtool, you may include this file under the
18same distribution terms that you use for the rest of that program.
19
20GNU Libltdl is distributed in the hope that it will be useful,
21but WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23GNU Lesser General Public License for more details.
24
25You should have received a copy of the GNU Lesser General Public
cristycee97112010-05-28 00:44:52 +000026License along with GNU Libltdl; see the file COPYING.LIB. If not, a
cristy3ed852e2009-09-05 21:47:34 +000027copy can be downloaded from http://www.gnu.org/licenses/lgpl.html,
28or obtained by writing to the Free Software Foundation, Inc.,
2951 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30*/
31
32#include "lt__private.h"
33#include "lt_system.h"
34#include "lt_dlloader.h"
35
36
37/* --- MANIFEST CONSTANTS --- */
38
39
40/* Standard libltdl search path environment variable name */
41#undef LTDL_SEARCHPATH_VAR
42#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
43
44/* Standard libtool archive file extension. */
45#undef LT_ARCHIVE_EXT
46#define LT_ARCHIVE_EXT ".la"
47
48/* max. filename length */
49#if !defined(LT_FILENAME_MAX)
50# define LT_FILENAME_MAX 1024
51#endif
52
53#if !defined(LT_LIBEXT)
54# define LT_LIBEXT "a"
55#endif
56
cristy11def542011-02-20 00:15:09 +000057#if !defined(LT_LIBPREFIX)
58# define LT_LIBPREFIX "lib"
59#endif
60
cristy3ed852e2009-09-05 21:47:34 +000061/* This is the maximum symbol size that won't require malloc/free */
62#undef LT_SYMBOL_LENGTH
63#define LT_SYMBOL_LENGTH 128
64
65/* This accounts for the _LTX_ separator */
66#undef LT_SYMBOL_OVERHEAD
67#define LT_SYMBOL_OVERHEAD 5
68
69/* Various boolean flags can be stored in the flags field of an
70 lt_dlhandle... */
71#define LT_DLIS_RESIDENT(handle) ((handle)->info.is_resident)
72#define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal)
73#define LT_DLIS_SYMLOCAL(handle) ((handle)->info.is_symlocal)
74
75
76static const char objdir[] = LT_OBJDIR;
77static const char archive_ext[] = LT_ARCHIVE_EXT;
78static const char libext[] = LT_LIBEXT;
cristy11def542011-02-20 00:15:09 +000079static const char libprefix[] = LT_LIBPREFIX;
cristy3ed852e2009-09-05 21:47:34 +000080#if defined(LT_MODULE_EXT)
81static const char shlib_ext[] = LT_MODULE_EXT;
82#endif
83#if defined(LT_DLSEARCH_PATH)
84static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH;
85#endif
86
87
88
89
90/* --- DYNAMIC MODULE LOADING --- */
91
92
93/* The type of a function used at each iteration of foreach_dirinpath(). */
94typedef int foreach_callback_func (char *filename, void *data1,
95 void *data2);
96/* foreachfile_callback itself calls a function of this type: */
97typedef int file_worker_func (const char *filename, void *data);
98
99
100static int foreach_dirinpath (const char *search_path,
101 const char *base_name,
102 foreach_callback_func *func,
103 void *data1, void *data2);
104static int find_file_callback (char *filename, void *data1,
105 void *data2);
106static int find_handle_callback (char *filename, void *data,
107 void *ignored);
108static int foreachfile_callback (char *filename, void *data1,
109 void *data2);
110
111
112static int canonicalize_path (const char *path, char **pcanonical);
113static int argzize_path (const char *path,
114 char **pargz, size_t *pargz_len);
115static FILE *find_file (const char *search_path,
116 const char *base_name, char **pdir);
117static lt_dlhandle *find_handle (const char *search_path,
118 const char *base_name,
119 lt_dlhandle *handle,
120 lt_dladvise advise);
121static int find_module (lt_dlhandle *handle, const char *dir,
122 const char *libdir, const char *dlname,
123 const char *old_name, int installed,
124 lt_dladvise advise);
125static int has_library_ext (const char *filename);
126static int load_deplibs (lt_dlhandle handle, char *deplibs);
127static int trim (char **dest, const char *str);
128static int try_dlopen (lt_dlhandle *handle,
129 const char *filename, const char *ext,
130 lt_dladvise advise);
131static int tryall_dlopen (lt_dlhandle *handle,
132 const char *filename,
133 lt_dladvise padvise,
134 const lt_dlvtable *vtable);
135static int unload_deplibs (lt_dlhandle handle);
136static int lt_argz_insert (char **pargz, size_t *pargz_len,
137 char *before, const char *entry);
138static int lt_argz_insertinorder (char **pargz, size_t *pargz_len,
139 const char *entry);
140static int lt_argz_insertdir (char **pargz, size_t *pargz_len,
141 const char *dirnam, struct dirent *dp);
142static int lt_dlpath_insertdir (char **ppath, char *before,
143 const char *dir);
144static int list_files_by_dir (const char *dirnam,
145 char **pargz, size_t *pargz_len);
146static int file_not_found (void);
147
148#ifdef HAVE_LIBDLLOADER
149static int loader_init_callback (lt_dlhandle handle);
150#endif /* HAVE_LIBDLLOADER */
151
152static int loader_init (lt_get_vtable *vtable_func,
153 lt_user_data data);
154
155static char *user_search_path= 0;
156static lt_dlhandle handles = 0;
157static int initialized = 0;
158
159/* Our memory failure callback sets the error message to be passed back
160 up to the client, so we must be careful to return from mallocation
161 callers if allocation fails (as this callback returns!!). */
162void
163lt__alloc_die_callback (void)
164{
165 LT__SETERROR (NO_MEMORY);
166}
167
168#ifdef HAVE_LIBDLLOADER
169/* This function is called to initialise each preloaded module loader,
170 and hook it into the list of loaders to be used when attempting to
171 dlopen an application module. */
172static int
173loader_init_callback (lt_dlhandle handle)
174{
175 lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable");
176 return loader_init (vtable_func, 0);
177}
178#endif /* HAVE_LIBDLLOADER */
179
180static int
181loader_init (lt_get_vtable *vtable_func, lt_user_data data)
182{
183 const lt_dlvtable *vtable = 0;
184 int errors = 0;
185
186 if (vtable_func)
187 {
188 vtable = (*vtable_func) (data);
189 }
190
191 /* lt_dlloader_add will LT__SETERROR if it fails. */
192 errors += lt_dlloader_add (vtable);
193
194 assert (errors || vtable);
195
196 if ((!errors) && vtable->dlloader_init)
197 {
198 if ((*vtable->dlloader_init) (vtable->dlloader_data))
199 {
200 LT__SETERROR (INIT_LOADER);
201 ++errors;
202 }
203 }
204
205 return errors;
206}
207
208/* Bootstrap the loader loading with the preopening loader. */
209#define get_vtable preopen_LTX_get_vtable
210#define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
211
212LT_BEGIN_C_DECLS
213LT_SCOPE const lt_dlvtable * get_vtable (lt_user_data data);
214LT_END_C_DECLS
215#ifdef HAVE_LIBDLLOADER
cristy11def542011-02-20 00:15:09 +0000216extern LT_DLSYM_CONST lt_dlsymlist preloaded_symbols[];
cristy3ed852e2009-09-05 21:47:34 +0000217#endif
218
219/* Initialize libltdl. */
220int
221lt_dlinit (void)
222{
223 int errors = 0;
224
225 /* Initialize only at first call. */
226 if (++initialized == 1)
227 {
228 lt__alloc_die = lt__alloc_die_callback;
229 handles = 0;
230 user_search_path = 0; /* empty search path */
231
232 /* First set up the statically loaded preload module loader, so
233 we can use it to preopen the other loaders we linked in at
234 compile time. */
235 errors += loader_init (get_vtable, 0);
236
237 /* Now open all the preloaded module loaders, so the application
238 can use _them_ to lt_dlopen its own modules. */
239#ifdef HAVE_LIBDLLOADER
240 if (!errors)
241 {
cristy98dddb52010-11-04 00:30:15 +0000242 errors += lt_dlpreload (preloaded_symbols);
cristy3ed852e2009-09-05 21:47:34 +0000243 }
244
245 if (!errors)
246 {
247 errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback);
248 }
249#endif /* HAVE_LIBDLLOADER */
250 }
251
252#ifdef LT_DEBUG_LOADERS
253 lt_dlloader_dump();
254#endif
255
256 return errors;
257}
258
259int
260lt_dlexit (void)
261{
262 /* shut down libltdl */
263 lt_dlloader *loader = 0;
264 lt_dlhandle handle = handles;
265 int errors = 0;
266
267 if (!initialized)
268 {
269 LT__SETERROR (SHUTDOWN);
270 ++errors;
271 goto done;
272 }
273
274 /* shut down only at last call. */
275 if (--initialized == 0)
276 {
277 int level;
278
279 while (handles && LT_DLIS_RESIDENT (handles))
280 {
281 handles = handles->next;
282 }
283
284 /* close all modules */
285 for (level = 1; handle; ++level)
286 {
287 lt_dlhandle cur = handles;
288 int saw_nonresident = 0;
289
290 while (cur)
291 {
292 lt_dlhandle tmp = cur;
293 cur = cur->next;
294 if (!LT_DLIS_RESIDENT (tmp))
295 {
296 saw_nonresident = 1;
297 if (tmp->info.ref_count <= level)
298 {
299 if (lt_dlclose (tmp))
300 {
301 ++errors;
302 }
303 /* Make sure that the handle pointed to by 'cur' still exists.
304 lt_dlclose recursively closes dependent libraries which removes
305 them from the linked list. One of these might be the one
306 pointed to by 'cur'. */
307 if (cur)
308 {
309 for (tmp = handles; tmp; tmp = tmp->next)
310 if (tmp == cur)
311 break;
312 if (! tmp)
313 cur = handles;
314 }
315 }
316 }
317 }
318 /* done if only resident modules are left */
319 if (!saw_nonresident)
320 break;
321 }
322
323 /* When removing loaders, we can only find out failure by testing
324 the error string, so avoid a spurious one from an earlier
325 failed command. */
326 if (!errors)
327 LT__SETERRORSTR (0);
328
329 /* close all loaders */
330 for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;)
331 {
332 lt_dlloader *next = (lt_dlloader *) lt_dlloader_next (loader);
333 lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader);
334
335 if ((vtable = lt_dlloader_remove ((char *) vtable->name)))
336 {
337 FREE (vtable);
338 }
339 else
340 {
341 /* ignore errors due to resident modules */
342 const char *err;
343 LT__GETERROR (err);
344 if (err)
345 ++errors;
346 }
347
348 loader = next;
349 }
350
351 FREE(user_search_path);
352 }
353
354 done:
355 return errors;
356}
357
358
359/* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME.
360 If the library is not successfully loaded, return non-zero. Otherwise,
361 the dlhandle is stored at the address given in PHANDLE. */
362static int
363tryall_dlopen (lt_dlhandle *phandle, const char *filename,
364 lt_dladvise advise, const lt_dlvtable *vtable)
365{
366 lt_dlhandle handle = handles;
367 const char * saved_error = 0;
368 int errors = 0;
369
370#ifdef LT_DEBUG_LOADERS
371 fprintf (stderr, "tryall_dlopen (%s, %s)\n",
372 filename ? filename : "(null)",
373 vtable ? vtable->name : "(ALL)");
374#endif
375
376 LT__GETERROR (saved_error);
377
378 /* check whether the module was already opened */
379 for (;handle; handle = handle->next)
380 {
381 if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */
382 || (handle->info.filename && filename
383 && streq (handle->info.filename, filename)))
384 {
385 break;
386 }
387 }
388
389 if (handle)
390 {
391 ++handle->info.ref_count;
392 *phandle = handle;
393 goto done;
394 }
395
396 handle = *phandle;
397 if (filename)
398 {
399 /* Comment out the check of file permissions using access.
400 This call seems to always return -1 with error EACCES.
401 */
402 /* We need to catch missing file errors early so that
403 file_not_found() can detect what happened.
404 if (access (filename, R_OK) != 0)
405 {
406 LT__SETERROR (FILE_NOT_FOUND);
407 ++errors;
408 goto done;
409 } */
410
411 handle->info.filename = lt__strdup (filename);
412 if (!handle->info.filename)
413 {
414 ++errors;
415 goto done;
416 }
417 }
418 else
419 {
420 handle->info.filename = 0;
421 }
422
423 {
424 lt_dlloader loader = lt_dlloader_next (0);
425 const lt_dlvtable *loader_vtable;
426
427 do
428 {
429 if (vtable)
430 loader_vtable = vtable;
431 else
432 loader_vtable = lt_dlloader_get (loader);
433
434#ifdef LT_DEBUG_LOADERS
435 fprintf (stderr, "Calling %s->module_open (%s)\n",
436 (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)",
437 filename ? filename : "(null)");
438#endif
439 handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data,
440 filename, advise);
441#ifdef LT_DEBUG_LOADERS
442 fprintf (stderr, " Result: %s\n",
443 handle->module ? "Success" : "Failed");
444#endif
445
446 if (handle->module != 0)
447 {
448 if (advise)
449 {
450 handle->info.is_resident = advise->is_resident;
451 handle->info.is_symglobal = advise->is_symglobal;
452 handle->info.is_symlocal = advise->is_symlocal;
453 }
454 break;
455 }
456 }
457 while (!vtable && (loader = lt_dlloader_next (loader)));
458
459 /* If VTABLE was given but couldn't open the module, or VTABLE wasn't
460 given but we exhausted all loaders without opening the module, bail
461 out! */
462 if ((vtable && !handle->module)
463 || (!vtable && !loader))
464 {
465 FREE (handle->info.filename);
466 ++errors;
467 goto done;
468 }
469
470 handle->vtable = loader_vtable;
471 }
472
473 LT__SETERRORSTR (saved_error);
474
475 done:
476 return errors;
477}
478
479
480static int
481tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
482 const char *dirname, const char *dlname,
483 lt_dladvise advise)
484{
485 int error = 0;
486 char *filename = 0;
487 size_t filename_len = 0;
488 size_t dirname_len = LT_STRLEN (dirname);
489
490 assert (handle);
491 assert (dirname);
492 assert (dlname);
493#if defined(LT_DIRSEP_CHAR)
494 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
495 should make it into this function: */
496 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
497#endif
498
499 if (dirname_len > 0)
500 if (dirname[dirname_len -1] == '/')
501 --dirname_len;
502 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
503
504 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
505 The PREFIX (if any) is handled below. */
506 filename = MALLOC (char, filename_len + 1);
507 if (!filename)
508 return 1;
509
510 sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
511
512 /* Now that we have combined DIRNAME and MODULENAME, if there is
513 also a PREFIX to contend with, simply recurse with the arguments
514 shuffled. Otherwise, attempt to open FILENAME as a module. */
515 if (prefix)
516 {
517 error += tryall_dlopen_module (handle, (const char *) 0,
518 prefix, filename, advise);
519 }
520 else if (tryall_dlopen (handle, filename, advise, 0) != 0)
521 {
522 ++error;
523 }
524
525 FREE (filename);
526 return error;
527}
528
529static int
530find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
531 const char *dlname, const char *old_name, int installed,
532 lt_dladvise advise)
533{
534 /* Try to open the old library first; if it was dlpreopened,
535 we want the preopened version of it, even if a dlopenable
536 module is available. */
cristy1f9e1ed2009-11-18 04:09:38 +0000537 if (old_name && tryall_dlopen (handle, old_name,
538 advise, lt_dlloader_find ("lt_preopen") ) == 0)
cristy3ed852e2009-09-05 21:47:34 +0000539 {
540 return 0;
541 }
542
543 /* Try to open the dynamic library. */
544 if (dlname)
545 {
546 /* try to open the installed module */
547 if (installed && libdir)
548 {
549 if (tryall_dlopen_module (handle, (const char *) 0,
550 libdir, dlname, advise) == 0)
551 return 0;
552 }
553
554 /* try to open the not-installed module */
555 if (!installed)
556 {
557 if (tryall_dlopen_module (handle, dir, objdir,
558 dlname, advise) == 0)
559 return 0;
560 }
561
562 /* maybe it was moved to another directory */
563 {
564 if (dir && (tryall_dlopen_module (handle, (const char *) 0,
565 dir, dlname, advise) == 0))
566 return 0;
567 }
568 }
569
570 return 1;
571}
572
573
574static int
575canonicalize_path (const char *path, char **pcanonical)
576{
577 char *canonical = 0;
578
579 assert (path && *path);
580 assert (pcanonical);
581
582 canonical = MALLOC (char, 1+ LT_STRLEN (path));
583 if (!canonical)
584 return 1;
585
586 {
587 size_t dest = 0;
588 size_t src;
589 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
590 {
591 /* Path separators are not copied to the beginning or end of
592 the destination, or if another separator would follow
593 immediately. */
594 if (path[src] == LT_PATHSEP_CHAR)
595 {
596 if ((dest == 0)
597 || (path[1+ src] == LT_PATHSEP_CHAR)
598 || (path[1+ src] == LT_EOS_CHAR))
599 continue;
600 }
601
602 /* Anything other than a directory separator is copied verbatim. */
603 if ((path[src] != '/')
604#if defined(LT_DIRSEP_CHAR)
605 && (path[src] != LT_DIRSEP_CHAR)
606#endif
607 )
608 {
609 canonical[dest++] = path[src];
610 }
611 /* Directory separators are converted and copied only if they are
612 not at the end of a path -- i.e. before a path separator or
613 NULL terminator. */
614 else if ((path[1+ src] != LT_PATHSEP_CHAR)
615 && (path[1+ src] != LT_EOS_CHAR)
616#if defined(LT_DIRSEP_CHAR)
617 && (path[1+ src] != LT_DIRSEP_CHAR)
618#endif
619 && (path[1+ src] != '/'))
620 {
621 canonical[dest++] = '/';
622 }
623 }
624
625 /* Add an end-of-string marker at the end. */
626 canonical[dest] = LT_EOS_CHAR;
627 }
628
629 /* Assign new value. */
630 *pcanonical = canonical;
631
632 return 0;
633}
634
635static int
636argzize_path (const char *path, char **pargz, size_t *pargz_len)
637{
638 error_t error;
639
640 assert (path);
641 assert (pargz);
642 assert (pargz_len);
643
644 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
645 {
646 switch (error)
647 {
648 case ENOMEM:
649 LT__SETERROR (NO_MEMORY);
650 break;
651 default:
652 LT__SETERROR (UNKNOWN);
653 break;
654 }
655
656 return 1;
657 }
658
659 return 0;
660}
661
662/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
663 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
664 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
665 it is appended to each SEARCH_PATH element before FUNC is called. */
666static int
667foreach_dirinpath (const char *search_path, const char *base_name,
668 foreach_callback_func *func, void *data1, void *data2)
669{
670 int result = 0;
671 size_t filenamesize = 0;
672 size_t lenbase = LT_STRLEN (base_name);
673 size_t argz_len = 0;
674 char *argz = 0;
675 char *filename = 0;
676 char *canonical = 0;
677
678 if (!search_path || !*search_path)
679 {
680 LT__SETERROR (FILE_NOT_FOUND);
681 goto cleanup;
682 }
683
684 if (canonicalize_path (search_path, &canonical) != 0)
685 goto cleanup;
686
687 if (argzize_path (canonical, &argz, &argz_len) != 0)
688 goto cleanup;
689
690 {
691 char *dir_name = 0;
692 while ((dir_name = argz_next (argz, argz_len, dir_name)))
693 {
694 size_t lendir = LT_STRLEN (dir_name);
695
696 if (1+ lendir + lenbase >= filenamesize)
697 {
698 FREE (filename);
699 filenamesize = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */
700 filename = MALLOC (char, filenamesize);
701 if (!filename)
702 goto cleanup;
703 }
704
705 assert (filenamesize > lendir);
706 strcpy (filename, dir_name);
707
708 if (base_name && *base_name)
709 {
710 if (filename[lendir -1] != '/')
711 filename[lendir++] = '/';
712 strcpy (filename +lendir, base_name);
713 }
714
715 if ((result = (*func) (filename, data1, data2)))
716 {
717 break;
718 }
719 }
720 }
721
722 cleanup:
723 FREE (argz);
724 FREE (canonical);
725 FREE (filename);
726
727 return result;
728}
729
730/* If FILEPATH can be opened, store the name of the directory component
731 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
732 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
733static int
734find_file_callback (char *filename, void *data1, void *data2)
735{
736 char **pdir = (char **) data1;
737 FILE **pfile = (FILE **) data2;
738 int is_done = 0;
739
740 assert (filename && *filename);
741 assert (pdir);
742 assert (pfile);
743
744 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
745 {
746 char *dirend = strrchr (filename, '/');
747
748 if (dirend > filename)
749 *dirend = LT_EOS_CHAR;
750
751 FREE (*pdir);
752 *pdir = lt__strdup (filename);
753 is_done = (*pdir == 0) ? -1 : 1;
754 }
755
756 return is_done;
757}
758
759static FILE *
760find_file (const char *search_path, const char *base_name, char **pdir)
761{
762 FILE *file = 0;
763
764 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
765
766 return file;
767}
768
769static int
770find_handle_callback (char *filename, void *data, void *data2)
771{
772 lt_dlhandle *phandle = (lt_dlhandle *) data;
773 int notfound = access (filename, R_OK);
774 lt_dladvise advise = (lt_dladvise) data2;
775
776 /* Bail out if file cannot be read... */
777 if (notfound)
778 return 0;
779
780 /* Try to dlopen the file, but do not continue searching in any
781 case. */
782 if (tryall_dlopen (phandle, filename, advise, 0) != 0)
783 *phandle = 0;
784
785 return 1;
786}
787
788/* If HANDLE was found return it, otherwise return 0. If HANDLE was
789 found but could not be opened, *HANDLE will be set to 0. */
790static lt_dlhandle *
791find_handle (const char *search_path, const char *base_name,
792 lt_dlhandle *phandle, lt_dladvise advise)
793{
794 if (!search_path)
795 return 0;
796
797 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
798 phandle, advise))
799 return 0;
800
801 return phandle;
802}
803
804#if !defined(LTDL_DLOPEN_DEPLIBS)
805static int
806load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs)
807{
808 handle->depcount = 0;
809 return 0;
810}
811
812#else /* defined(LTDL_DLOPEN_DEPLIBS) */
813static int
814load_deplibs (lt_dlhandle handle, char *deplibs)
815{
816 char *p, *save_search_path = 0;
817 int depcount = 0;
818 int i;
819 char **names = 0;
820 int errors = 0;
821
822 handle->depcount = 0;
823
824 if (!deplibs)
825 {
826 return errors;
827 }
828 ++errors;
829
830 if (user_search_path)
831 {
832 save_search_path = lt__strdup (user_search_path);
833 if (!save_search_path)
834 goto cleanup;
835 }
836
837 /* extract search paths and count deplibs */
838 p = deplibs;
839 while (*p)
840 {
841 if (!isspace ((unsigned char) *p))
842 {
843 char *end = p+1;
844 while (*end && !isspace((unsigned char) *end))
845 {
846 ++end;
847 }
848
849 if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
850 {
851 char save = *end;
852 *end = 0; /* set a temporary string terminator */
853 if (lt_dladdsearchdir(p+2))
854 {
855 goto cleanup;
856 }
857 *end = save;
858 }
859 else
860 {
861 ++depcount;
862 }
863
864 p = end;
865 }
866 else
867 {
868 ++p;
869 }
870 }
871
872
873 if (!depcount)
874 {
875 errors = 0;
876 goto cleanup;
877 }
878
879 names = MALLOC (char *, depcount);
880 if (!names)
881 goto cleanup;
882
883 /* now only extract the actual deplibs */
884 depcount = 0;
885 p = deplibs;
886 while (*p)
887 {
888 if (isspace ((unsigned char) *p))
889 {
890 ++p;
891 }
892 else
893 {
894 char *end = p+1;
895 while (*end && !isspace ((unsigned char) *end))
896 {
897 ++end;
898 }
899
900 if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
901 {
902 char *name;
903 char save = *end;
904 *end = 0; /* set a temporary string terminator */
905 if (strncmp(p, "-l", 2) == 0)
906 {
907 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
908 name = MALLOC (char, 1+ name_len);
909 if (name)
910 sprintf (name, "lib%s", p+2);
911 }
912 else
913 name = lt__strdup(p);
914
915 if (!name)
916 goto cleanup_names;
917
918 names[depcount++] = name;
919 *end = save;
920 }
921 p = end;
922 }
923 }
924
925 /* load the deplibs (in reverse order)
926 At this stage, don't worry if the deplibs do not load correctly,
927 they may already be statically linked into the loading application
928 for instance. There will be a more enlightening error message
929 later on if the loaded module cannot resolve all of its symbols. */
930 if (depcount)
931 {
932 lt_dlhandle cur = handle;
933 int j = 0;
934
935 cur->deplibs = MALLOC (lt_dlhandle, depcount);
936 if (!cur->deplibs)
937 goto cleanup_names;
938
939 for (i = 0; i < depcount; ++i)
940 {
941 cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
942 if (cur->deplibs[j])
943 {
944 ++j;
945 }
946 }
947
948 cur->depcount = j; /* Number of successfully loaded deplibs */
949 errors = 0;
950 }
951
952 cleanup_names:
953 for (i = 0; i < depcount; ++i)
954 {
955 FREE (names[i]);
956 }
957
958 cleanup:
959 FREE (names);
960 /* restore the old search path */
961 if (save_search_path) {
962 MEMREASSIGN (user_search_path, save_search_path);
963 }
964
965 return errors;
966}
967#endif /* defined(LTDL_DLOPEN_DEPLIBS) */
968
969static int
970unload_deplibs (lt_dlhandle handle)
971{
972 int i;
973 int errors = 0;
974 lt_dlhandle cur = handle;
975
976 if (cur->depcount)
977 {
978 for (i = 0; i < cur->depcount; ++i)
979 {
980 if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
981 {
982 errors += lt_dlclose (cur->deplibs[i]);
983 }
984 }
985 FREE (cur->deplibs);
986 }
987
988 return errors;
989}
990
991static int
992trim (char **dest, const char *str)
993{
994 /* remove the leading and trailing "'" from str
995 and store the result in dest */
996 const char *end = strrchr (str, '\'');
997 size_t len = LT_STRLEN (str);
998 char *tmp;
999
1000 FREE (*dest);
1001
cristy98dddb52010-11-04 00:30:15 +00001002 if (!end || end == str)
cristy3ed852e2009-09-05 21:47:34 +00001003 return 1;
1004
1005 if (len > 3 && str[0] == '\'')
1006 {
1007 tmp = MALLOC (char, end - str);
1008 if (!tmp)
1009 return 1;
1010
1011 memcpy(tmp, &str[1], (end - str) - 1);
1012 tmp[(end - str) - 1] = LT_EOS_CHAR;
1013 *dest = tmp;
1014 }
1015 else
1016 {
1017 *dest = 0;
1018 }
1019
1020 return 0;
1021}
1022
1023/* Read the .la file FILE. */
1024static int
1025parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs,
1026 char **old_name, int *installed)
1027{
1028 int errors = 0;
1029 size_t line_len = LT_FILENAME_MAX;
1030 char * line = MALLOC (char, line_len);
1031
1032 if (!line)
1033 {
1034 LT__SETERROR (FILE_NOT_FOUND);
1035 return 1;
1036 }
1037
1038 while (!feof (file))
1039 {
1040 line[line_len-2] = '\0';
1041 if (!fgets (line, (int) line_len, file))
1042 {
1043 break;
1044 }
1045
1046 /* Handle the case where we occasionally need to read a line
cristy85278ed2010-05-31 15:10:05 +00001047 that is longer than the initial buffer size.
cristy3ed852e2009-09-05 21:47:34 +00001048 Behave even if the file contains NUL bytes due to corruption. */
1049 while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file))
1050 {
1051 line = REALLOC (char, line, line_len *2);
1052 if (!line)
1053 {
1054 ++errors;
1055 goto cleanup;
1056 }
1057 line[line_len * 2 - 2] = '\0';
1058 if (!fgets (&line[line_len -1], (int) line_len +1, file))
1059 {
1060 break;
1061 }
1062 line_len *= 2;
1063 }
1064
1065 if (line[0] == '\n' || line[0] == '#')
1066 {
1067 continue;
1068 }
1069
1070#undef STR_DLNAME
1071#define STR_DLNAME "dlname="
1072 if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
1073 {
1074 errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]);
1075 }
1076
1077#undef STR_OLD_LIBRARY
1078#define STR_OLD_LIBRARY "old_library="
1079 else if (strncmp (line, STR_OLD_LIBRARY,
1080 sizeof (STR_OLD_LIBRARY) - 1) == 0)
1081 {
1082 errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
1083 }
cristy98dddb52010-11-04 00:30:15 +00001084
1085 /* Windows native tools do not understand the POSIX paths we store
1086 in libdir. */
cristy3ed852e2009-09-05 21:47:34 +00001087#undef STR_LIBDIR
1088#define STR_LIBDIR "libdir="
1089 else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
1090 {
1091 errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]);
cristy11def542011-02-20 00:15:09 +00001092#ifdef __WINDOWS__
1093 /* Disallow following unix-style paths on MinGW. */
1094 if (*libdir && (**libdir == '/' || **libdir == '\\'))
1095 **libdir = '\0';
cristy98dddb52010-11-04 00:30:15 +00001096#endif
cristy11def542011-02-20 00:15:09 +00001097 }
cristy3ed852e2009-09-05 21:47:34 +00001098
1099#undef STR_DL_DEPLIBS
1100#define STR_DL_DEPLIBS "dependency_libs="
1101 else if (strncmp (line, STR_DL_DEPLIBS,
1102 sizeof (STR_DL_DEPLIBS) - 1) == 0)
1103 {
1104 errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
1105 }
1106 else if (streq (line, "installed=yes\n"))
1107 {
1108 *installed = 1;
1109 }
1110 else if (streq (line, "installed=no\n"))
1111 {
1112 *installed = 0;
1113 }
1114
1115#undef STR_LIBRARY_NAMES
1116#define STR_LIBRARY_NAMES "library_names="
1117 else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES,
1118 sizeof (STR_LIBRARY_NAMES) - 1) == 0)
1119 {
1120 char *last_libname;
1121 errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
1122 if (!errors
1123 && *dlname
1124 && (last_libname = strrchr (*dlname, ' ')) != 0)
1125 {
1126 last_libname = lt__strdup (last_libname + 1);
1127 if (!last_libname)
1128 {
1129 ++errors;
1130 goto cleanup;
1131 }
1132 MEMREASSIGN (*dlname, last_libname);
1133 }
1134 }
1135
1136 if (errors)
1137 break;
1138 }
1139cleanup:
1140 FREE (line);
1141 return errors;
1142}
1143
1144
1145/* Try to open FILENAME as a module. */
1146static int
1147try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
1148 lt_dladvise advise)
1149{
1150 const char * saved_error = 0;
1151 char * archive_name = 0;
1152 char * canonical = 0;
1153 char * base_name = 0;
1154 char * dir = 0;
1155 char * name = 0;
1156 char * attempt = 0;
1157 int errors = 0;
1158 lt_dlhandle newhandle;
1159
1160 assert (phandle);
1161 assert (*phandle == 0);
1162
1163#ifdef LT_DEBUG_LOADERS
1164 fprintf (stderr, "try_dlopen (%s, %s)\n",
1165 filename ? filename : "(null)",
1166 ext ? ext : "(null)");
1167#endif
1168
1169 LT__GETERROR (saved_error);
1170
1171 /* dlopen self? */
1172 if (!filename)
1173 {
1174 *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1175 if (*phandle == 0)
1176 return 1;
1177
1178 newhandle = *phandle;
1179
1180 /* lt_dlclose()ing yourself is very bad! Disallow it. */
1181 newhandle->info.is_resident = 1;
1182
1183 if (tryall_dlopen (&newhandle, 0, advise, 0) != 0)
1184 {
1185 FREE (*phandle);
1186 return 1;
1187 }
1188
1189 goto register_handle;
1190 }
1191
1192 assert (filename && *filename);
1193
1194 if (ext)
1195 {
1196 attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1);
1197 if (!attempt)
1198 return 1;
1199
1200 sprintf(attempt, "%s%s", filename, ext);
1201 }
1202 else
1203 {
1204 attempt = lt__strdup (filename);
1205 if (!attempt)
1206 return 1;
1207 }
1208
1209 /* Doing this immediately allows internal functions to safely
1210 assume only canonicalized paths are passed. */
1211 if (canonicalize_path (attempt, &canonical) != 0)
1212 {
1213 ++errors;
1214 goto cleanup;
1215 }
1216
1217 /* If the canonical module name is a path (relative or absolute)
1218 then split it into a directory part and a name part. */
1219 base_name = strrchr (canonical, '/');
1220 if (base_name)
1221 {
1222 size_t dirlen = (1+ base_name) - canonical;
1223
1224 dir = MALLOC (char, 1+ dirlen);
1225 if (!dir)
1226 {
1227 ++errors;
1228 goto cleanup;
1229 }
1230
1231 strncpy (dir, canonical, dirlen);
1232 dir[dirlen] = LT_EOS_CHAR;
1233
1234 ++base_name;
1235 }
1236 else
1237 MEMREASSIGN (base_name, canonical);
1238
1239 assert (base_name && *base_name);
1240
1241 ext = strrchr (base_name, '.');
1242 if (!ext)
1243 {
1244 ext = base_name + LT_STRLEN (base_name);
1245 }
1246
1247 /* extract the module name from the file name */
1248 name = MALLOC (char, ext - base_name + 1);
1249 if (!name)
1250 {
1251 ++errors;
1252 goto cleanup;
1253 }
1254
1255 /* canonicalize the module name */
1256 {
1257 int i;
1258 for (i = 0; i < ext - base_name; ++i)
1259 {
1260 if (isalnum ((unsigned char)(base_name[i])))
1261 {
1262 name[i] = base_name[i];
1263 }
1264 else
1265 {
1266 name[i] = '_';
1267 }
1268 }
1269 name[ext - base_name] = LT_EOS_CHAR;
1270 }
1271
1272 /* Before trawling through the filesystem in search of a module,
1273 check whether we are opening a preloaded module. */
1274 if (!dir)
1275 {
1276 const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen");
1277
1278 if (vtable)
1279 {
cristy11def542011-02-20 00:15:09 +00001280 /* libprefix + name + "." + libext + NULL */
1281 archive_name = MALLOC (char, strlen (libprefix) + LT_STRLEN (name) + strlen (libext) + 2);
cristy3ed852e2009-09-05 21:47:34 +00001282 *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1283
1284 if ((*phandle == NULL) || (archive_name == NULL))
1285 {
1286 ++errors;
1287 goto cleanup;
1288 }
1289 newhandle = *phandle;
1290
1291 /* Preloaded modules are always named according to their old
1292 archive name. */
cristy11def542011-02-20 00:15:09 +00001293 if (strncmp(name, "lib", 3) == 0)
1294 {
1295 sprintf (archive_name, "%s%s.%s", libprefix, name + 3, libext);
1296 }
1297 else
1298 {
1299 sprintf (archive_name, "%s.%s", name, libext);
1300 }
cristy3ed852e2009-09-05 21:47:34 +00001301
1302 if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0)
1303 {
1304 goto register_handle;
1305 }
1306
1307 /* If we're still here, there was no matching preloaded module,
1308 so put things back as we found them, and continue searching. */
1309 FREE (*phandle);
1310 newhandle = NULL;
1311 }
1312 }
1313
1314 /* If we are allowing only preloaded modules, and we didn't find
1315 anything yet, give up on the search here. */
1316 if (advise && advise->try_preload_only)
1317 {
1318 goto cleanup;
1319 }
1320
1321 /* Check whether we are opening a libtool module (.la extension). */
1322 if (ext && streq (ext, archive_ext))
1323 {
1324 /* this seems to be a libtool module */
1325 FILE * file = 0;
1326 char * dlname = 0;
1327 char * old_name = 0;
1328 char * libdir = 0;
1329 char * deplibs = 0;
1330
1331 /* if we can't find the installed flag, it is probably an
1332 installed libtool archive, produced with an old version
1333 of libtool */
1334 int installed = 1;
1335
1336 /* Now try to open the .la file. If there is no directory name
1337 component, try to find it first in user_search_path and then other
1338 prescribed paths. Otherwise (or in any case if the module was not
1339 yet found) try opening just the module name as passed. */
1340 if (!dir)
1341 {
1342 const char *search_path = user_search_path;
1343
1344 if (search_path)
1345 file = find_file (user_search_path, base_name, &dir);
1346
1347 if (!file)
1348 {
1349 search_path = getenv (LTDL_SEARCHPATH_VAR);
1350 if (search_path)
1351 file = find_file (search_path, base_name, &dir);
1352 }
1353
1354#if defined(LT_MODULE_PATH_VAR)
1355 if (!file)
1356 {
1357 search_path = getenv (LT_MODULE_PATH_VAR);
1358 if (search_path)
1359 file = find_file (search_path, base_name, &dir);
1360 }
1361#endif
1362#if defined(LT_DLSEARCH_PATH)
1363 if (!file && *sys_dlsearch_path)
1364 {
1365 file = find_file (sys_dlsearch_path, base_name, &dir);
1366 }
1367#endif
1368 }
cristy1f9e1ed2009-11-18 04:09:38 +00001369 else
cristy3ed852e2009-09-05 21:47:34 +00001370 {
1371 file = fopen (attempt, LT_READTEXT_MODE);
1372 }
1373
1374 /* If we didn't find the file by now, it really isn't there. Set
1375 the status flag, and bail out. */
1376 if (!file)
1377 {
1378 LT__SETERROR (FILE_NOT_FOUND);
1379 ++errors;
1380 goto cleanup;
1381 }
1382
1383 /* read the .la file */
1384 if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
1385 &old_name, &installed) != 0)
1386 ++errors;
1387
1388 fclose (file);
1389
1390 /* allocate the handle */
1391 *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1392 if (*phandle == 0)
1393 ++errors;
1394
1395 if (errors)
1396 {
1397 FREE (dlname);
1398 FREE (old_name);
1399 FREE (libdir);
1400 FREE (deplibs);
1401 FREE (*phandle);
1402 goto cleanup;
1403 }
1404
1405 assert (*phandle);
1406
1407 if (load_deplibs (*phandle, deplibs) == 0)
1408 {
1409 newhandle = *phandle;
1410 /* find_module may replace newhandle */
1411 if (find_module (&newhandle, dir, libdir, dlname, old_name,
1412 installed, advise))
1413 {
1414 unload_deplibs (*phandle);
1415 ++errors;
1416 }
1417 }
1418 else
1419 {
1420 ++errors;
1421 }
1422
1423 FREE (dlname);
1424 FREE (old_name);
1425 FREE (libdir);
1426 FREE (deplibs);
1427
1428 if (errors)
1429 {
1430 FREE (*phandle);
1431 goto cleanup;
1432 }
1433
1434 if (*phandle != newhandle)
1435 {
1436 unload_deplibs (*phandle);
1437 }
1438 }
1439 else
1440 {
1441 /* not a libtool module */
1442 *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1443 if (*phandle == 0)
1444 {
1445 ++errors;
1446 goto cleanup;
1447 }
1448
1449 newhandle = *phandle;
1450
1451 /* If the module has no directory name component, try to find it
1452 first in user_search_path and then other prescribed paths.
1453 Otherwise (or in any case if the module was not yet found) try
1454 opening just the module name as passed. */
1455 if ((dir || (!find_handle (user_search_path, base_name,
1456 &newhandle, advise)
1457 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
1458 &newhandle, advise)
1459#if defined(LT_MODULE_PATH_VAR)
1460 && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name,
1461 &newhandle, advise)
1462#endif
1463#if defined(LT_DLSEARCH_PATH)
1464 && !find_handle (sys_dlsearch_path, base_name,
1465 &newhandle, advise)
1466#endif
1467 )))
1468 {
1469 if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0)
1470 {
1471 newhandle = NULL;
1472 }
1473 }
1474
1475 if (!newhandle)
1476 {
1477 FREE (*phandle);
1478 ++errors;
1479 goto cleanup;
1480 }
1481 }
1482
1483 register_handle:
1484 MEMREASSIGN (*phandle, newhandle);
1485
1486 if ((*phandle)->info.ref_count == 0)
1487 {
1488 (*phandle)->info.ref_count = 1;
1489 MEMREASSIGN ((*phandle)->info.name, name);
1490
1491 (*phandle)->next = handles;
1492 handles = *phandle;
1493 }
1494
1495 LT__SETERRORSTR (saved_error);
1496
1497 cleanup:
1498 FREE (dir);
1499 FREE (attempt);
1500 FREE (name);
1501 if (!canonical) /* was MEMREASSIGNed */
1502 FREE (base_name);
1503 FREE (canonical);
1504 FREE (archive_name);
1505
1506 return errors;
1507}
1508
1509
cristy98dddb52010-11-04 00:30:15 +00001510/* If the last error message stored was `FILE_NOT_FOUND', then return
cristy3ed852e2009-09-05 21:47:34 +00001511 non-zero. */
1512static int
1513file_not_found (void)
1514{
1515 const char *error = 0;
1516
1517 LT__GETERROR (error);
1518 if (error == LT__STRERROR (FILE_NOT_FOUND))
1519 return 1;
1520
1521 return 0;
1522}
1523
1524
1525/* Unless FILENAME already bears a suitable library extension, then
1526 return 0. */
1527static int
1528has_library_ext (const char *filename)
1529{
cristy98dddb52010-11-04 00:30:15 +00001530 const char * ext = 0;
cristy3ed852e2009-09-05 21:47:34 +00001531
1532 assert (filename);
1533
cristy7e0a5dc2010-10-17 19:16:33 +00001534 ext = strrchr (filename, '.');
cristy3ed852e2009-09-05 21:47:34 +00001535
1536 if (ext && ((streq (ext, archive_ext))
1537#if defined(LT_MODULE_EXT)
1538 || (streq (ext, shlib_ext))
1539#endif
1540 ))
1541 {
1542 return 1;
1543 }
1544
1545 return 0;
1546}
1547
1548
1549/* Initialise and configure a user lt_dladvise opaque object. */
1550
1551int
1552lt_dladvise_init (lt_dladvise *padvise)
1553{
1554 lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise));
1555 *padvise = advise;
1556 return (advise ? 0 : 1);
1557}
1558
1559int
1560lt_dladvise_destroy (lt_dladvise *padvise)
1561{
1562 if (padvise)
1563 FREE(*padvise);
1564 return 0;
1565}
1566
1567int
1568lt_dladvise_ext (lt_dladvise *padvise)
1569{
1570 assert (padvise && *padvise);
1571 (*padvise)->try_ext = 1;
1572 return 0;
1573}
1574
1575int
1576lt_dladvise_resident (lt_dladvise *padvise)
1577{
1578 assert (padvise && *padvise);
1579 (*padvise)->is_resident = 1;
1580 return 0;
1581}
1582
1583int
1584lt_dladvise_local (lt_dladvise *padvise)
1585{
1586 assert (padvise && *padvise);
1587 (*padvise)->is_symlocal = 1;
1588 return 0;
1589}
1590
1591int
1592lt_dladvise_global (lt_dladvise *padvise)
1593{
1594 assert (padvise && *padvise);
1595 (*padvise)->is_symglobal = 1;
1596 return 0;
1597}
1598
1599int
1600lt_dladvise_preload (lt_dladvise *padvise)
1601{
1602 assert (padvise && *padvise);
1603 (*padvise)->try_preload_only = 1;
1604 return 0;
1605}
1606
1607/* Libtool-1.5.x interface for loading a new module named FILENAME. */
1608lt_dlhandle
1609lt_dlopen (const char *filename)
1610{
1611 return lt_dlopenadvise (filename, NULL);
1612}
1613
1614
1615/* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
1616 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
1617 and if a file is still not found try again with MODULE_EXT appended
1618 instead. */
1619lt_dlhandle
1620lt_dlopenext (const char *filename)
1621{
1622 lt_dlhandle handle = 0;
1623 lt_dladvise advise;
1624
1625 if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise))
1626 handle = lt_dlopenadvise (filename, advise);
1627
1628 lt_dladvise_destroy (&advise);
1629 return handle;
1630}
1631
1632
1633lt_dlhandle
1634lt_dlopenadvise (const char *filename, lt_dladvise advise)
1635{
1636 lt_dlhandle handle = 0;
1637 int errors = 0;
cristy98dddb52010-11-04 00:30:15 +00001638 const char * saved_error = 0;
1639
1640 LT__GETERROR (saved_error);
cristy3ed852e2009-09-05 21:47:34 +00001641
1642 /* Can't have symbols hidden and visible at the same time! */
1643 if (advise && advise->is_symlocal && advise->is_symglobal)
1644 {
1645 LT__SETERROR (CONFLICTING_FLAGS);
1646 return 0;
1647 }
1648
1649 if (!filename
1650 || !advise
1651 || !advise->try_ext
1652 || has_library_ext (filename))
1653 {
1654 /* Just incase we missed a code path in try_dlopen() that reports
1655 an error, but forgot to reset handle... */
1656 if (try_dlopen (&handle, filename, NULL, advise) != 0)
1657 return 0;
1658
1659 return handle;
1660 }
1661 else if (filename && *filename)
1662 {
1663
1664 /* First try appending ARCHIVE_EXT. */
1665 errors += try_dlopen (&handle, filename, archive_ext, advise);
1666
1667 /* If we found FILENAME, stop searching -- whether we were able to
1668 load the file as a module or not. If the file exists but loading
1669 failed, it is better to return an error message here than to
1670 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
1671 in the module search path. */
1672 if (handle || ((errors > 0) && !file_not_found ()))
1673 return handle;
1674
1675#if defined(LT_MODULE_EXT)
1676 /* Try appending SHLIB_EXT. */
cristy98dddb52010-11-04 00:30:15 +00001677 LT__SETERRORSTR (saved_error);
cristy3ed852e2009-09-05 21:47:34 +00001678 errors = try_dlopen (&handle, filename, shlib_ext, advise);
1679
1680 /* As before, if the file was found but loading failed, return now
1681 with the current error message. */
1682 if (handle || ((errors > 0) && !file_not_found ()))
1683 return handle;
1684#endif
1685 }
1686
1687 /* Still here? Then we really did fail to locate any of the file
1688 names we tried. */
1689 LT__SETERROR (FILE_NOT_FOUND);
1690 return 0;
1691}
1692
1693
1694static int
1695lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
1696 const char *entry)
1697{
1698 error_t error;
1699
1700 /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
1701 pargz_len, NULL, entry) failed with EINVAL. */
1702 if (before)
1703 error = argz_insert (pargz, pargz_len, before, entry);
1704 else
1705 error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
1706
1707 if (error)
1708 {
1709 switch (error)
1710 {
1711 case ENOMEM:
1712 LT__SETERROR (NO_MEMORY);
1713 break;
1714 default:
1715 LT__SETERROR (UNKNOWN);
1716 break;
1717 }
1718 return 1;
1719 }
1720
1721 return 0;
1722}
1723
1724static int
1725lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
1726{
1727 char *before = 0;
1728
1729 assert (pargz);
1730 assert (pargz_len);
1731 assert (entry && *entry);
1732
1733 if (*pargz)
1734 while ((before = argz_next (*pargz, *pargz_len, before)))
1735 {
1736 int cmp = strcmp (entry, before);
1737
1738 if (cmp < 0) break;
1739 if (cmp == 0) return 0; /* No duplicates! */
1740 }
1741
1742 return lt_argz_insert (pargz, pargz_len, before, entry);
1743}
1744
1745static int
1746lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
1747 struct dirent *dp)
1748{
1749 char *buf = 0;
1750 size_t buf_len = 0;
1751 char *end = 0;
1752 size_t end_offset = 0;
1753 size_t dir_len = 0;
1754 int errors = 0;
1755
1756 assert (pargz);
1757 assert (pargz_len);
1758 assert (dp);
1759
1760 dir_len = LT_STRLEN (dirnam);
1761 end = dp->d_name + D_NAMLEN(dp);
1762
1763 /* Ignore version numbers. */
1764 {
1765 char *p;
1766 for (p = end; p -1 > dp->d_name; --p)
1767 if (strchr (".0123456789", p[-1]) == 0)
1768 break;
1769
1770 if (*p == '.')
1771 end = p;
1772 }
1773
1774 /* Ignore filename extension. */
1775 {
1776 char *p;
1777 for (p = end -1; p > dp->d_name; --p)
1778 if (*p == '.')
1779 {
1780 end = p;
1781 break;
1782 }
1783 }
1784
1785 /* Prepend the directory name. */
1786 end_offset = end - dp->d_name;
1787 buf_len = dir_len + 1+ end_offset;
1788 buf = MALLOC (char, 1+ buf_len);
1789 if (!buf)
1790 return ++errors;
1791
1792 assert (buf);
1793
1794 strcpy (buf, dirnam);
1795 strcat (buf, "/");
1796 strncat (buf, dp->d_name, end_offset);
1797 buf[buf_len] = LT_EOS_CHAR;
1798
1799 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
1800 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
1801 ++errors;
1802
1803 FREE (buf);
1804
1805 return errors;
1806}
1807
1808static int
1809list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
1810{
1811 DIR *dirp = 0;
1812 int errors = 0;
1813
1814 assert (dirnam && *dirnam);
1815 assert (pargz);
1816 assert (pargz_len);
1817 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
1818
1819 dirp = opendir (dirnam);
1820 if (dirp)
1821 {
1822 struct dirent *dp = 0;
1823
1824 while ((dp = readdir (dirp)))
1825 if (dp->d_name[0] != '.')
1826 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
1827 {
1828 ++errors;
1829 break;
1830 }
1831
1832 closedir (dirp);
1833 }
1834 else
1835 ++errors;
1836
1837 return errors;
1838}
1839
1840
1841/* If there are any files in DIRNAME, call the function passed in
1842 DATA1 (with the name of each file and DATA2 as arguments). */
1843static int
1844foreachfile_callback (char *dirname, void *data1, void *data2)
1845{
1846 file_worker_func *func = *(file_worker_func **) data1;
1847
1848 int is_done = 0;
1849 char *argz = 0;
1850 size_t argz_len = 0;
1851
1852 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
1853 goto cleanup;
1854 if (!argz)
1855 goto cleanup;
1856
1857 {
1858 char *filename = 0;
1859 while ((filename = argz_next (argz, argz_len, filename)))
1860 if ((is_done = (*func) (filename, data2)))
1861 break;
1862 }
1863
1864 cleanup:
1865 FREE (argz);
1866
1867 return is_done;
1868}
1869
1870
cristycee97112010-05-28 00:44:52 +00001871/* Call FUNC for each unique extensionless file in SEARCH_PATH, along
cristy3ed852e2009-09-05 21:47:34 +00001872 with DATA. The filenames passed to FUNC would be suitable for
1873 passing to lt_dlopenext. The extensions are stripped so that
1874 individual modules do not generate several entries (e.g. libfoo.la,
1875 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
1876 then the same directories that lt_dlopen would search are examined. */
1877int
1878lt_dlforeachfile (const char *search_path,
1879 int (*func) (const char *filename, void *data),
1880 void *data)
1881{
1882 int is_done = 0;
1883 file_worker_func **fpptr = &func;
1884
1885 if (search_path)
1886 {
1887 /* If a specific path was passed, search only the directories
1888 listed in it. */
1889 is_done = foreach_dirinpath (search_path, 0,
1890 foreachfile_callback, fpptr, data);
1891 }
1892 else
1893 {
1894 /* Otherwise search the default paths. */
1895 is_done = foreach_dirinpath (user_search_path, 0,
1896 foreachfile_callback, fpptr, data);
1897 if (!is_done)
1898 {
1899 is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
1900 foreachfile_callback, fpptr, data);
1901 }
1902
1903#if defined(LT_MODULE_PATH_VAR)
1904 if (!is_done)
1905 {
1906 is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
1907 foreachfile_callback, fpptr, data);
1908 }
1909#endif
1910#if defined(LT_DLSEARCH_PATH)
1911 if (!is_done && *sys_dlsearch_path)
1912 {
1913 is_done = foreach_dirinpath (sys_dlsearch_path, 0,
1914 foreachfile_callback, fpptr, data);
1915 }
1916#endif
1917 }
1918
1919 return is_done;
1920}
1921
1922int
1923lt_dlclose (lt_dlhandle handle)
1924{
1925 lt_dlhandle cur, last;
1926 int errors = 0;
1927
1928 /* check whether the handle is valid */
1929 last = cur = handles;
1930 while (cur && handle != cur)
1931 {
1932 last = cur;
1933 cur = cur->next;
1934 }
1935
1936 if (!cur)
1937 {
1938 LT__SETERROR (INVALID_HANDLE);
1939 ++errors;
1940 goto done;
1941 }
1942
1943 cur = handle;
1944 cur->info.ref_count--;
1945
1946 /* Note that even with resident modules, we must track the ref_count
1947 correctly incase the user decides to reset the residency flag
1948 later (even though the API makes no provision for that at the
1949 moment). */
1950 if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
1951 {
1952 lt_user_data data = cur->vtable->dlloader_data;
1953
1954 if (cur != handles)
1955 {
1956 last->next = cur->next;
1957 }
1958 else
1959 {
1960 handles = cur->next;
1961 }
1962
1963 errors += cur->vtable->module_close (data, cur->module);
1964 errors += unload_deplibs (handle);
1965
1966 /* It is up to the callers to free the data itself. */
1967 FREE (cur->interface_data);
1968
1969 FREE (cur->info.filename);
1970 FREE (cur->info.name);
1971 FREE (cur);
1972
1973 goto done;
1974 }
1975
1976 if (LT_DLIS_RESIDENT (handle))
1977 {
1978 LT__SETERROR (CLOSE_RESIDENT_MODULE);
1979 ++errors;
1980 }
1981
1982 done:
1983 return errors;
1984}
1985
1986void *
1987lt_dlsym (lt_dlhandle place, const char *symbol)
1988{
1989 size_t lensym;
1990 char lsym[LT_SYMBOL_LENGTH];
1991 char *sym;
1992 void *address;
1993 lt_user_data data;
1994 lt_dlhandle handle;
1995
1996 if (!place)
1997 {
1998 LT__SETERROR (INVALID_HANDLE);
1999 return 0;
2000 }
2001
2002 handle = place;
2003
2004 if (!symbol)
2005 {
2006 LT__SETERROR (SYMBOL_NOT_FOUND);
2007 return 0;
2008 }
2009
2010 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)
2011 + LT_STRLEN (handle->info.name);
2012
2013 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
2014 {
2015 sym = lsym;
2016 }
2017 else
2018 {
2019 sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
2020 if (!sym)
2021 {
2022 LT__SETERROR (BUFFER_OVERFLOW);
2023 return 0;
2024 }
2025 }
2026
2027 data = handle->vtable->dlloader_data;
2028 if (handle->info.name)
2029 {
2030 const char *saved_error;
2031
2032 LT__GETERROR (saved_error);
2033
2034 /* this is a libtool module */
2035 if (handle->vtable->sym_prefix)
2036 {
2037 strcpy(sym, handle->vtable->sym_prefix);
2038 strcat(sym, handle->info.name);
2039 }
2040 else
2041 {
2042 strcpy(sym, handle->info.name);
2043 }
2044
2045 strcat(sym, "_LTX_");
2046 strcat(sym, symbol);
2047
2048 /* try "modulename_LTX_symbol" */
2049 address = handle->vtable->find_sym (data, handle->module, sym);
2050 if (address)
2051 {
2052 if (sym != lsym)
2053 {
2054 FREE (sym);
2055 }
2056 return address;
2057 }
2058 LT__SETERRORSTR (saved_error);
2059 }
2060
2061 /* otherwise try "symbol" */
2062 if (handle->vtable->sym_prefix)
2063 {
2064 strcpy(sym, handle->vtable->sym_prefix);
2065 strcat(sym, symbol);
2066 }
2067 else
2068 {
2069 strcpy(sym, symbol);
2070 }
2071
2072 address = handle->vtable->find_sym (data, handle->module, sym);
2073 if (sym != lsym)
2074 {
2075 FREE (sym);
2076 }
2077
2078 return address;
2079}
2080
2081const char *
2082lt_dlerror (void)
2083{
2084 const char *error;
2085
2086 LT__GETERROR (error);
2087 LT__SETERRORSTR (0);
2088
cristy98dddb52010-11-04 00:30:15 +00002089 return error;
cristy3ed852e2009-09-05 21:47:34 +00002090}
2091
2092static int
2093lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
2094{
2095 int errors = 0;
2096 char *canonical = 0;
2097 char *argz = 0;
2098 size_t argz_len = 0;
2099
2100 assert (ppath);
2101 assert (dir && *dir);
2102
2103 if (canonicalize_path (dir, &canonical) != 0)
2104 {
2105 ++errors;
2106 goto cleanup;
2107 }
2108
2109 assert (canonical && *canonical);
2110
2111 /* If *PPATH is empty, set it to DIR. */
2112 if (*ppath == 0)
2113 {
2114 assert (!before); /* BEFORE cannot be set without PPATH. */
2115 assert (dir); /* Without DIR, don't call this function! */
2116
2117 *ppath = lt__strdup (dir);
2118 if (*ppath == 0)
2119 ++errors;
2120
2121 goto cleanup;
2122 }
2123
2124 assert (ppath && *ppath);
2125
2126 if (argzize_path (*ppath, &argz, &argz_len) != 0)
2127 {
2128 ++errors;
2129 goto cleanup;
2130 }
2131
2132 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
2133 if *PPATH is already canonicalized, and hence does not change length
2134 with respect to ARGZ. We canonicalize each entry as it is added to
2135 the search path, and don't call this function with (uncanonicalized)
2136 user paths, so this is a fair assumption. */
2137 if (before)
2138 {
2139 assert (*ppath <= before);
2140 assert ((int) (before - *ppath) <= (int) strlen (*ppath));
2141
2142 before = before - *ppath + argz;
2143 }
2144
2145 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
2146 {
2147 ++errors;
2148 goto cleanup;
2149 }
2150
2151 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
2152 MEMREASSIGN(*ppath, argz);
2153
2154 cleanup:
2155 FREE (argz);
2156 FREE (canonical);
2157
2158 return errors;
2159}
2160
2161int
2162lt_dladdsearchdir (const char *search_dir)
2163{
2164 int errors = 0;
2165
2166 if (search_dir && *search_dir)
2167 {
2168 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
2169 ++errors;
2170 }
2171
2172 return errors;
2173}
2174
2175int
2176lt_dlinsertsearchdir (const char *before, const char *search_dir)
2177{
2178 int errors = 0;
2179
2180 if (before)
2181 {
2182 if ((before < user_search_path)
2183 || (before >= user_search_path + LT_STRLEN (user_search_path)))
2184 {
2185 LT__SETERROR (INVALID_POSITION);
2186 return 1;
2187 }
2188 }
2189
2190 if (search_dir && *search_dir)
2191 {
2192 if (lt_dlpath_insertdir (&user_search_path,
2193 (char *) before, search_dir) != 0)
2194 {
2195 ++errors;
2196 }
2197 }
2198
2199 return errors;
2200}
2201
2202int
2203lt_dlsetsearchpath (const char *search_path)
2204{
2205 int errors = 0;
2206
2207 FREE (user_search_path);
2208
2209 if (!search_path || !LT_STRLEN (search_path))
2210 {
2211 return errors;
2212 }
2213
2214 if (canonicalize_path (search_path, &user_search_path) != 0)
2215 ++errors;
2216
2217 return errors;
2218}
2219
2220const char *
2221lt_dlgetsearchpath (void)
2222{
2223 const char *saved_path;
2224
2225 saved_path = user_search_path;
2226
2227 return saved_path;
2228}
2229
2230int
2231lt_dlmakeresident (lt_dlhandle handle)
2232{
2233 int errors = 0;
2234
2235 if (!handle)
2236 {
2237 LT__SETERROR (INVALID_HANDLE);
2238 ++errors;
2239 }
2240 else
2241 {
2242 handle->info.is_resident = 1;
2243 }
2244
2245 return errors;
2246}
2247
2248int
2249lt_dlisresident (lt_dlhandle handle)
2250{
2251 if (!handle)
2252 {
2253 LT__SETERROR (INVALID_HANDLE);
2254 return -1;
2255 }
2256
2257 return LT_DLIS_RESIDENT (handle);
2258}
2259
2260
2261
2262/* --- MODULE INFORMATION --- */
2263
2264typedef struct {
2265 const char *id_string;
2266 lt_dlhandle_interface *iface;
2267} lt__interface_id;
2268
2269lt_dlinterface_id
2270lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
2271{
2272 lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);
2273
2274 /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
2275 can then be detected with lt_dlerror() if we return 0. */
2276 if (interface_id)
2277 {
2278 interface_id->id_string = lt__strdup (id_string);
2279 if (!interface_id->id_string)
2280 FREE (interface_id);
2281 else
2282 interface_id->iface = iface;
2283 }
2284
2285 return (lt_dlinterface_id) interface_id;
2286}
2287
2288void lt_dlinterface_free (lt_dlinterface_id key)
2289{
2290 lt__interface_id *interface_id = (lt__interface_id *)key;
2291 FREE (interface_id->id_string);
2292 FREE (interface_id);
2293}
2294
2295void *
2296lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
2297{
2298 int n_elements = 0;
2299 void *stale = (void *) 0;
2300 lt_dlhandle cur = handle;
2301 int i;
2302
2303 if (cur->interface_data)
2304 while (cur->interface_data[n_elements].key)
2305 ++n_elements;
2306
2307 for (i = 0; i < n_elements; ++i)
2308 {
2309 if (cur->interface_data[i].key == key)
2310 {
2311 stale = cur->interface_data[i].data;
2312 break;
2313 }
2314 }
2315
2316 /* Ensure that there is enough room in this handle's interface_data
2317 array to accept a new element (and an empty end marker). */
2318 if (i == n_elements)
2319 {
2320 lt_interface_data *temp
2321 = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
2322
2323 if (!temp)
2324 {
2325 stale = 0;
2326 goto done;
2327 }
2328
2329 cur->interface_data = temp;
2330
2331 /* We only need this if we needed to allocate a new interface_data. */
2332 cur->interface_data[i].key = key;
2333 cur->interface_data[1+ i].key = 0;
2334 }
2335
2336 cur->interface_data[i].data = data;
2337
2338 done:
2339 return stale;
2340}
2341
2342void *
2343lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
2344{
2345 void *result = (void *) 0;
2346 lt_dlhandle cur = handle;
2347
2348 /* Locate the index of the element with a matching KEY. */
2349 if (cur->interface_data)
2350 {
2351 int i;
2352 for (i = 0; cur->interface_data[i].key; ++i)
2353 {
2354 if (cur->interface_data[i].key == key)
2355 {
2356 result = cur->interface_data[i].data;
2357 break;
2358 }
2359 }
2360 }
2361
2362 return result;
2363}
2364
2365const lt_dlinfo *
2366lt_dlgetinfo (lt_dlhandle handle)
2367{
2368 if (!handle)
2369 {
2370 LT__SETERROR (INVALID_HANDLE);
2371 return 0;
2372 }
2373
2374 return &(handle->info);
2375}
2376
2377
2378lt_dlhandle
2379lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
2380{
2381 lt_dlhandle handle = place;
2382 lt__interface_id *iterator = (lt__interface_id *) iface;
2383
2384 assert (iface); /* iface is a required argument */
2385
2386 if (!handle)
2387 handle = handles;
2388 else
2389 handle = handle->next;
2390
2391 /* advance while the interface check fails */
2392 while (handle && iterator->iface
2393 && ((*iterator->iface) (handle, iterator->id_string) != 0))
2394 {
2395 handle = handle->next;
2396 }
2397
2398 return handle;
2399}
2400
2401
2402lt_dlhandle
2403lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
2404{
2405 lt_dlhandle handle = 0;
2406
2407 assert (iface); /* iface is a required argument */
2408
2409 while ((handle = lt_dlhandle_iterate (iface, handle)))
2410 {
2411 lt_dlhandle cur = handle;
2412 if (cur && cur->info.name && streq (cur->info.name, module_name))
2413 break;
2414 }
2415
2416 return handle;
2417}
2418
2419
2420int
2421lt_dlhandle_map (lt_dlinterface_id iface,
2422 int (*func) (lt_dlhandle handle, void *data), void *data)
2423{
2424 lt__interface_id *iterator = (lt__interface_id *) iface;
2425 lt_dlhandle cur = handles;
2426
2427 assert (iface); /* iface is a required argument */
2428
2429 while (cur)
2430 {
2431 int errorcode = 0;
2432
2433 /* advance while the interface check fails */
2434 while (cur && iterator->iface
2435 && ((*iterator->iface) (cur, iterator->id_string) != 0))
2436 {
2437 cur = cur->next;
2438 }
2439
2440 if ((errorcode = (*func) (cur, data)) != 0)
2441 return errorcode;
2442 }
2443
2444 return 0;
2445}