Imported Debian patch 2.9.0-5
[debian/cc1111] / debian / patches / 04_libtool_fix
1 --- a/sim/ucsim/libltdl/ltdl.c
2 +++ b/sim/ucsim/libltdl/ltdl.c
3 @@ -1,1821 +1,267 @@
4  /* ltdl.c -- system independent dlopen wrapper
5 -   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
6 -   Originally by Thomas Tanner <tanner@ffii.org>
7 -   This file is part of GNU Libtool.
8 -
9 -This library is free software; you can redistribute it and/or
10 -modify it under the terms of the GNU Lesser General Public
11 -License as published by the Free Software Foundation; either
12 -version 2 of the License, or (at your option) any later version.
13 -
14 -As a special exception to the GNU Lesser General Public License,
15 -if you distribute this file as part of a program or library that
16 -is built using GNU libtool, you may include it under the same
17 -distribution terms that you use for the rest of that program.
18 -
19 -This library is distributed in the hope that it will be useful,
20 -but WITHOUT ANY WARRANTY; without even the implied warranty of
21 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22 -Lesser General Public License for more details.
23 -
24 -You should have received a copy of the GNU Lesser General Public
25 -License along with this library; if not, write to the Free Software
26 -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 -02111-1307  USA
28 -
29 -*/
30 -
31 -#if HAVE_CONFIG_H
32 -#  include <config.h>
33 -#endif
34 -
35 -#if HAVE_UNISTD_H
36 -#  include <unistd.h>
37 -#endif
38 -
39 -#if HAVE_STDIO_H
40 -#  include <stdio.h>
41 -#endif
42 -
43 -#if HAVE_STDLIB_H
44 -#  include <stdlib.h>
45 -#endif
46 -
47 -#if HAVE_STRING_H
48 -#  include <string.h>
49 -#else
50 -#  if HAVE_STRINGS_H
51 -#    include <strings.h>
52 -#  endif
53 -#endif
54 -
55 -#if HAVE_CTYPE_H
56 -#  include <ctype.h>
57 -#endif
58 -
59 -#if HAVE_MALLOC_H
60 -#  include <malloc.h>
61 -#endif
62 -
63 -#if HAVE_MEMORY_H
64 -#  include <memory.h>
65 -#endif
66 -
67 -#if HAVE_ERRNO_H
68 -#  include <errno.h>
69 -#endif
70 -
71 -#if HAVE_DIRENT_H
72 -#  include <dirent.h>
73 -#  define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
74 -#else
75 -#  define dirent direct
76 -#  define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
77 -#  if HAVE_SYS_NDIR_H
78 -#    include <sys/ndir.h>
79 -#  endif
80 -#  if HAVE_SYS_DIR_H
81 -#    include <sys/dir.h>
82 -#  endif
83 -#  if HAVE_NDIR_H
84 -#    include <ndir.h>
85 -#  endif
86 -#endif
87 -
88 -#if HAVE_ARGZ_H
89 -#  include <argz.h>
90 -#endif
91 -
92 -#if HAVE_ASSERT_H
93 -#  include <assert.h>
94 -#else
95 -#  define assert(arg)   ((void) 0)
96 -#endif
97 -
98 -#include "ltdl.h"
99 -
100 -#if WITH_DMALLOC
101 -#  include <dmalloc.h>
102 -#endif
103 -
104 -
105 -
106 -\f
107 -/* --- WINDOWS SUPPORT --- */
108 -
109 -
110 -#ifdef DLL_EXPORT
111 -#  define LT_GLOBAL_DATA        __declspec(dllexport)
112 -#else
113 -#  define LT_GLOBAL_DATA
114 -#endif
115 -
116 -/* fopen() mode flags for reading a text file */
117 -#undef  LT_READTEXT_MODE
118 -#ifdef __WINDOWS__
119 -#  define LT_READTEXT_MODE "rt"
120 -#else
121 -#  define LT_READTEXT_MODE "r"
122 -#endif
123 -
124 -
125 -
126 -\f
127 -/* --- MANIFEST CONSTANTS --- */
128 -
129 -
130 -/* Standard libltdl search path environment variable name  */
131 -#undef  LTDL_SEARCHPATH_VAR
132 -#define LTDL_SEARCHPATH_VAR     "LTDL_LIBRARY_PATH"
133 -
134 -/* Standard libtool archive file extension.  */
135 -#undef  LTDL_ARCHIVE_EXT
136 -#define LTDL_ARCHIVE_EXT        ".la"
137 -
138 -/* max. filename length */
139 -#ifndef LT_FILENAME_MAX
140 -#  define LT_FILENAME_MAX       1024
141 -#endif
142 -
143 -/* This is the maximum symbol size that won't require malloc/free */
144 -#undef  LT_SYMBOL_LENGTH
145 -#define LT_SYMBOL_LENGTH        128
146 -
147 -/* This accounts for the _LTX_ separator */
148 -#undef  LT_SYMBOL_OVERHEAD
149 -#define LT_SYMBOL_OVERHEAD      5
150 -
151 -
152 -
153 -\f
154 -/* --- MEMORY HANDLING --- */
155 -
156 -
157 -/* These are the functions used internally.  In addition to making
158 -   use of the associated function pointers above, they also perform
159 -   error handling.  */
160 -static char   *lt_estrdup       LT_PARAMS((const char *str));
161 -static lt_ptr lt_emalloc        LT_PARAMS((size_t size));
162 -static lt_ptr lt_erealloc       LT_PARAMS((lt_ptr addr, size_t size));
163 -
164 -static lt_ptr rpl_realloc       LT_PARAMS((lt_ptr ptr, size_t size));
165 -
166 -/* These are the pointers that can be changed by the caller:  */
167 -LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc)    LT_PARAMS((size_t size))
168 -                        = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
169 -LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc)   LT_PARAMS((lt_ptr ptr, size_t size))
170 -                        = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
171 -LT_GLOBAL_DATA void   (*lt_dlfree)      LT_PARAMS((lt_ptr ptr))
172 -                        = (void (*) LT_PARAMS((lt_ptr))) free;
173 -
174 -/* The following macros reduce the amount of typing needed to cast
175 -   assigned memory.  */
176 -#if WITH_DMALLOC
177 -
178 -#define LT_DLMALLOC(tp, n)      ((tp *) xmalloc ((n) * sizeof(tp)))
179 -#define LT_DLREALLOC(tp, p, n)  ((tp *) xrealloc ((p), (n) * sizeof(tp)))
180 -#define LT_DLFREE(p)                                            \
181 -        LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
182 -
183 -#define LT_EMALLOC(tp, n)       ((tp *) xmalloc ((n) * sizeof(tp)))
184 -#define LT_EREALLOC(tp, p, n)   ((tp *) xrealloc ((p), (n) * sizeof(tp)))
185 -
186 -#else
187 -
188 -#define LT_DLMALLOC(tp, n)      ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
189 -#define LT_DLREALLOC(tp, p, n)  ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
190 -#define LT_DLFREE(p)                                            \
191 -        LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
192 -
193 -#define LT_EMALLOC(tp, n)       ((tp *) lt_emalloc ((n) * sizeof(tp)))
194 -#define LT_EREALLOC(tp, p, n)   ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
195 -
196 -#endif
197 -
198 -#define LT_DLMEM_REASSIGN(p, q)                 LT_STMT_START { \
199 -        if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; }   \
200 -                                                } LT_STMT_END
201 -
202 -\f
203 -/* --- REPLACEMENT FUNCTIONS --- */
204 -
205 -
206 -#undef strdup
207 -#define strdup rpl_strdup
208 -
209 -static char *strdup LT_PARAMS((const char *str));
210 -
211 -static char *
212 -strdup(str)
213 -     const char *str;
214 -{
215 -  char *tmp = 0;
216 -
217 -  if (str)
218 -    {
219 -      tmp = LT_DLMALLOC (char, 1+ strlen (str));
220 -      if (tmp)
221 -        {
222 -          strcpy(tmp, str);
223 -        }
224 -    }
225 -
226 -  return tmp;
227 -}
228 -
229 -
230 -#if ! HAVE_STRCMP
231 -
232 -#undef strcmp
233 -#define strcmp rpl_strcmp
234 -
235 -static int strcmp LT_PARAMS((const char *str1, const char *str2));
236 -
237 -static int
238 -strcmp (str1, str2)
239 -     const char *str1;
240 -     const char *str2;
241 -{
242 -  if (str1 == str2)
243 -    return 0;
244 -  if (str1 == 0)
245 -    return -1;
246 -  if (str2 == 0)
247 -    return 1;
248 -
249 -  for (;*str1 && *str2; ++str1, ++str2)
250 -    {
251 -      if (*str1 != *str2)
252 -        break;
253 -    }
254 -
255 -  return (int)(*str1 - *str2);
256 -}
257 -#endif
258 -
259 -
260 -#if ! HAVE_STRCHR
261 -
262 -#  if HAVE_INDEX
263 -#    define strchr index
264 -#  else
265 -#    define strchr rpl_strchr
266 -
267 -static const char *strchr LT_PARAMS((const char *str, int ch));
268 -
269 -static const char*
270 -strchr(str, ch)
271 -     const char *str;
272 -     int ch;
273 -{
274 -  const char *p;
275 -
276 -  for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
277 -    /*NOWORK*/;
278 -
279 -  return (*p == (char)ch) ? p : 0;
280 -}
281 -
282 -#  endif
283 -#endif /* !HAVE_STRCHR */
284 -
285 -
286 -#if ! HAVE_STRRCHR
287 -
288 -#  if HAVE_RINDEX
289 -#    define strrchr rindex
290 -#  else
291 -#    define strrchr rpl_strrchr
292 -
293 -static const char *strrchr LT_PARAMS((const char *str, int ch));
294 -
295 -static const char*
296 -strrchr(str, ch)
297 -     const char *str;
298 -     int ch;
299 -{
300 -  const char *p, *q = 0;
301 -
302 -  for (p = str; *p != LT_EOS_CHAR; ++p)
303 -    {
304 -      if (*p == (char) ch)
305 -        {
306 -          q = p;
307 -        }
308 -    }
309 -
310 -  return q;
311 -}
312 -
313 -# endif
314 -#endif
315 -
316 -/* NOTE:  Neither bcopy nor the memcpy implementation below can
317 -          reliably handle copying in overlapping areas of memory.  Use
318 -          memmove (for which there is a fallback implmentation below)
319 -          if you need that behaviour.  */
320 -#if ! HAVE_MEMCPY
321 -
322 -#  if HAVE_BCOPY
323 -#    define memcpy(dest, src, size)     bcopy (src, dest, size)
324 -#  else
325 -#    define memcpy rpl_memcpy
326 -
327 -static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
328 -
329 -static lt_ptr
330 -memcpy (dest, src, size)
331 -     lt_ptr dest;
332 -     const lt_ptr src;
333 -     size_t size;
334 -{
335 -  size_t i = 0;
336 -
337 -  for (i = 0; i < size; ++i)
338 -    {
339 -      dest[i] = src[i];
340 -    }
341 -
342 -  return dest;
343 -}
344 -
345 -#  endif /* !HAVE_BCOPY */
346 -#endif   /* !HAVE_MEMCPY */
347 -
348 -#if ! HAVE_MEMMOVE
349 -#  define memmove rpl_memmove
350 -
351 -static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
352 -
353 -static lt_ptr
354 -memmove (dest, src, size)
355 -     lt_ptr dest;
356 -     const lt_ptr src;
357 -     size_t size;
358 -{
359 -  size_t i;
360 -
361 -  if (dest < src)
362 -    for (i = 0; i < size; ++i)
363 -      {
364 -        dest[i] = src[i];
365 -      }
366 -  else if (dest > src)
367 -    for (i = size -1; i >= 0; --i)
368 -      {
369 -        dest[i] = src[i];
370 -      }
371 -
372 -  return dest;
373 -}
374 -
375 -#endif /* !HAVE_MEMMOVE */
376 -
377 -
378 -/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
379 -    ``realloc is not entirely portable''
380 -   In any case we want to use the allocator supplied by the user without
381 -   burdening them with an lt_dlrealloc function pointer to maintain.
382 -   Instead implement our own version (with known boundary conditions)
383 -   using lt_dlmalloc and lt_dlfree. */
384 -
385 -#undef realloc
386 -#define realloc rpl_realloc
387 -
388 -static lt_ptr
389 -realloc (ptr, size)
390 -     lt_ptr ptr;
391 -     size_t size;
392 -{
393 -  if (size == 0)
394 -    {
395 -      /* For zero or less bytes, free the original memory */
396 -      if (ptr != 0)
397 -        {
398 -          lt_dlfree (ptr);
399 -        }
400 -
401 -      return (lt_ptr) 0;
402 -    }
403 -  else if (ptr == 0)
404 -    {
405 -      /* Allow reallocation of a NULL pointer.  */
406 -      return lt_dlmalloc (size);
407 -    }
408 -  else
409 -    {
410 -      /* Allocate a new block, copy and free the old block.  */
411 -      lt_ptr mem = lt_dlmalloc (size);
412 -
413 -      if (mem)
414 -        {
415 -          memcpy (mem, ptr, size);
416 -          lt_dlfree (ptr);
417 -        }
418 -
419 -      /* Note that the contents of PTR are not damaged if there is
420 -         insufficient memory to realloc.  */
421 -      return mem;
422 -    }
423 -}
424 -
425 -
426 -#if ! HAVE_ARGZ_APPEND
427 -#  define argz_append rpl_argz_append
428 -
429 -static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
430 -                                        const char *buf, size_t buf_len));
431 -
432 -static error_t
433 -argz_append (pargz, pargz_len, buf, buf_len)
434 -     char **pargz;
435 -     size_t *pargz_len;
436 -     const char *buf;
437 -     size_t buf_len;
438 -{
439 -  size_t argz_len;
440 -  char  *argz;
441 -
442 -  assert (pargz);
443 -  assert (pargz_len);
444 -  assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
445 -
446 -  /* If nothing needs to be appended, no more work is required.  */
447 -  if (buf_len == 0)
448 -    return 0;
449 -
450 -  /* Ensure there is enough room to append BUF_LEN.  */
451 -  argz_len = *pargz_len + buf_len;
452 -  argz = LT_DLREALLOC (char, *pargz, argz_len);
453 -  if (!argz)
454 -    return ENOMEM;
455 -
456 -  /* Copy characters from BUF after terminating '\0' in ARGZ.  */
457 -  memcpy (argz + *pargz_len, buf, buf_len);
458 -
459 -  /* Assign new values.  */
460 -  *pargz = argz;
461 -  *pargz_len = argz_len;
462 -
463 -  return 0;
464 -}
465 -#endif /* !HAVE_ARGZ_APPEND */
466 -
467 -
468 -#if ! HAVE_ARGZ_CREATE_SEP
469 -#  define argz_create_sep rpl_argz_create_sep
470 -
471 -static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
472 -                                            char **pargz, size_t *pargz_len));
473 -
474 -static error_t
475 -argz_create_sep (str, delim, pargz, pargz_len)
476 -     const char *str;
477 -     int delim;
478 -     char **pargz;
479 -     size_t *pargz_len;
480 -{
481 -  size_t argz_len;
482 -  char *argz = 0;
483 -
484 -  assert (str);
485 -  assert (pargz);
486 -  assert (pargz_len);
487 -
488 -  /* Make a copy of STR, but replacing each occurence of
489 -     DELIM with '\0'.  */
490 -  argz_len = 1+ LT_STRLEN (str);
491 -  if (argz_len)
492 -    {
493 -      const char *p;
494 -      char *q;
495 -
496 -      argz = LT_DLMALLOC (char, argz_len);
497 -      if (!argz)
498 -        return ENOMEM;
499 -
500 -      for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
501 -        {
502 -          if (*p == delim)
503 -            {
504 -              /* Ignore leading delimiters, and fold consecutive
505 -                 delimiters in STR into a single '\0' in ARGZ.  */
506 -              if ((q > argz) && (q[-1] != LT_EOS_CHAR))
507 -                *q++ = LT_EOS_CHAR;
508 -              else
509 -                --argz_len;
510 -            }
511 -          else
512 -            *q++ = *p;
513 -        }
514 -      /* Copy terminating LT_EOS_CHAR.  */
515 -      *q = *p;
516 -    }
517 -
518 -  /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory.  */
519 -  if (!argz_len)
520 -    LT_DLFREE (argz);
521 -
522 -  /* Assign new values.  */
523 -  *pargz = argz;
524 -  *pargz_len = argz_len;
525 -
526 -  return 0;
527 -}
528 -#endif /* !HAVE_ARGZ_CREATE_SEP */
529 -
530 -
531 -#if ! HAVE_ARGZ_INSERT
532 -#  define argz_insert rpl_argz_insert
533 -
534 -static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
535 -                                        char *before, const char *entry));
536 -
537 -static error_t
538 -argz_insert (pargz, pargz_len, before, entry)
539 -     char **pargz;
540 -     size_t *pargz_len;
541 -     char *before;
542 -     const char *entry;
543 -{
544 -  assert (pargz);
545 -  assert (pargz_len);
546 -  assert (entry && *entry);
547 -
548 -  /* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL,
549 -     or BEFORE points into an address within the ARGZ vector.  */
550 -  assert ((!*pargz && !*pargz_len && !before)
551 -          || ((*pargz <= before) && (before < (*pargz + *pargz_len))));
552 -
553 -  /* No BEFORE address indicates ENTRY should be inserted after the
554 -     current last element.  */
555 -  if (!before)
556 -    return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
557 -
558 -  /* This probably indicates a programmer error, but to preserve
559 -     semantics, scan back to the start of an entry if BEFORE points
560 -     into the middle of it.  */
561 -  while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR))
562 -    --before;
563 -
564 -  {
565 -    size_t entry_len    = 1+ LT_STRLEN (entry);
566 -    size_t argz_len     = *pargz_len + entry_len;
567 -    size_t offset       = before - *pargz;
568 -    char   *argz        = LT_DLREALLOC (char, *pargz, argz_len);
569 -
570 -    if (!argz)
571 -      return ENOMEM;
572 -
573 -    /* Make BEFORE point to the equivalent offset in ARGZ that it
574 -       used to have in *PARGZ incase realloc() moved the block.  */
575 -    before = argz + offset;
576 -
577 -    /* Move the ARGZ entries starting at BEFORE up into the new
578 -       space at the end -- making room to copy ENTRY into the
579 -       resulting gap.  */
580 -    memmove (before + entry_len, before, *pargz_len - offset);
581 -    memcpy  (before, entry, entry_len);
582 -
583 -    /* Assign new values.  */
584 -    *pargz = argz;
585 -    *pargz_len = argz_len;
586 -  }
587 -
588 -  return 0;
589 -}
590 -#endif /* !HAVE_ARGZ_INSERT */
591 -
592 -
593 -#if ! HAVE_ARGZ_NEXT
594 -#  define argz_next rpl_argz_next
595 -
596 -static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
597 -                                    const char *entry));
598 -
599 -static char *
600 -argz_next (argz, argz_len, entry)
601 -     char *argz;
602 -     size_t argz_len;
603 -     const char *entry;
604 -{
605 -  assert ((argz && argz_len) || (!argz && !argz_len));
606 -
607 -  if (entry)
608 -    {
609 -      /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
610 -         within the ARGZ vector.  */
611 -      assert ((!argz && !argz_len)
612 -              || ((argz <= entry) && (entry < (argz + argz_len))));
613 -
614 -      /* Move to the char immediately after the terminating
615 -         '\0' of ENTRY.  */
616 -      entry = 1+ strchr (entry, LT_EOS_CHAR);
617 -
618 -      /* Return either the new ENTRY, or else NULL if ARGZ is
619 -         exhausted.  */
620 -      return (entry >= argz + argz_len) ? 0 : (char *) entry;
621 -    }
622 -  else
623 -    {
624 -      /* This should probably be flagged as a programmer error,
625 -         since starting an argz_next loop with the iterator set
626 -         to ARGZ is safer.  To preserve semantics, handle the NULL
627 -         case by returning the start of ARGZ (if any).  */
628 -      if (argz_len > 0)
629 -        return argz;
630 -      else
631 -        return 0;
632 -    }
633 -}
634 -#endif /* !HAVE_ARGZ_NEXT */
635 -
636 -
637 -
638 -#if ! HAVE_ARGZ_STRINGIFY
639 -#  define argz_stringify rpl_argz_stringify
640 -
641 -static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
642 -                                       int sep));
643 -
644 -static void
645 -argz_stringify (argz, argz_len, sep)
646 -     char *argz;
647 -     size_t argz_len;
648 -     int sep;
649 -{
650 -  assert ((argz && argz_len) || (!argz && !argz_len));
651 -
652 -  if (sep)
653 -    {
654 -      --argz_len;               /* don't stringify the terminating EOS */
655 -      while (--argz_len > 0)
656 -        {
657 -          if (argz[argz_len] == LT_EOS_CHAR)
658 -            argz[argz_len] = sep;
659 -        }
660 -    }
661 -}
662 -#endif /* !HAVE_ARGZ_STRINGIFY */
663 -
664 -
665 -
666 -\f
667 -/* --- TYPE DEFINITIONS -- */
668 -
669 -
670 -/* This type is used for the array of caller data sets in each handler. */
671 -typedef struct {
672 -  lt_dlcaller_id        key;
673 -  lt_ptr                data;
674 -} lt_caller_data;
675 -
676 -
677 -
678 -\f
679 -/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
680 -
681 -
682 -/* Extract the diagnostic strings from the error table macro in the same
683 -   order as the enumerated indices in ltdl.h. */
684 -
685 -static const char *lt_dlerror_strings[] =
686 -  {
687 -#define LT_ERROR(name, diagnostic)      (diagnostic),
688 -    lt_dlerror_table
689 -#undef LT_ERROR
690 -
691 -    0
692 -  };
693 -
694 -/* This structure is used for the list of registered loaders. */
695 -struct lt_dlloader {
696 -  struct lt_dlloader   *next;
697 -  const char           *loader_name;    /* identifying name for each loader */
698 -  const char           *sym_prefix;     /* prefix for symbols */
699 -  lt_module_open       *module_open;
700 -  lt_module_close      *module_close;
701 -  lt_find_sym          *find_sym;
702 -  lt_dlloader_exit     *dlloader_exit;
703 -  lt_user_data          dlloader_data;
704 -};
705 -
706 -struct lt_dlhandle_struct {
707 -  struct lt_dlhandle_struct   *next;
708 -  lt_dlloader          *loader;         /* dlopening interface */
709 -  lt_dlinfo             info;
710 -  int                   depcount;       /* number of dependencies */
711 -  lt_dlhandle          *deplibs;        /* dependencies */
712 -  lt_module             module;         /* system module handle */
713 -  lt_ptr                system;         /* system specific data */
714 -  lt_caller_data       *caller_data;    /* per caller associated data */
715 -  int                   flags;          /* various boolean stats */
716 -};
717 -
718 -/* Various boolean flags can be stored in the flags field of an
719 -   lt_dlhandle_struct... */
720 -#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
721 -#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
722 -
723 -#define LT_DLRESIDENT_FLAG          (0x01 << 0)
724 -/* ...add more flags here... */
725 -
726 -#define LT_DLIS_RESIDENT(handle)    LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
727 -
728 -
729 -#define LT_DLSTRERROR(name)     lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
730 -
731 -static  const char      objdir[]                = LTDL_OBJDIR;
732 -static  const char      archive_ext[]           = LTDL_ARCHIVE_EXT;
733 -#ifdef  LTDL_SHLIB_EXT
734 -static  const char      shlib_ext[]             = LTDL_SHLIB_EXT;
735 -#endif
736 -#ifdef  LTDL_SYSSEARCHPATH
737 -static  const char      sys_search_path[]       = LTDL_SYSSEARCHPATH;
738 -#endif
739 -
740 -
741 -
742 -\f
743 -/* --- MUTEX LOCKING --- */
744 -
745 -
746 -/* Macros to make it easier to run the lock functions only if they have
747 -   been registered.  The reason for the complicated lock macro is to
748 -   ensure that the stored error message from the last error is not
749 -   accidentally erased if the current function doesn't generate an
750 -   error of its own.  */
751 -#define LT_DLMUTEX_LOCK()                       LT_STMT_START { \
752 -        if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)();    \
753 -                                                } LT_STMT_END
754 -#define LT_DLMUTEX_UNLOCK()                     LT_STMT_START { \
755 -        if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
756 -                                                } LT_STMT_END
757 -#define LT_DLMUTEX_SETERROR(errormsg)           LT_STMT_START { \
758 -        if (lt_dlmutex_seterror_func)                           \
759 -                (*lt_dlmutex_seterror_func) (errormsg);         \
760 -        else    lt_dllast_error = (errormsg);   } LT_STMT_END
761 -#define LT_DLMUTEX_GETERROR(errormsg)           LT_STMT_START { \
762 -        if (lt_dlmutex_seterror_func)                           \
763 -                (errormsg) = (*lt_dlmutex_geterror_func) ();    \
764 -        else    (errormsg) = lt_dllast_error;   } LT_STMT_END
765 -
766 -/* The mutex functions stored here are global, and are necessarily the
767 -   same for all threads that wish to share access to libltdl.  */
768 -static  lt_dlmutex_lock     *lt_dlmutex_lock_func     = 0;
769 -static  lt_dlmutex_unlock   *lt_dlmutex_unlock_func   = 0;
770 -static  lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
771 -static  lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
772 -static  const char          *lt_dllast_error          = 0;
773 -
774 -
775 -/* Either set or reset the mutex functions.  Either all the arguments must
776 -   be valid functions, or else all can be NULL to turn off locking entirely.
777 -   The registered functions should be manipulating a static global lock
778 -   from the lock() and unlock() callbacks, which needs to be reentrant.  */
779 -int
780 -lt_dlmutex_register (lock, unlock, seterror, geterror)
781 -     lt_dlmutex_lock *lock;
782 -     lt_dlmutex_unlock *unlock;
783 -     lt_dlmutex_seterror *seterror;
784 -     lt_dlmutex_geterror *geterror;
785 -{
786 -  lt_dlmutex_unlock *old_unlock = unlock;
787 -  int                errors     = 0;
788 -
789 -  /* Lock using the old lock() callback, if any.  */
790 -  LT_DLMUTEX_LOCK ();
791 -
792 -  if ((lock && unlock && seterror && geterror)
793 -      || !(lock || unlock || seterror || geterror))
794 -    {
795 -      lt_dlmutex_lock_func     = lock;
796 -      lt_dlmutex_unlock_func   = unlock;
797 -      lt_dlmutex_geterror_func = geterror;
798 -    }
799 -  else
800 -    {
801 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
802 -      ++errors;
803 -    }
804 -
805 -  /* Use the old unlock() callback we saved earlier, if any.  Otherwise
806 -     record any errors using internal storage.  */
807 -  if (old_unlock)
808 -    (*old_unlock) ();
809 -
810 -  /* Return the number of errors encountered during the execution of
811 -     this function.  */
812 -  return errors;
813 -}
814 -
815 -
816 -
817 -\f
818 -/* --- ERROR HANDLING --- */
819 -
820 -
821 -static  const char    **user_error_strings      = 0;
822 -static  int             errorcount              = LT_ERROR_MAX;
823 -
824 -int
825 -lt_dladderror (diagnostic)
826 -     const char *diagnostic;
827 -{
828 -  int           errindex = 0;
829 -  int           result   = -1;
830 -  const char  **temp     = (const char **) 0;
831 -
832 -  assert (diagnostic);
833 -
834 -  LT_DLMUTEX_LOCK ();
835 -
836 -  errindex = errorcount - LT_ERROR_MAX;
837 -  temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
838 -  if (temp)
839 -    {
840 -      user_error_strings                = temp;
841 -      user_error_strings[errindex]      = diagnostic;
842 -      result                            = errorcount++;
843 -    }
844 -
845 -  LT_DLMUTEX_UNLOCK ();
846 -
847 -  return result;
848 -}
849 -
850 -int
851 -lt_dlseterror (errindex)
852 -     int errindex;
853 -{
854 -  int           errors   = 0;
855 -
856 -  LT_DLMUTEX_LOCK ();
857 -
858 -  if (errindex >= errorcount || errindex < 0)
859 -    {
860 -      /* Ack!  Error setting the error message! */
861 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
862 -      ++errors;
863 -    }
864 -  else if (errindex < LT_ERROR_MAX)
865 -    {
866 -      /* No error setting the error message! */
867 -      LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
868 -    }
869 -  else
870 -    {
871 -      /* No error setting the error message! */
872 -      LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
873 -    }
874 -
875 -  LT_DLMUTEX_UNLOCK ();
876 -
877 -  return errors;
878 -}
879 -
880 -static lt_ptr
881 -lt_emalloc (size)
882 -     size_t size;
883 -{
884 -  lt_ptr mem = lt_dlmalloc (size);
885 -  if (size && !mem)
886 -    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
887 -  return mem;
888 -}
889 -
890 -static lt_ptr
891 -lt_erealloc (addr, size)
892 -     lt_ptr addr;
893 -     size_t size;
894 -{
895 -  lt_ptr mem = realloc (addr, size);
896 -  if (size && !mem)
897 -    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
898 -  return mem;
899 -}
900 -
901 -static char *
902 -lt_estrdup (str)
903 -     const char *str;
904 -{
905 -  char *copy = strdup (str);
906 -  if (LT_STRLEN (str) && !copy)
907 -    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
908 -  return copy;
909 -}
910 -
911 -
912 -
913 -\f
914 -/* --- DLOPEN() INTERFACE LOADER --- */
915 -
916 -
917 -/* The Cygwin dlopen implementation prints a spurious error message to
918 -   stderr if its call to LoadLibrary() fails for any reason.  We can
919 -   mitigate this by not using the Cygwin implementation, and falling
920 -   back to our own LoadLibrary() wrapper. */
921 -#if HAVE_LIBDL && !defined(__CYGWIN__)
922 -
923 -/* dynamic linking with dlopen/dlsym */
924 -
925 -#if HAVE_DLFCN_H
926 -#  include <dlfcn.h>
927 -#endif
928 -
929 -#if HAVE_SYS_DL_H
930 -#  include <sys/dl.h>
931 -#endif
932 -
933 -#ifdef RTLD_GLOBAL
934 -#  define LT_GLOBAL             RTLD_GLOBAL
935 -#else
936 -#  ifdef DL_GLOBAL
937 -#    define LT_GLOBAL           DL_GLOBAL
938 -#  endif
939 -#endif /* !RTLD_GLOBAL */
940 -#ifndef LT_GLOBAL
941 -#  define LT_GLOBAL             0
942 -#endif /* !LT_GLOBAL */
943 -
944 -/* We may have to define LT_LAZY_OR_NOW in the command line if we
945 -   find out it does not work in some platform. */
946 -#ifndef LT_LAZY_OR_NOW
947 -#  ifdef RTLD_LAZY
948 -#    define LT_LAZY_OR_NOW      RTLD_LAZY
949 -#  else
950 -#    ifdef DL_LAZY
951 -#      define LT_LAZY_OR_NOW    DL_LAZY
952 -#    endif
953 -#  endif /* !RTLD_LAZY */
954 -#endif
955 -#ifndef LT_LAZY_OR_NOW
956 -#  ifdef RTLD_NOW
957 -#    define LT_LAZY_OR_NOW      RTLD_NOW
958 -#  else
959 -#    ifdef DL_NOW
960 -#      define LT_LAZY_OR_NOW    DL_NOW
961 -#    endif
962 -#  endif /* !RTLD_NOW */
963 -#endif
964 -#ifndef LT_LAZY_OR_NOW
965 -#  define LT_LAZY_OR_NOW        0
966 -#endif /* !LT_LAZY_OR_NOW */
967 -
968 -#if HAVE_DLERROR
969 -#  define DLERROR(arg)  dlerror ()
970 -#else
971 -#  define DLERROR(arg)  LT_DLSTRERROR (arg)
972 -#endif
973 -
974 -static lt_module
975 -sys_dl_open (loader_data, filename)
976 -     lt_user_data loader_data;
977 -     const char *filename;
978 -{
979 -  lt_module   module   = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
980 -
981 -  if (!module)
982 -    {
983 -      LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
984 -    }
985 -
986 -  return module;
987 -}
988 -
989 -static int
990 -sys_dl_close (loader_data, module)
991 -     lt_user_data loader_data;
992 -     lt_module module;
993 -{
994 -  int errors = 0;
995 -
996 -  if (dlclose (module) != 0)
997 -    {
998 -      LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
999 -      ++errors;
1000 -    }
1001 -
1002 -  return errors;
1003 -}
1004 -
1005 -static lt_ptr
1006 -sys_dl_sym (loader_data, module, symbol)
1007 -     lt_user_data loader_data;
1008 -     lt_module module;
1009 -     const char *symbol;
1010 -{
1011 -  lt_ptr address = dlsym (module, symbol);
1012 -
1013 -  if (!address)
1014 -    {
1015 -      LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
1016 -    }
1017 -
1018 -  return address;
1019 -}
1020 -
1021 -static struct lt_user_dlloader sys_dl =
1022 -  {
1023 -#  ifdef NEED_USCORE
1024 -    "_",
1025 -#  else
1026 -    0,
1027 -#  endif
1028 -    sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
1029 -
1030 -
1031 -#endif /* HAVE_LIBDL */
1032 -
1033 -
1034 -\f
1035 -/* --- SHL_LOAD() INTERFACE LOADER --- */
1036 -
1037 -#if HAVE_SHL_LOAD
1038 -
1039 -/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1040 -
1041 -#ifdef HAVE_DL_H
1042 -#  include <dl.h>
1043 -#endif
1044 -
1045 -/* some flags are missing on some systems, so we provide
1046 - * harmless defaults.
1047 - *
1048 - * Mandatory:
1049 - * BIND_IMMEDIATE  - Resolve symbol references when the library is loaded.
1050 - * BIND_DEFERRED   - Delay code symbol resolution until actual reference.
1051 - *
1052 - * Optionally:
1053 - * BIND_FIRST      - Place the library at the head of the symbol search
1054 - *                   order.
1055 - * BIND_NONFATAL   - The default BIND_IMMEDIATE behavior is to treat all
1056 - *                   unsatisfied symbols as fatal.  This flag allows
1057 - *                   binding of unsatisfied code symbols to be deferred
1058 - *                   until use.
1059 - *                   [Perl: For certain libraries, like DCE, deferred
1060 - *                   binding often causes run time problems. Adding
1061 - *                   BIND_NONFATAL to BIND_IMMEDIATE still allows
1062 - *                   unresolved references in situations like this.]
1063 - * BIND_NOSTART    - Do not call the initializer for the shared library
1064 - *                   when the library is loaded, nor on a future call to
1065 - *                   shl_unload().
1066 - * BIND_VERBOSE    - Print verbose messages concerning possible
1067 - *                   unsatisfied symbols.
1068 - *
1069 - * hp9000s700/hp9000s800:
1070 - * BIND_RESTRICTED - Restrict symbols visible by the library to those
1071 - *                   present at library load time.
1072 - * DYNAMIC_PATH    - Allow the loader to dynamically search for the
1073 - *                   library specified by the path argument.
1074 - */
1075 -
1076 -#ifndef DYNAMIC_PATH
1077 -#  define DYNAMIC_PATH          0
1078 -#endif
1079 -#ifndef BIND_RESTRICTED
1080 -#  define BIND_RESTRICTED       0
1081 -#endif
1082 -
1083 -#define LT_BIND_FLAGS   (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1084 -
1085 -static lt_module
1086 -sys_shl_open (loader_data, filename)
1087 -     lt_user_data loader_data;
1088 -     const char *filename;
1089 -{
1090 -  static shl_t self = (shl_t) 0;
1091 -  lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1092 -
1093 -  /* Since searching for a symbol against a NULL module handle will also
1094 -     look in everything else that was already loaded and exported with
1095 -     the -E compiler flag, we always cache a handle saved before any
1096 -     modules are loaded.  */
1097 -  if (!self)
1098 -    {
1099 -      lt_ptr address;
1100 -      shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1101 -    }
1102 -
1103 -  if (!filename)
1104 -    {
1105 -      module = self;
1106 -    }
1107 -  else
1108 -    {
1109 -      module = shl_load (filename, LT_BIND_FLAGS, 0L);
1110 -
1111 -      if (!module)
1112 -        {
1113 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1114 -        }
1115 -    }
1116 -
1117 -  return module;
1118 -}
1119 -
1120 -static int
1121 -sys_shl_close (loader_data, module)
1122 -     lt_user_data loader_data;
1123 -     lt_module module;
1124 -{
1125 -  int errors = 0;
1126 -
1127 -  if (module && (shl_unload ((shl_t) (module)) != 0))
1128 -    {
1129 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1130 -      ++errors;
1131 -    }
1132 -
1133 -  return errors;
1134 -}
1135 -
1136 -static lt_ptr
1137 -sys_shl_sym (loader_data, module, symbol)
1138 -     lt_user_data loader_data;
1139 -     lt_module module;
1140 -     const char *symbol;
1141 -{
1142 -  lt_ptr address = 0;
1143 -
1144 -  /* sys_shl_open should never return a NULL module handle */
1145 -  if (module == (lt_module) 0)
1146 -  {
1147 -    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1148 -  }
1149 -  else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
1150 -    {
1151 -      if (!address)
1152 -        {
1153 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1154 -        }
1155 -    }
1156 -
1157 -  return address;
1158 -}
1159 -
1160 -static struct lt_user_dlloader sys_shl = {
1161 -  0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
1162 -};
1163 -
1164 -#endif /* HAVE_SHL_LOAD */
1165 -
1166 -
1167 -
1168 -\f
1169 -/* --- LOADLIBRARY() INTERFACE LOADER --- */
1170 -
1171 -#ifdef __WINDOWS__
1172 -
1173 -/* dynamic linking for Win32 */
1174 -
1175 -#include <windows.h>
1176 -
1177 -/* Forward declaration; required to implement handle search below. */
1178 -static lt_dlhandle handles;
1179 -
1180 -static lt_module
1181 -sys_wll_open (loader_data, filename)
1182 -     lt_user_data loader_data;
1183 -     const char *filename;
1184 -{
1185 -  lt_dlhandle   cur;
1186 -  lt_module     module     = 0;
1187 -  const char   *errormsg   = 0;
1188 -  char         *searchname = 0;
1189 -  char         *ext;
1190 -  char          self_name_buf[MAX_PATH];
1191 -
1192 -  if (!filename)
1193 -    {
1194 -      /* Get the name of main module */
1195 -      *self_name_buf = 0;
1196 -      GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
1197 -      filename = ext = self_name_buf;
1198 -    }
1199 -  else
1200 -    {
1201 -      ext = strrchr (filename, '.');
1202 -    }
1203 -
1204 -  if (ext)
1205 -    {
1206 -      /* FILENAME already has an extension. */
1207 -      searchname = lt_estrdup (filename);
1208 -    }
1209 -  else
1210 -    {
1211 -      /* Append a `.' to stop Windows from adding an
1212 -         implicit `.dll' extension. */
1213 -      searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
1214 -      if (searchname)
1215 -        sprintf (searchname, "%s.", filename);
1216 -    }
1217 -  if (!searchname)
1218 -    return 0;
1219 -
1220 -#if __CYGWIN__
1221 -  {
1222 -    char wpath[MAX_PATH];
1223 -    cygwin_conv_to_full_win32_path(searchname, wpath);
1224 -    module = LoadLibrary(wpath);
1225 -  }
1226 -#else
1227 -  module = LoadLibrary (searchname);
1228 -#endif
1229 -  LT_DLFREE (searchname);
1230 -
1231 -  /* libltdl expects this function to fail if it is unable
1232 -     to physically load the library.  Sadly, LoadLibrary
1233 -     will search the loaded libraries for a match and return
1234 -     one of them if the path search load fails.
1235 -
1236 -     We check whether LoadLibrary is returning a handle to
1237 -     an already loaded module, and simulate failure if we
1238 -     find one. */
1239 -  LT_DLMUTEX_LOCK ();
1240 -  cur = handles;
1241 -  while (cur)
1242 -    {
1243 -      if (!cur->module)
1244 -        {
1245 -          cur = 0;
1246 -          break;
1247 -        }
1248 -
1249 -      if (cur->module == module)
1250 -        {
1251 -          break;
1252 -        }
1253 -
1254 -      cur = cur->next;
1255 -  }
1256 -  LT_DLMUTEX_UNLOCK ();
1257 -
1258 -  if (cur || !module)
1259 -    {
1260 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1261 -      module = 0;
1262 -    }
1263 -
1264 -  return module;
1265 -}
1266 -
1267 -static int
1268 -sys_wll_close (loader_data, module)
1269 -     lt_user_data loader_data;
1270 -     lt_module module;
1271 -{
1272 -  int         errors   = 0;
1273 -
1274 -  if (FreeLibrary(module) == 0)
1275 -    {
1276 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1277 -      ++errors;
1278 -    }
1279 -
1280 -  return errors;
1281 -}
1282 -
1283 -static lt_ptr
1284 -sys_wll_sym (loader_data, module, symbol)
1285 -     lt_user_data loader_data;
1286 -     lt_module module;
1287 -     const char *symbol;
1288 -{
1289 -  lt_ptr      address  = GetProcAddress (module, symbol);
1290 -
1291 -  if (!address)
1292 -    {
1293 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1294 -    }
1295 -
1296 -  return address;
1297 -}
1298 -
1299 -static struct lt_user_dlloader sys_wll = {
1300 -  0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1301 -};
1302 -
1303 -#endif /* __WINDOWS__ */
1304  
1305 +   Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
1306 +                2007, 2008 Free Software Foundation, Inc.
1307 +   Written by Thomas Tanner, 1998
1308  
1309 +   NOTE: The canonical source of this file is maintained with the
1310 +   GNU Libtool package.  Report bugs to bug-libtool@gnu.org.
1311  
1312 -\f
1313 -/* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1314 -
1315 -
1316 -#ifdef __BEOS__
1317 -
1318 -/* dynamic linking for BeOS */
1319 -
1320 -#include <kernel/image.h>
1321 -
1322 -static lt_module
1323 -sys_bedl_open (loader_data, filename)
1324 -     lt_user_data loader_data;
1325 -     const char *filename;
1326 -{
1327 -  image_id image = 0;
1328 -
1329 -  if (filename)
1330 -    {
1331 -      image = load_add_on (filename);
1332 -    }
1333 -  else
1334 -    {
1335 -      image_info info;
1336 -      int32 cookie = 0;
1337 -      if (get_next_image_info (0, &cookie, &info) == B_OK)
1338 -        image = load_add_on (info.name);
1339 -    }
1340 -
1341 -  if (image <= 0)
1342 -    {
1343 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1344 -      image = 0;
1345 -    }
1346 -
1347 -  return (lt_module) image;
1348 -}
1349 -
1350 -static int
1351 -sys_bedl_close (loader_data, module)
1352 -     lt_user_data loader_data;
1353 -     lt_module module;
1354 -{
1355 -  int errors = 0;
1356 -
1357 -  if (unload_add_on ((image_id) module) != B_OK)
1358 -    {
1359 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1360 -      ++errors;
1361 -    }
1362 -
1363 -  return errors;
1364 -}
1365 -
1366 -static lt_ptr
1367 -sys_bedl_sym (loader_data, module, symbol)
1368 -     lt_user_data loader_data;
1369 -     lt_module module;
1370 -     const char *symbol;
1371 -{
1372 -  lt_ptr address = 0;
1373 -  image_id image = (image_id) module;
1374 -
1375 -  if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1376 -    {
1377 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1378 -      address = 0;
1379 -    }
1380 +GNU Libltdl is free software; you can redistribute it and/or
1381 +modify it under the terms of the GNU Lesser General Public
1382 +License as published by the Free Software Foundation; either
1383 +version 2 of the License, or (at your option) any later version.
1384  
1385 -  return address;
1386 -}
1387 +As a special exception to the GNU Lesser General Public License,
1388 +if you distribute this file as part of a program or library that
1389 +is built using GNU Libtool, you may include this file under the
1390 +same distribution terms that you use for the rest of that program.
1391  
1392 -static struct lt_user_dlloader sys_bedl = {
1393 -  0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1394 -};
1395 +GNU Libltdl is distributed in the hope that it will be useful,
1396 +but WITHOUT ANY WARRANTY; without even the implied warranty of
1397 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1398 +GNU Lesser General Public License for more details.
1399  
1400 -#endif /* __BEOS__ */
1401 +You should have received a copy of the GNU Lesser General Public
1402 +License along with GNU Libltdl; see the file COPYING.LIB.  If not, a
1403 +copy can be downloaded from  http://www.gnu.org/licenses/lgpl.html,
1404 +or obtained by writing to the Free Software Foundation, Inc.,
1405 +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1406 +*/
1407  
1408 +#include "lt__private.h"
1409 +#include "lt_system.h"
1410 +#include "lt_dlloader.h"
1411  
1412  
1413 -\f
1414 -/* --- DLD_LINK() INTERFACE LOADER --- */
1415 +/* --- MANIFEST CONSTANTS --- */
1416  
1417  
1418 -#if HAVE_DLD
1419 +/* Standard libltdl search path environment variable name  */
1420 +#undef  LTDL_SEARCHPATH_VAR
1421 +#define LTDL_SEARCHPATH_VAR    "LTDL_LIBRARY_PATH"
1422  
1423 -/* dynamic linking with dld */
1424 +/* Standard libtool archive file extension.  */
1425 +#undef  LT_ARCHIVE_EXT
1426 +#define LT_ARCHIVE_EXT ".la"
1427  
1428 -#if HAVE_DLD_H
1429 -#include <dld.h>
1430 +/* max. filename length */
1431 +#if !defined(LT_FILENAME_MAX)
1432 +#  define LT_FILENAME_MAX      1024
1433  #endif
1434  
1435 -static lt_module
1436 -sys_dld_open (loader_data, filename)
1437 -     lt_user_data loader_data;
1438 -     const char *filename;
1439 -{
1440 -  lt_module module = strdup (filename);
1441 -
1442 -  if (dld_link (filename) != 0)
1443 -    {
1444 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1445 -      LT_DLFREE (module);
1446 -      module = 0;
1447 -    }
1448 -
1449 -  return module;
1450 -}
1451 -
1452 -static int
1453 -sys_dld_close (loader_data, module)
1454 -     lt_user_data loader_data;
1455 -     lt_module module;
1456 -{
1457 -  int errors = 0;
1458 -
1459 -  if (dld_unlink_by_file ((char*)(module), 1) != 0)
1460 -    {
1461 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1462 -      ++errors;
1463 -    }
1464 -  else
1465 -    {
1466 -      LT_DLFREE (module);
1467 -    }
1468 -
1469 -  return errors;
1470 -}
1471 +#if !defined(LT_LIBEXT)
1472 +#  define LT_LIBEXT "a"
1473 +#endif
1474  
1475 -static lt_ptr
1476 -sys_dld_sym (loader_data, module, symbol)
1477 -     lt_user_data loader_data;
1478 -     lt_module module;
1479 -     const char *symbol;
1480 -{
1481 -  lt_ptr address = dld_get_func (symbol);
1482 +/* This is the maximum symbol size that won't require malloc/free */
1483 +#undef LT_SYMBOL_LENGTH
1484 +#define LT_SYMBOL_LENGTH       128
1485  
1486 -  if (!address)
1487 -    {
1488 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1489 -    }
1490 +/* This accounts for the _LTX_ separator */
1491 +#undef LT_SYMBOL_OVERHEAD
1492 +#define LT_SYMBOL_OVERHEAD     5
1493  
1494 -  return address;
1495 -}
1496 +/* Various boolean flags can be stored in the flags field of an
1497 +   lt_dlhandle... */
1498 +#define LT_DLIS_RESIDENT(handle)  ((handle)->info.is_resident)
1499 +#define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal)
1500 +#define LT_DLIS_SYMLOCAL(handle)  ((handle)->info.is_symlocal)
1501  
1502 -static struct lt_user_dlloader sys_dld = {
1503 -  0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1504 -};
1505  
1506 -#endif /* HAVE_DLD */
1507 +static const char      objdir[]                = LT_OBJDIR;
1508 +static const char      archive_ext[]           = LT_ARCHIVE_EXT;
1509 +static  const char     libext[]                = LT_LIBEXT;
1510 +#if defined(LT_MODULE_EXT)
1511 +static const char      shlib_ext[]             = LT_MODULE_EXT;
1512 +#endif
1513 +#if defined(LT_DLSEARCH_PATH)
1514 +static const char      sys_dlsearch_path[]     = LT_DLSEARCH_PATH;
1515 +#endif
1516  
1517  
1518  
1519  \f
1520 -/* --- DLPREOPEN() INTERFACE LOADER --- */
1521 -
1522 -
1523 -/* emulate dynamic linking using preloaded_symbols */
1524 -
1525 -typedef struct lt_dlsymlists_t
1526 -{
1527 -  struct lt_dlsymlists_t       *next;
1528 -  const lt_dlsymlist           *syms;
1529 -} lt_dlsymlists_t;
1530 -
1531 -static  const lt_dlsymlist     *default_preloaded_symbols       = 0;
1532 -static  lt_dlsymlists_t        *preloaded_symbols               = 0;
1533 -
1534 -static int
1535 -presym_init (loader_data)
1536 -     lt_user_data loader_data;
1537 -{
1538 -  int errors = 0;
1539 -
1540 -  LT_DLMUTEX_LOCK ();
1541 -
1542 -  preloaded_symbols = 0;
1543 -  if (default_preloaded_symbols)
1544 -    {
1545 -      errors = lt_dlpreload (default_preloaded_symbols);
1546 -    }
1547 +/* --- DYNAMIC MODULE LOADING --- */
1548  
1549 -  LT_DLMUTEX_UNLOCK ();
1550  
1551 -  return errors;
1552 +/* The type of a function used at each iteration of  foreach_dirinpath().  */
1553 +typedef int    foreach_callback_func (char *filename, void *data1,
1554 +                                      void *data2);
1555 +/* foreachfile_callback itself calls a function of this type: */
1556 +typedef int    file_worker_func      (const char *filename, void *data);
1557 +
1558 +
1559 +static int     foreach_dirinpath     (const char *search_path,
1560 +                                      const char *base_name,
1561 +                                      foreach_callback_func *func,
1562 +                                      void *data1, void *data2);
1563 +static int     find_file_callback    (char *filename, void *data1,
1564 +                                      void *data2);
1565 +static int     find_handle_callback  (char *filename, void *data,
1566 +                                      void *ignored);
1567 +static int     foreachfile_callback  (char *filename, void *data1,
1568 +                                      void *data2);
1569 +
1570 +
1571 +static int     canonicalize_path     (const char *path, char **pcanonical);
1572 +static int     argzize_path          (const char *path,
1573 +                                      char **pargz, size_t *pargz_len);
1574 +static FILE   *find_file             (const char *search_path,
1575 +                                      const char *base_name, char **pdir);
1576 +static lt_dlhandle *find_handle      (const char *search_path,
1577 +                                      const char *base_name,
1578 +                                      lt_dlhandle *handle,
1579 +                                      lt_dladvise advise);
1580 +static int     find_module           (lt_dlhandle *handle, const char *dir,
1581 +                                      const char *libdir, const char *dlname,
1582 +                                      const char *old_name, int installed,
1583 +                                      lt_dladvise advise);
1584 +static  int     has_library_ext       (const char *filename);
1585 +static int     load_deplibs          (lt_dlhandle handle,  char *deplibs);
1586 +static int     trim                  (char **dest, const char *str);
1587 +static int     try_dlopen            (lt_dlhandle *handle,
1588 +                                      const char *filename, const char *ext,
1589 +                                      lt_dladvise advise);
1590 +static int     tryall_dlopen         (lt_dlhandle *handle,
1591 +                                      const char *filename,
1592 +                                      lt_dladvise padvise,
1593 +                                      const lt_dlvtable *vtable);
1594 +static int     unload_deplibs        (lt_dlhandle handle);
1595 +static int     lt_argz_insert        (char **pargz, size_t *pargz_len,
1596 +                                      char *before, const char *entry);
1597 +static int     lt_argz_insertinorder (char **pargz, size_t *pargz_len,
1598 +                                      const char *entry);
1599 +static int     lt_argz_insertdir     (char **pargz, size_t *pargz_len,
1600 +                                      const char *dirnam, struct dirent *dp);
1601 +static int     lt_dlpath_insertdir   (char **ppath, char *before,
1602 +                                      const char *dir);
1603 +static int     list_files_by_dir     (const char *dirnam,
1604 +                                      char **pargz, size_t *pargz_len);
1605 +static int     file_not_found        (void);
1606 +
1607 +#ifdef HAVE_LIBDLLOADER
1608 +static int     loader_init_callback  (lt_dlhandle handle);
1609 +#endif /* HAVE_LIBDLLOADER */
1610 +
1611 +static int     loader_init           (lt_get_vtable *vtable_func,
1612 +                                      lt_user_data data);
1613 +
1614 +static char           *user_search_path= 0;
1615 +static lt_dlhandle     handles = 0;
1616 +static int             initialized     = 0;
1617 +
1618 +/* Our memory failure callback sets the error message to be passed back
1619 +   up to the client, so we must be careful to return from mallocation
1620 +   callers if allocation fails (as this callback returns!!).  */
1621 +void
1622 +lt__alloc_die_callback (void)
1623 +{
1624 +  LT__SETERROR (NO_MEMORY);
1625 +}
1626 +
1627 +#ifdef HAVE_LIBDLLOADER
1628 +/* This function is called to initialise each preloaded module loader,
1629 +   and hook it into the list of loaders to be used when attempting to
1630 +   dlopen an application module.  */
1631 +static int
1632 +loader_init_callback (lt_dlhandle handle)
1633 +{
1634 +  lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable");
1635 +  return loader_init (vtable_func, 0);
1636  }
1637 +#endif /* HAVE_LIBDLLOADER */
1638  
1639  static int
1640 -presym_free_symlists ()
1641 +loader_init (lt_get_vtable *vtable_func, lt_user_data data)
1642  {
1643 -  lt_dlsymlists_t *lists;
1644 -
1645 -  LT_DLMUTEX_LOCK ();
1646 +  const lt_dlvtable *vtable = 0;
1647 +  int errors = 0;
1648  
1649 -  lists = preloaded_symbols;
1650 -  while (lists)
1651 +  if (vtable_func)
1652      {
1653 -      lt_dlsymlists_t   *tmp = lists;
1654 -
1655 -      lists = lists->next;
1656 -      LT_DLFREE (tmp);
1657 +      vtable = (*vtable_func) (data);
1658      }
1659 -  preloaded_symbols = 0;
1660 -
1661 -  LT_DLMUTEX_UNLOCK ();
1662 -
1663 -  return 0;
1664 -}
1665 -
1666 -static int
1667 -presym_exit (loader_data)
1668 -     lt_user_data loader_data;
1669 -{
1670 -  presym_free_symlists ();
1671 -  return 0;
1672 -}
1673 -
1674 -static int
1675 -presym_add_symlist (preloaded)
1676 -     const lt_dlsymlist *preloaded;
1677 -{
1678 -  lt_dlsymlists_t *tmp;
1679 -  lt_dlsymlists_t *lists;
1680 -  int              errors   = 0;
1681  
1682 -  LT_DLMUTEX_LOCK ();
1683 +  /* lt_dlloader_add will LT__SETERROR if it fails.  */
1684 +  errors += lt_dlloader_add (vtable);
1685  
1686 -  lists = preloaded_symbols;
1687 -  while (lists)
1688 -    {
1689 -      if (lists->syms == preloaded)
1690 -        {
1691 -          goto done;
1692 -        }
1693 -      lists = lists->next;
1694 -    }
1695 +  assert (errors || vtable);
1696  
1697 -  tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
1698 -  if (tmp)
1699 -    {
1700 -      memset (tmp, 0, sizeof(lt_dlsymlists_t));
1701 -      tmp->syms = preloaded;
1702 -      tmp->next = preloaded_symbols;
1703 -      preloaded_symbols = tmp;
1704 -    }
1705 -  else
1706 +  if ((!errors) && vtable->dlloader_init)
1707      {
1708 -      ++errors;
1709 +      if ((*vtable->dlloader_init) (vtable->dlloader_data))
1710 +       {
1711 +         LT__SETERROR (INIT_LOADER);
1712 +         ++errors;
1713 +       }
1714      }
1715  
1716 - done:
1717 -  LT_DLMUTEX_UNLOCK ();
1718    return errors;
1719  }
1720  
1721 -static lt_module
1722 -presym_open (loader_data, filename)
1723 -     lt_user_data loader_data;
1724 -     const char *filename;
1725 -{
1726 -  lt_dlsymlists_t *lists;
1727 -  lt_module        module = (lt_module) 0;
1728 -
1729 -  LT_DLMUTEX_LOCK ();
1730 -  lists = preloaded_symbols;
1731 -
1732 -  if (!lists)
1733 -    {
1734 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
1735 -      goto done;
1736 -    }
1737 -
1738 -  /* Can't use NULL as the reflective symbol header, as NULL is
1739 -     used to mark the end of the entire symbol list.  Self-dlpreopened
1740 -     symbols follow this magic number, chosen to be an unlikely
1741 -     clash with a real module name.  */
1742 -  if (!filename)
1743 -    {
1744 -      filename = "@PROGRAM@";
1745 -    }
1746 -
1747 -  while (lists)
1748 -    {
1749 -      const lt_dlsymlist *syms = lists->syms;
1750 -
1751 -      while (syms->name)
1752 -        {
1753 -          if (!syms->address && strcmp(syms->name, filename) == 0)
1754 -            {
1755 -              module = (lt_module) syms;
1756 -              goto done;
1757 -            }
1758 -          ++syms;
1759 -        }
1760 -
1761 -      lists = lists->next;
1762 -    }
1763 -
1764 -  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
1765 -
1766 - done:
1767 -  LT_DLMUTEX_UNLOCK ();
1768 -  return module;
1769 -}
1770 -
1771 -static int
1772 -presym_close (loader_data, module)
1773 -     lt_user_data loader_data;
1774 -     lt_module module;
1775 -{
1776 -  /* Just to silence gcc -Wall */
1777 -  module = 0;
1778 -  return 0;
1779 -}
1780 -
1781 -static lt_ptr
1782 -presym_sym (loader_data, module, symbol)
1783 -     lt_user_data loader_data;
1784 -     lt_module module;
1785 -     const char *symbol;
1786 -{
1787 -  lt_dlsymlist *syms = (lt_dlsymlist*) module;
1788 -
1789 -  ++syms;
1790 -  while (syms->address)
1791 -    {
1792 -      if (strcmp(syms->name, symbol) == 0)
1793 -        {
1794 -          return syms->address;
1795 -        }
1796 -
1797 -    ++syms;
1798 -  }
1799 -
1800 -  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1801 -
1802 -  return 0;
1803 -}
1804 -
1805 -static struct lt_user_dlloader presym = {
1806 -  0, presym_open, presym_close, presym_sym, presym_exit, 0
1807 -};
1808 -
1809 -
1810 -
1811 -
1812 -\f
1813 -/* --- DYNAMIC MODULE LOADING --- */
1814 -
1815 -
1816 -/* The type of a function used at each iteration of  foreach_dirinpath().  */
1817 -typedef int     foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
1818 -                                                 lt_ptr data2));
1819 +/* Bootstrap the loader loading with the preopening loader.  */
1820 +#define get_vtable             preopen_LTX_get_vtable
1821 +#define preloaded_symbols      LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
1822  
1823 -static  int     foreach_dirinpath     LT_PARAMS((const char *search_path,
1824 -                                                 const char *base_name,
1825 -                                                 foreach_callback_func *func,
1826 -                                                 lt_ptr data1, lt_ptr data2));
1827 -
1828 -static  int     find_file_callback    LT_PARAMS((char *filename, lt_ptr data,
1829 -                                                 lt_ptr ignored));
1830 -static  int     find_handle_callback  LT_PARAMS((char *filename, lt_ptr data,
1831 -                                                 lt_ptr ignored));
1832 -static  int     foreachfile_callback  LT_PARAMS((char *filename, lt_ptr data1,
1833 -                                                 lt_ptr data2));
1834 -
1835 -
1836 -static  int     canonicalize_path     LT_PARAMS((const char *path,
1837 -                                                 char **pcanonical));
1838 -static  int     argzize_path          LT_PARAMS((const char *path,
1839 -                                                 char **pargz,
1840 -                                                 size_t *pargz_len));
1841 -static  FILE   *find_file             LT_PARAMS((const char *search_path,
1842 -                                                 const char *base_name,
1843 -                                                 char **pdir));
1844 -static  lt_dlhandle *find_handle      LT_PARAMS((const char *search_path,
1845 -                                                 const char *base_name,
1846 -                                                 lt_dlhandle *handle));
1847 -static  int     find_module           LT_PARAMS((lt_dlhandle *handle,
1848 -                                                 const char *dir,
1849 -                                                 const char *libdir,
1850 -                                                 const char *dlname,
1851 -                                                 const char *old_name,
1852 -                                                 int installed));
1853 -static  int     free_vars             LT_PARAMS((char *dlname, char *oldname,
1854 -                                                 char *libdir, char *deplibs));
1855 -static  int     load_deplibs          LT_PARAMS((lt_dlhandle handle,
1856 -                                                 char *deplibs));
1857 -static  int     trim                  LT_PARAMS((char **dest,
1858 -                                                 const char *str));
1859 -static  int     try_dlopen            LT_PARAMS((lt_dlhandle *handle,
1860 -                                                 const char *filename));
1861 -static  int     tryall_dlopen         LT_PARAMS((lt_dlhandle *handle,
1862 -                                                 const char *filename));
1863 -static  int     unload_deplibs        LT_PARAMS((lt_dlhandle handle));
1864 -static  int     lt_argz_insert        LT_PARAMS((char **pargz,
1865 -                                                 size_t *pargz_len,
1866 -                                                 char *before,
1867 -                                                 const char *entry));
1868 -static  int     lt_argz_insertinorder LT_PARAMS((char **pargz,
1869 -                                                 size_t *pargz_len,
1870 -                                                 const char *entry));
1871 -static  int     lt_argz_insertdir     LT_PARAMS((char **pargz,
1872 -                                                 size_t *pargz_len,
1873 -                                                 const char *dirnam,
1874 -                                                 struct dirent *dp));
1875 -static  int     lt_dlpath_insertdir   LT_PARAMS((char **ppath,
1876 -                                                 char *before,
1877 -                                                 const char *dir));
1878 -static  int     list_files_by_dir     LT_PARAMS((const char *dirnam,
1879 -                                                 char **pargz,
1880 -                                                 size_t *pargz_len));
1881 -static  int     file_not_found        LT_PARAMS((void));
1882 -
1883 -static  char           *user_search_path= 0;
1884 -static  lt_dlloader    *loaders         = 0;
1885 -static  lt_dlhandle     handles         = 0;
1886 -static  int             initialized     = 0;
1887 +LT_BEGIN_C_DECLS
1888 +LT_SCOPE const lt_dlvtable *   get_vtable (lt_user_data data);
1889 +LT_END_C_DECLS
1890 +#ifdef HAVE_LIBDLLOADER
1891 +extern lt_dlsymlist            preloaded_symbols;
1892 +#endif
1893  
1894  /* Initialize libltdl. */
1895  int
1896 -lt_dlinit ()
1897 +lt_dlinit (void)
1898  {
1899 -  int         errors   = 0;
1900 -
1901 -  LT_DLMUTEX_LOCK ();
1902 +  int  errors  = 0;
1903  
1904    /* Initialize only at first call. */
1905    if (++initialized == 1)
1906      {
1907 -      handles = 0;
1908 -      user_search_path = 0; /* empty search path */
1909 -
1910 -#if HAVE_LIBDL && !defined(__CYGWIN__)
1911 -      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
1912 -#endif
1913 -#if HAVE_SHL_LOAD
1914 -      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
1915 -#endif
1916 -#ifdef __WINDOWS__
1917 -      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
1918 -#endif
1919 -#ifdef __BEOS__
1920 -      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
1921 -#endif
1922 -#if HAVE_DLD
1923 -      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
1924 -#endif
1925 -      errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
1926 -
1927 -      if (presym_init (presym.dlloader_data))
1928 -        {
1929 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
1930 -          ++errors;
1931 -        }
1932 -      else if (errors != 0)
1933 -        {
1934 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
1935 -          ++errors;
1936 -        }
1937 -    }
1938 -
1939 -  LT_DLMUTEX_UNLOCK ();
1940 -
1941 -  return errors;
1942 -}
1943 -
1944 -int
1945 -lt_dlpreload (preloaded)
1946 -     const lt_dlsymlist *preloaded;
1947 -{
1948 -  int errors = 0;
1949 -
1950 -  if (preloaded)
1951 -    {
1952 -      errors = presym_add_symlist (preloaded);
1953 +      lt__alloc_die    = lt__alloc_die_callback;
1954 +      handles          = 0;
1955 +      user_search_path = 0; /* empty search path */
1956 +
1957 +      /* First set up the statically loaded preload module loader, so
1958 +        we can use it to preopen the other loaders we linked in at
1959 +        compile time.  */
1960 +      errors += loader_init (get_vtable, 0);
1961 +
1962 +      /* Now open all the preloaded module loaders, so the application
1963 +        can use _them_ to lt_dlopen its own modules.  */
1964 +#ifdef HAVE_LIBDLLOADER
1965 +      if (!errors)
1966 +       {
1967 +         errors += lt_dlpreload (&preloaded_symbols);
1968 +       }
1969 +
1970 +      if (!errors)
1971 +       {
1972 +         errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback);
1973 +       }
1974 +#endif /* HAVE_LIBDLLOADER */
1975      }
1976 -  else
1977 -    {
1978 -      presym_free_symlists();
1979  
1980 -      LT_DLMUTEX_LOCK ();
1981 -      if (default_preloaded_symbols)
1982 -        {
1983 -          errors = lt_dlpreload (default_preloaded_symbols);
1984 -        }
1985 -      LT_DLMUTEX_UNLOCK ();
1986 -    }
1987 +#ifdef LT_DEBUG_LOADERS
1988 +  lt_dlloader_dump();
1989 +#endif
1990  
1991    return errors;
1992  }
1993  
1994  int
1995 -lt_dlpreload_default (preloaded)
1996 -     const lt_dlsymlist *preloaded;
1997 -{
1998 -  LT_DLMUTEX_LOCK ();
1999 -  default_preloaded_symbols = preloaded;
2000 -  LT_DLMUTEX_UNLOCK ();
2001 -  return 0;
2002 -}
2003 -
2004 -int
2005 -lt_dlexit ()
2006 +lt_dlexit (void)
2007  {
2008    /* shut down libltdl */
2009 -  lt_dlloader *loader;
2010 -  int          errors   = 0;
2011 -
2012 -  LT_DLMUTEX_LOCK ();
2013 -  loader = loaders;
2014 +  lt_dlloader *loader   = 0;
2015 +  lt_dlhandle  handle   = handles;
2016 +  int         errors   = 0;
2017  
2018    if (!initialized)
2019      {
2020 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
2021 +      LT__SETERROR (SHUTDOWN);
2022        ++errors;
2023        goto done;
2024      }
2025 @@ -1823,171 +269,236 @@
2026    /* shut down only at last call. */
2027    if (--initialized == 0)
2028      {
2029 -      int       level;
2030 +      int      level;
2031  
2032        while (handles && LT_DLIS_RESIDENT (handles))
2033 -        {
2034 -          handles = handles->next;
2035 -        }
2036 +       {
2037 +         handles = handles->next;
2038 +       }
2039  
2040        /* close all modules */
2041 -      for (level = 1; handles; ++level)
2042 -        {
2043 -          lt_dlhandle cur = handles;
2044 -          int saw_nonresident = 0;
2045 -
2046 -          while (cur)
2047 -            {
2048 -              lt_dlhandle tmp = cur;
2049 -              cur = cur->next;
2050 -              if (!LT_DLIS_RESIDENT (tmp))
2051 -                saw_nonresident = 1;
2052 -              if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
2053 -                {
2054 -                  if (lt_dlclose (tmp))
2055 -                    {
2056 -                      ++errors;
2057 -                    }
2058 -                }
2059 -            }
2060 -          /* done if only resident modules are left */
2061 -          if (!saw_nonresident)
2062 -            break;
2063 -        }
2064 +      for (level = 1; handle; ++level)
2065 +       {
2066 +         lt_dlhandle cur = handles;
2067 +         int saw_nonresident = 0;
2068 +
2069 +         while (cur)
2070 +           {
2071 +             lt_dlhandle tmp = cur;
2072 +             cur = cur->next;
2073 +             if (!LT_DLIS_RESIDENT (tmp))
2074 +               {
2075 +                 saw_nonresident = 1;
2076 +                 if (tmp->info.ref_count <= level)
2077 +                   {
2078 +                     if (lt_dlclose (tmp))
2079 +                       {
2080 +                         ++errors;
2081 +                       }
2082 +                     /* Make sure that the handle pointed to by 'cur' still exists.
2083 +                        lt_dlclose recursively closes dependent libraries which removes
2084 +                        them from the linked list.  One of these might be the one
2085 +                        pointed to by 'cur'.  */
2086 +                     if (cur)
2087 +                       {
2088 +                         for (tmp = handles; tmp; tmp = tmp->next)
2089 +                           if (tmp == cur)
2090 +                             break;
2091 +                         if (! tmp)
2092 +                           cur = handles;
2093 +                       }
2094 +                   }
2095 +               }
2096 +           }
2097 +         /* done if only resident modules are left */
2098 +         if (!saw_nonresident)
2099 +           break;
2100 +       }
2101 +
2102 +      /* When removing loaders, we can only find out failure by testing
2103 +        the error string, so avoid a spurious one from an earlier
2104 +        failed command. */
2105 +      if (!errors)
2106 +       LT__SETERRORSTR (0);
2107  
2108        /* close all loaders */
2109 -      while (loader)
2110 -        {
2111 -          lt_dlloader *next = loader->next;
2112 -          lt_user_data data = loader->dlloader_data;
2113 -          if (loader->dlloader_exit && loader->dlloader_exit (data))
2114 -            {
2115 -              ++errors;
2116 -            }
2117 -
2118 -          LT_DLMEM_REASSIGN (loader, next);
2119 -        }
2120 -      loaders = 0;
2121 +      for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;)
2122 +       {
2123 +         lt_dlloader *next   = (lt_dlloader *) lt_dlloader_next (loader);
2124 +         lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader);
2125 +
2126 +         if ((vtable = lt_dlloader_remove ((char *) vtable->name)))
2127 +           {
2128 +             FREE (vtable);
2129 +           }
2130 +         else
2131 +           {
2132 +             /* ignore errors due to resident modules */
2133 +             const char *err;
2134 +             LT__GETERROR (err);
2135 +             if (err)
2136 +               ++errors;
2137 +           }
2138 +
2139 +         loader = next;
2140 +       }
2141 +
2142 +      FREE(user_search_path);
2143      }
2144  
2145   done:
2146 -  LT_DLMUTEX_UNLOCK ();
2147    return errors;
2148  }
2149  
2150 +
2151 +/* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME.
2152 +   If the library is not successfully loaded, return non-zero.  Otherwise,
2153 +   the dlhandle is stored at the address given in PHANDLE.  */
2154  static int
2155 -tryall_dlopen (handle, filename)
2156 -     lt_dlhandle *handle;
2157 -     const char *filename;
2158 -{
2159 -  lt_dlhandle    cur;
2160 -  lt_dlloader   *loader;
2161 -  const char    *saved_error;
2162 -  int            errors         = 0;
2163 +tryall_dlopen (lt_dlhandle *phandle, const char *filename,
2164 +              lt_dladvise advise, const lt_dlvtable *vtable)
2165 +{
2166 +  lt_dlhandle  handle          = handles;
2167 +  const char * saved_error     = 0;
2168 +  int          errors          = 0;
2169  
2170 -  LT_DLMUTEX_GETERROR (saved_error);
2171 -  LT_DLMUTEX_LOCK ();
2172 +#ifdef LT_DEBUG_LOADERS
2173 +  fprintf (stderr, "tryall_dlopen (%s, %s)\n",
2174 +          filename ? filename : "(null)",
2175 +          vtable ? vtable->name : "(ALL)");
2176 +#endif
2177  
2178 -  cur    = handles;
2179 -  loader = loaders;
2180 +  LT__GETERROR (saved_error);
2181  
2182    /* check whether the module was already opened */
2183 -  while (cur)
2184 +  for (;handle; handle = handle->next)
2185      {
2186 -      /* try to dlopen the program itself? */
2187 -      if (!cur->info.filename && !filename)
2188 -        {
2189 -          break;
2190 -        }
2191 -
2192 -      if (cur->info.filename && filename
2193 -          && strcmp (cur->info.filename, filename) == 0)
2194 -        {
2195 -          break;
2196 -        }
2197 -
2198 -      cur = cur->next;
2199 +      if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */
2200 +         || (handle->info.filename && filename
2201 +             && streq (handle->info.filename, filename)))
2202 +       {
2203 +         break;
2204 +       }
2205      }
2206  
2207 -  if (cur)
2208 +  if (handle)
2209      {
2210 -      ++cur->info.ref_count;
2211 -      *handle = cur;
2212 +      ++handle->info.ref_count;
2213 +      *phandle = handle;
2214        goto done;
2215      }
2216  
2217 -  cur = *handle;
2218 +  handle = *phandle;
2219    if (filename)
2220      {
2221 -      cur->info.filename = lt_estrdup (filename);
2222 -      if (!cur->info.filename)
2223 -        {
2224 -          ++errors;
2225 -          goto done;
2226 -        }
2227 +      /* Comment out the check of file permissions using access.
2228 +        This call seems to always return -1 with error EACCES.
2229 +      */
2230 +      /* We need to catch missing file errors early so that
2231 +        file_not_found() can detect what happened.
2232 +      if (access (filename, R_OK) != 0)
2233 +       {
2234 +         LT__SETERROR (FILE_NOT_FOUND);
2235 +         ++errors;
2236 +         goto done;
2237 +       } */
2238 +
2239 +      handle->info.filename = lt__strdup (filename);
2240 +      if (!handle->info.filename)
2241 +       {
2242 +         ++errors;
2243 +         goto done;
2244 +       }
2245      }
2246    else
2247      {
2248 -      cur->info.filename = 0;
2249 +      handle->info.filename = 0;
2250      }
2251  
2252 -  while (loader)
2253 -    {
2254 -      lt_user_data data = loader->dlloader_data;
2255 +  {
2256 +    lt_dlloader loader = lt_dlloader_next (0);
2257 +    const lt_dlvtable *loader_vtable;
2258  
2259 -      cur->module = loader->module_open (data, filename);
2260 +    do
2261 +      {
2262 +       if (vtable)
2263 +         loader_vtable = vtable;
2264 +       else
2265 +         loader_vtable = lt_dlloader_get (loader);
2266 +
2267 +#ifdef LT_DEBUG_LOADERS
2268 +       fprintf (stderr, "Calling %s->module_open (%s)\n",
2269 +                (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)",
2270 +                filename ? filename : "(null)");
2271 +#endif
2272 +       handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data,
2273 +                                                       filename, advise);
2274 +#ifdef LT_DEBUG_LOADERS
2275 +       fprintf (stderr, "  Result: %s\n",
2276 +                handle->module ? "Success" : "Failed");
2277 +#endif
2278 +
2279 +       if (handle->module != 0)
2280 +         {
2281 +           if (advise)
2282 +             {
2283 +               handle->info.is_resident  = advise->is_resident;
2284 +               handle->info.is_symglobal = advise->is_symglobal;
2285 +               handle->info.is_symlocal  = advise->is_symlocal;
2286 +             }
2287 +           break;
2288 +         }
2289 +      }
2290 +    while (!vtable && (loader = lt_dlloader_next (loader)));
2291  
2292 -      if (cur->module != 0)
2293 -        {
2294 -          break;
2295 -        }
2296 -      loader = loader->next;
2297 -    }
2298 +    /* If VTABLE was given but couldn't open the module, or VTABLE wasn't
2299 +       given but we exhausted all loaders without opening the module, bail
2300 +       out!  */
2301 +    if ((vtable && !handle->module)
2302 +       || (!vtable && !loader))
2303 +      {
2304 +       FREE (handle->info.filename);
2305 +       ++errors;
2306 +       goto done;
2307 +      }
2308  
2309 -  if (!loader)
2310 -    {
2311 -      LT_DLFREE (cur->info.filename);
2312 -      ++errors;
2313 -      goto done;
2314 -    }
2315 +    handle->vtable = loader_vtable;
2316 +  }
2317  
2318 -  cur->loader   = loader;
2319 -  LT_DLMUTEX_SETERROR (saved_error);
2320 +  LT__SETERRORSTR (saved_error);
2321  
2322   done:
2323 -  LT_DLMUTEX_UNLOCK ();
2324 -
2325    return errors;
2326  }
2327  
2328 +
2329  static int
2330 -tryall_dlopen_module (handle, prefix, dirname, dlname)
2331 -     lt_dlhandle *handle;
2332 -     const char *prefix;
2333 -     const char *dirname;
2334 -     const char *dlname;
2335 -{
2336 -  int      error        = 0;
2337 -  char     *filename    = 0;
2338 -  size_t   filename_len = 0;
2339 -  size_t   dirname_len  = LT_STRLEN (dirname);
2340 +tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
2341 +                     const char *dirname, const char *dlname,
2342 +                     lt_dladvise advise)
2343 +{
2344 +  int      error       = 0;
2345 +  char     *filename   = 0;
2346 +  size_t   filename_len        = 0;
2347 +  size_t   dirname_len = LT_STRLEN (dirname);
2348  
2349    assert (handle);
2350    assert (dirname);
2351    assert (dlname);
2352 -#ifdef LT_DIRSEP_CHAR
2353 +#if defined(LT_DIRSEP_CHAR)
2354    /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2355       should make it into this function:  */
2356    assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
2357  #endif
2358  
2359 -  if (dirname[dirname_len -1] == '/')
2360 -    --dirname_len;
2361 +  if (dirname_len > 0)
2362 +    if (dirname[dirname_len -1] == '/')
2363 +      --dirname_len;
2364    filename_len = dirname_len + 1 + LT_STRLEN (dlname);
2365  
2366    /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2367       The PREFIX (if any) is handled below.  */
2368 -  filename  = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
2369 +  filename  = MALLOC (char, filename_len + 1);
2370    if (!filename)
2371      return 1;
2372  
2373 @@ -1998,31 +509,28 @@
2374       shuffled.  Otherwise, attempt to open FILENAME as a module.  */
2375    if (prefix)
2376      {
2377 -      error += tryall_dlopen_module (handle,
2378 -                                     (const char *) 0, prefix, filename);
2379 +      error += tryall_dlopen_module (handle, (const char *) 0,
2380 +                                    prefix, filename, advise);
2381      }
2382 -  else if (tryall_dlopen (handle, filename) != 0)
2383 +  else if (tryall_dlopen (handle, filename, advise, 0) != 0)
2384      {
2385        ++error;
2386      }
2387  
2388 -  LT_DLFREE (filename);
2389 +  FREE (filename);
2390    return error;
2391  }
2392  
2393  static int
2394 -find_module (handle, dir, libdir, dlname, old_name, installed)
2395 -     lt_dlhandle *handle;
2396 -     const char *dir;
2397 -     const char *libdir;
2398 -     const char *dlname;
2399 -     const char *old_name;
2400 -     int installed;
2401 +find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
2402 +            const char *dlname,  const char *old_name, int installed,
2403 +            lt_dladvise advise)
2404  {
2405    /* Try to open the old library first; if it was dlpreopened,
2406       we want the preopened version of it, even if a dlopenable
2407       module is available.  */
2408 -  if (old_name && tryall_dlopen (handle, old_name) == 0)
2409 +  if (old_name && tryall_dlopen (handle, old_name,
2410 +                         advise, lt_dlloader_find ("lt_preopen") ) == 0)
2411      {
2412        return 0;
2413      }
2414 @@ -2032,24 +540,25 @@
2415      {
2416        /* try to open the installed module */
2417        if (installed && libdir)
2418 -        {
2419 -          if (tryall_dlopen_module (handle,
2420 -                                    (const char *) 0, libdir, dlname) == 0)
2421 -            return 0;
2422 -        }
2423 +       {
2424 +         if (tryall_dlopen_module (handle, (const char *) 0,
2425 +                                   libdir, dlname, advise) == 0)
2426 +           return 0;
2427 +       }
2428  
2429        /* try to open the not-installed module */
2430        if (!installed)
2431 -        {
2432 -          if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2433 -            return 0;
2434 -        }
2435 +       {
2436 +         if (tryall_dlopen_module (handle, dir, objdir,
2437 +                                   dlname, advise) == 0)
2438 +           return 0;
2439 +       }
2440  
2441        /* maybe it was moved to another directory */
2442        {
2443 -          if (tryall_dlopen_module (handle,
2444 -                                    (const char *) 0, dir, dlname) == 0)
2445 -            return 0;
2446 +         if (dir && (tryall_dlopen_module (handle, (const char *) 0,
2447 +                                           dir, dlname, advise) == 0))
2448 +           return 0;
2449        }
2450      }
2451  
2452 @@ -2058,16 +567,14 @@
2453  
2454  
2455  static int
2456 -canonicalize_path (path, pcanonical)
2457 -     const char *path;
2458 -     char **pcanonical;
2459 +canonicalize_path (const char *path, char **pcanonical)
2460  {
2461    char *canonical = 0;
2462  
2463    assert (path && *path);
2464    assert (pcanonical);
2465  
2466 -  canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2467 +  canonical = MALLOC (char, 1+ LT_STRLEN (path));
2468    if (!canonical)
2469      return 1;
2470  
2471 @@ -2076,38 +583,38 @@
2472      size_t src;
2473      for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2474        {
2475 -        /* Path separators are not copied to the beginning or end of
2476 -           the destination, or if another separator would follow
2477 -           immediately.  */
2478 -        if (path[src] == LT_PATHSEP_CHAR)
2479 -          {
2480 -            if ((dest == 0)
2481 -                || (path[1+ src] == LT_PATHSEP_CHAR)
2482 -                || (path[1+ src] == LT_EOS_CHAR))
2483 -              continue;
2484 -          }
2485 -
2486 -        /* Anything other than a directory separator is copied verbatim.  */
2487 -        if ((path[src] != '/')
2488 -#ifdef LT_DIRSEP_CHAR
2489 -            && (path[src] != LT_DIRSEP_CHAR)
2490 -#endif
2491 -            )
2492 -          {
2493 -            canonical[dest++] = path[src];
2494 -          }
2495 -        /* Directory separators are converted and copied only if they are
2496 -           not at the end of a path -- i.e. before a path separator or
2497 -           NULL terminator.  */
2498 -        else if ((path[1+ src] != LT_PATHSEP_CHAR)
2499 -                 && (path[1+ src] != LT_EOS_CHAR)
2500 -#ifdef LT_DIRSEP_CHAR
2501 -                 && (path[1+ src] != LT_DIRSEP_CHAR)
2502 -#endif
2503 -                 && (path[1+ src] != '/'))
2504 -          {
2505 -            canonical[dest++] = '/';
2506 -          }
2507 +       /* Path separators are not copied to the beginning or end of
2508 +          the destination, or if another separator would follow
2509 +          immediately.  */
2510 +       if (path[src] == LT_PATHSEP_CHAR)
2511 +         {
2512 +           if ((dest == 0)
2513 +               || (path[1+ src] == LT_PATHSEP_CHAR)
2514 +               || (path[1+ src] == LT_EOS_CHAR))
2515 +             continue;
2516 +         }
2517 +
2518 +       /* Anything other than a directory separator is copied verbatim.  */
2519 +       if ((path[src] != '/')
2520 +#if defined(LT_DIRSEP_CHAR)
2521 +           && (path[src] != LT_DIRSEP_CHAR)
2522 +#endif
2523 +           )
2524 +         {
2525 +           canonical[dest++] = path[src];
2526 +         }
2527 +       /* Directory separators are converted and copied only if they are
2528 +          not at the end of a path -- i.e. before a path separator or
2529 +          NULL terminator.  */
2530 +       else if ((path[1+ src] != LT_PATHSEP_CHAR)
2531 +                && (path[1+ src] != LT_EOS_CHAR)
2532 +#if defined(LT_DIRSEP_CHAR)
2533 +                && (path[1+ src] != LT_DIRSEP_CHAR)
2534 +#endif
2535 +                && (path[1+ src] != '/'))
2536 +         {
2537 +           canonical[dest++] = '/';
2538 +         }
2539        }
2540  
2541      /* Add an end-of-string marker at the end.  */
2542 @@ -2121,10 +628,7 @@
2543  }
2544  
2545  static int
2546 -argzize_path (path, pargz, pargz_len)
2547 -     const char *path;
2548 -     char **pargz;
2549 -     size_t *pargz_len;
2550 +argzize_path (const char *path, char **pargz, size_t *pargz_len)
2551  {
2552    error_t error;
2553  
2554 @@ -2135,14 +639,14 @@
2555    if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2556      {
2557        switch (error)
2558 -        {
2559 -        case ENOMEM:
2560 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2561 -          break;
2562 -        default:
2563 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2564 -          break;
2565 -        }
2566 +       {
2567 +       case ENOMEM:
2568 +         LT__SETERROR (NO_MEMORY);
2569 +         break;
2570 +       default:
2571 +         LT__SETERROR (UNKNOWN);
2572 +         break;
2573 +       }
2574  
2575        return 1;
2576      }
2577 @@ -2155,26 +659,20 @@
2578     non-zero or all elements are exhausted.  If BASE_NAME is non-NULL,
2579     it is appended to each SEARCH_PATH element before FUNC is called.  */
2580  static int
2581 -foreach_dirinpath (search_path, base_name, func, data1, data2)
2582 -     const char *search_path;
2583 -     const char *base_name;
2584 -     foreach_callback_func *func;
2585 -     lt_ptr data1;
2586 -     lt_ptr data2;
2587 -{
2588 -  int    result         = 0;
2589 -  int    filenamesize   = 0;
2590 -  size_t lenbase        = LT_STRLEN (base_name);
2591 -  size_t argz_len       = 0;
2592 -  char *argz            = 0;
2593 -  char *filename        = 0;
2594 -  char *canonical       = 0;
2595 -
2596 -  LT_DLMUTEX_LOCK ();
2597 +foreach_dirinpath (const char *search_path, const char *base_name,
2598 +                  foreach_callback_func *func, void *data1, void *data2)
2599 +{
2600 +  int   result         = 0;
2601 +  size_t filenamesize  = 0;
2602 +  size_t lenbase       = LT_STRLEN (base_name);
2603 +  size_t argz_len      = 0;
2604 +  char *argz           = 0;
2605 +  char *filename       = 0;
2606 +  char *canonical      = 0;
2607  
2608    if (!search_path || !*search_path)
2609      {
2610 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2611 +      LT__SETERROR (FILE_NOT_FOUND);
2612        goto cleanup;
2613      }
2614  
2615 @@ -2188,38 +686,38 @@
2616      char *dir_name = 0;
2617      while ((dir_name = argz_next (argz, argz_len, dir_name)))
2618        {
2619 -        size_t lendir = LT_STRLEN (dir_name);
2620 +       size_t lendir = LT_STRLEN (dir_name);
2621  
2622 -        if (lendir +1 +lenbase >= filenamesize)
2623 -        {
2624 -          LT_DLFREE (filename);
2625 -          filenamesize  = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2626 -          filename      = LT_EMALLOC (char, filenamesize);
2627 -          if (!filename)
2628 -            goto cleanup;
2629 -        }
2630 -
2631 -        strncpy (filename, dir_name, lendir);
2632 -        if (base_name && *base_name)
2633 -          {
2634 -            if (filename[lendir -1] != '/')
2635 -              filename[lendir++] = '/';
2636 -            strcpy (filename +lendir, base_name);
2637 -          }
2638 -
2639 -        if ((result = (*func) (filename, data1, data2)))
2640 -          {
2641 -            break;
2642 -          }
2643 +       if (1+ lendir + lenbase >= filenamesize)
2644 +       {
2645 +         FREE (filename);
2646 +         filenamesize  = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */
2647 +         filename      = MALLOC (char, filenamesize);
2648 +         if (!filename)
2649 +           goto cleanup;
2650 +       }
2651 +
2652 +       assert (filenamesize > lendir);
2653 +       strcpy (filename, dir_name);
2654 +
2655 +       if (base_name && *base_name)
2656 +         {
2657 +           if (filename[lendir -1] != '/')
2658 +             filename[lendir++] = '/';
2659 +           strcpy (filename +lendir, base_name);
2660 +         }
2661 +
2662 +       if ((result = (*func) (filename, data1, data2)))
2663 +         {
2664 +           break;
2665 +         }
2666        }
2667    }
2668  
2669   cleanup:
2670 -  LT_DLFREE (argz);
2671 -  LT_DLFREE (canonical);
2672 -  LT_DLFREE (filename);
2673 -
2674 -  LT_DLMUTEX_UNLOCK ();
2675 +  FREE (argz);
2676 +  FREE (canonical);
2677 +  FREE (filename);
2678  
2679    return result;
2680  }
2681 @@ -2228,14 +726,11 @@
2682     in DATA1, and the opened FILE* structure address in DATA2.  Otherwise
2683     DATA1 is unchanged, but DATA2 is set to a pointer to NULL.  */
2684  static int
2685 -find_file_callback (filename, data1, data2)
2686 -     char *filename;
2687 -     lt_ptr data1;
2688 -     lt_ptr data2;
2689 -{
2690 -  char       **pdir     = (char **) data1;
2691 -  FILE       **pfile    = (FILE **) data2;
2692 -  int        is_done    = 0;
2693 +find_file_callback (char *filename, void *data1, void *data2)
2694 +{
2695 +  char      **pdir     = (char **) data1;
2696 +  FILE      **pfile    = (FILE **) data2;
2697 +  int       is_done    = 0;
2698  
2699    assert (filename && *filename);
2700    assert (pdir);
2701 @@ -2246,10 +741,10 @@
2702        char *dirend = strrchr (filename, '/');
2703  
2704        if (dirend > filename)
2705 -        *dirend   = LT_EOS_CHAR;
2706 +       *dirend   = LT_EOS_CHAR;
2707  
2708 -      LT_DLFREE (*pdir);
2709 -      *pdir   = lt_estrdup (filename);
2710 +      FREE (*pdir);
2711 +      *pdir   = lt__strdup (filename);
2712        is_done = (*pdir == 0) ? -1 : 1;
2713      }
2714  
2715 @@ -2257,10 +752,7 @@
2716  }
2717  
2718  static FILE *
2719 -find_file (search_path, base_name, pdir)
2720 -     const char *search_path;
2721 -     const char *base_name;
2722 -     char **pdir;
2723 +find_file (const char *search_path, const char *base_name, char **pdir)
2724  {
2725    FILE *file = 0;
2726  
2727 @@ -2270,22 +762,20 @@
2728  }
2729  
2730  static int
2731 -find_handle_callback (filename, data, ignored)
2732 -     char *filename;
2733 -     lt_ptr data;
2734 -     lt_ptr ignored;
2735 +find_handle_callback (char *filename, void *data, void *data2)
2736  {
2737 -  lt_dlhandle  *handle  = (lt_dlhandle *) data;
2738 -  int           found   = access (filename, R_OK);
2739 +  lt_dlhandle  *phandle                = (lt_dlhandle *) data;
2740 +  int          notfound        = access (filename, R_OK);
2741 +  lt_dladvise   advise         = (lt_dladvise) data2;
2742  
2743    /* Bail out if file cannot be read...  */
2744 -  if (!found)
2745 +  if (notfound)
2746      return 0;
2747  
2748    /* Try to dlopen the file, but do not continue searching in any
2749       case.  */
2750 -  if (tryall_dlopen (handle, filename) != 0)
2751 -    *handle = 0;
2752 +  if (tryall_dlopen (phandle, filename, advise, 0) != 0)
2753 +    *phandle = 0;
2754  
2755    return 1;
2756  }
2757 @@ -2293,91 +783,87 @@
2758  /* If HANDLE was found return it, otherwise return 0.  If HANDLE was
2759     found but could not be opened, *HANDLE will be set to 0.  */
2760  static lt_dlhandle *
2761 -find_handle (search_path, base_name, handle)
2762 -     const char *search_path;
2763 -     const char *base_name;
2764 -     lt_dlhandle *handle;
2765 +find_handle (const char *search_path, const char *base_name,
2766 +            lt_dlhandle *phandle, lt_dladvise advise)
2767  {
2768    if (!search_path)
2769      return 0;
2770  
2771    if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2772 -                          handle, 0))
2773 +                         phandle, advise))
2774      return 0;
2775  
2776 -  return handle;
2777 +  return phandle;
2778 +}
2779 +
2780 +#if !defined(LTDL_DLOPEN_DEPLIBS)
2781 +static int
2782 +load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs)
2783 +{
2784 +  handle->depcount = 0;
2785 +  return 0;
2786  }
2787  
2788 +#else /* defined(LTDL_DLOPEN_DEPLIBS) */
2789  static int
2790 -load_deplibs (handle, deplibs)
2791 -     lt_dlhandle handle;
2792 -     char *deplibs;
2793 +load_deplibs (lt_dlhandle handle, char *deplibs)
2794  {
2795 -#if LTDL_DLOPEN_DEPLIBS
2796 -  char  *p, *save_search_path = 0;
2797 +  char *p, *save_search_path = 0;
2798    int   depcount = 0;
2799 -  int   i;
2800 -  char  **names = 0;
2801 -#endif
2802 -  int   errors = 0;
2803 +  int  i;
2804 +  char **names = 0;
2805 +  int  errors = 0;
2806  
2807    handle->depcount = 0;
2808  
2809 -#if LTDL_DLOPEN_DEPLIBS
2810    if (!deplibs)
2811      {
2812        return errors;
2813      }
2814    ++errors;
2815  
2816 -  LT_DLMUTEX_LOCK ();
2817    if (user_search_path)
2818      {
2819 -      save_search_path = lt_estrdup (user_search_path);
2820 +      save_search_path = lt__strdup (user_search_path);
2821        if (!save_search_path)
2822 -        goto cleanup;
2823 +       goto cleanup;
2824      }
2825  
2826    /* extract search paths and count deplibs */
2827    p = deplibs;
2828    while (*p)
2829      {
2830 -      if (!isspace ((int) *p))
2831 -        {
2832 -          char *end = p+1;
2833 -          while (*end && !isspace((int) *end))
2834 -            {
2835 -              ++end;
2836 -            }
2837 -
2838 -          if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2839 -            {
2840 -              char save = *end;
2841 -              *end = 0; /* set a temporary string terminator */
2842 -              if (lt_dladdsearchdir(p+2))
2843 -                {
2844 -                  goto cleanup;
2845 -                }
2846 -              *end = save;
2847 -            }
2848 -          else
2849 -            {
2850 -              ++depcount;
2851 -            }
2852 +      if (!isspace ((unsigned char) *p))
2853 +       {
2854 +         char *end = p+1;
2855 +         while (*end && !isspace((unsigned char) *end))
2856 +           {
2857 +             ++end;
2858 +           }
2859 +
2860 +         if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2861 +           {
2862 +             char save = *end;
2863 +             *end = 0; /* set a temporary string terminator */
2864 +             if (lt_dladdsearchdir(p+2))
2865 +               {
2866 +                 goto cleanup;
2867 +               }
2868 +             *end = save;
2869 +           }
2870 +         else
2871 +           {
2872 +             ++depcount;
2873 +           }
2874  
2875 -          p = end;
2876 -        }
2877 +         p = end;
2878 +       }
2879        else
2880 -        {
2881 -          ++p;
2882 -        }
2883 +       {
2884 +         ++p;
2885 +       }
2886      }
2887  
2888 -  /* restore the old search path */
2889 -  LT_DLFREE (user_search_path);
2890 -  user_search_path = save_search_path;
2891 -
2892 -  LT_DLMUTEX_UNLOCK ();
2893  
2894    if (!depcount)
2895      {
2896 @@ -2385,7 +871,7 @@
2897        goto cleanup;
2898      }
2899  
2900 -  names = LT_EMALLOC (char *, depcount * sizeof (char*));
2901 +  names = MALLOC (char *, depcount);
2902    if (!names)
2903      goto cleanup;
2904  
2905 @@ -2395,40 +881,40 @@
2906    while (*p)
2907      {
2908        if (isspace ((unsigned char) *p))
2909 -        {
2910 -          ++p;
2911 -        }
2912 +       {
2913 +         ++p;
2914 +       }
2915        else
2916 -        {
2917 -          char *end = p+1;
2918 -          while (*end && !isspace ((unsigned char) *end))
2919 -            {
2920 -              ++end;
2921 -            }
2922 -
2923 -          if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2924 -            {
2925 -              char *name;
2926 -              char save = *end;
2927 -              *end = 0; /* set a temporary string terminator */
2928 -              if (strncmp(p, "-l", 2) == 0)
2929 -                {
2930 -                  size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2931 -                  name = LT_EMALLOC (char, 1+ name_len);
2932 -                  if (name)
2933 -                    sprintf (name, "lib%s", p+2);
2934 -                }
2935 -              else
2936 -                name = lt_estrdup(p);
2937 -
2938 -              if (!name)
2939 -                goto cleanup_names;
2940 -
2941 -              names[depcount++] = name;
2942 -              *end = save;
2943 -            }
2944 -          p = end;
2945 -        }
2946 +       {
2947 +         char *end = p+1;
2948 +         while (*end && !isspace ((unsigned char) *end))
2949 +           {
2950 +             ++end;
2951 +           }
2952 +
2953 +         if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2954 +           {
2955 +             char *name;
2956 +             char save = *end;
2957 +             *end = 0; /* set a temporary string terminator */
2958 +             if (strncmp(p, "-l", 2) == 0)
2959 +               {
2960 +                 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2961 +                 name = MALLOC (char, 1+ name_len);
2962 +                 if (name)
2963 +                   sprintf (name, "lib%s", p+2);
2964 +               }
2965 +             else
2966 +               name = lt__strdup(p);
2967 +
2968 +             if (!name)
2969 +               goto cleanup_names;
2970 +
2971 +             names[depcount++] = name;
2972 +             *end = save;
2973 +           }
2974 +         p = end;
2975 +       }
2976      }
2977  
2978    /* load the deplibs (in reverse order)
2979 @@ -2438,80 +924,87 @@
2980       later on if the loaded module cannot resolve all of its symbols.  */
2981    if (depcount)
2982      {
2983 -      int       j = 0;
2984 +      lt_dlhandle cur = handle;
2985 +      int      j = 0;
2986  
2987 -      handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2988 -      if (!handle->deplibs)
2989 -        goto cleanup;
2990 +      cur->deplibs = MALLOC (lt_dlhandle, depcount);
2991 +      if (!cur->deplibs)
2992 +       goto cleanup_names;
2993  
2994        for (i = 0; i < depcount; ++i)
2995 -        {
2996 -          handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
2997 -          if (handle->deplibs[j])
2998 -            {
2999 -              ++j;
3000 -            }
3001 -        }
3002 +       {
3003 +         cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
3004 +         if (cur->deplibs[j])
3005 +           {
3006 +             ++j;
3007 +           }
3008 +       }
3009  
3010 -      handle->depcount  = j;    /* Number of successfully loaded deplibs */
3011 -      errors            = 0;
3012 +      cur->depcount    = j;    /* Number of successfully loaded deplibs */
3013 +      errors           = 0;
3014      }
3015  
3016   cleanup_names:
3017    for (i = 0; i < depcount; ++i)
3018      {
3019 -      LT_DLFREE (names[i]);
3020 +      FREE (names[i]);
3021      }
3022  
3023   cleanup:
3024 -  LT_DLFREE (names);
3025 -#endif
3026 +  FREE (names);
3027 +  /* restore the old search path */
3028 +  if (save_search_path) {
3029 +    MEMREASSIGN (user_search_path, save_search_path);
3030 +  }
3031  
3032    return errors;
3033  }
3034 +#endif /* defined(LTDL_DLOPEN_DEPLIBS) */
3035  
3036  static int
3037 -unload_deplibs (handle)
3038 -     lt_dlhandle handle;
3039 +unload_deplibs (lt_dlhandle handle)
3040  {
3041    int i;
3042    int errors = 0;
3043 +  lt_dlhandle cur = handle;
3044  
3045 -  if (handle->depcount)
3046 +  if (cur->depcount)
3047      {
3048 -      for (i = 0; i < handle->depcount; ++i)
3049 -        {
3050 -          if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
3051 -            {
3052 -              errors += lt_dlclose (handle->deplibs[i]);
3053 -            }
3054 -        }
3055 +      for (i = 0; i < cur->depcount; ++i)
3056 +       {
3057 +         if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
3058 +           {
3059 +             errors += lt_dlclose (cur->deplibs[i]);
3060 +           }
3061 +       }
3062 +      FREE (cur->deplibs);
3063      }
3064  
3065    return errors;
3066  }
3067  
3068  static int
3069 -trim (dest, str)
3070 -     char **dest;
3071 -     const char *str;
3072 +trim (char **dest, const char *str)
3073  {
3074    /* remove the leading and trailing "'" from str
3075       and store the result in dest */
3076    const char *end   = strrchr (str, '\'');
3077 -  size_t len        = LT_STRLEN (str);
3078 +  size_t len       = LT_STRLEN (str);
3079    char *tmp;
3080  
3081 -  LT_DLFREE (*dest);
3082 +  FREE (*dest);
3083 +
3084 +  if (!end)
3085 +    return 1;
3086  
3087    if (len > 3 && str[0] == '\'')
3088      {
3089 -      tmp = LT_EMALLOC (char, end - str);
3090 +      tmp = MALLOC (char, end - str);
3091        if (!tmp)
3092 -        return 1;
3093 +       return 1;
3094  
3095 -      strncpy(tmp, &str[1], (end - str) - 1);
3096 -      tmp[len-3] = LT_EOS_CHAR;
3097 +      memcpy(tmp, &str[1], (end - str) - 1);
3098 +      tmp[(end - str) - 1] = LT_EOS_CHAR;
3099        *dest = tmp;
3100      }
3101    else
3102 @@ -2522,67 +1015,187 @@
3103    return 0;
3104  }
3105  
3106 +/* Read the .la file FILE. */
3107  static int
3108 -free_vars (dlname, oldname, libdir, deplibs)
3109 -     char *dlname;
3110 -     char *oldname;
3111 -     char *libdir;
3112 -     char *deplibs;
3113 -{
3114 -  LT_DLFREE (dlname);
3115 -  LT_DLFREE (oldname);
3116 -  LT_DLFREE (libdir);
3117 -  LT_DLFREE (deplibs);
3118 +parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs,
3119 +    char **old_name, int *installed)
3120 +{
3121 +  int          errors = 0;
3122 +  size_t       line_len = LT_FILENAME_MAX;
3123 +  char *       line = MALLOC (char, line_len);
3124  
3125 -  return 0;
3126 +  if (!line)
3127 +    {
3128 +      LT__SETERROR (FILE_NOT_FOUND);
3129 +      return 1;
3130 +    }
3131 +
3132 +  while (!feof (file))
3133 +    {
3134 +      line[line_len-2] = '\0';
3135 +      if (!fgets (line, (int) line_len, file))
3136 +       {
3137 +         break;
3138 +       }
3139 +
3140 +      /* Handle the case where we occasionally need to read a line
3141 +        that is longer than the initial buffer size.
3142 +        Behave even if the file contains NUL bytes due to corruption. */
3143 +      while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file))
3144 +       {
3145 +         line = REALLOC (char, line, line_len *2);
3146 +         if (!line)
3147 +           {
3148 +             ++errors;
3149 +             goto cleanup;
3150 +           }
3151 +         line[line_len * 2 - 2] = '\0';
3152 +         if (!fgets (&line[line_len -1], (int) line_len +1, file))
3153 +           {
3154 +             break;
3155 +           }
3156 +         line_len *= 2;
3157 +       }
3158 +
3159 +      if (line[0] == '\n' || line[0] == '#')
3160 +       {
3161 +         continue;
3162 +       }
3163 +
3164 +#undef  STR_DLNAME
3165 +#define STR_DLNAME     "dlname="
3166 +      if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3167 +       {
3168 +         errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]);
3169 +       }
3170 +
3171 +#undef  STR_OLD_LIBRARY
3172 +#define STR_OLD_LIBRARY        "old_library="
3173 +      else if (strncmp (line, STR_OLD_LIBRARY,
3174 +           sizeof (STR_OLD_LIBRARY) - 1) == 0)
3175 +       {
3176 +         errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3177 +       }
3178 +#undef  STR_LIBDIR
3179 +#define STR_LIBDIR     "libdir="
3180 +      else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3181 +       {
3182 +         errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]);
3183 +       }
3184 +
3185 +#undef  STR_DL_DEPLIBS
3186 +#define STR_DL_DEPLIBS "dependency_libs="
3187 +      else if (strncmp (line, STR_DL_DEPLIBS,
3188 +           sizeof (STR_DL_DEPLIBS) - 1) == 0)
3189 +       {
3190 +         errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3191 +       }
3192 +      else if (streq (line, "installed=yes\n"))
3193 +       {
3194 +         *installed = 1;
3195 +       }
3196 +      else if (streq (line, "installed=no\n"))
3197 +       {
3198 +         *installed = 0;
3199 +       }
3200 +
3201 +#undef  STR_LIBRARY_NAMES
3202 +#define STR_LIBRARY_NAMES "library_names="
3203 +      else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES,
3204 +           sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3205 +       {
3206 +         char *last_libname;
3207 +         errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3208 +         if (!errors
3209 +             && *dlname
3210 +             && (last_libname = strrchr (*dlname, ' ')) != 0)
3211 +           {
3212 +             last_libname = lt__strdup (last_libname + 1);
3213 +             if (!last_libname)
3214 +               {
3215 +                 ++errors;
3216 +                 goto cleanup;
3217 +               }
3218 +             MEMREASSIGN (*dlname, last_libname);
3219 +           }
3220 +       }
3221 +
3222 +      if (errors)
3223 +       break;
3224 +    }
3225 +cleanup:
3226 +  FREE (line);
3227 +  return errors;
3228  }
3229  
3230 +
3231 +/* Try to open FILENAME as a module. */
3232  static int
3233 -try_dlopen (phandle, filename)
3234 -     lt_dlhandle *phandle;
3235 -     const char *filename;
3236 -{
3237 -  const char *  ext             = 0;
3238 -  const char *  saved_error     = 0;
3239 -  char *        canonical       = 0;
3240 -  char *        base_name       = 0;
3241 -  char *        dir             = 0;
3242 -  char *        name            = 0;
3243 -  int           errors          = 0;
3244 -  lt_dlhandle   newhandle;
3245 +try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
3246 +           lt_dladvise advise)
3247 +{
3248 +  const char * saved_error     = 0;
3249 +  char *       archive_name    = 0;
3250 +  char *       canonical       = 0;
3251 +  char *       base_name       = 0;
3252 +  char *       dir             = 0;
3253 +  char *       name            = 0;
3254 +  char *        attempt                = 0;
3255 +  int          errors          = 0;
3256 +  lt_dlhandle  newhandle;
3257  
3258    assert (phandle);
3259    assert (*phandle == 0);
3260  
3261 -  LT_DLMUTEX_GETERROR (saved_error);
3262 +#ifdef LT_DEBUG_LOADERS
3263 +  fprintf (stderr, "try_dlopen (%s, %s)\n",
3264 +          filename ? filename : "(null)",
3265 +          ext ? ext : "(null)");
3266 +#endif
3267 +
3268 +  LT__GETERROR (saved_error);
3269  
3270    /* dlopen self? */
3271    if (!filename)
3272      {
3273 -      *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3274 +      *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
3275        if (*phandle == 0)
3276 -        return 1;
3277 +       return 1;
3278  
3279 -      memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3280 -      newhandle = *phandle;
3281 +      newhandle        = *phandle;
3282  
3283        /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
3284 -      LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
3285 +      newhandle->info.is_resident = 1;
3286  
3287 -      if (tryall_dlopen (&newhandle, 0) != 0)
3288 -        {
3289 -          LT_DLFREE (*phandle);
3290 -          return 1;
3291 -        }
3292 +      if (tryall_dlopen (&newhandle, 0, advise, 0) != 0)
3293 +       {
3294 +         FREE (*phandle);
3295 +         return 1;
3296 +       }
3297  
3298        goto register_handle;
3299      }
3300  
3301    assert (filename && *filename);
3302  
3303 +  if (ext)
3304 +    {
3305 +      attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1);
3306 +      if (!attempt)
3307 +       return 1;
3308 +
3309 +      sprintf(attempt, "%s%s", filename, ext);
3310 +    }
3311 +  else
3312 +    {
3313 +      attempt = lt__strdup (filename);
3314 +      if (!attempt)
3315 +       return 1;
3316 +    }
3317 +
3318    /* Doing this immediately allows internal functions to safely
3319       assume only canonicalized paths are passed.  */
3320 -  if (canonicalize_path (filename, &canonical) != 0)
3321 +  if (canonicalize_path (attempt, &canonical) != 0)
3322      {
3323        ++errors;
3324        goto cleanup;
3325 @@ -2595,12 +1208,12 @@
3326      {
3327        size_t dirlen = (1+ base_name) - canonical;
3328  
3329 -      dir = LT_EMALLOC (char, 1+ dirlen);
3330 +      dir = MALLOC (char, 1+ dirlen);
3331        if (!dir)
3332 -        {
3333 -          ++errors;
3334 -          goto cleanup;
3335 -        }
3336 +       {
3337 +         ++errors;
3338 +         goto cleanup;
3339 +       }
3340  
3341        strncpy (dir, canonical, dirlen);
3342        dir[dirlen] = LT_EOS_CHAR;
3343 @@ -2608,447 +1221,476 @@
3344        ++base_name;
3345      }
3346    else
3347 -    LT_DLMEM_REASSIGN (base_name, canonical);
3348 +    MEMREASSIGN (base_name, canonical);
3349  
3350    assert (base_name && *base_name);
3351  
3352 -  /* Check whether we are opening a libtool module (.la extension).  */
3353    ext = strrchr (base_name, '.');
3354 -  if (ext && strcmp (ext, archive_ext) == 0)
3355 +  if (!ext)
3356      {
3357 -      /* this seems to be a libtool module */
3358 -      FILE *    file     = 0;
3359 -      char *    dlname   = 0;
3360 -      char *    old_name = 0;
3361 -      char *    libdir   = 0;
3362 -      char *    deplibs  = 0;
3363 -      char *    line     = 0;
3364 -      size_t    line_len;
3365 +      ext = base_name + LT_STRLEN (base_name);
3366 +    }
3367  
3368 -      /* if we can't find the installed flag, it is probably an
3369 -         installed libtool archive, produced with an old version
3370 -         of libtool */
3371 -      int       installed = 1;
3372 -
3373 -      /* extract the module name from the file name */
3374 -      name = LT_EMALLOC (char, ext - base_name + 1);
3375 -      if (!name)
3376 -        {
3377 -          ++errors;
3378 -          goto cleanup;
3379 -        }
3380 +  /* extract the module name from the file name */
3381 +  name = MALLOC (char, ext - base_name + 1);
3382 +  if (!name)
3383 +    {
3384 +      ++errors;
3385 +      goto cleanup;
3386 +    }
3387  
3388 -      /* canonicalize the module name */
3389 +  /* canonicalize the module name */
3390 +  {
3391 +    int i;
3392 +    for (i = 0; i < ext - base_name; ++i)
3393        {
3394 -        size_t i;
3395 -        for (i = 0; i < ext - base_name; ++i)
3396 -          {
3397 -            if (isalnum ((unsigned char)(base_name[i])))
3398 -              {
3399 -                name[i] = base_name[i];
3400 -              }
3401 -            else
3402 -              {
3403 -                name[i] = '_';
3404 -              }
3405 -          }
3406 -        name[ext - base_name] = LT_EOS_CHAR;
3407 +       if (isalnum ((unsigned char)(base_name[i])))
3408 +         {
3409 +           name[i] = base_name[i];
3410 +         }
3411 +       else
3412 +         {
3413 +           name[i] = '_';
3414 +         }
3415        }
3416 +    name[ext - base_name] = LT_EOS_CHAR;
3417 +  }
3418 +
3419 +  /* Before trawling through the filesystem in search of a module,
3420 +     check whether we are opening a preloaded module.  */
3421 +  if (!dir)
3422 +    {
3423 +      const lt_dlvtable *vtable        = lt_dlloader_find ("lt_preopen");
3424 +
3425 +      if (vtable)
3426 +       {
3427 +         /* name + "." + libext + NULL */
3428 +         archive_name = MALLOC (char, LT_STRLEN (name) + LT_STRLEN (libext) + 2);
3429 +         *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
3430 +
3431 +         if ((*phandle == NULL) || (archive_name == NULL))
3432 +           {
3433 +             ++errors;
3434 +             goto cleanup;
3435 +           }
3436 +         newhandle = *phandle;
3437 +
3438 +         /* Preloaded modules are always named according to their old
3439 +            archive name.  */
3440 +         sprintf (archive_name, "%s.%s", name, libext);
3441 +
3442 +         if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0)
3443 +           {
3444 +             goto register_handle;
3445 +           }
3446 +
3447 +         /* If we're still here, there was no matching preloaded module,
3448 +            so put things back as we found them, and continue searching.  */
3449 +         FREE (*phandle);
3450 +         newhandle = NULL;
3451 +       }
3452 +    }
3453 +
3454 +  /* If we are allowing only preloaded modules, and we didn't find
3455 +     anything yet, give up on the search here.  */
3456 +  if (advise && advise->try_preload_only)
3457 +    {
3458 +      goto cleanup;
3459 +    }
3460 +
3461 +  /* Check whether we are opening a libtool module (.la extension).  */
3462 +  if (ext && streq (ext, archive_ext))
3463 +    {
3464 +      /* this seems to be a libtool module */
3465 +      FILE *   file     = 0;
3466 +      char *   dlname   = 0;
3467 +      char *   old_name = 0;
3468 +      char *   libdir   = 0;
3469 +      char *   deplibs  = 0;
3470 +
3471 +      /* if we can't find the installed flag, it is probably an
3472 +        installed libtool archive, produced with an old version
3473 +        of libtool */
3474 +      int      installed = 1;
3475  
3476        /* Now try to open the .la file.  If there is no directory name
3477 -         component, try to find it first in user_search_path and then other
3478 -         prescribed paths.  Otherwise (or in any case if the module was not
3479 -         yet found) try opening just the module name as passed.  */
3480 +        component, try to find it first in user_search_path and then other
3481 +        prescribed paths.  Otherwise (or in any case if the module was not
3482 +        yet found) try opening just the module name as passed.  */
3483        if (!dir)
3484 -        {
3485 -          const char *search_path;
3486 +       {
3487 +         const char *search_path = user_search_path;
3488 +
3489 +         if (search_path)
3490 +           file = find_file (user_search_path, base_name, &dir);
3491  
3492 -          LT_DLMUTEX_LOCK ();
3493 -          search_path = user_search_path;
3494 -          if (search_path)
3495 -            file = find_file (user_search_path, base_name, &dir);
3496 -          LT_DLMUTEX_UNLOCK ();
3497 -
3498 -          if (!file)
3499 -            {
3500 -              search_path = getenv (LTDL_SEARCHPATH_VAR);
3501 -              if (search_path)
3502 -                file = find_file (search_path, base_name, &dir);
3503 -            }
3504 -
3505 -#ifdef LTDL_SHLIBPATH_VAR
3506 -          if (!file)
3507 -            {
3508 -              search_path = getenv (LTDL_SHLIBPATH_VAR);
3509 -              if (search_path)
3510 -                file = find_file (search_path, base_name, &dir);
3511 -            }
3512 -#endif
3513 -#ifdef LTDL_SYSSEARCHPATH
3514 -          if (!file && sys_search_path)
3515 -            {
3516 -              file = find_file (sys_search_path, base_name, &dir);
3517 -            }
3518 +         if (!file)
3519 +           {
3520 +             search_path = getenv (LTDL_SEARCHPATH_VAR);
3521 +             if (search_path)
3522 +               file = find_file (search_path, base_name, &dir);
3523 +           }
3524 +
3525 +#if defined(LT_MODULE_PATH_VAR)
3526 +         if (!file)
3527 +           {
3528 +             search_path = getenv (LT_MODULE_PATH_VAR);
3529 +             if (search_path)
3530 +               file = find_file (search_path, base_name, &dir);
3531 +           }
3532 +#endif
3533 +#if defined(LT_DLSEARCH_PATH)
3534 +         if (!file && *sys_dlsearch_path)
3535 +           {
3536 +             file = find_file (sys_dlsearch_path, base_name, &dir);
3537 +           }
3538  #endif
3539 -        }
3540 -      if (!file)
3541 -        {
3542 -          file = fopen (filename, LT_READTEXT_MODE);
3543 -        }
3544 +       }
3545 +      else
3546 +       {
3547 +         file = fopen (attempt, LT_READTEXT_MODE);
3548 +       }
3549  
3550        /* If we didn't find the file by now, it really isn't there.  Set
3551 -         the status flag, and bail out.  */
3552 +        the status flag, and bail out.  */
3553        if (!file)
3554 -        {
3555 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3556 -          ++errors;
3557 -          goto cleanup;
3558 -        }
3559 -
3560 -      line_len = LT_FILENAME_MAX;
3561 -      line = LT_EMALLOC (char, line_len);
3562 -      if (!line)
3563 -        {
3564 -          fclose (file);
3565 -          ++errors;
3566 -          goto cleanup;
3567 -        }
3568 +       {
3569 +         LT__SETERROR (FILE_NOT_FOUND);
3570 +         ++errors;
3571 +         goto cleanup;
3572 +       }
3573  
3574        /* read the .la file */
3575 -      while (!feof (file))
3576 -        {
3577 -          if (!fgets (line, (int) line_len, file))
3578 -            {
3579 -              break;
3580 -            }
3581 -
3582 -          /* Handle the case where we occasionally need to read a line
3583 -             that is longer than the initial buffer size.  */
3584 -          while (line[LT_STRLEN(line) -1] != '\n')
3585 -            {
3586 -              line = LT_DLREALLOC (char, line, line_len *2);
3587 -              if (!fgets (&line[line_len -1], (int) line_len +1, file))
3588 -                {
3589 -                  break;
3590 -                }
3591 -              line_len *= 2;
3592 -            }
3593 -
3594 -          if (line[0] == '\n' || line[0] == '#')
3595 -            {
3596 -              continue;
3597 -            }
3598 -
3599 -#undef  STR_DLNAME
3600 -#define STR_DLNAME      "dlname="
3601 -          if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3602 -            {
3603 -              errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
3604 -            }
3605 -
3606 -#undef  STR_OLD_LIBRARY
3607 -#define STR_OLD_LIBRARY "old_library="
3608 -          else if (strncmp (line, STR_OLD_LIBRARY,
3609 -                            sizeof (STR_OLD_LIBRARY) - 1) == 0)
3610 -            {
3611 -              errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3612 -            }
3613 -#undef  STR_LIBDIR
3614 -#define STR_LIBDIR      "libdir="
3615 -          else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3616 -            {
3617 -              errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
3618 -            }
3619 -
3620 -#undef  STR_DL_DEPLIBS
3621 -#define STR_DL_DEPLIBS  "dependency_libs="
3622 -          else if (strncmp (line, STR_DL_DEPLIBS,
3623 -                            sizeof (STR_DL_DEPLIBS) - 1) == 0)
3624 -            {
3625 -              errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3626 -            }
3627 -          else if (strcmp (line, "installed=yes\n") == 0)
3628 -            {
3629 -              installed = 1;
3630 -            }
3631 -          else if (strcmp (line, "installed=no\n") == 0)
3632 -            {
3633 -              installed = 0;
3634 -            }
3635 -
3636 -#undef  STR_LIBRARY_NAMES
3637 -#define STR_LIBRARY_NAMES "library_names="
3638 -          else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
3639 -                                        sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3640 -            {
3641 -              char *last_libname;
3642 -              errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3643 -              if (!errors
3644 -                  && dlname
3645 -                  && (last_libname = strrchr (dlname, ' ')) != 0)
3646 -                {
3647 -                  last_libname = lt_estrdup (last_libname + 1);
3648 -                  if (!last_libname)
3649 -                    {
3650 -                      ++errors;
3651 -                      goto cleanup;
3652 -                    }
3653 -                  LT_DLMEM_REASSIGN (dlname, last_libname);
3654 -                }
3655 -            }
3656 -
3657 -          if (errors)
3658 -            break;
3659 -        }
3660 +      if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
3661 +           &old_name, &installed) != 0)
3662 +       ++errors;
3663  
3664        fclose (file);
3665 -      LT_DLFREE (line);
3666  
3667        /* allocate the handle */
3668 -      *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3669 +      *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
3670        if (*phandle == 0)
3671 -        ++errors;
3672 +       ++errors;
3673  
3674        if (errors)
3675 -        {
3676 -          free_vars (dlname, old_name, libdir, deplibs);
3677 -          LT_DLFREE (*phandle);
3678 -          goto cleanup;
3679 -        }
3680 +       {
3681 +         FREE (dlname);
3682 +         FREE (old_name);
3683 +         FREE (libdir);
3684 +         FREE (deplibs);
3685 +         FREE (*phandle);
3686 +         goto cleanup;
3687 +       }
3688  
3689        assert (*phandle);
3690  
3691 -      memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3692        if (load_deplibs (*phandle, deplibs) == 0)
3693 -        {
3694 -          newhandle = *phandle;
3695 -          /* find_module may replace newhandle */
3696 -          if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
3697 -            {
3698 -              unload_deplibs (*phandle);
3699 -              ++errors;
3700 -            }
3701 -        }
3702 +       {
3703 +         newhandle = *phandle;
3704 +         /* find_module may replace newhandle */
3705 +         if (find_module (&newhandle, dir, libdir, dlname, old_name,
3706 +                          installed, advise))
3707 +           {
3708 +             unload_deplibs (*phandle);
3709 +             ++errors;
3710 +           }
3711 +       }
3712        else
3713 -        {
3714 -          ++errors;
3715 -        }
3716 +       {
3717 +         ++errors;
3718 +       }
3719 +
3720 +      FREE (dlname);
3721 +      FREE (old_name);
3722 +      FREE (libdir);
3723 +      FREE (deplibs);
3724  
3725 -      free_vars (dlname, old_name, libdir, deplibs);
3726        if (errors)
3727 -        {
3728 -          LT_DLFREE (*phandle);
3729 -          goto cleanup;
3730 -        }
3731 +       {
3732 +         FREE (*phandle);
3733 +         goto cleanup;
3734 +       }
3735  
3736        if (*phandle != newhandle)
3737 -        {
3738 -          unload_deplibs (*phandle);
3739 -        }
3740 +       {
3741 +         unload_deplibs (*phandle);
3742 +       }
3743      }
3744    else
3745      {
3746        /* not a libtool module */
3747 -      *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3748 +      *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
3749        if (*phandle == 0)
3750 -        {
3751 -          ++errors;
3752 -          goto cleanup;
3753 -        }
3754 +       {
3755 +         ++errors;
3756 +         goto cleanup;
3757 +       }
3758  
3759 -      memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3760        newhandle = *phandle;
3761  
3762        /* If the module has no directory name component, try to find it
3763 -         first in user_search_path and then other prescribed paths.
3764 -         Otherwise (or in any case if the module was not yet found) try
3765 -         opening just the module name as passed.  */
3766 -      if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
3767 -                   && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3768 -                                    &newhandle)
3769 -#ifdef LTDL_SHLIBPATH_VAR
3770 -                   && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
3771 -                                    &newhandle)
3772 -#endif
3773 -#ifdef LTDL_SYSSEARCHPATH
3774 -                   && !find_handle (sys_search_path, base_name, &newhandle)
3775 -#endif
3776 -                   )))
3777 -        {
3778 -          tryall_dlopen (&newhandle, filename);
3779 -        }
3780 +        first in user_search_path and then other prescribed paths.
3781 +        Otherwise (or in any case if the module was not yet found) try
3782 +        opening just the module name as passed.  */
3783 +      if ((dir || (!find_handle (user_search_path, base_name,
3784 +                                &newhandle, advise)
3785 +                  && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3786 +                                   &newhandle, advise)
3787 +#if defined(LT_MODULE_PATH_VAR)
3788 +                  && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name,
3789 +                                   &newhandle, advise)
3790 +#endif
3791 +#if defined(LT_DLSEARCH_PATH)
3792 +                  && !find_handle (sys_dlsearch_path, base_name,
3793 +                                   &newhandle, advise)
3794 +#endif
3795 +                  )))
3796 +       {
3797 +         if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0)
3798 +           {
3799 +             newhandle = NULL;
3800 +           }
3801 +       }
3802  
3803        if (!newhandle)
3804 -        {
3805 -          LT_DLFREE (*phandle);
3806 -          ++errors;
3807 -          goto cleanup;
3808 -        }
3809 +       {
3810 +         FREE (*phandle);
3811 +         ++errors;
3812 +         goto cleanup;
3813 +       }
3814      }
3815  
3816   register_handle:
3817 -  LT_DLMEM_REASSIGN (*phandle, newhandle);
3818 +  MEMREASSIGN (*phandle, newhandle);
3819  
3820    if ((*phandle)->info.ref_count == 0)
3821      {
3822 -      (*phandle)->info.ref_count        = 1;
3823 -      LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
3824 +      (*phandle)->info.ref_count       = 1;
3825 +      MEMREASSIGN ((*phandle)->info.name, name);
3826  
3827 -      LT_DLMUTEX_LOCK ();
3828 -      (*phandle)->next          = handles;
3829 -      handles                   = *phandle;
3830 -      LT_DLMUTEX_UNLOCK ();
3831 +      (*phandle)->next = handles;
3832 +      handles          = *phandle;
3833      }
3834  
3835 -  LT_DLMUTEX_SETERROR (saved_error);
3836 +  LT__SETERRORSTR (saved_error);
3837  
3838   cleanup:
3839 -  LT_DLFREE (dir);
3840 -  LT_DLFREE (name);
3841 -  LT_DLFREE (canonical);
3842 +  FREE (dir);
3843 +  FREE (attempt);
3844 +  FREE (name);
3845 +  if (!canonical)              /* was MEMREASSIGNed */
3846 +    FREE (base_name);
3847 +  FREE (canonical);
3848 +  FREE (archive_name);
3849  
3850    return errors;
3851  }
3852  
3853 -lt_dlhandle
3854 -lt_dlopen (filename)
3855 -     const char *filename;
3856 -{
3857 -  lt_dlhandle handle = 0;
3858 -
3859 -  /* Just incase we missed a code path in try_dlopen() that reports
3860 -     an error, but forgets to reset handle... */
3861 -  if (try_dlopen (&handle, filename) != 0)
3862 -    return 0;
3863 -
3864 -  return handle;
3865 -}
3866  
3867  /* If the last error messge store was `FILE_NOT_FOUND', then return
3868     non-zero.  */
3869  static int
3870 -file_not_found ()
3871 +file_not_found (void)
3872  {
3873    const char *error = 0;
3874  
3875 -  LT_DLMUTEX_GETERROR (error);
3876 -  if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
3877 +  LT__GETERROR (error);
3878 +  if (error == LT__STRERROR (FILE_NOT_FOUND))
3879      return 1;
3880  
3881    return 0;
3882  }
3883  
3884 -/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3885 -   open the FILENAME as passed.  Otherwise try appending ARCHIVE_EXT,
3886 -   and if a file is still not found try again with SHLIB_EXT appended
3887 -   instead.  */
3888 -lt_dlhandle
3889 -lt_dlopenext (filename)
3890 -     const char *filename;
3891 -{
3892 -  lt_dlhandle   handle          = 0;
3893 -  char *        tmp             = 0;
3894 -  char *        ext             = 0;
3895 -  size_t        len;
3896 -  int           errors          = 0;
3897  
3898 -  if (!filename)
3899 -    {
3900 -      return lt_dlopen (filename);
3901 -    }
3902 +/* Unless FILENAME already bears a suitable library extension, then
3903 +   return 0.  */
3904 +static int
3905 +has_library_ext (const char *filename)
3906 +{
3907 +  char *       ext     = 0;
3908  
3909    assert (filename);
3910  
3911 -  len = LT_STRLEN (filename);
3912    ext = strrchr (filename, '.');
3913  
3914 -  /* If FILENAME already bears a suitable extension, there is no need
3915 -     to try appending additional extensions.  */
3916 -  if (ext && ((strcmp (ext, archive_ext) == 0)
3917 -#ifdef LTDL_SHLIB_EXT
3918 -              || (strcmp (ext, shlib_ext) == 0)
3919 +  if (ext && ((streq (ext, archive_ext))
3920 +#if defined(LT_MODULE_EXT)
3921 +            || (streq (ext, shlib_ext))
3922  #endif
3923 -      ))
3924 +    ))
3925      {
3926 -      return lt_dlopen (filename);
3927 +      return 1;
3928      }
3929  
3930 -  /* First try appending ARCHIVE_EXT.  */
3931 -  tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
3932 -  if (!tmp)
3933 -    return 0;
3934 +  return 0;
3935 +}
3936  
3937 -  strcpy (tmp, filename);
3938 -  strcat (tmp, archive_ext);
3939 -  errors = try_dlopen (&handle, tmp);
3940 -
3941 -  /* If we found FILENAME, stop searching -- whether we were able to
3942 -     load the file as a module or not.  If the file exists but loading
3943 -     failed, it is better to return an error message here than to
3944 -     report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3945 -     in the module search path.  */
3946 -  if (handle || ((errors > 0) && file_not_found ()))
3947 -    {
3948 -      LT_DLFREE (tmp);
3949 -      return handle;
3950 -    }
3951  
3952 -#ifdef LTDL_SHLIB_EXT
3953 -  /* Try appending SHLIB_EXT.   */
3954 -  if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
3955 -    {
3956 -      LT_DLFREE (tmp);
3957 -      tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
3958 -      if (!tmp)
3959 -        return 0;
3960 +/* Initialise and configure a user lt_dladvise opaque object.  */
3961  
3962 -      strcpy (tmp, filename);
3963 -    }
3964 -  else
3965 +int
3966 +lt_dladvise_init (lt_dladvise *padvise)
3967 +{
3968 +  lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise));
3969 +  *padvise = advise;
3970 +  return (advise ? 0 : 1);
3971 +}
3972 +
3973 +int
3974 +lt_dladvise_destroy (lt_dladvise *padvise)
3975 +{
3976 +  if (padvise)
3977 +    FREE(*padvise);
3978 +  return 0;
3979 +}
3980 +
3981 +int
3982 +lt_dladvise_ext (lt_dladvise *padvise)
3983 +{
3984 +  assert (padvise && *padvise);
3985 +  (*padvise)->try_ext = 1;
3986 +  return 0;
3987 +}
3988 +
3989 +int
3990 +lt_dladvise_resident (lt_dladvise *padvise)
3991 +{
3992 +  assert (padvise && *padvise);
3993 +  (*padvise)->is_resident = 1;
3994 +  return 0;
3995 +}
3996 +
3997 +int
3998 +lt_dladvise_local (lt_dladvise *padvise)
3999 +{
4000 +  assert (padvise && *padvise);
4001 +  (*padvise)->is_symlocal = 1;
4002 +  return 0;
4003 +}
4004 +
4005 +int
4006 +lt_dladvise_global (lt_dladvise *padvise)
4007 +{
4008 +  assert (padvise && *padvise);
4009 +  (*padvise)->is_symglobal = 1;
4010 +  return 0;
4011 +}
4012 +
4013 +int
4014 +lt_dladvise_preload (lt_dladvise *padvise)
4015 +{
4016 +  assert (padvise && *padvise);
4017 +  (*padvise)->try_preload_only = 1;
4018 +  return 0;
4019 +}
4020 +
4021 +/* Libtool-1.5.x interface for loading a new module named FILENAME.  */
4022 +lt_dlhandle
4023 +lt_dlopen (const char *filename)
4024 +{
4025 +  return lt_dlopenadvise (filename, NULL);
4026 +}
4027 +
4028 +
4029 +/* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
4030 +   open the FILENAME as passed.  Otherwise try appending ARCHIVE_EXT,
4031 +   and if a file is still not found try again with MODULE_EXT appended
4032 +   instead.  */
4033 +lt_dlhandle
4034 +lt_dlopenext (const char *filename)
4035 +{
4036 +  lt_dlhandle  handle  = 0;
4037 +  lt_dladvise  advise;
4038 +
4039 +  if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise))
4040 +    handle = lt_dlopenadvise (filename, advise);
4041 +
4042 +  lt_dladvise_destroy (&advise);
4043 +  return handle;
4044 +}
4045 +
4046 +
4047 +lt_dlhandle
4048 +lt_dlopenadvise (const char *filename, lt_dladvise advise)
4049 +{
4050 +  lt_dlhandle  handle  = 0;
4051 +  int          errors  = 0;
4052 +
4053 +  /* Can't have symbols hidden and visible at the same time!  */
4054 +  if (advise && advise->is_symlocal && advise->is_symglobal)
4055      {
4056 -      tmp[len] = LT_EOS_CHAR;
4057 +      LT__SETERROR (CONFLICTING_FLAGS);
4058 +      return 0;
4059      }
4060  
4061 -  strcat(tmp, shlib_ext);
4062 -  errors = try_dlopen (&handle, tmp);
4063 +  if (!filename
4064 +      || !advise
4065 +      || !advise->try_ext
4066 +      || has_library_ext (filename))
4067 +    {
4068 +      /* Just incase we missed a code path in try_dlopen() that reports
4069 +        an error, but forgot to reset handle... */
4070 +      if (try_dlopen (&handle, filename, NULL, advise) != 0)
4071 +       return 0;
4072  
4073 -  /* As before, if the file was found but loading failed, return now
4074 -     with the current error message.  */
4075 -  if (handle || ((errors > 0) && file_not_found ()))
4076 -    {
4077 -      LT_DLFREE (tmp);
4078        return handle;
4079      }
4080 +  else if (filename && *filename)
4081 +    {
4082 +
4083 +      /* First try appending ARCHIVE_EXT.  */
4084 +      errors += try_dlopen (&handle, filename, archive_ext, advise);
4085 +
4086 +      /* If we found FILENAME, stop searching -- whether we were able to
4087 +        load the file as a module or not.  If the file exists but loading
4088 +        failed, it is better to return an error message here than to
4089 +        report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
4090 +        in the module search path.  */
4091 +      if (handle || ((errors > 0) && !file_not_found ()))
4092 +       return handle;
4093 +
4094 +#if defined(LT_MODULE_EXT)
4095 +      /* Try appending SHLIB_EXT.   */
4096 +      errors = try_dlopen (&handle, filename, shlib_ext, advise);
4097 +
4098 +      /* As before, if the file was found but loading failed, return now
4099 +        with the current error message.  */
4100 +      if (handle || ((errors > 0) && !file_not_found ()))
4101 +       return handle;
4102  #endif
4103 +    }
4104  
4105    /* Still here?  Then we really did fail to locate any of the file
4106       names we tried.  */
4107 -  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
4108 -  LT_DLFREE (tmp);
4109 +  LT__SETERROR (FILE_NOT_FOUND);
4110    return 0;
4111  }
4112  
4113  
4114  static int
4115 -lt_argz_insert (pargz, pargz_len, before, entry)
4116 -     char **pargz;
4117 -     size_t *pargz_len;
4118 -     char *before;
4119 -     const char *entry;
4120 +lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
4121 +               const char *entry)
4122  {
4123    error_t error;
4124  
4125 -  if ((error = argz_insert (pargz, pargz_len, before, entry)))
4126 +  /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
4127 +     pargz_len, NULL, entry) failed with EINVAL.  */
4128 +  if (before)
4129 +    error = argz_insert (pargz, pargz_len, before, entry);
4130 +  else
4131 +    error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
4132 +
4133 +  if (error)
4134      {
4135        switch (error)
4136 -        {
4137 -        case ENOMEM:
4138 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
4139 -          break;
4140 -        default:
4141 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
4142 -          break;
4143 -        }
4144 +       {
4145 +       case ENOMEM:
4146 +         LT__SETERROR (NO_MEMORY);
4147 +         break;
4148 +       default:
4149 +         LT__SETERROR (UNKNOWN);
4150 +         break;
4151 +       }
4152        return 1;
4153      }
4154  
4155 @@ -3056,10 +1698,7 @@
4156  }
4157  
4158  static int
4159 -lt_argz_insertinorder (pargz, pargz_len, entry)
4160 -     char **pargz;
4161 -     size_t *pargz_len;
4162 -     const char *entry;
4163 +lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
4164  {
4165    char *before = 0;
4166  
4167 @@ -3070,42 +1709,39 @@
4168    if (*pargz)
4169      while ((before = argz_next (*pargz, *pargz_len, before)))
4170        {
4171 -        int cmp = strcmp (entry, before);
4172 +       int cmp = strcmp (entry, before);
4173  
4174 -        if (cmp < 0)  break;
4175 -        if (cmp == 0) return 0; /* No duplicates! */
4176 +       if (cmp < 0)  break;
4177 +       if (cmp == 0) return 0; /* No duplicates! */
4178        }
4179  
4180    return lt_argz_insert (pargz, pargz_len, before, entry);
4181  }
4182  
4183  static int
4184 -lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
4185 -     char **pargz;
4186 -     size_t *pargz_len;
4187 -     const char *dirnam;
4188 -     struct dirent *dp;
4189 +lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
4190 +                  struct dirent *dp)
4191  {
4192 -  char   *buf       = 0;
4193 +  char   *buf      = 0;
4194    size_t buf_len    = 0;
4195 -  char   *end       = 0;
4196 +  char   *end      = 0;
4197    size_t end_offset = 0;
4198    size_t dir_len    = 0;
4199 -  int    errors     = 0;
4200 +  int    errors            = 0;
4201  
4202    assert (pargz);
4203    assert (pargz_len);
4204    assert (dp);
4205  
4206    dir_len = LT_STRLEN (dirnam);
4207 -  end     = dp->d_name + LT_D_NAMLEN(dp);
4208 +  end     = dp->d_name + D_NAMLEN(dp);
4209  
4210    /* Ignore version numbers.  */
4211    {
4212      char *p;
4213      for (p = end; p -1 > dp->d_name; --p)
4214        if (strchr (".0123456789", p[-1]) == 0)
4215 -        break;
4216 +       break;
4217  
4218      if (*p == '.')
4219        end = p;
4220 @@ -3116,16 +1752,16 @@
4221      char *p;
4222      for (p = end -1; p > dp->d_name; --p)
4223        if (*p == '.')
4224 -        {
4225 -          end = p;
4226 -          break;
4227 -        }
4228 +       {
4229 +         end = p;
4230 +         break;
4231 +       }
4232    }
4233  
4234    /* Prepend the directory name.  */
4235 -  end_offset    = end - dp->d_name;
4236 -  buf_len       = dir_len + 1+ end_offset;
4237 -  buf           = LT_EMALLOC (char, 1+ buf_len);
4238 +  end_offset   = end - dp->d_name;
4239 +  buf_len      = dir_len + 1+ end_offset;
4240 +  buf          = MALLOC (char, 1+ buf_len);
4241    if (!buf)
4242      return ++errors;
4243  
4244 @@ -3140,19 +1776,16 @@
4245    if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
4246      ++errors;
4247  
4248 -  LT_DLFREE (buf);
4249 +  FREE (buf);
4250  
4251    return errors;
4252  }
4253  
4254  static int
4255 -list_files_by_dir (dirnam, pargz, pargz_len)
4256 -     const char *dirnam;
4257 -     char **pargz;
4258 -     size_t *pargz_len;
4259 +list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
4260  {
4261 -  DIR   *dirp     = 0;
4262 -  int    errors   = 0;
4263 +  DIR  *dirp     = 0;
4264 +  int    errors          = 0;
4265  
4266    assert (dirnam && *dirnam);
4267    assert (pargz);
4268 @@ -3162,15 +1795,15 @@
4269    dirp = opendir (dirnam);
4270    if (dirp)
4271      {
4272 -      struct dirent *dp = 0;
4273 +      struct dirent *dp        = 0;
4274  
4275        while ((dp = readdir (dirp)))
4276 -        if (dp->d_name[0] != '.')
4277 -          if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
4278 -            {
4279 -              ++errors;
4280 -              break;
4281 -            }
4282 +       if (dp->d_name[0] != '.')
4283 +         if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
4284 +           {
4285 +             ++errors;
4286 +             break;
4287 +           }
4288  
4289        closedir (dirp);
4290      }
4291 @@ -3184,15 +1817,11 @@
4292  /* If there are any files in DIRNAME, call the function passed in
4293     DATA1 (with the name of each file and DATA2 as arguments).  */
4294  static int
4295 -foreachfile_callback (dirname, data1, data2)
4296 -     char *dirname;
4297 -     lt_ptr data1;
4298 -     lt_ptr data2;
4299 +foreachfile_callback (char *dirname, void *data1, void *data2)
4300  {
4301 -  int (*func) LT_PARAMS((const char *filename, lt_ptr data))
4302 -        = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
4303 +  file_worker_func *func = *(file_worker_func **) data1;
4304  
4305 -  int     is_done  = 0;
4306 +  int    is_done  = 0;
4307    char   *argz     = 0;
4308    size_t  argz_len = 0;
4309  
4310 @@ -3205,11 +1834,11 @@
4311      char *filename = 0;
4312      while ((filename = argz_next (argz, argz_len, filename)))
4313        if ((is_done = (*func) (filename, data2)))
4314 -        break;
4315 +       break;
4316    }
4317  
4318   cleanup:
4319 -  LT_DLFREE (argz);
4320 +  FREE (argz);
4321  
4322    return is_done;
4323  }
4324 @@ -3222,44 +1851,44 @@
4325     libfoo.so, libfoo.so.1, libfoo.so.1.0.0).  If SEARCH_PATH is NULL,
4326     then the same directories that lt_dlopen would search are examined.  */
4327  int
4328 -lt_dlforeachfile (search_path, func, data)
4329 -     const char *search_path;
4330 -     int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
4331 -     lt_ptr data;
4332 +lt_dlforeachfile (const char *search_path,
4333 +                 int (*func) (const char *filename, void *data),
4334 +                 void *data)
4335  {
4336    int is_done = 0;
4337 +  file_worker_func **fpptr = &func;
4338  
4339    if (search_path)
4340      {
4341        /* If a specific path was passed, search only the directories
4342 -         listed in it.  */
4343 +        listed in it.  */
4344        is_done = foreach_dirinpath (search_path, 0,
4345 -                                   foreachfile_callback, func, data);
4346 +                                  foreachfile_callback, fpptr, data);
4347      }
4348    else
4349      {
4350        /* Otherwise search the default paths.  */
4351        is_done = foreach_dirinpath (user_search_path, 0,
4352 -                                   foreachfile_callback, func, data);
4353 +                                  foreachfile_callback, fpptr, data);
4354        if (!is_done)
4355 -        {
4356 -          is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
4357 -                                       foreachfile_callback, func, data);
4358 -        }
4359 +       {
4360 +         is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
4361 +                                      foreachfile_callback, fpptr, data);
4362 +       }
4363  
4364 -#ifdef LTDL_SHLIBPATH_VAR
4365 -      if (!is_done)
4366 -        {
4367 -          is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
4368 -                                       foreachfile_callback, func, data);
4369 -        }
4370 -#endif
4371 -#ifdef LTDL_SYSSEARCHPATH
4372 +#if defined(LT_MODULE_PATH_VAR)
4373        if (!is_done)
4374 -        {
4375 -          is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
4376 -                                       foreachfile_callback, func, data);
4377 -        }
4378 +       {
4379 +         is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
4380 +                                      foreachfile_callback, fpptr, data);
4381 +       }
4382 +#endif
4383 +#if defined(LT_DLSEARCH_PATH)
4384 +      if (!is_done && *sys_dlsearch_path)
4385 +       {
4386 +         is_done = foreach_dirinpath (sys_dlsearch_path, 0,
4387 +                                      foreachfile_callback, fpptr, data);
4388 +       }
4389  #endif
4390      }
4391  
4392 @@ -3267,14 +1896,11 @@
4393  }
4394  
4395  int
4396 -lt_dlclose (handle)
4397 -     lt_dlhandle handle;
4398 +lt_dlclose (lt_dlhandle handle)
4399  {
4400    lt_dlhandle cur, last;
4401    int errors = 0;
4402  
4403 -  LT_DLMUTEX_LOCK ();
4404 -
4405    /* check whether the handle is valid */
4406    last = cur = handles;
4407    while (cur && handle != cur)
4408 @@ -3285,80 +1911,80 @@
4409  
4410    if (!cur)
4411      {
4412 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4413 +      LT__SETERROR (INVALID_HANDLE);
4414        ++errors;
4415        goto done;
4416      }
4417  
4418 -  handle->info.ref_count--;
4419 +  cur = handle;
4420 +  cur->info.ref_count--;
4421  
4422    /* Note that even with resident modules, we must track the ref_count
4423       correctly incase the user decides to reset the residency flag
4424       later (even though the API makes no provision for that at the
4425       moment).  */
4426 -  if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
4427 +  if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
4428      {
4429 -      lt_user_data data = handle->loader->dlloader_data;
4430 +      lt_user_data data = cur->vtable->dlloader_data;
4431  
4432 -      if (handle != handles)
4433 -        {
4434 -          last->next = handle->next;
4435 -        }
4436 +      if (cur != handles)
4437 +       {
4438 +         last->next = cur->next;
4439 +       }
4440        else
4441 -        {
4442 -          handles = handle->next;
4443 -        }
4444 +       {
4445 +         handles = cur->next;
4446 +       }
4447  
4448 -      errors += handle->loader->module_close (data, handle->module);
4449 -      errors += unload_deplibs(handle);
4450 +      errors += cur->vtable->module_close (data, cur->module);
4451 +      errors += unload_deplibs (handle);
4452  
4453        /* It is up to the callers to free the data itself.  */
4454 -      LT_DLFREE (handle->caller_data);
4455 +      FREE (cur->interface_data);
4456  
4457 -      LT_DLFREE (handle->info.filename);
4458 -      LT_DLFREE (handle->info.name);
4459 -      LT_DLFREE (handle);
4460 +      FREE (cur->info.filename);
4461 +      FREE (cur->info.name);
4462 +      FREE (cur);
4463  
4464        goto done;
4465      }
4466  
4467    if (LT_DLIS_RESIDENT (handle))
4468      {
4469 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
4470 +      LT__SETERROR (CLOSE_RESIDENT_MODULE);
4471        ++errors;
4472      }
4473  
4474   done:
4475 -  LT_DLMUTEX_UNLOCK ();
4476 -
4477    return errors;
4478  }
4479  
4480 -lt_ptr
4481 -lt_dlsym (handle, symbol)
4482 -     lt_dlhandle handle;
4483 -     const char *symbol;
4484 +void *
4485 +lt_dlsym (lt_dlhandle place, const char *symbol)
4486  {
4487    size_t lensym;
4488 -  char  lsym[LT_SYMBOL_LENGTH];
4489 -  char  *sym;
4490 -  lt_ptr address;
4491 +  char lsym[LT_SYMBOL_LENGTH];
4492 +  char *sym;
4493 +  void *address;
4494    lt_user_data data;
4495 +  lt_dlhandle handle;
4496  
4497 -  if (!handle)
4498 +  if (!place)
4499      {
4500 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4501 +      LT__SETERROR (INVALID_HANDLE);
4502        return 0;
4503      }
4504  
4505 +  handle = place;
4506 +
4507    if (!symbol)
4508      {
4509 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
4510 +      LT__SETERROR (SYMBOL_NOT_FOUND);
4511        return 0;
4512      }
4513  
4514 -  lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
4515 -                                        + LT_STRLEN (handle->info.name);
4516 +  lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)
4517 +                                       + LT_STRLEN (handle->info.name);
4518  
4519    if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
4520      {
4521 @@ -3366,52 +1992,52 @@
4522      }
4523    else
4524      {
4525 -      sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
4526 +      sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
4527        if (!sym)
4528 -        {
4529 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
4530 -          return 0;
4531 -        }
4532 +       {
4533 +         LT__SETERROR (BUFFER_OVERFLOW);
4534 +         return 0;
4535 +       }
4536      }
4537  
4538 -  data = handle->loader->dlloader_data;
4539 +  data = handle->vtable->dlloader_data;
4540    if (handle->info.name)
4541      {
4542        const char *saved_error;
4543  
4544 -      LT_DLMUTEX_GETERROR (saved_error);
4545 +      LT__GETERROR (saved_error);
4546  
4547        /* this is a libtool module */
4548 -      if (handle->loader->sym_prefix)
4549 -        {
4550 -          strcpy(sym, handle->loader->sym_prefix);
4551 -          strcat(sym, handle->info.name);
4552 -        }
4553 +      if (handle->vtable->sym_prefix)
4554 +       {
4555 +         strcpy(sym, handle->vtable->sym_prefix);
4556 +         strcat(sym, handle->info.name);
4557 +       }
4558        else
4559 -        {
4560 -          strcpy(sym, handle->info.name);
4561 -        }
4562 +       {
4563 +         strcpy(sym, handle->info.name);
4564 +       }
4565  
4566        strcat(sym, "_LTX_");
4567        strcat(sym, symbol);
4568  
4569        /* try "modulename_LTX_symbol" */
4570 -      address = handle->loader->find_sym (data, handle->module, sym);
4571 +      address = handle->vtable->find_sym (data, handle->module, sym);
4572        if (address)
4573 -        {
4574 -          if (sym != lsym)
4575 -            {
4576 -              LT_DLFREE (sym);
4577 -            }
4578 -          return address;
4579 -        }
4580 -      LT_DLMUTEX_SETERROR (saved_error);
4581 +       {
4582 +         if (sym != lsym)
4583 +           {
4584 +             FREE (sym);
4585 +           }
4586 +         return address;
4587 +       }
4588 +      LT__SETERRORSTR (saved_error);
4589      }
4590  
4591    /* otherwise try "symbol" */
4592 -  if (handle->loader->sym_prefix)
4593 +  if (handle->vtable->sym_prefix)
4594      {
4595 -      strcpy(sym, handle->loader->sym_prefix);
4596 +      strcpy(sym, handle->vtable->sym_prefix);
4597        strcat(sym, symbol);
4598      }
4599    else
4600 @@ -3419,36 +2045,33 @@
4601        strcpy(sym, symbol);
4602      }
4603  
4604 -  address = handle->loader->find_sym (data, handle->module, sym);
4605 +  address = handle->vtable->find_sym (data, handle->module, sym);
4606    if (sym != lsym)
4607      {
4608 -      LT_DLFREE (sym);
4609 +      FREE (sym);
4610      }
4611  
4612    return address;
4613  }
4614  
4615  const char *
4616 -lt_dlerror ()
4617 +lt_dlerror (void)
4618  {
4619    const char *error;
4620  
4621 -  LT_DLMUTEX_GETERROR (error);
4622 -  LT_DLMUTEX_SETERROR (0);
4623 +  LT__GETERROR (error);
4624 +  LT__SETERRORSTR (0);
4625  
4626 -  return error ? error : LT_DLSTRERROR (UNKNOWN);
4627 +  return error ? error : NULL;
4628  }
4629  
4630  static int
4631 -lt_dlpath_insertdir (ppath, before, dir)
4632 -     char **ppath;
4633 -     char *before;
4634 -     const char *dir;
4635 +lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
4636  {
4637 -  int    errors         = 0;
4638 -  char  *canonical      = 0;
4639 -  char  *argz           = 0;
4640 -  size_t argz_len       = 0;
4641 +  int    errors                = 0;
4642 +  char  *canonical     = 0;
4643 +  char  *argz          = 0;
4644 +  size_t argz_len      = 0;
4645  
4646    assert (ppath);
4647    assert (dir && *dir);
4648 @@ -3464,14 +2087,14 @@
4649    /* If *PPATH is empty, set it to DIR.  */
4650    if (*ppath == 0)
4651      {
4652 -      assert (!before);         /* BEFORE cannot be set without PPATH.  */
4653 -      assert (dir);             /* Without DIR, don't call this function!  */
4654 +      assert (!before);                /* BEFORE cannot be set without PPATH.  */
4655 +      assert (dir);            /* Without DIR, don't call this function!  */
4656  
4657 -      *ppath = lt_estrdup (dir);
4658 +      *ppath = lt__strdup (dir);
4659        if (*ppath == 0)
4660 -        ++errors;
4661 +       ++errors;
4662  
4663 -      return errors;
4664 +      goto cleanup;
4665      }
4666  
4667    assert (ppath && *ppath);
4668 @@ -3490,7 +2113,7 @@
4669    if (before)
4670      {
4671        assert (*ppath <= before);
4672 -      assert (before - *ppath <= strlen (*ppath));
4673 +      assert ((int) (before - *ppath) <= (int) strlen (*ppath));
4674  
4675        before = before - *ppath + argz;
4676      }
4677 @@ -3502,127 +2125,108 @@
4678      }
4679  
4680    argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
4681 -  LT_DLMEM_REASSIGN (*ppath,  argz);
4682 +  MEMREASSIGN(*ppath, argz);
4683  
4684   cleanup:
4685 -  LT_DLFREE (canonical);
4686 -  LT_DLFREE (argz);
4687 +  FREE (argz);
4688 +  FREE (canonical);
4689  
4690    return errors;
4691  }
4692  
4693  int
4694 -lt_dladdsearchdir (search_dir)
4695 -     const char *search_dir;
4696 +lt_dladdsearchdir (const char *search_dir)
4697  {
4698    int errors = 0;
4699  
4700    if (search_dir && *search_dir)
4701      {
4702 -      LT_DLMUTEX_LOCK ();
4703        if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
4704 -        ++errors;
4705 -      LT_DLMUTEX_UNLOCK ();
4706 +       ++errors;
4707      }
4708  
4709    return errors;
4710  }
4711  
4712  int
4713 -lt_dlinsertsearchdir (before, search_dir)
4714 -     const char *before;
4715 -     const char *search_dir;
4716 +lt_dlinsertsearchdir (const char *before, const char *search_dir)
4717  {
4718    int errors = 0;
4719  
4720    if (before)
4721      {
4722 -      LT_DLMUTEX_LOCK ();
4723        if ((before < user_search_path)
4724 -          || (before >= user_search_path + LT_STRLEN (user_search_path)))
4725 -        {
4726 -          LT_DLMUTEX_UNLOCK ();
4727 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
4728 -          return 1;
4729 -        }
4730 -      LT_DLMUTEX_UNLOCK ();
4731 +         || (before >= user_search_path + LT_STRLEN (user_search_path)))
4732 +       {
4733 +         LT__SETERROR (INVALID_POSITION);
4734 +         return 1;
4735 +       }
4736      }
4737  
4738    if (search_dir && *search_dir)
4739      {
4740 -      LT_DLMUTEX_LOCK ();
4741        if (lt_dlpath_insertdir (&user_search_path,
4742 -                               (char *) before, search_dir) != 0)
4743 -        {
4744 -          ++errors;
4745 -        }
4746 -      LT_DLMUTEX_UNLOCK ();
4747 +                              (char *) before, search_dir) != 0)
4748 +       {
4749 +         ++errors;
4750 +       }
4751      }
4752  
4753    return errors;
4754  }
4755  
4756  int
4757 -lt_dlsetsearchpath (search_path)
4758 -     const char *search_path;
4759 +lt_dlsetsearchpath (const char *search_path)
4760  {
4761 -  int   errors      = 0;
4762 +  int   errors     = 0;
4763  
4764 -  LT_DLMUTEX_LOCK ();
4765 -  LT_DLFREE (user_search_path);
4766 -  LT_DLMUTEX_UNLOCK ();
4767 +  FREE (user_search_path);
4768  
4769    if (!search_path || !LT_STRLEN (search_path))
4770      {
4771        return errors;
4772      }
4773  
4774 -  LT_DLMUTEX_LOCK ();
4775    if (canonicalize_path (search_path, &user_search_path) != 0)
4776      ++errors;
4777 -  LT_DLMUTEX_UNLOCK ();
4778  
4779    return errors;
4780  }
4781  
4782  const char *
4783 -lt_dlgetsearchpath ()
4784 +lt_dlgetsearchpath (void)
4785  {
4786    const char *saved_path;
4787  
4788 -  LT_DLMUTEX_LOCK ();
4789    saved_path = user_search_path;
4790 -  LT_DLMUTEX_UNLOCK ();
4791  
4792    return saved_path;
4793  }
4794  
4795  int
4796 -lt_dlmakeresident (handle)
4797 -     lt_dlhandle handle;
4798 +lt_dlmakeresident (lt_dlhandle handle)
4799  {
4800    int errors = 0;
4801  
4802    if (!handle)
4803      {
4804 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4805 +      LT__SETERROR (INVALID_HANDLE);
4806        ++errors;
4807      }
4808    else
4809      {
4810 -      LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4811 +      handle->info.is_resident = 1;
4812      }
4813  
4814    return errors;
4815  }
4816  
4817  int
4818 -lt_dlisresident (handle)
4819 -     lt_dlhandle handle;
4820 +lt_dlisresident        (lt_dlhandle handle)
4821  {
4822    if (!handle)
4823      {
4824 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4825 +      LT__SETERROR (INVALID_HANDLE);
4826        return -1;
4827      }
4828  
4829 @@ -3631,369 +2235,187 @@
4830  
4831  
4832  
4833 -\f
4834  /* --- MODULE INFORMATION --- */
4835  
4836 -const lt_dlinfo *
4837 -lt_dlgetinfo (handle)
4838 -     lt_dlhandle handle;
4839 -{
4840 -  if (!handle)
4841 -    {
4842 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4843 -      return 0;
4844 -    }
4845 -
4846 -  return &(handle->info);
4847 -}
4848 -
4849 -lt_dlhandle
4850 -lt_dlhandle_next (place)
4851 -     lt_dlhandle place;
4852 -{
4853 -  return place ? place->next : handles;
4854 -}
4855 -
4856 -int
4857 -lt_dlforeach (func, data)
4858 -     int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
4859 -     lt_ptr data;
4860 -{
4861 -  int errors = 0;
4862 -  lt_dlhandle cur;
4863 -
4864 -  LT_DLMUTEX_LOCK ();
4865 -
4866 -  cur = handles;
4867 -  while (cur)
4868 -    {
4869 -      lt_dlhandle tmp = cur;
4870 -
4871 -      cur = cur->next;
4872 -      if ((*func) (tmp, data))
4873 -        {
4874 -          ++errors;
4875 -          break;
4876 -        }
4877 +typedef struct {
4878 +  const char *id_string;
4879 +  lt_dlhandle_interface *iface;
4880 +} lt__interface_id;
4881 +
4882 +lt_dlinterface_id
4883 +lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
4884 +{
4885 +  lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);
4886 +
4887 +  /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
4888 +     can then be detected with lt_dlerror() if we return 0.  */
4889 +  if (interface_id)
4890 +    {
4891 +      interface_id->id_string = lt__strdup (id_string);
4892 +      if (!interface_id->id_string)
4893 +       FREE (interface_id);
4894 +      else
4895 +       interface_id->iface = iface;
4896      }
4897  
4898 -  LT_DLMUTEX_UNLOCK ();
4899 -
4900 -  return errors;
4901 +  return (lt_dlinterface_id) interface_id;
4902  }
4903  
4904 -lt_dlcaller_id
4905 -lt_dlcaller_register ()
4906 +void lt_dlinterface_free (lt_dlinterface_id key)
4907  {
4908 -  static lt_dlcaller_id last_caller_id = 0;
4909 -  int result;
4910 -
4911 -  LT_DLMUTEX_LOCK ();
4912 -  result = ++last_caller_id;
4913 -  LT_DLMUTEX_UNLOCK ();
4914 -
4915 -  return result;
4916 +  lt__interface_id *interface_id = (lt__interface_id *)key;
4917 +  FREE (interface_id->id_string);
4918 +  FREE (interface_id);
4919  }
4920  
4921 -lt_ptr
4922 -lt_dlcaller_set_data (key, handle, data)
4923 -     lt_dlcaller_id key;
4924 -     lt_dlhandle handle;
4925 -     lt_ptr data;
4926 +void *
4927 +lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
4928  {
4929    int n_elements = 0;
4930 -  lt_ptr stale = (lt_ptr) 0;
4931 +  void *stale = (void *) 0;
4932 +  lt_dlhandle cur = handle;
4933    int i;
4934  
4935 -  /* This needs to be locked so that the caller data can be updated
4936 -     simultaneously by different threads.  */
4937 -  LT_DLMUTEX_LOCK ();
4938 -
4939 -  if (handle->caller_data)
4940 -    while (handle->caller_data[n_elements].key)
4941 +  if (cur->interface_data)
4942 +    while (cur->interface_data[n_elements].key)
4943        ++n_elements;
4944  
4945    for (i = 0; i < n_elements; ++i)
4946      {
4947 -      if (handle->caller_data[i].key == key)
4948 -        {
4949 -          stale = handle->caller_data[i].data;
4950 -          break;
4951 -        }
4952 +      if (cur->interface_data[i].key == key)
4953 +       {
4954 +         stale = cur->interface_data[i].data;
4955 +         break;
4956 +       }
4957      }
4958  
4959 -  /* Ensure that there is enough room in this handle's caller_data
4960 +  /* Ensure that there is enough room in this handle's interface_data
4961       array to accept a new element (and an empty end marker).  */
4962    if (i == n_elements)
4963      {
4964 -      lt_caller_data *temp
4965 -        = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
4966 +      lt_interface_data *temp
4967 +       = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
4968  
4969        if (!temp)
4970 -        {
4971 -          stale = 0;
4972 -          goto done;
4973 -        }
4974 +       {
4975 +         stale = 0;
4976 +         goto done;
4977 +       }
4978  
4979 -      handle->caller_data = temp;
4980 +      cur->interface_data = temp;
4981  
4982 -      /* We only need this if we needed to allocate a new caller_data.  */
4983 -      handle->caller_data[i].key  = key;
4984 -      handle->caller_data[1+ i].key = 0;
4985 +      /* We only need this if we needed to allocate a new interface_data.  */
4986 +      cur->interface_data[i].key       = key;
4987 +      cur->interface_data[1+ i].key    = 0;
4988      }
4989  
4990 -  handle->caller_data[i].data = data;
4991 +  cur->interface_data[i].data = data;
4992  
4993   done:
4994 -  LT_DLMUTEX_UNLOCK ();
4995 -
4996    return stale;
4997  }
4998  
4999 -lt_ptr
5000 -lt_dlcaller_get_data  (key, handle)
5001 -     lt_dlcaller_id key;
5002 -     lt_dlhandle handle;
5003 -{
5004 -  lt_ptr result = (lt_ptr) 0;
5005 -
5006 -  /* This needs to be locked so that the caller data isn't updated by
5007 -     another thread part way through this function.  */
5008 -  LT_DLMUTEX_LOCK ();
5009 +void *
5010 +lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
5011 +{
5012 +  void *result = (void *) 0;
5013 +  lt_dlhandle cur = handle;
5014  
5015    /* Locate the index of the element with a matching KEY.  */
5016 -  {
5017 -    int i;
5018 -    for (i = 0; handle->caller_data[i].key; ++i)
5019 -      {
5020 -        if (handle->caller_data[i].key == key)
5021 -          {
5022 -            result = handle->caller_data[i].data;
5023 -            break;
5024 -          }
5025 -      }
5026 -  }
5027 -
5028 -  LT_DLMUTEX_UNLOCK ();
5029 +  if (cur->interface_data)
5030 +    {
5031 +      int i;
5032 +      for (i = 0; cur->interface_data[i].key; ++i)
5033 +       {
5034 +         if (cur->interface_data[i].key == key)
5035 +           {
5036 +             result = cur->interface_data[i].data;
5037 +             break;
5038 +           }
5039 +       }
5040 +    }
5041  
5042    return result;
5043  }
5044  
5045 -
5046 -\f
5047 -/* --- USER MODULE LOADER API --- */
5048 -
5049 -
5050 -int
5051 -lt_dlloader_add (place, dlloader, loader_name)
5052 -     lt_dlloader *place;
5053 -     const struct lt_user_dlloader *dlloader;
5054 -     const char *loader_name;
5055 +const lt_dlinfo *
5056 +lt_dlgetinfo (lt_dlhandle handle)
5057  {
5058 -  int errors = 0;
5059 -  lt_dlloader *node = 0, *ptr = 0;
5060 -
5061 -  if ((dlloader == 0)   /* diagnose null parameters */
5062 -      || (dlloader->module_open == 0)
5063 -      || (dlloader->module_close == 0)
5064 -      || (dlloader->find_sym == 0))
5065 -    {
5066 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5067 -      return 1;
5068 -    }
5069 -
5070 -  /* Create a new dlloader node with copies of the user callbacks.  */
5071 -  node = LT_EMALLOC (lt_dlloader, 1);
5072 -  if (!node)
5073 -    return 1;
5074 -
5075 -  node->next            = 0;
5076 -  node->loader_name     = loader_name;
5077 -  node->sym_prefix      = dlloader->sym_prefix;
5078 -  node->dlloader_exit   = dlloader->dlloader_exit;
5079 -  node->module_open     = dlloader->module_open;
5080 -  node->module_close    = dlloader->module_close;
5081 -  node->find_sym        = dlloader->find_sym;
5082 -  node->dlloader_data   = dlloader->dlloader_data;
5083 -
5084 -  LT_DLMUTEX_LOCK ();
5085 -  if (!loaders)
5086 -    {
5087 -      /* If there are no loaders, NODE becomes the list! */
5088 -      loaders = node;
5089 -    }
5090 -  else if (!place)
5091 -    {
5092 -      /* If PLACE is not set, add NODE to the end of the
5093 -         LOADERS list. */
5094 -      for (ptr = loaders; ptr->next; ptr = ptr->next)
5095 -        {
5096 -          /*NOWORK*/;
5097 -        }
5098 -
5099 -      ptr->next = node;
5100 -    }
5101 -  else if (loaders == place)
5102 -    {
5103 -      /* If PLACE is the first loader, NODE goes first. */
5104 -      node->next = place;
5105 -      loaders = node;
5106 -    }
5107 -  else
5108 +  if (!handle)
5109      {
5110 -      /* Find the node immediately preceding PLACE. */
5111 -      for (ptr = loaders; ptr->next != place; ptr = ptr->next)
5112 -        {
5113 -          /*NOWORK*/;
5114 -        }
5115 -
5116 -      if (ptr->next != place)
5117 -        {
5118 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5119 -          ++errors;
5120 -        }
5121 -      else
5122 -        {
5123 -          /* Insert NODE between PTR and PLACE. */
5124 -          node->next = place;
5125 -          ptr->next  = node;
5126 -        }
5127 +      LT__SETERROR (INVALID_HANDLE);
5128 +      return 0;
5129      }
5130  
5131 -  LT_DLMUTEX_UNLOCK ();
5132 -
5133 -  return errors;
5134 +  return &(handle->info);
5135  }
5136  
5137 -int
5138 -lt_dlloader_remove (loader_name)
5139 -     const char *loader_name;
5140 -{
5141 -  lt_dlloader *place = lt_dlloader_find (loader_name);
5142 -  lt_dlhandle handle;
5143 -  int errors = 0;
5144 -
5145 -  if (!place)
5146 -    {
5147 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5148 -      return 1;
5149 -    }
5150  
5151 -  LT_DLMUTEX_LOCK ();
5152 +lt_dlhandle
5153 +lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
5154 +{
5155 +  lt_dlhandle handle = place;
5156 +  lt__interface_id *iterator = (lt__interface_id *) iface;
5157  
5158 -  /* Fail if there are any open modules which use this loader. */
5159 -  for  (handle = handles; handle; handle = handle->next)
5160 -    {
5161 -      if (handle->loader == place)
5162 -        {
5163 -          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
5164 -          ++errors;
5165 -          goto done;
5166 -        }
5167 -    }
5168 +  assert (iface); /* iface is a required argument */
5169  
5170 -  if (place == loaders)
5171 -    {
5172 -      /* PLACE is the first loader in the list. */
5173 -      loaders = loaders->next;
5174 -    }
5175 +  if (!handle)
5176 +    handle = handles;
5177    else
5178 -    {
5179 -      /* Find the loader before the one being removed. */
5180 -      lt_dlloader *prev;
5181 -      for (prev = loaders; prev->next; prev = prev->next)
5182 -        {
5183 -          if (!strcmp (prev->next->loader_name, loader_name))
5184 -            {
5185 -              break;
5186 -            }
5187 -        }
5188 +    handle = handle->next;
5189  
5190 -      place = prev->next;
5191 -      prev->next = prev->next->next;
5192 -    }
5193 -
5194 -  if (place->dlloader_exit)
5195 +  /* advance while the interface check fails */
5196 +  while (handle && iterator->iface
5197 +        && ((*iterator->iface) (handle, iterator->id_string) != 0))
5198      {
5199 -      errors = place->dlloader_exit (place->dlloader_data);
5200 +      handle = handle->next;
5201      }
5202  
5203 -  LT_DLFREE (place);
5204 -
5205 - done:
5206 -  LT_DLMUTEX_UNLOCK ();
5207 -
5208 -  return errors;
5209 +  return handle;
5210  }
5211  
5212 -lt_dlloader *
5213 -lt_dlloader_next (place)
5214 -     lt_dlloader *place;
5215 -{
5216 -  lt_dlloader *next;
5217 -
5218 -  LT_DLMUTEX_LOCK ();
5219 -  next = place ? place->next : loaders;
5220 -  LT_DLMUTEX_UNLOCK ();
5221 -
5222 -  return next;
5223 -}
5224  
5225 -const char *
5226 -lt_dlloader_name (place)
5227 -     lt_dlloader *place;
5228 +lt_dlhandle
5229 +lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
5230  {
5231 -  const char *name = 0;
5232 +  lt_dlhandle handle = 0;
5233  
5234 -  if (place)
5235 -    {
5236 -      LT_DLMUTEX_LOCK ();
5237 -      name = place ? place->loader_name : 0;
5238 -      LT_DLMUTEX_UNLOCK ();
5239 -    }
5240 -  else
5241 +  assert (iface); /* iface is a required argument */
5242 +
5243 +  while ((handle = lt_dlhandle_iterate (iface, handle)))
5244      {
5245 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5246 +      lt_dlhandle cur = handle;
5247 +      if (cur && cur->info.name && streq (cur->info.name, module_name))
5248 +       break;
5249      }
5250  
5251 -  return name;
5252 +  return handle;
5253  }
5254  
5255 -lt_user_data *
5256 -lt_dlloader_data (place)
5257 -     lt_dlloader *place;
5258 +
5259 +int
5260 +lt_dlhandle_map (lt_dlinterface_id iface,
5261 +                int (*func) (lt_dlhandle handle, void *data), void *data)
5262  {
5263 -  lt_user_data *data = 0;
5264 +  lt__interface_id *iterator = (lt__interface_id *) iface;
5265 +  lt_dlhandle cur = handles;
5266  
5267 -  if (place)
5268 -    {
5269 -      LT_DLMUTEX_LOCK ();
5270 -      data = place ? &(place->dlloader_data) : 0;
5271 -      LT_DLMUTEX_UNLOCK ();
5272 -    }
5273 -  else
5274 -    {
5275 -      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
5276 -    }
5277 +  assert (iface); /* iface is a required argument */
5278  
5279 -  return data;
5280 -}
5281 +  while (cur)
5282 +    {
5283 +      int errorcode = 0;
5284  
5285 -lt_dlloader *
5286 -lt_dlloader_find (loader_name)
5287 -     const char *loader_name;
5288 -{
5289 -  lt_dlloader *place = 0;
5290 +      /* advance while the interface check fails */
5291 +      while (cur && iterator->iface
5292 +            && ((*iterator->iface) (cur, iterator->id_string) != 0))
5293 +       {
5294 +         cur = cur->next;
5295 +       }
5296  
5297 -  LT_DLMUTEX_LOCK ();
5298 -  for (place = loaders; place; place = place->next)
5299 -    {
5300 -      if (strcmp (place->loader_name, loader_name) == 0)
5301 -        {
5302 -          break;
5303 -        }
5304 +      if ((errorcode = (*func) (cur, data)) != 0)
5305 +       return errorcode;
5306      }
5307 -  LT_DLMUTEX_UNLOCK ();
5308  
5309 -  return place;
5310 +  return 0;
5311  }