+2004-07-15 Gary V. Vaughan <gary@gnu.org>
+
+ This pervasive changeset makes two intertwined deep changes to the
+ operation of libtool (neither would work alone). First, there is
+ a new feature that allows libraries to preopen modules. This
+ entails a backwards incompatible change to the libltdl API for
+ separating out the preloaded symbol lists by owner. Second, in
+ the tradition of "eating our own dogfood", libltdl now preloads
+ its own dlloaders. The internal API for dlloaders has also had to
+ change in a backwards incompatible way in support of the new
+ library preloading feature. If you don't use preloaded libraries,
+ you needn't change your project sources, though you will need to
+ recompile against the new libltdl. The API changes are mostly
+ confined to dlloaders, so you probably needn't worry about those
+ (unless you have written a custom loader that you want libltdl to
+ use):
+
+ * configure.ac (AC_CONFIG_FILES): Add libltdl/loaders/Makefile.
+ * libltdl/configure.ac (AC_CONFIG_FILES): Add loaders/Makefile.
+ * libltdl/loaders: New directory for module loaders, to simplify
+ Makefile rules, and to give the loaders themselves names that are
+ unique in the first few characters.
+ * libtoolize.in (func_copy_all_files): Copy recursively to pick up
+ the loaders directory contents.
+ * libltdl/loaders/Makefile.am: New file. Move module building
+ rules to here...
+ * libltdl/Makefile.am: ...from here.
+ (VERSION_INFO): Bumped version info to signify interface changes.
+ (libltdl_la_CPPFLAGS, libltdlc_la_CPPFLAGS): Set LTDLOPEN
+ appropriately for each library.
+ * libltdl/loader-dld_link.c, libltdl/loader-dlopen.c,
+ libltdl/loader-dyld.c, libltdl/loader-load_add_on.c,
+ libltdl/loader-loadlibrary.c libltdl/loader-preopen.c,
+ libltdl/loader-shl_load.c: Moved from here...
+ * libltdl/loaders/dld_link.c, libltdl/loaders/dlopen.c,
+ libltdl/loaders/dyld.c, libltdl/loaders/load_add_on.c,
+ libltdl/loaders/loadlibrary.c libltdl/loaders/preopen.c,
+ libltdl/loaders/shl_load.c: ...to here.
+ (get_vtable): New entry function for each.
+ * libltdl/loaders/preopen.c (lt_dlsymlists_t): Replaced by...
+ (symlist_chain): ...a new structure which maps lists of preloaded
+ symbols from the object that loads them.
+ (lt_dlpreload_open): New function to automatically open all
+ preloaded modules belonging to a named object (ORIGINATOR).
+ * libltdl/lt__alloc.c (lt__zalloc): New function to return a block
+ of zeroed out new memory.
+ * libltdl/lt__alloc.h (lt__zalloc): Prototype it.
+ * libltdl/lt__private.h (lt__alloc_die_callback): Add missing
+ prototype.
+ (lt__error_strings): Make this opaque to callers.
+ * libltdl/lt_error.c (lt__error_strings): Move the implementation
+ to here.
+ * libltdl/lt_dlloader.h (lt_user_dlloader): Add extra fields to
+ make originator focused preloading possible. *BREAKS BACKWARDS
+ COMPATIBILITY*
+ (lt_dlloader_add): Take advantage of new fields to simplify
+ paramater list.
+ * libltdl/lt_system.h (LT_STR): New ANSI stringification macro.
+ (LT_CONC): Fix it to work from within macros.
+ * libltdl/ltdl.c (loader_init, loader_init_callback): Simplify
+ dlloader loading.
+ (get_vtable, preloaded_symbols): Point these at the preopen.c
+ symbols to bootstrap the loader chain.
+ (lt_dlinit): Load the preopen dlloader manually, and then use it
+ to load any other preloaded dlloaders.
+ (lt_dlloader_add): Simplify parameter list. Populate new
+ fields. Chain new loaders according to priority field.
+ * libltdl/ltdl.h (lt_dlsymlist): Add a new originator field.
+ (lt_dlpreload_callback_func): Type of a callback for automatic
+ lt_dlpreload_open loading.
+ (LTDL_SET_PRELOADED_SYMBOLS): Adjust to hook into preloaded
+ symbols from the "@PROGRAM@" originator.
+ * tests/demo/dlmain.c (main): Use mangled preloaded_symbols symbol.
+ * tests/pdemo/longer_file_name_dlmain.c (main): Ditto.
+ * ltmain.in: Don't spew spurious warnings when dlopening and
+ dlpreopening modules.
+ (func_generate_dlsyms): Factored out from multiple copies in the
+ rest of the code. Generate originator keyed symbol lists.
+ (func_extract_archives): Also factored. Extract the contents of
+ convenience archives for linking with dependent libraries when
+ --whole-archive is not available.
+ [darwin]: Don't try to link $old_library unless it exists, and
+ $lib is a bundle.
+ * m4/ltdl.m4 (AC_LTDL_DLLIB): Check for all possible dynamic
+ loading libraries/apis rather that stopping when an acceptable one
+ is discovered.
+ (LT_DLLOADERS): New variable for holding dlloaders that can be
+ preloaded.
+ * doc/libtool.texi: Document interface changes.
+ * NEWS: Updated.
+
2004-07-12 Peter O'Gorman <peter@pogma.com>
* m4/libtool.m4 [darwin]: Set whole_archive_flag_spec to '' for xlc,
and when -all_load is also specified Apple's /usr/bin/libtool barfs
and dies.
-2004-07-08 Gary V. Vaughan <gary@gnu.org>
+2004-07-07 Gary V. Vaughan <gary@gnu.org>
* libltdl/ltdl.h (lt_dlinfo): Move private module field to here...
* libltdl/ltdl.c (lt_dlhandle_struct): ...from here. Changed all
* Mode inferrence removed, shorthand for choosing modes added.
* Specifying -allow-undefined is now an error.
* Speed up max_cmd_len check.
+* libltdl can now preopen modules from within a library, and libtool will
+ accept -dlpreopen options when linking either a shared library or a
+ convenience library.
* New function in libltdl: lt_dlhandle_find provides access to module handles
by module name.
+* New function in libltdl: lt_dlpreload_open opens all preloaded modules.
* libltdl no longer loads shared libraries with global symbol resolution,
this caused problems when the symbols were intended to be overriden further
up the stack; it is also not recommended practice.
## -------- ##
## Outputs. ##
## -------- ##
-AC_CONFIG_FILES([Makefile libltdl/Makefile doc/Makefile tests/Makefile])
+AC_CONFIG_FILES([Makefile libltdl/Makefile libltdl/loaders/Makefile
+ doc/Makefile tests/Makefile])
AC_OUTPUT
a consistent way.
@item
-It is not always obvious with which suffix a shared library should be
+It is not always obvious with what suffix a shared library should be
installed. This makes it difficult for @file{Makefile} rules, since they
generally assume that file names are the same from host to host.
@example
a23$ @kbd{libtool link gcc -g -O -o libhello.la foo.o hello.o}
libtool: cannot build libtool library `libhello.la' from non-libtool \
- objects
+ objects
a23$
@end example
Aha! Libtool caught a common error@dots{} trying to build a library
from standard objects instead of library objects. This doesn't matter
-for static libraries, but on shared library systems, it is of great
-importance.
+so much for static libraries, but on shared library systems, it is of
+great importance.
So, let's try again, this time with the library object files. Remember
also that we need to add @kbd{-lm} to the link command line because
directly or indirectly, into a single program or library, otherwise you
may get errors about symbol redefinitions.
+The key is remembering that a convenience library contains @sc{pic}
+objects, and can linked where a list of @sc{pic} objects makes sense;
+i.e. into a shared library. A static convenience library contains
+non-@sc{pic} objects, so can be linked into an old static library, or
+a program.
+
When @sc{gnu} Automake is used, you should use @code{noinst_LTLIBRARIES}
instead of @code{lib_LTLIBRARIES} for convenience libraries, so that
the @samp{-rpath} option is not passed when they are linked.
@code{-export-dynamic} or by falling back to @samp{-dlpreopen self}.
@item -dlpreopen @var{file}
-Link @var{file} into the output program, and add its symbols to
-@var{lt_preloaded_symbols} (@pxref{Dlpreopening}). If @var{file} is
+Link @var{file} into the output program, and add its symbols to the
+list of preloaded symbols (@pxref{Dlpreopening}). If @var{file} is
@code{self}, the symbols of the program itself will be added to
-@var{lt_preloaded_symbols}.
-If @var{file} is @code{force} Libtool will make sure that
-@var{lt_preloaded_symbols} is always @emph{defined}, regardless of whether
-it's empty or not.
+preloaded symbol lists. If @var{file} is @code{force} Libtool will
+make sure that a preloaded symbol list is always @emph{defined},
+regardless of whether it's empty or not.
@item -export-dynamic
Allow symbols from @var{output-file} to be resolved with @code{dlsym}
First, to link a program against a libtool library, just use the
@samp{program_LDADD}@footnote{@c
@c
-With recent @sc{gnu} Automake (1.5 or newer), the flags @samp{-dlopen}
+Since @sc{gnu} Automake 1.5, the flags @samp{-dlopen}
or @samp{-dlpreopen} (@pxref{Link mode}) can be employed with the
@var{program_LDADD} variable. Unfortunately, older releases didn't
accept these flags, so if you are stuck with an ancient Automake, we
@item pic-only
Change the default behaviour for @command{libtool} to try to use only
-PIC objects. The user may still override this default by specifying
+@sc{pic} objects. The user may still override this default by specifying
@samp{--with-pic} to @command{configure}.
@item no-pic
Change the default behaviour of @command{libtool} to try to use only
-non-PIC objects. The user may still override this default by
+non-@sc{pic} objects. The user may still override this default by
specifying @samp{--without-pic} to @command{configure}.
@end table
libtoolize}), it will tell you where to find a definition of
@code{LT_INIT}. If you use Automake, the @code{aclocal} program
will automatically add @code{LT_INIT} support to your
-@code{configure} script.
+@file{configure} script when it sees the invocation of @code{LT_INIT}
+in @file{configure.ac}.
Because of these changes, and the runtime version compatibility checks
-Libtool now executes, we now advise @emph{against} including a copy of
-@file{libtool.m4} (and bretheren) in @file{acinclude.m4}. When you
-@command{libtoolize} your project, a copy of the relevant macro
-definitions will be placed in your @code{AC_CONFIG_MACRO_DIR}, where
-@command{aclocal} can reference them directly from @file{aclocal.m4}.
+Libtool now executes, we now advise @strong{against} including a copy of
+@file{libtool.m4} (and bretheren) in @file{acinclude.m4}. Instead,
+you should set your project macro directory with
+@code{AC_CONFIG_MACRO_DIR}. When you @command{libtoolize} your
+project, a copy of the relevant macro definitions will be placed in
+your @code{AC_CONFIG_MACRO_DIR}, where @command{aclocal} can reference
+them directly from @file{aclocal.m4}.
@node Distributing
If @command{libtoolize} detects an explicit call to
@code{AC_CONFIG_MACRO_DIR} (@pxref{Input, , The Autoconf Manual,
autoconf, The Autoconf Manual}) in your @file{configure.ac}, it will
-put the Libtool macros in the specified directory. Otherwise they are
-dumped in the project root directory.
+put the Libtool macros in the specified directory.
@findex AC_CONFIG_AUX_DIR
If @command{libtoolize} detects an explicit call to
@example
The GIMP uses @sc{gnu} Libtool in order to build shared libraries on a
-variety of systems. While this is very nice for making usable
+variety of systems. While this is very nice for making usable
binaries, it can be a pain when trying to debug a program. For that
reason, compilation of shared libraries can be turned off by
specifying the @samp{--disable-shared} option to @file{configure}.
The @code{long double} type is not supported by many compilers.
@end itemize
+
@node Inter-library dependencies
@chapter Inter-library dependencies
@cindex dependencies between libraries
process, dynamic linking is transparent to the application.
@item
-The application calling functions such as @code{dlopen},@footnote{HP-UX,
-to be different, uses a function named @code{shl_load}.} which load
+The application calling functions such as @code{dlopen}, which load
arbitrary, user-specified modules at runtime. This type of dynamic
linking is explicitly controlled by the application.
@end enumerate
application program that dlopens other modules or a libtool library
that will also be dlopened.
-For example, if we wanted to build a shared library, @file{libhello},
+For example, if we wanted to build a shared library, @file{hello},
that would later be dlopened by an application, we would add
@samp{-module} to the other link flags:
@example
-burger$ @kbd{libtool link gcc -module -o libhello.la foo.lo \
+burger$ @kbd{libtool link gcc -module -o hello.la foo.lo \
hello.lo -rpath /usr/local/lib -lm}
burger$
@end example
using the @samp{-dlopen} or @samp{-dlpreopen} flags when you link your
program (@pxref{Link mode}).
-@deftypefn {Structure} {struct} lt_dlsymlist @{ @w{const char *@var{name};} @w{lt_ptr @var{address};} @}
+@deftypefn {Structure} {struct} lt_dlsymbol @{ @w{const char *@var{name};} @w{void *@var{address};} @}
The @var{name} attribute is a null-terminated character string of the
symbol name, such as @code{"fprintf"}. The @var{address} attribute is a
generic pointer to the appropriate object, such as @code{&fprintf}.
@end deftypefn
+@deftypefn {Structure} {struct} lt_dlsymlist @{ @w{const char *@var{originator};} @w{const lt_dlsymbol @var{symbols}[];} @}
+The @var{originator} attribute is a null-terminated character string,
+naming the compilation unit that @var{symbols} were preloaded on
+behalf of. This is usually the basename of a library,
+@file{libltdl.la} has a corresponding @var{originator} value of
+@samp{libltdl}; if the @var{symbols} are for the benefit of the
+application proper, then @var{originator} is @samp{@@PROGRAM@@},
+though Libtool takes care of that detail if you use
+@samp{LTDL_SET_PRELOADED_SYMBOLS}.
+@end deftypefn
+
@deftypevar {const lt_dlsymlist *} lt_preloaded_symbols
An array of @var{lt_symbol} structures, representing all the preloaded
-symbols linked into the program. For each @samp{-dlpreloaded} file
-there is an element with the @var{name} of the file and a @var{address}
+symbols linked into the program proper. For each module
+@samp{-dlpreloaded} by the Libtool linked program
+there is an element with the @var{name} of the module and a @var{address}
of @code{0}, followed by all symbols exported from this file.
-For the executable itself the special name @@PROGRAM@@ is used.
-The last element has a @var{name} and @var{address} of @code{0}.
+For the executable itself the special name @samp{@@PROGRAM@@} is used.
+The last element of all has a @var{name} and @var{address} of
+@code{0}.
@end deftypevar
Some compilers may allow identifiers which are not valid in ANSI C, such
letters, digits, and underscores), so non-ANSI symbols will not appear
in @var{lt_preloaded_symbols}.
+@deftypefun int lt_dlpreload (const lt_dlsymlist *@var{preloaded})
+Register the list of preloaded modules @var{preloaded}.
+If @var{preloaded} is @code{NULL}, then all previously registered
+symbol lists, except the list set by @code{lt_dlpreload_default},
+are deleted. Return 0 on success.
+@end deftypefun
+
+@deftypefun int lt_dlpreload_default (const lt_dlsymlist *@var{preloaded})
+Set the default list of preloaded modules to @var{preloaded}, which
+won't be deleted by @code{lt_dlpreload}. Note that this function does
+@emph{not} require libltdl to be initialized using @code{lt_dlinit} and
+can be used in the program to register the default preloaded modules.
+Instead of calling this function directly, most programs will use the
+macro @code{LTDL_SET_PRELOADED_SYMBOLS}.
+
+Return 0 on success.
+@end deftypefun
+
+@defmac LTDL_SET_PRELOADED_SYMBOLS
+Set the default list of preloaded symbols.
+Should be used in your program to initialize libltdl's
+list of preloaded modules.
+
+@example
+#include <ltdl.h>
+
+int main() @{
+ /* ... */
+ LTDL_SET_PRELOADED_SYMBOLS();
+ /* ... */
+@}
+@end example
+@end defmac
+
+@deftypefn {Function Type} {int} lt_dlpreload_callback_func (lt_dlhandle @var{handle})
+Functions of this type can be passed to @code{lt_dlpreload_open},
+which in turn will call back into a function thus passed for each
+preloaded module that it opens.
+@end deftypefn
+
+@deftypefun int lt_dlpreload_open (@w{const char *@var{originator},} @w{lt_dlpreload_callback_func *@var{func})}
+Load all of the preloaded modules for @var{originator}. For every
+module opened in this way, call @var{func}.
+
+@noindent
+To open all of the modules preloaded into @file{libhell.la}
+(presumably from within the @samp{libhell.a} initialisation code):
+
+@example
+#define preloaded_symbols lt_libhell_LTX_preloaded_symbols
+
+static int hell_preload_callback (lt_dlhandle handle);
+
+int
+hell_init (void)
+@{
+ @dots{}
+ if (lt_dlpreload (&preloaded_symbols) == 0)
+ @{
+ lt_dlpreload_open ("libhell", preload_callback);
+ @}
+ @dots{}
+@}
+@end example
+
+@noindent
+Note that to prevent clashes between multiple preloaded modules, the
+preloaded symbols are accessed via a mangled symbol name: to get the
+symbols preloaded into @samp{libhell}, you must prefix
+@samp{preloaded_symbols} with @samp{lt_}; the originator name,
+@samp{libhell} in this case; and @samp{_LTX_}. That is,
+@samp{lt_libhell_LTX_preloaded_symbols} here.
+@end deftypefun
+
+
@node Finding the dlname
@section Finding the correct name to dlopen
@cindex names of dynamic modules
or since it was last called.
@end deftypefun
-@deftypefun int lt_dlpreload (const lt_dlsymlist *@var{preloaded})
-Register the list of preloaded modules @var{preloaded}.
-If @var{preloaded} is @code{NULL}, then all previously registered
-symbol lists, except the list set by @code{lt_dlpreload_default},
-are deleted. Return 0 on success.
-@end deftypefun
-
-@deftypefun int lt_dlpreload_default (const lt_dlsymlist *@var{preloaded})
-Set the default list of preloaded modules to @var{preloaded}, which
-won't be deleted by @code{lt_dlpreload}. Note that this function does
-@emph{not} require libltdl to be initialized using @code{lt_dlinit} and
-can be used in the program to register the default preloaded modules.
-Instead of calling this function directly, most programs will use the
-macro @code{LTDL_SET_PRELOADED_SYMBOLS}.
-
-Return 0 on success.
-@end deftypefun
-
-@defmac LTDL_SET_PRELOADED_SYMBOLS
-Set the default list of preloaded symbols.
-Should be used in your program to initialize libltdl's
-list of preloaded modules.
-
-@example
-#include <ltdl.h>
-
-int main() @{
- /* ... */
- LTDL_SET_PRELOADED_SYMBOLS();
- /* ... */
-@}
-@end example
-@end defmac
-
@deftypefun int lt_dladdsearchdir (const char *@var{search_dir})
Append the search directory @var{search_dir} to the current user-defined
library search path. Return 0 on success.
@file{demo-nofast.test} configures @file{demo/libtool} to
disable the fast-install mode (@samp{--enable-fast-install=no}).
@file{demo-pic.test} configures @file{demo/libtool} to
-prefer building PIC code (@samp{--with-pic}), @file{demo-nopic.test}
-to prefer non-PIC code (@samp{--without-pic}).
+prefer building @sc{pic} code (@samp{--with-pic}), @file{demo-nopic.test}
+to prefer non-@sc{pic} code (@samp{--without-pic}).
@item deplibs.test
@pindex deplibs.test
other systems.
@item man pages for @code{ld} and @code{cc}
-These generally describe what flags are used to generate PIC, to create
+These generally describe what flags are used to generate @sc{pic}, to create
shared libraries, and to link against only static libraries. You may
need to follow some cross references to find the information that is
required.
@subsection Compilers
The only compiler characteristics that affect libtool are the flags
-needed (if any) to generate PIC objects. In general, if a C compiler
-supports certain PIC flags, then any derivative compilers support the
+needed (if any) to generate @sc{pic} objects. In general, if a C compiler
+supports certain @sc{pic} flags, then any derivative compilers support the
same flags. Until there are some noteworthy exceptions to this rule,
this section will document only C compilers.
@table @code
@item aix3*
@itemx aix4*
-Most AIX compilers have no PIC flags, since AIX (with the exception of
+Most AIX compilers have no @sc{pic} flags, since AIX (with the exception of
AIX for IA-64) runs on PowerPC and RS/6000 chips. @footnote{All code compiled
for the PowerPC and RS/6000 chips (@code{powerpc-*-*}, @code{powerpcle-*-*},
and @code{rs6000-*-*}) is position-independent, regardless of the operating
system or compiler suite. So, ``regular objects'' can be used to build
-shared libraries on these systems and no special PIC compiler flags are
+shared libraries on these systems and no special @sc{pic} compiler flags are
required.}
@item hpux10*
-Use @samp{+Z} to generate PIC.
+Use @samp{+Z} to generate @sc{pic}.
@item osf3*
-Digital/UNIX 3.x does not have PIC flags, at least not on the PowerPC
+Digital/UNIX 3.x does not have @sc{pic} flags, at least not on the PowerPC
platform.
@item solaris2*
-Use @samp{-KPIC} to generate PIC.
+Use @samp{-KPIC} to generate @sc{pic}.
@item sunos4*
-Use @samp{-PIC} to generate PIC.
+Use @samp{-PIC} to generate @sc{pic}.
@end table
@node Reloadable objects
@example
trick$ cd ~/bin
-trick$ sed '/^# ltmain\.sh/q' /home/src/libtool/libtool > libtool
+trick$ sed 's%^\(macro_version=\).*$%\1@@VERSION@@%;
+ s%^\(macro_revision=\).*$%\1@@TIMESTAMP@@%;
+ /^# ltmain\.sh/q' /home/src/libtool/libtool > libtool
trick$ echo '. /home/src/libtool/ltmain.in' >> libtool
trick$ chmod +x libtool
trick$ libtool --version
## the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
## Boston, MA 02111-1307, USA.
-BUILT_SOURCES =
-MOSTLYCLEANFILES =
-EXTRA_DIST =
+SUBDIRS = loaders .
-AUTOMAKE_OPTIONS = foreign
-ACLOCAL_AMFLAGS = -I m4
-AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
-DEFS = -DHAVE_CONFIG_H="<$(CONFIG_H)>" -DLTDL
+BUILT_SOURCES =
+MOSTLYCLEANFILES =
+EXTRA_DIST =
-pkgincludedir = $(includedir)/libltdl
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I m4
+DEFS = -DHAVE_CONFIG_H="<$(CONFIG_H)>" -DLTDL
+AM_CPPFLAGS = -I$(top_builddir)/.. -I$(top_srcdir)/..
+AM_LDFLAGS = -no-undefined
+VERSION_INFO = -version-info 6:0:0
+
+pkgincludedir = $(includedir)/libltdl
+
+lib_LTLIBRARIES = libdlloader.la
+libdlloader_la_SOURCES = lt_error.h lt_error.c \
+ lt__private.h lt_dlloader.h \
+ lt__alloc.h lt__alloc.c \
+ lt__glibc.h lt_system.h
+libdlloader_la_LDFLAGS = $(VERSION_INFO)
+libdlloader_la_LIBADD = $(LTLIBOBJS)
+
+## Libltdl brings it all together:
if INSTALL_LTDL
-include_HEADERS = ltdl.h
-pkginclude_HEADERS = lt_system.h lt_error.h
-lib_LTLIBRARIES = libltdl.la
+include_HEADERS = ltdl.h
+pkginclude_HEADERS = lt_system.h lt_error.h
+lib_LTLIBRARIES += libltdl.la
endif
if CONVENIENCE_LTDL
-noinst_LTLIBRARIES = libltdlc.la
+noinst_LTLIBRARIES = libltdlc.la
endif
-## Make sure these will be cleaned even when they're not built by
-## default.
-CLEANFILES = libltdl.la libltdlc.la
+libltdl_la_SOURCES = ltdl.h ltdl.c loaders/preopen.c
+libltdl_la_CPPFLAGS = -DLTDLOPEN=libltdl $(AM_CPPFLAGS)
+libltdl_la_LDFLAGS = $(VERSION_INFO) $(LT_DLPREOPEN)
+libltdl_la_LIBADD = libdlloader.la
-libltdl_la_SOURCES = loader-preopen.c \
- lt__alloc.c lt__alloc.h lt__dirent.h lt__glibc.h \
- lt__private.h lt_dlloader.h \
- lt_error.c lt_error.h lt_system.h \
- ltdl.c ltdl.h
-libltdl_la_LDFLAGS = -no-undefined -version-info 5:0:2
-libltdl_la_LIBADD = $(LIBADD_DL) $(LTLIBOBJS)
-
-libltdlc_la_SOURCES = $(libltdl_la_SOURCES)
-libltdlc_la_LIBADD = $(LIBADD_DL) $(LTLIBOBJS)
+libltdlc_la_SOURCES = $(libltdl_la_SOURCES)
+libltdlc_la_CPPFLAGS = -DLTDLOPEN=libltdlc $(AM_CPPFLAGS)
+libltdlc_la_LDFLAGS = $(LT_DLPREOPEN)
+libltdlc_la_LIBADD = $(libdlloader_la_OBJECTS) $(libdlloader_la_LIBADD)
## These are installed as a subdirectory of pkgdatadir so that
## libtoolize --ltdl can find them later:
-ltdldatadir = $(pkgdatadir)/libltdl
-ltdldata_DATA = COPYING.LIB Makefile.am README configure.ac \
- argz_.h argz.c $(libltdl_la_SOURCES) \
- loader-dld_link.c loader-dlopen.c loader-dyld.c \
- loader-load_add_on.c loader-loadlibrary.c loader-shl_load.c \
- lt__dirent.c
+ltdldatadir = $(pkgdatadir)/libltdl
+nobase_ltdldata_DATA = COPYING.LIB Makefile.am README configure.ac \
+ $(libltdl_la_SOURCES) $(libdlloader_la_SOURCES) \
+ lt__dirent.c lt__dirent.h argz_.h argz.c
+
+## Make sure these will be cleaned even when they're not built by default:
+CLEANFILES = libltdl.la libltdlc.la libdlloader.la
## --------------------------- ##
## -------- ##
## Outputs. ##
## -------- ##
-AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([Makefile loaders/Makefile])
AC_OUTPUT
+++ /dev/null
-/* loader-dld_link.c -- dynamic linking with dld
- Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
- Originally by Thomas Tanner <tanner@ffii.org>
-
- NOTE: The canonical source of this file is maintained with the
- GNU Libtool package. Report bugs to bug-libtool@gnu.org.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-As a special exception to the GNU Lesser General Public License,
-if you distribute this file as part of a program or library that
-is built using GNU libtool, you may include it under the same
-distribution terms that you use for the rest of that program.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA
-
-*/
-
-#include "lt__private.h"
-#include "lt_dlloader.h"
-
-#if defined(HAVE_DLD_H)
-# include <dld.h>
-#endif
-
-static lt_module
-sys_dld_open (lt_user_data loader_data, const char *filename)
-{
- lt_module module = lt__strdup (filename);
-
- if (dld_link (filename) != 0)
- {
- LT__SETERROR (CANNOT_OPEN);
- FREE (module);
- }
-
- return module;
-}
-
-static int
-sys_dld_close (lt_user_data loader_data, lt_module module)a
-{
- int errors = 0;
-
- if (dld_unlink_by_file ((char*)(module), 1) != 0)
- {
- LT__SETERROR (CANNOT_CLOSE);
- ++errors;
- }
- else
- {
- FREE (module);
- }
-
- return errors;
-}
-
-static void *
-sys_dld_sym (lt_user_data loader_data, lt_module module, const char *symbol)
-{
- void *address = dld_get_func (symbol);
-
- if (!address)
- {
- LT__SETERROR (SYMBOL_NOT_FOUND);
- }
-
- return address;
-}
-
-struct lt_user_dlloader lt__sys_dld = {
- 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
-};
+++ /dev/null
-/* loader-load_add_on.c -- dynamic linking for BeOS
- Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
- Originally by Thomas Tanner <tanner@ffii.org>
-
- NOTE: The canonical source of this file is maintained with the
- GNU Libtool package. Report bugs to bug-libtool@gnu.org.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-As a special exception to the GNU Lesser General Public License,
-if you distribute this file as part of a program or library that
-is built using GNU libtool, you may include it under the same
-distribution terms that you use for the rest of that program.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA
-
-*/
-
-#include "lt__private.h"
-#include "lt_dlloader.h"
-
-#include <kernel/image.h>
-
-static lt_module
-sys_bedl_open (lt_user_data loader_data, const char *filename)
-{
- image_id image = 0;
-
- if (filename)
- {
- image = load_add_on (filename);
- }
- else
- {
- image_info info;
- int32 cookie = 0;
- if (get_next_image_info (0, &cookie, &info) == B_OK)
- image = load_add_on (info.name);
- }
-
- if (image <= 0)
- {
- LT__SETERROR (CANNOT_OPEN);
- image = 0;
- }
-
- return (lt_module) image;
-}
-
-static int
-sys_bedl_close (lt_user_data loader_data, lt_module module)
-{
- int errors = 0;
-
- if (unload_add_on ((image_id) module) != B_OK)
- {
- LT__SETERROR (CANNOT_CLOSE);
- ++errors;
- }
-
- return errors;
-}
-
-static void *
-sys_bedl_sym (lt_user_data loader_data, lt_module module, const char *symbol)
-{
- void *address = 0;
- image_id image = (image_id) module;
-
- if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
- {
- LT__SETERROR (SYMBOL_NOT_FOUND);
- address = 0;
- }
-
- return address;
-}
-
-struct lt_user_dlloader lt__sys_bedl = {
- 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
-};
+++ /dev/null
-/* loader-preopen.c -- emulate dynamic linking using preloaded_symbols
- Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
- Originally by Thomas Tanner <tanner@ffii.org>
-
- NOTE: The canonical source of this file is maintained with the
- GNU Libtool package. Report bugs to bug-libtool@gnu.org.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-As a special exception to the GNU Lesser General Public License,
-if you distribute this file as part of a program or library that
-is built using GNU libtool, you may include it under the same
-distribution terms that you use for the rest of that program.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA
-
-*/
-
-#include "lt__private.h"
-#include "lt_dlloader.h"
-
-
-typedef struct lt_dlsymlists_t
-{
- struct lt_dlsymlists_t *next;
- const lt_dlsymlist *syms;
-} lt_dlsymlists_t;
-
-static lt_dlsymlists_t *preloaded_symbols = 0;
-static const lt_dlsymlist *default_preloaded_symbols = 0;
-
-
-int
-lt__presym_init (lt_user_data loader_data)
-{
- int errors = 0;
-
- preloaded_symbols = 0;
- if (default_preloaded_symbols)
- {
- errors = lt_dlpreload (default_preloaded_symbols);
- }
-
- return errors;
-}
-
-static int
-presym_free_symlists (void)
-{
- lt_dlsymlists_t *lists;
-
- lists = preloaded_symbols;
- while (lists)
- {
- lt_dlsymlists_t *tmp = lists;
-
- lists = lists->next;
- FREE (tmp);
- }
- preloaded_symbols = 0;
-
- return 0;
-}
-
-int
-lt__presym_add_symlist (const lt_dlsymlist *preloaded)
-{
- lt_dlsymlists_t *tmp;
- lt_dlsymlists_t *lists;
- int errors = 0;
-
- lists = preloaded_symbols;
- while (lists)
- {
- if (lists->syms == preloaded)
- {
- goto done;
- }
- lists = lists->next;
- }
-
- tmp = MALLOC (lt_dlsymlists_t, 1);
- if (tmp)
- {
- memset (tmp, 0, sizeof(lt_dlsymlists_t));
- tmp->syms = preloaded;
- tmp->next = preloaded_symbols;
- preloaded_symbols = tmp;
- }
- else
- {
- ++errors;
- }
-
- done:
- return errors;
-}
-
-static lt_module
-presym_open (lt_user_data loader_data, const char *filename)
-{
- lt_dlsymlists_t *lists;
- lt_module module = (lt_module) 0;
-
- lists = preloaded_symbols;
-
- if (!lists)
- {
- LT__SETERROR (NO_SYMBOLS);
- goto done;
- }
-
- /* Can't use NULL as the reflective symbol header, as NULL is
- used to mark the end of the entire symbol list. Self-dlpreopened
- symbols follow this magic number, chosen to be an unlikely
- clash with a real module name. */
- if (!filename)
- {
- filename = "@PROGRAM@";
- }
-
- while (lists)
- {
- const lt_dlsymlist *syms = lists->syms;
-
- while (syms->name)
- {
- if (!syms->address && strcmp(syms->name, filename) == 0)
- {
- module = (lt_module) syms;
- goto done;
- }
- ++syms;
- }
-
- lists = lists->next;
- }
-
- LT__SETERROR (FILE_NOT_FOUND);
-
- done:
- return module;
-}
-
-static int
-presym_close (lt_user_data loader_data, lt_module module)
-{
- /* Just to silence gcc -Wall */
- module = 0;
- return 0;
-}
-
-static void *
-presym_sym (lt_user_data loader_data, lt_module module, const char *symbol)
-{
- lt_dlsymlist *syms = (lt_dlsymlist*) module;
-
- ++syms;
- while (syms->address)
- {
- if (strcmp(syms->name, symbol) == 0)
- {
- return syms->address;
- }
-
- ++syms;
- }
-
- LT__SETERROR (SYMBOL_NOT_FOUND);
-
- return 0;
-}
-
-static int
-presym_exit (lt_user_data loader_data)
-{
- presym_free_symlists ();
- return 0;
-}
-
-struct lt_user_dlloader lt__presym = {
- 0, presym_open, presym_close, presym_sym, presym_exit, 0
-};
-
-
-int
-lt_dlpreload (const lt_dlsymlist *preloaded)
-{
- int errors = 0;
-
- if (preloaded)
- {
- errors = lt__presym_add_symlist (preloaded);
- }
- else
- {
- presym_free_symlists();
-
- if (default_preloaded_symbols)
- {
- errors = lt_dlpreload (default_preloaded_symbols);
- }
- }
-
- return errors;
-}
-
-int
-lt_dlpreload_default (const lt_dlsymlist *preloaded)
-{
- default_preloaded_symbols = preloaded;
- return 0;
-}
--- /dev/null
+## Process this file with automake to produce Makefile.in
+##
+## Copyright (C) 2004 Free Software Foundation
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING. If not, write to
+## the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+## Boston, MA 02111-1307, USA.
+
+BUILT_SOURCES =
+MOSTLYCLEANFILES =
+EXTRA_DIST =
+
+AUTOMAKE_OPTIONS = foreign
+
+DEFS = -DHAVE_CONFIG_H="<$(CONFIG_H)>" -DLTDL
+AM_CPPFLAGS = -I$(top_builddir)/.. -I$(top_srcdir)/.. \
+ -I.. -I$(srcdir)/..
+AM_LDFLAGS = -no-undefined -module -avoid-version -export-dynamic
+
+pkgincludedir = $(includedir)/libltdl
+
+
+## The loaders are preopened by libltdl, itself always built from
+## pic-objects (either as a shared library, or a convenience library),
+## so the loaders themselves must be made from pic-objects too. We
+## use convenience libraries for that purpose:
+noinst_LTLIBRARIES = $(LT_DLLOADERS)
+EXTRA_LTLIBRARIES = dlopen.la dld_link.la dyld.la load_add_on.la \
+ loadlibrary.la shl_load.la
+
+## Build loaders (other than preopen) as modules:
+dlopen_la_LIBADD = ../libdlloader.la $(LIBADD_DLOPEN)
+shl_load_la_LIBADD = ../libdlloader.la $(LIBADD_SHL_LOAD)
+dyld_la_LIBADD = ../libdlloader.la
+load_add_on_la_LIBADD = ../libdlloader.la
+loadlibrary_la_LIBADD = ../libdlloader.la
+dld_link_la_LIBADD = ../libdlloader.la -ldld
+
+
+## These are installed as a subdirectory of pkgdatadir so that
+## libtoolize --ltdl can find them later:
+ltdldatadir = $(pkgdatadir)/libltdl/loaders
+ltdldata_DATA = Makefile.am dld_link.c dlopen.c dyld.c \
+ load_add_on.c loadlibrary.c shl_load.c
+
+../libdlloader.la:
+ cd ..; $(MAKE) $(MAKEFLAGS) libdlloader.la
--- /dev/null
+/* loader-dld_link.c -- dynamic linking with dld
+ Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
+ Originally by Thomas Tanner <tanner@ffii.org>
+
+ NOTE: The canonical source of this file is maintained with the
+ GNU Libtool package. Report bugs to bug-libtool@gnu.org.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+As a special exception to the GNU Lesser General Public License,
+if you distribute this file as part of a program or library that
+is built using GNU libtool, you may include it under the same
+distribution terms that you use for the rest of that program.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA
+
+*/
+
+#include "lt__private.h"
+#include "lt_dlloader.h"
+
+/* Use the preprocessor to rename non-static symbols to avoid namespace
+ collisions when the loader code is statically linked into libltdl.
+ Use the "<module_name>_LTX_" prefix so that the symbol addresses can
+ be fetched from the preloaded symbol list by lt_dlsym(): */
+#define get_vtable dld_link_LTX_get_vtable
+
+extern lt_user_dlloader *get_vtable (lt_user_data loader_data);
+
+
+/* Boilerplate code to set up the vtable for hooking this loader into
+ libltdl's loader list: */
+static lt_module vm_open (lt_user_data loader_data, const char *filename);
+static int vm_close (lt_user_data loader_data, lt_module module);
+static void * vm_sym (lt_user_data loader_data, lt_module module,
+ const char *symbolname);
+
+/* Return the vtable for this loader, only the name and sym_prefix
+ attributes (plus the virtual function implementations, obviously)
+ change between loaders. */
+lt_user_dlloader *
+get_vtable (lt_user_data loader_data)
+{
+ static lt_user_dlloader *vtable = 0;
+
+ if (!vtable)
+ {
+ vtable = lt__zalloc (sizeof *vtable);
+ }
+
+ if (!vtable->name)
+ {
+ vtable->name = "lt_dld_link";
+ vtable->module_open = vm_open;
+ vtable->module_close = vm_close;
+ vtable->find_sym = vm_sym;
+ vtable->dlloader_data = loader_data;
+ vtable->priority = LT_DLLOADER_APPEND;
+ }
+
+ if (vtable->dlloader_data != loader_data)
+ {
+ LT__SETERROR (INIT_LOADER);
+ return 0;
+ }
+
+ return vtable;
+}
+
+
+
+/* --- IMPLEMENTATION --- */
+
+
+#if defined(HAVE_DLD_H)
+# include <dld.h>
+#endif
+
+/* A function called through the vtable to open a module with this
+ loader. Returns an opaque representation of the newly opened
+ module for processing with this loader's other vtable functions. */
+static lt_module
+vm_open (lt_user_data loader_data, const char *filename)
+{
+ lt_module module = lt__strdup (filename);
+
+ if (dld_link (filename) != 0)
+ {
+ LT__SETERROR (CANNOT_OPEN);
+ FREE (module);
+ }
+
+ return module;
+}
+
+/* A function called through the vtable when a particular module
+ should be unloaded. */
+static int
+vm_close (lt_user_data loader_data, lt_module module)
+{
+ int errors = 0;
+
+ if (dld_unlink_by_file ((char*)(module), 1) != 0)
+ {
+ LT__SETERROR (CANNOT_CLOSE);
+ ++errors;
+ }
+ else
+ {
+ FREE (module);
+ }
+
+ return errors;
+}
+
+/* A function called through the vtable to get the address of
+ a symbol loaded from a particular module. */
+static void *
+vm_sym (lt_user_data loader_data, lt_module module, const char *name)
+{
+ void *address = dld_get_func (name);
+
+ if (!address)
+ {
+ LT__SETERROR (SYMBOL_NOT_FOUND);
+ }
+
+ return address;
+}
*/
-#include "lt__private.h"
#include "lt_dlloader.h"
+#include "lt__private.h"
+
+/* Use the preprocessor to rename non-static symbols to avoid namespace
+ collisions when the loader code is statically linked into libltdl.
+ Use the "<module_name>_LTX_" prefix so that the symbol addresses can
+ be fetched from the preloaded symbol list by lt_dlsym(): */
+#define get_vtable dlopen_LTX_get_vtable
+
+extern lt_user_dlloader *get_vtable (lt_user_data loader_data);
+
+
+/* Boilerplate code to set up the vtable for hooking this loader into
+ libltdl's loader list: */
+static lt_module vm_open (lt_user_data loader_data, const char *filename);
+static int vm_close (lt_user_data loader_data, lt_module module);
+static void * vm_sym (lt_user_data loader_data, lt_module module,
+ const char *symbolname);
+
+/* Return the vtable for this loader, only the name and sym_prefix
+ attributes (plus the virtual function implementations, obviously)
+ change between loaders. */
+lt_user_dlloader *
+get_vtable (lt_user_data loader_data)
+{
+ static lt_user_dlloader *vtable = 0;
+
+ if (!vtable)
+ {
+ vtable = lt__zalloc (sizeof *vtable);
+ }
+
+ if (!vtable->name)
+ {
+ vtable->name = "lt_dlopen";
+#if defined(NEED_USCORE)
+ vtable->sym_prefix = "_";
+#endif
+ vtable->module_open = vm_open;
+ vtable->module_close = vm_close;
+ vtable->find_sym = vm_sym;
+ vtable->dlloader_data = loader_data;
+ vtable->priority = LT_DLLOADER_PREPEND;
+ }
+
+ if (vtable->dlloader_data != loader_data)
+ {
+ LT__SETERROR (INIT_LOADER);
+ return 0;
+ }
+
+ return vtable;
+}
+
+
+
+/* --- IMPLEMENTATION --- */
+
#if defined(HAVE_DLFCN_H)
# include <dlfcn.h>
# include <sys/dl.h>
#endif
+
/* We may have to define LT_LAZY_OR_NOW in the command line if we
find out it does not work in some platform. */
#if !defined(LT_LAZY_OR_NOW)
#define DL__SETERROR(errorcode) \
LT__SETERRORSTR (DLERROR (errorcode))
+/* A function called through the vtable to open a module with this
+ loader. Returns an opaque representation of the newly opened
+ module for processing with this loader's other vtable functions. */
static lt_module
-sys_dl_open (lt_user_data loader_data, const char *filename)
+vm_open (lt_user_data loader_data, const char *filename)
{
- lt_module module = dlopen (filename, LT_LAZY_OR_NOW);
+ lt_module module = dlopen (filename, LT_LAZY_OR_NOW);
if (!module)
{
return module;
}
+
+/* A function called through the vtable when a particular module
+ should be unloaded. */
static int
-sys_dl_close (lt_user_data loader_data, lt_module module)
+vm_close (lt_user_data loader_data, lt_module module)
{
int errors = 0;
return errors;
}
+
+/* A function called through the vtable to get the address of
+ a symbol loaded from a particular module. */
static void *
-sys_dl_sym (lt_user_data loader_data, lt_module module, const char *symbol)
+vm_sym (lt_user_data loader_data, lt_module module, const char *name)
{
- void *address = dlsym (module, symbol);
+ void *address = dlsym (module, name);
if (!address)
{
return address;
}
-
-struct lt_user_dlloader lt__sys_dl =
- {
-# if defined(NEED_USCORE)
- "_",
-# else
- 0,
-# endif
- sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
*/
-#include "lt__private.h"
#include "lt_dlloader.h"
+#include "lt__private.h"
+
+/* Use the preprocessor to rename non-static symbols to avoid namespace
+ collisions when the loader code is statically linked into libltdl.
+ Use the "<module_name>_LTX_" prefix so that the symbol addresses can
+ be fetched from the preloaded symbol list by lt_dlsym(): */
+#define get_vtable dyld_LTX_get_vtable
+
+extern lt_user_dlloader *get_vtable (lt_user_data loader_data);
+
+
+/* Boilerplate code to set up the vtable for hooking this loader into
+ libltdl's loader list: */
+static int vl_init (lt_user_data loader_data);
+static int vl_exit (lt_user_data loader_data);
+static lt_module vm_open (lt_user_data loader_data, const char *filename);
+static int vm_close (lt_user_data loader_data, lt_module module);
+static void * vm_sym (lt_user_data loader_data, lt_module module,
+ const char *symbolname);
+
+/* Return the vtable for this loader, only the name and sym_prefix
+ attributes (plus the virtual function implementations, obviously)
+ change between loaders. */
+lt_user_dlloader *
+get_vtable (lt_user_data loader_data)
+{
+ static lt_user_dlloader *vtable = 0;
+
+ if (!vtable)
+ {
+ vtable = lt__zalloc (sizeof *vtable);
+ }
+
+ if (!vtable->name)
+ {
+ vtable->name = "lt_dyld";
+ vtable->sym_prefix = "_";
+ vtable->dlloader_init = vl_init;
+ vtable->module_open = vm_open;
+ vtable->module_close = vm_close;
+ vtable->find_sym = vm_sym;
+ vtable->dlloader_data = loader_data;
+ vtable->priority = LT_DLLOADER_APPEND;
+ }
+
+ if (vtable->dlloader_data != loader_data)
+ {
+ LT__SETERROR (INIT_LOADER);
+ return 0;
+ }
+
+ return vtable;
+}
+
+
+
+/* --- IMPLEMENTATION --- */
+
#if defined(HAVE_MACH_O_DYLD_H)
# if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
# define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
#endif
-typedef struct mach_header mach_header;
-typedef struct dylib_command dylib_command;
-
-static const mach_header *(*lt__addimage) (const char *image_name,
- unsigned long options) = 0;
-static NSSymbol (*lt__image_symbol) (const mach_header *image,
- const char *symbolName,
- unsigned long options) = 0;
-static enum DYLD_BOOL (*lt__image_symbol_p) (const mach_header *image,
- const char *symbolName) = 0;
-static enum DYLD_BOOL (*lt__module_export) (NSModule module) = 0;
-
-static int dyld_cannot_close = 0;
-
#if !defined(NSADDIMAGE_OPTION_NONE)
# define NSADDIMAGE_OPTION_NONE 0x0
#endif
# define LT__MAGIC MH_CIGAM
#endif
-#define DYLD__SETERROR(errorcode) \
- LT__SETERRORSTR (lt__dylderror (errorcode))
-
-/* Return the dyld error string, or the passed in error string if none. */
-static const char *
-lt__dylderror (int errnum)
-{
- NSLinkEditErrors ler;
- int lerno;
- const char *file;
- const char *errstr;
-
- NSLinkEditError (&ler, &lerno, &file, &errstr);
-
- if (! (errstr && *errstr))
- {
- errstr = lt__error_strings[errnum] ;
- }
-
- return errstr;
-}
-
-/* There should probably be an apple dyld api for this. */
-static const mach_header *
-lt__nsmodule_get_header (NSModule module)
-{
- int i = _dyld_image_count();
- const char *modname = NSNameOfModule (module);
- const mach_header *mh = 0;
-
- if (!modname)
- return NULL;
-
- while (i > 0)
- {
- --i;
- if (strcmp (_dyld_get_image_name (i), modname) != 0)
- {
- mh = _dyld_get_image_header (i);
- break;
- }
- }
-
- return mh;
-}
-
-/* NSAddImage is also used to get the loaded image, but it only works if
- the lib is installed, for uninstalled libs we need to check the
- install_names against each other. Note that this is still broken if
- DYLD_IMAGE_SUFFIX is set and a different lib was loaded as a result. */
-static const char *
-lt__header_get_instnam (const mach_header *mh)
-{
- unsigned long offset = sizeof(mach_header);
- const char* result = 0;
- int j;
-
- for (j = 0; j < mh->ncmds; j++)
- {
- struct load_command *lc;
-
- lc = (struct load_command*) (((unsigned long) mh) + offset);
- if (LC_ID_DYLIB == lc->cmd)
- {
- result=(char*)(((dylib_command*) lc)->dylib.name.offset +
- (unsigned long) lc);
- }
- offset += lc->cmdsize;
- }
-
- return result;
-}
-
-static const mach_header *
-lt__match_loadedlib (const char *name)
-{
- const mach_header *mh = 0;
- int i = _dyld_image_count();
-
- while (i > 0)
- {
- const char *id;
-
- --i;
- id = lt__header_get_instnam (_dyld_get_image_header (i));
- if (id && (strcmp (id, name) != 0))
- {
- mh = _dyld_get_image_header (i);
- break;
- }
- }
+#define DYLD__SETMYERROR(errmsg) LT__SETERRORSTR (dylderror (errmsg))
+#define DYLD__SETERROR(errcode) DYLD__SETMYERROR (LT__STRERROR (errcode))
- return mh;
-}
-
-/* Safe to assume our mh is good. */
-static NSSymbol
-lt__linkedlib_symbol (const char *symname, const mach_header *mh)
-{
- NSSymbol symbol = 0;
-
- if (lt__image_symbol && NSIsSymbolNameDefined (symname))
- {
- unsigned long offset = sizeof(mach_header);
- struct load_command *lc;
- int j;
-
- for (j = 0; j < mh->ncmds; j++)
- {
- lc = (struct load_command*) (((unsigned long) mh) + offset);
- if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
- {
- unsigned long base = ((dylib_command *) lc)->dylib.name.offset;
- char *name = (char *) (base + (unsigned long) lc);
- const mach_header *mh1 = lt__match_loadedlib (name);
+typedef struct mach_header mach_header;
+typedef struct dylib_command dylib_command;
- if (!mh1)
- {
- /* Maybe NSAddImage can find it */
- mh1 = lt__addimage (name,
- NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
- | NSADDIMAGE_OPTION_WITH_SEARCHING
- | NSADDIMAGE_OPTION_RETURN_ON_ERROR);
- }
+static const char *dylderror (const char *errmsg);
+static const mach_header *lt__nsmodule_get_header (NSModule module);
+static const char *lt__header_get_instnam (const mach_header *mh);
+static const mach_header *lt__match_loadedlib (const char *name);
+static NSSymbol lt__linkedlib_symbol (const char *symname, const mach_header *mh);
- if (mh1)
- {
- symbol = lt__image_symbol (mh1, symname, LT__SYMLOOKUP_OPTS);
- if (symbol)
- break;
- }
- }
+static const mach_header *(*lt__addimage) (const char *image_name,
+ unsigned long options) = 0;
+static NSSymbol (*lt__image_symbol) (const mach_header *image,
+ const char *symbolName,
+ unsigned long options) = 0;
+static enum DYLD_BOOL (*lt__image_symbol_p) (const mach_header *image,
+ const char *symbolName) = 0;
+static enum DYLD_BOOL (*lt__module_export) (NSModule module) = 0;
- offset += lc->cmdsize;
- }
- }
+static int dyld_cannot_close = 0;
- return symbol;
-}
-int
-lt__sys_dyld_init (void)
+/* A function called through the vtable to initialise this loader. */
+static int
+vl_init (lt_user_data loader_data)
{
int errors = 0;
return errors;
}
+
+/* A function called through the vtable to open a module with this
+ loader. Returns an opaque representation of the newly opened
+ module for processing with this loader's other vtable functions. */
static lt_module
-sys_dyld_open (lt_user_data loader_data, const char *filename)
+vm_open (lt_user_data loader_data, const char *filename)
{
lt_module module = 0;
NSObjectFileImage ofi = 0;
NSADDIMAGE_OPTION_RETURN_ON_ERROR);
}
break;
+
+ case NSObjectFileImageFailure:
+ case NSObjectFileImageArch:
+ case NSObjectFileImageFormat:
+ case NSObjectFileImageAccess:
+ /*NOWORK*/
+ break;
}
if (!module)
{
- DYLD__SETERROR (LT_ERROR_CANNOT_OPEN);
+ DYLD__SETERROR (CANNOT_OPEN);
}
return module;
}
+
+/* A function called through the vtable when a particular module
+ should be unloaded. */
static int
-sys_dyld_close (lt_user_data loader_data, lt_module module)
+vm_close (lt_user_data loader_data, lt_module module)
{
int errors = 0;
int flags = 0;
if (mh->magic == LT__MAGIC)
{
- DYLD__SETERROR(dyld_cannot_close);
+ lt_dlseterror (dyld_cannot_close);
++errors;
}
else
#endif
if (!NSUnLinkModule (module, flags))
{
- DYLD__SETERROR (LT_ERROR_CANNOT_CLOSE);
+ DYLD__SETERROR (CANNOT_CLOSE);
++errors;
}
}
return errors;
}
+/* A function called through the vtable to get the address of
+ a symbol loaded from a particular module. */
static void *
-sys_dyld_sym (lt_user_data loader_data, lt_module module, const char *symbol)
+vm_sym (lt_user_data loader_data, lt_module module, const char *name)
{
NSSymbol *nssym = 0;
- mach_header *mh = (mach_header *) module;
+ const mach_header *mh = (const mach_header *) module;
char saveError[256] = "Symbol not found";
- if (module == (lt_module)-1)
+ if (module == (lt_module) -1)
{
void *address, *unused;
- _dyld_lookup_and_bind(symbol, (unsigned long*) &address, &unused);
+ _dyld_lookup_and_bind (name, (unsigned long*) &address, &unused);
return address;
}
{
if (lt__image_symbol_p && lt__image_symbol)
{
- if (lt__image_symbol_p (mh, symbol))
+ if (lt__image_symbol_p (mh, name))
{
- nssym = lt__image_symbol (mh, symbol, LT__SYMLOOKUP_OPTS);
+ nssym = lt__image_symbol (mh, name, LT__SYMLOOKUP_OPTS);
}
}
}
else
{
- nssym = NSLookupSymbolInModule (module, symbol);
+ nssym = NSLookupSymbolInModule (module, name);
}
if (!nssym)
{
- strncpy (saveError, lt__dylderror (LT_ERROR_SYMBOL_NOT_FOUND), 255);
+ strncpy (saveError, dylderror (LT__STRERROR (SYMBOL_NOT_FOUND)), 255);
saveError[255] = 0;
if (!mh)
{
mh = (mach_header *)lt__nsmodule_get_header (module);
}
- nssym = lt__linkedlib_symbol (symbol, mh);
+ nssym = lt__linkedlib_symbol (name, mh);
}
if (!nssym)
return nssym ? NSAddressOfSymbol (nssym) : 0;
}
-struct lt_user_dlloader lt__sys_dyld =
- { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
+
+
+
+/* --- HELPER FUNCTIONS --- */
+
+
+/* Return the dyld error string, or the passed in error string if none. */
+static const char *
+dylderror (const char *errmsg)
+{
+ NSLinkEditErrors ler;
+ int lerno;
+ const char *file;
+ const char *errstr;
+
+ NSLinkEditError (&ler, &lerno, &file, &errstr);
+
+ if (! (errstr && *errstr))
+ {
+ errstr = errmsg;
+ }
+
+ return errstr;
+}
+
+/* There should probably be an apple dyld api for this. */
+static const mach_header *
+lt__nsmodule_get_header (NSModule module)
+{
+ int i = _dyld_image_count();
+ const char *modname = NSNameOfModule (module);
+ const mach_header *mh = 0;
+
+ if (!modname)
+ return NULL;
+
+ while (i > 0)
+ {
+ --i;
+ if (strcmp (_dyld_get_image_name (i), modname) != 0)
+ {
+ mh = _dyld_get_image_header (i);
+ break;
+ }
+ }
+
+ return mh;
+}
+
+/* NSAddImage is also used to get the loaded image, but it only works if
+ the lib is installed, for uninstalled libs we need to check the
+ install_names against each other. Note that this is still broken if
+ DYLD_IMAGE_SUFFIX is set and a different lib was loaded as a result. */
+static const char *
+lt__header_get_instnam (const mach_header *mh)
+{
+ unsigned long offset = sizeof(mach_header);
+ const char* result = 0;
+ int j;
+
+ for (j = 0; j < mh->ncmds; j++)
+ {
+ struct load_command *lc;
+
+ lc = (struct load_command*) (((unsigned long) mh) + offset);
+ if (LC_ID_DYLIB == lc->cmd)
+ {
+ result=(char*)(((dylib_command*) lc)->dylib.name.offset +
+ (unsigned long) lc);
+ }
+ offset += lc->cmdsize;
+ }
+
+ return result;
+}
+
+static const mach_header *
+lt__match_loadedlib (const char *name)
+{
+ const mach_header *mh = 0;
+ int i = _dyld_image_count();
+
+ while (i > 0)
+ {
+ const char *id;
+
+ --i;
+ id = lt__header_get_instnam (_dyld_get_image_header (i));
+ if (id && (strcmp (id, name) != 0))
+ {
+ mh = _dyld_get_image_header (i);
+ break;
+ }
+ }
+
+ return mh;
+}
+
+/* Safe to assume our mh is good. */
+static NSSymbol
+lt__linkedlib_symbol (const char *symname, const mach_header *mh)
+{
+ NSSymbol symbol = 0;
+
+ if (lt__image_symbol && NSIsSymbolNameDefined (symname))
+ {
+ unsigned long offset = sizeof(mach_header);
+ struct load_command *lc;
+ int j;
+
+ for (j = 0; j < mh->ncmds; j++)
+ {
+ lc = (struct load_command*) (((unsigned long) mh) + offset);
+ if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
+ {
+ unsigned long base = ((dylib_command *) lc)->dylib.name.offset;
+ char *name = (char *) (base + (unsigned long) lc);
+ const mach_header *mh1 = lt__match_loadedlib (name);
+
+ if (!mh1)
+ {
+ /* Maybe NSAddImage can find it */
+ mh1 = lt__addimage (name,
+ NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
+ | NSADDIMAGE_OPTION_WITH_SEARCHING
+ | NSADDIMAGE_OPTION_RETURN_ON_ERROR);
+ }
+
+ if (mh1)
+ {
+ symbol = lt__image_symbol (mh1, symname, LT__SYMLOOKUP_OPTS);
+ if (symbol)
+ break;
+ }
+ }
+
+ offset += lc->cmdsize;
+ }
+ }
+
+ return symbol;
+}
--- /dev/null
+/* loader-load_add_on.c -- dynamic linking for BeOS
+ Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
+ Originally by Thomas Tanner <tanner@ffii.org>
+
+ NOTE: The canonical source of this file is maintained with the
+ GNU Libtool package. Report bugs to bug-libtool@gnu.org.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+As a special exception to the GNU Lesser General Public License,
+if you distribute this file as part of a program or library that
+is built using GNU libtool, you may include it under the same
+distribution terms that you use for the rest of that program.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA
+
+*/
+
+#include "lt__private.h"
+#include "lt_dlloader.h"
+
+/* Use the preprocessor to rename non-static symbols to avoid namespace
+ collisions when the loader code is statically linked into libltdl.
+ Use the "<module_name>_LTX_" prefix so that the symbol addresses can
+ be fetched from the preloaded symbol list by lt_dlsym(): */
+#define get_vtable load_add_on_LTX_get_vtable
+
+extern lt_user_dlloader *get_vtable (lt_user_data loader_data);
+
+
+/* Boilerplate code to set up the vtable for hooking this loader into
+ libltdl's loader list: */
+static lt_module vm_open (lt_user_data loader_data, const char *filename);
+static int vm_close (lt_user_data loader_data, lt_module module);
+static void * vm_sym (lt_user_data loader_data, lt_module module,
+ const char *symbolname);
+
+/* Return the vtable for this loader, only the name and sym_prefix
+ attributes (plus the virtual function implementations, obviously)
+ change between loaders. */
+lt_user_dlloader *
+get_vtable (lt_user_data loader_data)
+{
+ static lt_user_dlloader *vtable = 0;
+
+ if (!vtable)
+ {
+ vtable = lt__zalloc (sizeof *vtable);
+ }
+
+ if (!vtable->name)
+ {
+ vtable->name = "lt_load_add_on";
+ vtable->module_open = vm_open;
+ vtable->module_close = vm_close;
+ vtable->find_sym = vm_sym;
+ vtable->dlloader_data = loader_data;
+ vtable->priority = LT_DLLOADER_APPEND;
+ }
+
+ if (vtable->dlloader_data != loader_data)
+ {
+ LT__SETERROR (INIT_LOADER);
+ return 0;
+ }
+
+ return vtable;
+}
+
+
+
+/* --- IMPLEMENTATION --- */
+
+
+#include <kernel/image.h>
+
+/* A function called through the vtable to open a module with this
+ loader. Returns an opaque representation of the newly opened
+ module for processing with this loader's other vtable functions. */
+static lt_module
+vm_open (lt_user_data loader_data, const char *filename)
+{
+ image_id image = 0;
+
+ if (filename)
+ {
+ image = load_add_on (filename);
+ }
+ else
+ {
+ image_info info;
+ int32 cookie = 0;
+ if (get_next_image_info (0, &cookie, &info) == B_OK)
+ image = load_add_on (info.name);
+ }
+
+ if (image <= 0)
+ {
+ LT__SETERROR (CANNOT_OPEN);
+ image = 0;
+ }
+
+ return (lt_module) image;
+}
+
+
+/* A function called through the vtable when a particular module
+ should be unloaded. */
+static int
+vm_close (lt_user_data loader_data, lt_module module)
+{
+ int errors = 0;
+
+ if (unload_add_on ((image_id) module) != B_OK)
+ {
+ LT__SETERROR (CANNOT_CLOSE);
+ ++errors;
+ }
+
+ return errors;
+}
+
+
+/* A function called through the vtable to get the address of
+ a symbol loaded from a particular module. */
+static void *
+vm_sym (lt_user_data loader_data, lt_module module, const char *name)
+{
+ void *address = 0;
+ image_id image = (image_id) module;
+
+ if (get_image_symbol (image, name, B_SYMBOL_TYPE_ANY, address) != B_OK)
+ {
+ LT__SETERROR (SYMBOL_NOT_FOUND);
+ address = 0;
+ }
+
+ return address;
+}
#include "lt__private.h"
#include "lt_dlloader.h"
+/* Use the preprocessor to rename non-static symbols to avoid namespace
+ collisions when the loader code is statically linked into libltdl.
+ Use the "<module_name>_LTX_" prefix so that the symbol addresses can
+ be fetched from the preloaded symbol list by lt_dlsym(): */
+#define get_vtable loadlibrary_LTX_get_vtable
+
+extern lt_user_dlloader *get_vtable (lt_user_data loader_data);
+
+
+/* Boilerplate code to set up the vtable for hooking this loader into
+ libltdl's loader list: */
+static lt_module vm_open (lt_user_data loader_data, const char *filename);
+static int vm_close (lt_user_data loader_data, lt_module module);
+static void * vm_sym (lt_user_data loader_data, lt_module module,
+ const char *symbolname);
+
+/* Return the vtable for this loader, only the name and sym_prefix
+ attributes (plus the virtual function implementations, obviously)
+ change between loaders. */
+lt_user_dlloader *
+get_vtable (lt_user_data loader_data)
+{
+ static lt_user_dlloader *vtable = 0;
+
+ if (!vtable)
+ {
+ vtable = lt__zalloc (sizeof *vtable);
+ }
+
+ if (!vtable->name)
+ {
+ vtable->name = "lt_loadlibrary";
+ vtable->module_open = vm_open;
+ vtable->module_close = vm_close;
+ vtable->find_sym = vm_sym;
+ vtable->dlloader_data = loader_data;
+ vtable->priority = LT_DLLOADER_APPEND;
+ }
+
+ if (vtable->dlloader_data != loader_data)
+ {
+ LT__SETERROR (INIT_LOADER);
+ return 0;
+ }
+
+ return vtable;
+}
+
+
+
+/* --- IMPLEMENTATION --- */
+
+
#include <windows.h>
/* Forward declaration; required to implement handle search below. */
static lt_dlhandle handles;
+
+/* A function called through the vtable to open a module with this
+ loader. Returns an opaque representation of the newly opened
+ module for processing with this loader's other vtable functions. */
static lt_module
-sys_wll_open (lt_user_data loader_data, const char *filename)
+vm_open (lt_user_data loader_data, const char *filename)
{
lt_dlhandle cur = 0;
lt_module module = 0;
return module;
}
+
+/* A function called through the vtable when a particular module
+ should be unloaded. */
static int
-sys_wll_close (lt_user_data loader_data, lt_module module)
+vm_close (lt_user_data loader_data, lt_module module)
{
- int errors = 0;
+ int errors = 0;
if (FreeLibrary(module) == 0)
{
return errors;
}
+
+/* A function called through the vtable to get the address of
+ a symbol loaded from a particular module. */
static void *
-sys_wll_sym (lt_user_data loader_data, lt_module module,const char *symbol)
+vm_sym (lt_user_data loader_data, lt_module module, const char *name)
{
- void * address = GetProcAddress (module, symbol);
+ void *address = GetProcAddress (module, name);
if (!address)
{
return address;
}
-
-struct lt_user_dlloader lt__sys_wll = {
- 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
-};
--- /dev/null
+/* loader-preopen.c -- emulate dynamic linking using preloaded_symbols
+ Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
+ Originally by Thomas Tanner <tanner@ffii.org>
+
+ NOTE: The canonical source of this file is maintained with the
+ GNU Libtool package. Report bugs to bug-libtool@gnu.org.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+As a special exception to the GNU Lesser General Public License,
+if you distribute this file as part of a program or library that
+is built using GNU libtool, you may include it under the same
+distribution terms that you use for the rest of that program.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA
+
+*/
+
+#include "lt_dlloader.h"
+#include "lt__private.h"
+
+/* Use the preprocessor to rename non-static symbols to avoid namespace
+ collisions when the loader code is statically linked into libltdl.
+ Use the "<module_name>_LTX_" prefix so that the symbol addresses can
+ be fetched from the preloaded symbol list by lt_dlsym(): */
+#define get_vtable preopen_LTX_get_vtable
+
+extern lt_user_dlloader *get_vtable (lt_user_data loader_data);
+
+
+/* Boilerplate code to set up the vtable for hooking this loader into
+ libltdl's loader list: */
+static int vl_init (lt_user_data loader_data);
+static int vl_exit (lt_user_data loader_data);
+static lt_module vm_open (lt_user_data loader_data, const char *filename);
+static int vm_close (lt_user_data loader_data, lt_module module);
+static void * vm_sym (lt_user_data loader_data, lt_module module,
+ const char *symbolname);
+
+/* Return the vtable for this loader, only the name and sym_prefix
+ attributes (plus the virtual function implementations, obviously)
+ change between loaders. */
+lt_user_dlloader *
+get_vtable (lt_user_data loader_data)
+{
+ static lt_user_dlloader *vtable = 0;
+
+ if (!vtable)
+ {
+ vtable = lt__malloc (sizeof *vtable);
+ }
+
+ if (!vtable->name)
+ {
+ vtable->name = "lt_preopen";
+ vtable->sym_prefix = 0;
+ vtable->dlloader_init = vl_init;
+ vtable->dlloader_exit = vl_exit;
+ vtable->module_open = vm_open;
+ vtable->module_close = vm_close;
+ vtable->find_sym = vm_sym;
+ vtable->dlloader_data = loader_data;
+ vtable->priority = LT_DLLOADER_PREPEND;
+ }
+
+ if (vtable->dlloader_data != loader_data)
+ {
+ LT__SETERROR (INIT_LOADER);
+ return 0;
+ }
+
+ return vtable;
+}
+
+
+
+/* --- IMPLEMENTATION --- */
+
+
+/* Wrapper type to chain together symbol lists of various origins. */
+typedef struct symlist_chain
+{
+ struct symlist_chain *next;
+ const lt_dlsymlist *symlist;
+} symlist_chain;
+
+
+static int add_symlist (const lt_dlsymlist *symlist);
+static int free_symlists (void);
+
+/* The start of the symbol lists chain. */
+static symlist_chain *preloaded_symlists = 0;
+
+/* A symbol list preloaded before lt_init() was called. */
+static const lt_dlsymlist *default_preloaded_symbols = 0;
+
+
+/* A function called through the vtable to initialise this loader. */
+static int
+vl_init (lt_user_data loader_data)
+{
+ int errors = 0;
+
+ preloaded_symlists = 0;
+ if (default_preloaded_symbols)
+ {
+ errors = lt_dlpreload (default_preloaded_symbols);
+ }
+
+ return errors;
+}
+
+
+/* A function called through the vtable when this loader is no
+ longer needed by the application. */
+static int
+vl_exit (lt_user_data loader_data)
+{
+ free_symlists ();
+ return 0;
+}
+
+
+/* A function called through the vtable to open a module with this
+ loader. Returns an opaque representation of the newly opened
+ module for processing with this loader's other vtable functions. */
+static lt_module
+vm_open (lt_user_data loader_data, const char *filename)
+{
+ symlist_chain *lists;
+ lt_module module = 0;
+
+ if (!preloaded_symlists)
+ {
+ LT__SETERROR (NO_SYMBOLS);
+ goto done;
+ }
+
+ /* Can't use NULL as the reflective symbol header, as NULL is
+ used to mark the end of the entire symbol list. Self-dlpreopened
+ symbols follow this magic number, chosen to be an unlikely
+ clash with a real module name. */
+ if (!filename)
+ {
+ filename = "@PROGRAM@";
+ }
+
+ for (lists = preloaded_symlists; lists; lists = lists->next)
+ {
+ const lt_dlsymbol *symbol;
+ for (symbol= lists->symlist->symbols; symbol->name; ++symbol)
+ {
+ if (!symbol->address && strcmp(symbol->name, filename) == 0)
+ {
+ module = (lt_module) lists->symlist;
+ goto done;
+ }
+ }
+ }
+
+ LT__SETERROR (FILE_NOT_FOUND);
+
+ done:
+ return module;
+}
+
+
+/* A function called through the vtable when a particular module
+ should be unloaded. */
+static int
+vm_close (lt_user_data loader_data, lt_module module)
+{
+ /* Just to silence gcc -Wall */
+ module = 0;
+ return 0;
+}
+
+
+/* A function called through the vtable to get the address of
+ a symbol loaded from a particular module. */
+static void *
+vm_sym (lt_user_data loader_data, lt_module module, const char *name)
+{
+ lt_dlsymlist *symlist = (lt_dlsymlist*) module;
+ const lt_dlsymbol *symbol = symlist->symbols;
+
+ ++symbol; /* Skip header. */
+
+ while (symbol->name)
+ {
+ if (strcmp (symbol->name, name) == 0)
+ {
+ return symbol->address;
+ }
+
+ ++symbol;
+ }
+
+ LT__SETERROR (SYMBOL_NOT_FOUND);
+
+ return 0;
+}
+
+
+
+/* --- HELPER FUNCTIONS --- */
+
+
+/* The symbol lists themselves are not allocated from the heap, but
+ we can unhook them and free up the chain of links between them. */
+static int
+free_symlists (void)
+{
+ symlist_chain *lists;
+
+ lists = preloaded_symlists;
+ while (lists)
+ {
+ symlist_chain *next = lists->next;
+ FREE (lists);
+ lists = next;
+ }
+ preloaded_symlists = 0;
+
+ return 0;
+}
+
+/* Add a new symbol list to the global chain. */
+static int
+add_symlist (const lt_dlsymlist *symlist)
+{
+ symlist_chain *lists;
+ int errors = 0;
+
+ /* Search for duplicate entries: */
+ for (lists = preloaded_symlists;
+ lists && lists->symlist != symlist; lists = lists->next)
+ /*NOWORK*/;
+
+ /* Don't add the same list twice: */
+ if (!lists)
+ {
+ symlist_chain *tmp = lt__zalloc (sizeof *tmp);
+
+ if (tmp)
+ {
+ tmp->symlist = symlist;
+ tmp->next = preloaded_symlists;
+ preloaded_symlists = tmp;
+ }
+ else
+ {
+ ++errors;
+ }
+ }
+
+ return errors;
+}
+
+
+
+/* --- PRELOADING API CALL IMPLEMENTATIONS --- */
+
+
+/* Save a default symbol list for later. */
+int
+lt_dlpreload_default (const lt_dlsymlist *preloaded)
+{
+ default_preloaded_symbols = preloaded;
+ return 0;
+}
+
+
+/* Add a symbol list to the global chain, or with a NULL argument,
+ revert to just the default list. */
+int
+lt_dlpreload (const lt_dlsymlist *preloaded)
+{
+ int errors = 0;
+
+ if (preloaded)
+ {
+ errors = add_symlist (preloaded);
+ }
+ else
+ {
+ free_symlists();
+
+ if (default_preloaded_symbols)
+ {
+ errors = lt_dlpreload (default_preloaded_symbols);
+ }
+ }
+
+ return errors;
+}
+
+
+/* Open all the preloaded modules from the named originator, executing
+ a callback for each one. */
+int
+lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func)
+{
+ symlist_chain *list;
+ int errors = 0;
+ int found = 0;
+
+ /* For each symlist in the chain... */
+ for (list = preloaded_symlists; list; list = list->next)
+ {
+ /* ...that was preloaded by the requesting ORIGINATOR... */
+ if (strcmp (list->symlist->originator, originator) == 0)
+ {
+ const lt_dlsymbol *symbol;
+ unsigned int idx = 0;
+
+ ++found;
+
+ /* ...load the symbols per source compilation unit: */
+ while ((symbol = &list->symlist->symbols[idx++])->name != 0)
+ {
+ if ((symbol->address == 0)
+ && (strcmp (symbol->name, "@PROGRAM@") != 0))
+ {
+ lt_dlhandle handle = lt_dlopen (symbol->name);
+ if (handle == 0)
+ {
+ ++errors;
+ }
+ else
+ {
+ errors += (*func) (handle);
+ }
+ }
+ }
+ }
+
+ if (!found)
+ {
+ LT__SETERROR(CANNOT_OPEN);
+ ++errors;
+ }
+ }
+
+ return errors;
+}
#include "lt__private.h"
#include "lt_dlloader.h"
+/* Use the preprocessor to rename non-static symbols to avoid namespace
+ collisions when the loader code is statically linked into libltdl.
+ Use the "<module_name>_LTX_" prefix so that the symbol addresses can
+ be fetched from the preloaded symbol list by lt_dlsym(): */
+#define get_vtable shl_load_LTX_get_vtable
+
+extern lt_user_dlloader *get_vtable (lt_user_data loader_data);
+
+
+/* Boilerplate code to set up the vtable for hooking this loader into
+ libltdl's loader list: */
+static lt_module vm_open (lt_user_data loader_data, const char *filename);
+static int vm_close (lt_user_data loader_data, lt_module module);
+static void * vm_sym (lt_user_data loader_data, lt_module module,
+ const char *symbolname);
+
+/* Return the vtable for this loader, only the name and sym_prefix
+ attributes (plus the virtual function implementations, obviously)
+ change between loaders. */
+lt_user_dlloader *
+get_vtable (lt_user_data loader_data)
+{
+ static lt_user_dlloader *vtable = 0;
+
+ if (!vtable)
+ {
+ vtable = lt__zalloc (sizeof *vtable);
+ }
+
+ if (!vtable->name)
+ {
+ vtable->name = "lt_shl_load";
+ vtable->module_open = vm_open;
+ vtable->module_close = vm_close;
+ vtable->find_sym = vm_sym;
+ vtable->dlloader_data = loader_data;
+ vtable->priority = LT_DLLOADER_APPEND;
+ }
+
+ if (vtable->dlloader_data != loader_data)
+ {
+ LT__SETERROR (INIT_LOADER);
+ return 0;
+ }
+
+ return vtable;
+}
+
+
+
+/* --- IMPLEMENTATION --- */
+
+
#if defined(HAVE_DL_H)
# include <dl.h>
#endif
#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
+
+/* A function called through the vtable to open a module with this
+ loader. Returns an opaque representation of the newly opened
+ module for processing with this loader's other vtable functions. */
static lt_module
-sys_shl_open (lt_user_data loader_data, const char *filenam)
+vm_open (lt_user_data loader_data, const char *filename)
{
static shl_t self = (shl_t) 0;
lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
return module;
}
+/* A function called through the vtable when a particular module
+ should be unloaded. */
static int
-sys_shl_close (lt_user_data loader_data, lt_module module)
+vm_close (lt_user_data loader_data, lt_module module)
{
int errors = 0;
return errors;
}
+
+/* A function called through the vtable to get the address of
+ a symbol loaded from a particular module. */
static void *
-sys_shl_sym (lt_user_data loader_data, lt_module module, const char *symbol)
+vm_sym (lt_user_data loader_data, lt_module module, const char *name)
{
void *address = 0;
{
LT__SETERROR (INVALID_HANDLE);
}
- else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
+ else if (!shl_findsym((shl_t*) &module, name, TYPE_UNDEFINED, &address))
{
if (!address)
{
return address;
}
-
-struct lt_user_dlloader lt__sys_shl = {
- 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
-};
#include <stdio.h>
#include "lt__alloc.h"
+#include "lt__private.h"
static void alloc_die_default (void);
return mem;
}
+void *
+lt__zalloc (size_t n)
+{
+ void *mem;
+
+ if ((mem = lt__malloc (n)))
+ memset (mem, 0, n);
+
+ return mem;
+}
+
void *
lt__realloc (void *mem, size_t n)
{
extern void (*lt__alloc_die) (void);
void *lt__malloc (size_t n);
+void *lt__zalloc (size_t n);
void *lt__realloc (void *mem, size_t n);
void *lt__memdup (void const *mem, size_t n);
extern int errno;
#endif
+void lt__alloc_die_callback (void);
/* --- ERROR HANDLING --- */
/* Extract the diagnostic strings from the error table macro in the same
order as the enumerated indices in lt_error.h. */
-static const char *lt__error_strings[] =
- {
-#define LT_ERROR(name, diagnostic) (diagnostic),
- lt_dlerror_table
-#undef LT_ERROR
-
- 0
- };
+LT_SCOPE const char *lt__error_strings[];
#define LT__STRERROR(name) lt__error_strings[LT_CONC(LT_ERROR_,name)]
#define LT_DLLOADER_H 1
#include <libltdl/lt_system.h>
+#include <libltdl/lt_error.h>
LT_BEGIN_C_DECLS
+typedef struct lt_user_dlloader lt_user_dlloader;
typedef struct lt_dlloader lt_dlloader;
typedef void * lt_user_data;
typedef void * lt_module;
-/* Function pointer types for creating user defined module loaders. */
+/* Type of a function to get a loader's vtable: */
+typedef lt_user_dlloader *lt_get_vtable (lt_user_data loader_data);
+
+/* Function pointer types for creating user defined module loaders: */
+typedef int lt_dlloader_init (lt_user_data loader_data);
+typedef int lt_dlloader_exit (lt_user_data loader_data);
typedef lt_module lt_module_open (lt_user_data loader_data,
const char *filename);
typedef int lt_module_close (lt_user_data loader_data,
lt_module handle);
typedef void * lt_find_sym (lt_user_data loader_data,
lt_module handle, const char *symbol);
-typedef int lt_dlloader_exit (lt_user_data loader_data);
+
+/* Default priority is LT_DLLOADER_PREPEND if none is explicitly given. */
+typedef enum {
+ LT_DLLOADER_PREPEND = 0, LT_DLLOADER_APPEND
+} lt_dlloader_priority;
struct lt_user_dlloader {
- const char *sym_prefix;
- lt_module_open *module_open;
- lt_module_close *module_close;
- lt_find_sym *find_sym;
- lt_dlloader_exit *dlloader_exit;
+ const char * name;
+ const char * sym_prefix;
+ lt_module_open * module_open;
+ lt_module_close * module_close;
+ lt_find_sym * find_sym;
+ lt_dlloader_init * dlloader_init;
+ lt_dlloader_exit * dlloader_exit;
lt_user_data dlloader_data;
+ lt_dlloader_priority priority;
};
LT_SCOPE lt_dlloader *lt_dlloader_next (lt_dlloader *place);
LT_SCOPE lt_dlloader *lt_dlloader_find (const char *loader_name);
LT_SCOPE const char *lt_dlloader_name (lt_dlloader *place);
LT_SCOPE lt_user_data *lt_dlloader_data (lt_dlloader *place);
-LT_SCOPE int lt_dlloader_add (lt_dlloader *place,
- const struct lt_user_dlloader *dlloader,
- const char *loader_name);
+LT_SCOPE int lt_dlloader_add
+ (const struct lt_user_dlloader *dlloader,
+ lt_user_data data);
LT_SCOPE int lt_dlloader_remove (const char *loader_name);
#include "lt__private.h"
LT_GLOBAL_DATA const char *lt__last_error = 0;
+LT_GLOBAL_DATA const char *lt__error_strings[] =
+ {
+#define LT_ERROR(name, diagnostic) (diagnostic),
+ lt_dlerror_table
+#undef LT_ERROR
+
+ 0
+ };
static const char **user_error_strings = 0;
static int errorcount = LT_ERROR_MAX;
LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \
LT_ERROR(SHUTDOWN, "library already shutdown") \
LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \
- LT_ERROR(INVALID_MUTEX_ARGS, "internal error (code withdrawn)") \
+ LT_ERROR(INVALID_MUTEX_ARGS, "internal error (code withdrawn)") \
LT_ERROR(INVALID_POSITION, "invalid search path insert position")
/* Enumerate the symbolic error names. */
# define LT_READTEXT_MODE "r"
#endif
-/* LT_CONC creates a new concatenated symbol for the compiler
- in a portable way. */
-#if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER)
-# define LT_CONC(s,t) s##t
-#else
-# define LT_CONC(s,t) s/**/t
+/* The extra indirection to the LT__STR and LT__CONC macros is required so
+ that if the arguments to LT_STR() (or LT_CONC()) are themselves macros,
+ they will be expanded before being quoted. */
+#ifndef LT_STR
+# define LT__STR(arg) #arg
+# define LT_STR(arg) LT__STR(arg)
+#endif
+
+#ifndef LT_CONC
+# define LT__CONC(a, b) a##b
+# define LT_CONC(a, b) LT__CONC(a, b)
+#endif
+#ifndef LT_CONC3
+# define LT__CONC3(a, b, c) a##b##c
+# define LT_CONC3(a, b, c) LT__CONC3(a, b, c)
#endif
-#endif /*!defined(LT__SYSTEM_H)*/
+#endif /*!defined(LT_SYSTEM_H)*/
*/
+#include "lt_system.h"
#include "lt_dlloader.h"
#include "lt__private.h"
-/* --- DLLOADER VIRTUAL FUNCTION TABLES --- */
-
-#if defined(HAVE_LIBDL)
-LT_SCOPE struct lt_user_dlloader lt__sys_dl;
-#endif
-#if defined(HAVE_SHL_LOAD)
-LT_SCOPE struct lt_user_dlloader lt__sys_shl;
-#endif
-#if defined(__WINDOWS__) || defined(__CYGWIN__)
-LT_SCOPE struct lt_user_dlloader lt__sys_wll;
-#endif
-#if defined(__BEOS__)
-LT_SCOPE struct lt_user_dlloader lt__sys_bedl;
-#endif
-#if defined(HAVE_DLD)
-LT_SCOPE struct lt_user_dlloader lt__sys_dld;
-#endif
-#if defined(HAVE_DYLD)
-LT_SCOPE struct lt_user_dlloader lt__sys_dyld;
-LT_SCOPE int lt__sys_dyld_init (void);
-#endif
-LT_SCOPE struct lt_user_dlloader lt__presym;
-LT_SCOPE int lt__presym_init (lt_user_data loader_data);
-
-
\f
/* --- DYNAMIC MODULE LOADING --- */
char **pargz, size_t *pargz_len);
static int file_not_found (void);
+static int loader_init_callback (lt_dlhandle handle);
+static int loader_init (lt_get_vtable *vtable_func,
+ lt_user_data data);
+
static char *user_search_path= 0;
static lt_dlloader *loaders = 0;
static lt_dlhandle handles = 0;
LT__SETERROR (NO_MEMORY);
}
+/* This function is called to initialise each preloaded module loader,
+ and hook it into the list of loaders to be used when attempting to
+ dlopen an application module. */
+static int
+loader_init_callback (lt_dlhandle handle)
+{
+ return loader_init (lt_dlsym (handle, "get_vtable"), 0);
+}
+
+static int
+loader_init (lt_get_vtable *vtable_func, lt_user_data data)
+{
+ lt_user_dlloader *vtable = 0;
+ int errors = 0;
+
+ if (vtable_func)
+ {
+ vtable = (*vtable_func) (data);
+ }
+
+ if (!vtable)
+ {
+ LT__SETERROR (INVALID_LOADER);
+ ++errors;
+ }
+
+ if (!errors)
+ {
+ if (lt_dlloader_add (vtable, data))
+ {
+ LT__SETERROR (DLOPEN_NOT_SUPPORTED);
+ ++errors;
+ }
+ }
+
+ if ((!errors) && vtable->dlloader_init)
+ {
+ if ((*vtable->dlloader_init) (vtable->dlloader_data))
+ {
+ LT__SETERROR (INIT_LOADER);
+ ++errors;
+ }
+ }
+
+ return errors;
+}
+
+/* Bootstrap the loader loading with the preopening loader. */
+#define get_vtable preopen_LTX_get_vtable
+#define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
+
+extern lt_user_dlloader * get_vtable (lt_user_data data);
+extern lt_dlsymlist preloaded_symbols;
+
/* Initialize libltdl. */
int
lt_dlinit (void)
/* Initialize only at first call. */
if (++initialized == 1)
{
- lt__alloc_die = lt__alloc_die_callback;
-
- handles = 0;
- user_search_path = 0; /* empty search path */
+ lt__alloc_die = lt__alloc_die_callback;
+ handles = 0;
+ user_search_path = 0; /* empty search path */
- /* Append the available loaders to the internal list in the order
- they should be used -- if the first fails, then try again with
- the next loader in the chain. */
-# define LOADER_APPEND 0
-
- /* All ltdl supplied loaders are in the /dl[a-z-]+/ namespace. */
- errors += lt_dlloader_add (LOADER_APPEND, <__presym, "dlpreload");
-#if defined(HAVE_DLD)
- errors += lt_dlloader_add (LOADER_APPEND, <__sys_dld, "dld");
-#endif
-#if defined(HAVE_DYLD)
- errors += lt_dlloader_add (LOADER_APPEND, <__sys_dyld, "dldyld");
- errors += lt__sys_dyld_init();
-#endif
-#if defined(__BEOS__)
- errors += lt_dlloader_add (LOADER_APPEND, <__sys_bedl, "dlopen");
-#endif
-#if defined(HAVE_SHL_LOAD)
- errors += lt_dlloader_add (LOADER_APPEND, <__sys_shl, "dlopen");
-#endif
-#if defined(HAVE_LIBDL)
- errors += lt_dlloader_add (LOADER_APPEND, <__sys_dl, "dlopen");
-#endif
-#if defined(__WINDOWS__) || defined(__CYGWIN__)
- errors += lt_dlloader_add (LOADER_APPEND, <__sys_wll, "dlopen");
-#endif
+ /* First set up the statically loaded preload module loader, so
+ we can use it to preopen the other loaders we linked in at
+ compile time. */
+ errors += loader_init (get_vtable, 0);
- if (lt__presym_init (lt__presym.dlloader_data))
+ /* Now open all the preloaded module loaders, so the application
+ can use them to lt_dlopen their own modules. */
+ if (!errors)
{
- LT__SETERROR (INIT_LOADER);
- ++errors;
+ errors += lt_dlpreload (&preloaded_symbols);
}
- else if (errors != 0)
+ if (!errors)
{
- LT__SETERROR (DLOPEN_NOT_SUPPORTED);
- ++errors;
+ errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback);
}
}
assert (base_name && *base_name);
- /* Check whether we are opening a libtool module (.la extension). */
ext = strrchr (base_name, '.');
- if (ext && strcmp (ext, archive_ext) == 0)
- {
- /* this seems to be a libtool module */
- FILE * file = 0;
- char * dlname = 0;
- char * old_name = 0;
- char * libdir = 0;
- char * deplibs = 0;
- char * line = 0;
- size_t line_len;
-
- /* if we can't find the installed flag, it is probably an
- installed libtool archive, produced with an old version
- of libtool */
- int installed = 1;
/* extract the module name from the file name */
name = MALLOC (char, ext - base_name + 1);
name[ext - base_name] = LT_EOS_CHAR;
}
+ /* Check whether we are opening a libtool module (.la extension). */
+ if (ext && strcmp (ext, archive_ext) == 0)
+ {
+ /* this seems to be a libtool module */
+ FILE * file = 0;
+ char * dlname = 0;
+ char * old_name = 0;
+ char * libdir = 0;
+ char * deplibs = 0;
+ char * line = 0;
+ size_t line_len;
+
+ /* if we can't find the installed flag, it is probably an
+ installed libtool archive, produced with an old version
+ of libtool */
+ int installed = 1;
+
+
/* Now try to open the .la file. If there is no directory name
component, try to find it first in user_search_path and then other
prescribed paths. Otherwise (or in any case if the module was not
int
-lt_dlloader_add (lt_dlloader *place, const struct lt_user_dlloader *dlloader,
- const char *loader_name)
+lt_dlloader_add (const struct lt_user_dlloader *dlloader,
+ lt_user_data data)
{
int errors = 0;
lt_dlloader *node = 0, *ptr = 0;
}
/* Create a new dlloader node with copies of the user callbacks. */
- node = MALLOC (lt_dlloader, 1);
+ node = lt__malloc (sizeof *node);
if (!node)
return 1;
+ /* There is no need to record the dlloader->dlloader_init function,
+ since we won't need it again. */
node->next = 0;
- node->loader_name = loader_name;
+ node->loader_name = dlloader->name;
node->sym_prefix = dlloader->sym_prefix;
- node->dlloader_exit = dlloader->dlloader_exit;
node->module_open = dlloader->module_open;
node->module_close = dlloader->module_close;
node->find_sym = dlloader->find_sym;
+ node->dlloader_exit = dlloader->dlloader_exit;
node->dlloader_data = dlloader->dlloader_data;
- if (!loaders)
- {
- /* If there are no loaders, NODE becomes the list! */
- loaders = node;
- }
- else if (!place)
+ switch (dlloader->priority)
{
- /* If PLACE is not set, add NODE to the end of the
- LOADERS list. */
- for (ptr = loaders; ptr->next; ptr = ptr->next)
- {
- /*NOWORK*/;
- }
+ case LT_DLLOADER_PREPEND:
+ /* Tack NODE on the front of the LOADERS list. */
+ node->next = loaders;
+ loaders = node;
+ break;
+ case LT_DLLOADER_APPEND:
+ /* Add NODE to the end of the LOADERS list. */
+ for (ptr = loaders; ptr->next; ptr = ptr->next)
+ /*NOWORK*/;
ptr->next = node;
- }
- else if (loaders == place)
- {
- /* If PLACE is the first loader, NODE goes first. */
- node->next = place;
- loaders = node;
- }
- else
- {
- /* Find the node immediately preceding PLACE. */
- for (ptr = loaders; ptr->next != place; ptr = ptr->next)
- {
- /*NOWORK*/;
- }
+ break;
- if (ptr->next != place)
- {
- LT__SETERROR (INVALID_LOADER);
- ++errors;
- }
- else
- {
- /* Insert NODE between PTR and PLACE. */
- node->next = place;
- ptr->next = node;
- }
+ default:
+ LT__SETERROR (INVALID_LOADER);
+ ++errors;
+ break;
}
return errors;
if (warned++ == 0)
{
- fputs ("libltdl: WARNING: lt_dlmutex_register() is deprecated.\n"
+ fputs ("libltdl: WARNING: lt_dlmutex_register() is deprecated,\n"
"libltdl: WARNING: this version of libltdl is not thread safe.\n",
stderr);
}
+
+ return 0;
}
symbols for a dlpreopened module. */
typedef struct {
const char *name;
- void * address;
+ void *address;
+} lt_dlsymbol;
+
+typedef struct {
+ const char *originator;
+ const lt_dlsymbol symbols[];
} lt_dlsymlist;
+typedef int lt_dlpreload_callback_func (lt_dlhandle handle);
+
LT_SCOPE int lt_dlpreload (const lt_dlsymlist *preloaded);
LT_SCOPE int lt_dlpreload_default (const lt_dlsymlist *preloaded);
+LT_SCOPE int lt_dlpreload_open (const char *originator,
+ lt_dlpreload_callback_func *func);
+#define lt_preloaded_symbols lt__PROGRAM__LTX_preloaded_symbols
#define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \
- extern const lt_dlsymlist lt_preloaded_symbols[]; \
- lt_dlpreload_default(lt_preloaded_symbols); \
+ extern const lt_dlsymlist lt_preloaded_symbols; \
+ lt_dlpreload_default(<_preloaded_symbols); \
}LT_STMT_END
return $my_return_status
}
-# func_copy_all_files srcdir destdir [glob_exclude] [copy_cb=func_copy]
+# func_copy_all_files [-r] srcdir destdir [glob_exclude] [copy_cb=func_copy]
# For each file in SRCDIR, then try to copy the file to DESTDIR by calling
-# COPY_CB with the src and dest files. If GLOB_EXCLUDE is given, exclude
-# any matching filenames from the copy. If COPY_CB is passed, then the
-# check for overwriting without opt_force is the callbacks responsibility:
-# This allows using callbacks like func_serial_update, which perform their
-# own checks to decide whether to overwrite the dest file.
+# COPY_CB with the src and dest files. With the `-r' option, recurse into
+# subdirectories of srcdir too. If GLOB_EXCLUDE is given, exclude any
+# matching filenames from the copy. If COPY_CB is passed, then the check
+# for overwriting without opt_force is the callbacks responsibility: This
+# allows using callbacks like func_serial_update, which perform their own
+# checks to decide whether to overwrite the dest file.
func_copy_all_files ()
{
+ my_opt_recurse=false
+ if test "X$1" = X-r; then
+ my_opt_recurse=:
+ shift
+ fi
+
my_srcdir="$1"
my_destdir="$2"
my_glob_exclude="$3"
my_copy_cb="${4-func_copy}"
my_srcfiles=
- for my_filename in `cd "$my_srcdir" && ls`; do
+ my_basedir="$my_srcdir"
+ my_srcdirs="$my_srcdir"
+ my_save_IFS="$IFS"
+ IFS=:
+ while test -n "$my_srcdirs"; do
- # ignore excluded filenames
- if test -n "$my_glob_exclude"; then
- eval 'case $my_filename in '$my_glob_exclude') continue ;; esac'
- fi
+ IFS="$my_save_IFS"
+ my_srcdir=`echo "$my_srcdirs" | sed 's,:.*,,g'`
+ my_srcdirs=`echo "$my_srcdirs" | sed 's,:*[^:][^:]*:*,,'`
- my_srcfiles="$my_srcfiles${my_srcfiles:+:}$my_filename"
+ for my_filename in `cd "$my_srcdir" && ls`; do
+ # ignore excluded filenames
+ if test -n "$my_glob_exclude"; then
+ eval 'case $my_filename in '$my_glob_exclude') continue ;; esac'
+ fi
+
+ # Add to the appropriate list
+ if test -f "$my_srcdir/$my_filename"; then
+ my_srcfile=`echo "$my_srcdir/$my_filename" |sed "s,^$my_basedir/*,,"`
+ my_srcfiles="$my_srcfiles${my_srcfiles:+:}$my_srcfile"
+ elif $my_opt_recurse && test -d "$my_srcdir/$my_filename"; then
+ my_srcdirs="$my_srcdirs${my_srcdirs:+:}$my_srcdir/$my_filename"
+ fi
+
+ done
done
+ IFS="$my_save_IFS"
- func_copy_some_files "$my_srcdir" "$my_srcfiles" \
+ func_copy_some_files "$my_basedir" "$my_srcfiles" \
"$my_destdir" "$my_copy_cb"
}
# Copy all the files from installed libltdl to this project, if the
# user specified `--ltdl'.
if test -n "$ltdldir"; then
- eval func_copy_all_files "$pkgdatadir/libltdl" "$ltdldir"
+ eval func_copy_all_files -r "$pkgdatadir/libltdl" "$ltdldir"
# libtoolize the newly copied libltdl tree
( cd "$ltdldir" && "$progpath" $libtoolize_flags ) || exit $EXIT_FAILURE
VERSION=@VERSION@
TIMESTAMP="@TIMESTAMP@"
-
# Check that we have a working $echo.
if test "X$1" = X--no-reexec; then
# Discard the --no-reexec flag, and continue.
esac
fi
}
+
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms () {
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`echo "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ $show "$rm $nlist ${nlist}S ${nlist}T"
+ $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+ # Parse the name list into a source file.
+ $show "creating $output_objdir/$my_dlsyms"
+
+ test -z "$run" && $echo > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ $show "generating symbol list for \`$output'"
+
+ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for arg in $progfiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$output.exp"
+ $run $rm $export_symbols
+ $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ else
+ $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+ $run eval '$GREP -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval 'mv "$nlist"T "$nlist"'
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
+ $run eval '$echo ": $name " >> "$nlist"'
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $mv "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ $echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *originator;
+ const struct {
+ const char *name;
+ void *address;
+ } symbols[];
+}
+lt_${my_prefix}_LTX_preloaded_symbols =
+{\
+ \"$my_originator\",
+ {
+"
+
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+
+ $echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+ }
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$my_dlsyms\")"
+ $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' || exit $?
+
+ # Clean up the generated files.
+ $show "$rm $output_objdir/$my_dlsyms $nlist ${nlist}S ${nlist}T"
+ $run $rm "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$my_dlsyms'" 1>&2
+ exit $EXIT_FAILURE
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+}
+
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives () {
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+ my_status=""
+
+ $show "${rm}r $my_gentop"
+ $run ${rm}r "$my_gentop"
+ $show "$mkdir $my_gentop"
+ $run $mkdir "$my_gentop"
+ my_status=$?
+ if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
+ exit $my_status
+ fi
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
+ my_xdir="$my_gentop/$my_xlib"
+
+ $show "${rm}r $my_xdir"
+ $run ${rm}r "$my_xdir"
+ $show "$mkdir $my_xdir"
+ $run $mkdir "$my_xdir"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$my_xdir"; then
+ exit $status
+ fi
+
+ # We will extract separately just the conflicting names and we will
+ # no longer touch any unique names. It is faster to leave these
+ # extract automatically by $AR in one run.
+ $show "(cd $my_xdir && $AR x $my_xabs)"
+ $run eval "(cd \$my_xdir && $AR x \$my_xabs)" || exit $?
+ if ($AR t "$my_xabs" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+ $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+ $AR t "$my_xabs" | sort | uniq -cd | while read -r count name
+ do
+ i=1
+ while test "$i" -le "$count"
+ do
+ # Put our $i before any first dot (extension)
+ # Never overwrite any file
+ name_to="$name"
+ while test "X$name_to" = "X$name" || test -f "$my_xdir/$name_to"
+ do
+ name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+ done
+ $show "(cd $my_xdir && $AR xN $i $my_xabs '$name' && $mv '$name' '$name_to')"
+ $run eval "(cd \$my_xdir && $AR xN $i \$my_xabs '$name' && $mv '$name' '$name_to')" || exit $?
+ i=`expr $i + 1`
+ done
+ done
+ fi
+
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
# End of Shell function definitions
#####################################
# A libtool-controlled object.
# Check to see that this really is a libtool object.
- if (${SED} -e '2q' $arg | $GREP "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ if (${SED} -e '2q' $arg | $GREP "^# Generated by ltmain.sh ") >/dev/null 2>&1; then
pic_object=
non_pic_object=
need_relink=no # whether we're linking any uninstalled libtool libraries
notinst_deplibs= # not-installed libtool libraries
notinst_path= # paths that contain not-installed libtool libraries
+
case $linkmode in
lib)
- passes="conv link"
+ passes="conv dlpreopen link"
for file in $dlfiles $dlprefiles; do
case $file in
*.la) ;;
*) passes="conv"
;;
esac
+
for pass in $passes; do
if test "$linkmode,$pass" = "lib,link" ||
test "$linkmode,$pass" = "prog,scan"; then
link) libs="$deplibs %DEPLIBS% $dependency_libs $inherited_linker_flags" ;;
esac
fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ libs="$dlprefiles"
+ fi
if test "$pass" = dlopen; then
# Collect dlpreopened libraries
save_deplibs="$deplibs"
deplibs=
fi
+
for deplib in $libs; do
lib=
found=no
fi
case $linkmode in
lib)
- if test "$deplibs_check_method" != pass_all; then
- $echo
- $echo "*** Warning: Trying to link with static lib archive $deplib."
- $echo "*** I have the capability to make that library automatically link in when"
- $echo "*** you link to this library. But I can only do this if you have a"
- $echo "*** shared version of the library, which you do not appear to have"
- $echo "*** because the file extensions .$libext of this argument makes me believe"
- $echo "*** that it is just a static archive that I should not used here."
- else
- $echo
- $echo "*** Warning: Linking the shared library $output against the"
- $echo "*** static library $deplib is not portable!"
- deplibs="$deplib $deplibs"
- fi
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $lib "*) ;;
+ *)
+ if test "$deplibs_check_method" != pass_all; then
+ $echo
+ $echo "*** Warning: Trying to link with static lib archive $deplib."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have"
+ $echo "*** because the file extensions .$libext of this argument makes me believe"
+ $echo "*** that it is just a static archive that I should not use here."
+ else
+ $echo
+ $echo "*** Warning: Linking the shared library $output against the"
+ $echo "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
continue
;;
prog)
continue
;;
esac # case $deplib
+
if test "$found" = yes || test -f "$lib"; then :
else
$echo "$modename: cannot find the library \`$lib'" 1>&2
fi
# Check to see that this really is a libtool archive.
- if (${SED} -e '2q' $lib | $GREP "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ if (${SED} -e '2q' $lib | $GREP "^# Generated by ltmain.sh ") >/dev/null 2>&1; then :
else
$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
exit $EXIT_FAILURE
# This library was specified with -dlpreopen.
if test "$pass" = dlpreopen; then
- if test -z "$libdir"; then
- $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ $echo "$modename: only libraries may -dlpreopen a convenience library: \`$lib'" 1>&2
exit $EXIT_FAILURE
fi
# Prefer using a static library (so that no silly _DYNAMIC symbols
# are required to link).
if test -n "$old_library"; then
newdlprefiles="$newdlprefiles $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
# Otherwise, use the dlname, so that lt_dlopen finds it.
elif test -n "$dlname"; then
newdlprefiles="$newdlprefiles $dir/$dlname"
# This is a shared library
# Warn about portability, can't link against -module's on some
- # systems (darwin)
- if test "$shouldnotlink" = yes && test "$pass" = link ; then
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for module in $dlprefiles; do
+ if test "X$module" = "X$lib"; then
+ dlopenmodule="$module"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
$echo
if test "$linkmode" = prog; then
$echo "*** Warning: Linking the executable $output against the loadable module"
case $host in
*-*-sco3.2v5* ) add_dir="-L$dir" ;;
*-*-darwin* )
- # if the lib is a module then we can not link against
- # it, someone is ignoring the new warnings I added
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
if /usr/bin/file -L $add 2> /dev/null |
- $GREP "bundle" >/dev/null ; then
- $echo "** Warning, lib $linklib is a module, not a shared library"
- if test -z "$old_library" ; then
- $echo
- $echo "** And there doesn't seem to be a static archive available"
- $echo "** The link will probably fail, sorry"
- else
+ $GREP "bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $echo "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ $echo
+ $echo "*** And there doesn't seem to be a static archive available"
+ $echo "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
add="$dir/$old_library"
fi
fi
done # for pass
if test "$linkmode" = prog; then
dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
dlprefiles="$newdlprefiles"
fi
# Don't allow undefined symbols.
allow_undefined_flag="$no_undefined_flag"
fi
+
fi
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ libobjs="$libobjs $symfileobj"
+
if test "$mode" != relink; then
# Remove our outputs, but don't remove object files since they
# may have been created when compiling PIC objects.
case $host in
*-*-rhapsody* | *-*-darwin1.[012])
- # On Rhapsody replace the C library is the System framework
+ # On Rhapsody replace the C library with the System framework
newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
;;
esac
tmp_deplibs=
for test_deplib in $deplibs; do
- case " $convenience " in
- *" $test_deplib "*) ;;
- *)
- tmp_deplibs="$tmp_deplibs $test_deplib"
- ;;
- esac
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ tmp_deplibs="$tmp_deplibs $test_deplib"
+ ;;
+ esac
done
deplibs="$tmp_deplibs"
eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
else
gentop="$output_objdir/${outputname}x"
- $show "${rm}r $gentop"
- $run ${rm}r "$gentop"
- $show "$mkdir $gentop"
- $run $mkdir "$gentop"
- status=$?
- if test "$status" -ne 0 && test ! -d "$gentop"; then
- exit $status
- fi
generated="$generated $gentop"
- for xlib in $convenience; do
- # Extract the objects.
- case $xlib in
- [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
- *) xabs=`pwd`"/$xlib" ;;
- esac
- xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
- xdir="$gentop/$xlib"
-
- $show "${rm}r $xdir"
- $run ${rm}r "$xdir"
- $show "$mkdir $xdir"
- $run $mkdir "$xdir"
- status=$?
- if test "$status" -ne 0 && test ! -d "$xdir"; then
- exit $status
- fi
- # We will extract separately just the conflicting names and we will no
- # longer touch any unique names. It is faster to leave these extract
- # automatically by $AR in one run.
- $show "(cd $xdir && $AR x $xabs)"
- $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
- if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
- $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
- $AR t "$xabs" | sort | uniq -cd | while read -r count name
- do
- i=1
- while test "$i" -le "$count"
- do
- # Put our $i before any first dot (extension)
- # Never overwrite any file
- name_to="$name"
- while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
- do
- name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
- done
- $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
- $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
- i=`expr $i + 1`
- done
- done
- fi
-
- libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
- done
+ func_extract_archives $gentop $convenience
+ libobjs="$libobjs $func_extract_archives_result"
fi
fi
cmds=$module_cmds
fi
else
- if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
- eval test_cmds=\"$archive_expsym_cmds\"
- cmds=$archive_expsym_cmds
- else
- eval test_cmds=\"$archive_cmds\"
- cmds=$archive_cmds
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
fi
fi
cmds=$module_cmds
fi
else
- if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
- cmds=$archive_expsym_cmds
- else
- cmds=$archive_cmds
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
fi
fi
# to the just-reset $cmds.
eval cmds=\"\$cmds~\$rm $delfiles\"
fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ libobjs="$libobjs $func_extract_archives_result"
+ fi
+
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
else
gentop="$output_objdir/${obj}x"
- $show "${rm}r $gentop"
- $run ${rm}r "$gentop"
- $show "$mkdir $gentop"
- $run $mkdir "$gentop"
- status=$?
- if test "$status" -ne 0 && test ! -d "$gentop"; then
- exit $status
- fi
generated="$generated $gentop"
- for xlib in $convenience; do
- # Extract the objects.
- case $xlib in
- [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
- *) xabs=`pwd`"/$xlib" ;;
- esac
- xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
- xdir="$gentop/$xlib"
-
- $show "${rm}r $xdir"
- $run ${rm}r "$xdir"
- $show "$mkdir $xdir"
- $run $mkdir "$xdir"
- status=$?
- if test "$status" -ne 0 && test ! -d "$xdir"; then
- exit $status
- fi
- # We will extract separately just the conflicting names and we will no
- # longer touch any unique names. It is faster to leave these extract
- # automatically by $AR in one run.
- $show "(cd $xdir && $AR x $xabs)"
- $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
- if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
- $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
- $AR t "$xabs" | sort | uniq -cd | while read -r count name
- do
- i=1
- while test "$i" -le "$count"
- do
- # Put our $i before any first dot (extension)
- # Never overwrite any file
- name_to="$name"
- while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
- do
- name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
- done
- $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
- $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
- i=`expr $i + 1`
- done
- done
- fi
-
- reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
- done
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
fi
fi
finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
fi
- dlsyms=
- if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
- if test -n "$NM" && test -n "$global_symbol_pipe"; then
- dlsyms="${outputname}S.c"
- else
- $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
- fi
- fi
-
- if test -n "$dlsyms"; then
- case $dlsyms in
- "") ;;
- *.c)
- # Discover the nlist of each of the dlfiles.
- nlist="$output_objdir/${outputname}.nm"
-
- $show "$rm $nlist ${nlist}S ${nlist}T"
- $run $rm "$nlist" "${nlist}S" "${nlist}T"
-
- # Parse the name list into a source file.
- $show "creating $output_objdir/$dlsyms"
-
- test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
-/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
-/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
-
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-
-/* Prevent the only kind of declaration conflicts we can make. */
-#define lt_preloaded_symbols some_other_symbol
-
-/* External symbol declarations for the compiler. */\
-"
-
- if test "$dlself" = yes; then
- $show "generating symbol list for \`$output'"
-
- test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
-
- # Add our own program objects to the symbol list.
- progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
- for arg in $progfiles; do
- $show "extracting global C symbols from \`$arg'"
- $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
- done
-
- if test -n "$exclude_expsyms"; then
- $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
- $run eval '$mv "$nlist"T "$nlist"'
- fi
-
- if test -n "$export_symbols_regex"; then
- $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
- $run eval '$mv "$nlist"T "$nlist"'
- fi
-
- # Prepare the list of exported symbols
- if test -z "$export_symbols"; then
- export_symbols="$output_objdir/$output.exp"
- $run $rm $export_symbols
- $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
- else
- $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
- $run eval '$GREP -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
- $run eval 'mv "$nlist"T "$nlist"'
- fi
- fi
-
- for arg in $dlprefiles; do
- $show "extracting global C symbols from \`$arg'"
- name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
- $run eval '$echo ": $name " >> "$nlist"'
- $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
- done
-
- if test -z "$run"; then
- # Make sure we have at least an empty file.
- test -f "$nlist" || : > "$nlist"
-
- if test -n "$exclude_expsyms"; then
- $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
- $mv "$nlist"T "$nlist"
- fi
-
- # Try sorting and uniquifying the output.
- if $GREP -v "^: " < "$nlist" |
- if sort -k 3 </dev/null >/dev/null 2>&1; then
- sort -k 3
- else
- sort +2
- fi |
- uniq > "$nlist"S; then
- :
- else
- $GREP -v "^: " < "$nlist" > "$nlist"S
- fi
-
- if test -f "$nlist"S; then
- eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
- else
- $echo '/* NONE */' >> "$output_objdir/$dlsyms"
- fi
-
- $echo >> "$output_objdir/$dlsyms" "\
-
-#undef lt_preloaded_symbols
-
-#if defined (__STDC__) && __STDC__
-# define lt_ptr void *
-#else
-# define lt_ptr char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- lt_ptr address;
-}
-lt_preloaded_symbols[] =
-{\
-"
-
- eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
-
- $echo >> "$output_objdir/$dlsyms" "\
- {0, (lt_ptr) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
- return lt_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif\
-"
- fi
-
- pic_flag_for_symtable=
- case $host in
- # compiling the symbol table file with pic_flag works around
- # a FreeBSD bug that causes programs to crash when -lm is
- # linked before any other PIC object. But we must not use
- # pic_flag when linking with -static. The problem exists in
- # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
- *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
- case "$compile_command " in
- *" -static "*) ;;
- *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
- esac;;
- *-*-hpux*)
- case "$compile_command " in
- *" -static "*) ;;
- *) pic_flag_for_symtable=" $pic_flag";;
- esac
- esac
-
- # Now compile the dynamic symbol file.
- $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
- $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
-
- # Clean up the generated files.
- $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
- $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
-
- # Transform the symbol file into the correct name.
- compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
- finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
- ;;
- *)
- $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
- else
- # We keep going just in case the user didn't refer to
- # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
- # really was required.
-
- # Nullify the symbol file.
- compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
- finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
- fi
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
# Replace the output file specification.
status=$?
# Delete the generated files.
- if test -n "$dlsyms"; then
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
$show "$rm $output_objdir/${outputname}S.${objext}"
$run $rm "$output_objdir/${outputname}S.${objext}"
fi
for oldlib in $oldlibs; do
if test "$build_libtool_libs" = convenience; then
- oldobjs="$libobjs_save"
+ oldobjs="$libobjs_save $symfileobj"
addlibs="$convenience"
build_libtool_libs=no
else
build_libtool_libs=no
else
oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$dlsymsobj"; then
+ oldobjs="$oldobjs $symfileobj"
+ fi
fi
addlibs="$old_convenience"
fi
if test -n "$addlibs"; then
gentop="$output_objdir/${outputname}x"
- $show "${rm}r $gentop"
- $run ${rm}r "$gentop"
- $show "$mkdir $gentop"
- $run $mkdir "$gentop"
- status=$?
- if test "$status" -ne 0 && test ! -d "$gentop"; then
- exit $status
- fi
generated="$generated $gentop"
- # Add in members from convenience archives.
- for xlib in $addlibs; do
- # Extract the objects.
- case $xlib in
- [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
- *) xabs=`pwd`"/$xlib" ;;
- esac
- xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
- xdir="$gentop/$xlib"
-
- $show "${rm}r $xdir"
- $run ${rm}r "$xdir"
- $show "$mkdir $xdir"
- $run $mkdir "$xdir"
- status=$?
- if test "$status" -ne 0 && test ! -d "$xdir"; then
- exit $status
- fi
- # We will extract separately just the conflicting names and we will no
- # longer touch any unique names. It is faster to leave these extract
- # automatically by $AR in one run.
- $show "(cd $xdir && $AR x $xabs)"
- $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
- if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
- $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
- $AR t "$xabs" | sort | uniq -cd | while read -r count name
- do
- i=1
- while test "$i" -le "$count"
- do
- # Put our $i before any first dot (extension)
- # Never overwrite any file
- name_to="$name"
- while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
- do
- name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
- done
- $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
- $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
- i=`expr $i + 1`
- done
- done
- fi
-
- oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
- done
+ func_extract_archives $gentop $addlibs
+ oldobjs="$oldobjs $func_extract_archives_result"
fi
# Do each command in the archive commands.
if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
- cmds=$old_archive_from_new_cmds
+ cmds=$old_archive_from_new_cmds
else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ oldobjs="$oldobjs $func_extract_archives_result"
+ fi
+
eval cmds=\"$old_archive_cmds\"
if len=`expr "X$cmds" : ".*"` &&
done
dependency_libs="$newdependency_libs"
newdlfiles=
+
for lib in $dlfiles; do
- name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
- if test -z "$libdir"; then
- $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
- exit $EXIT_FAILURE
- fi
- newdlfiles="$newdlfiles $libdir/$name"
+ case $lib in
+ *.la)
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit $EXIT_FAILURE
+ fi
+ newdlfiles="$newdlfiles $libdir/$name"
+ ;;
+ *) newdlfiles="$newdlfiles $lib" ;;
+ esac
done
dlfiles="$newdlfiles"
newdlprefiles=
for lib in $dlprefiles; do
- name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
- if test -z "$libdir"; then
- $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
- exit $EXIT_FAILURE
- fi
- newdlprefiles="$newdlprefiles $libdir/$name"
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit $EXIT_FAILURE
+ fi
+ newdlprefiles="$newdlprefiles $libdir/$name"
+ ;;
+ esac
done
dlprefiles="$newdlprefiles"
else
*.la)
# Check to see that this really is a libtool archive.
- if (${SED} -e '2q' $file | $GREP "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ if (${SED} -e '2q' $file | $GREP "^# Generated by ltmain.sh ") >/dev/null 2>&1; then :
else
$echo "$modename: \`$file' is not a valid libtool archive" 1>&2
$echo "$help" 1>&2
lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
# Define system-specific variables.
case $host_os in
symcode='[[ABCDEGRST]]'
fi
lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
- lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
;;
irix* | nonstopux*)
symcode='[[BCDEGRST]]'
eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
cat <<_LT_EOF >> conftest.$ac_ext
-#if defined (__STDC__) && __STDC__
-# define lt_ptr_t void *
-#else
-# define lt_ptr_t char *
-# define const
-#endif
-/* The mapping between symbol names and symbols. */
+/* The mapping between symbol names and symbols. */
const struct {
- const char *name;
- lt_ptr_t address;
+ const char *originator;
+ const struct {
+ const char *name;
+ void *address;
+ } symbols[[]];
}
-lt_preloaded_symbols[[]] =
+lt__PROGRAM__LTX_preloaded_symbols =
{
+ "@PROGRAM@",
+ {
_LT_EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
cat <<\_LT_EOF >> conftest.$ac_ext
- {0, (lt_ptr_t) 0}
+ {0, (void *) 0}
+ }
};
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
#ifdef __cplusplus
}
#endif
# AC_LTDL_DLLIB
# -------------
AC_DEFUN([AC_LTDL_DLLIB],
-[LIBADD_DL=
-AC_SUBST(LIBADD_DL)
+[m4_pattern_allow([^LT_DLLOADERS$])
+LT_DLLOADERS=
+AC_SUBST([LT_DLLOADERS])
+
AC_LANG_PUSH([C])
-AC_CHECK_FUNC([shl_load],
- [AC_DEFINE([HAVE_SHL_LOAD], [1],
- [Define if you have the shl_load function.])
- AC_LIBOBJ([loader-shl_load])],
- [AC_CHECK_LIB([dld], [shl_load],
- [AC_DEFINE([HAVE_SHL_LOAD], [1],
- [Define if you have the shl_load function.])
- LIBADD_DL="$LIBADD_DL -ldld"
- AC_LIBOBJ([loader-shl_load])],
- [AC_CHECK_LIB([dl], [dlopen],
- [AC_DEFINE([HAVE_LIBDL], [1],
- [Define if you have the libdl library or equivalent.])
- LIBADD_DL="-ldl" libltdl_cv_lib_dl_dlopen="yes"
- AC_LIBOBJ([loader-dlopen])],
- [AC_TRY_LINK([#if HAVE_DLFCN_H
+LIBADD_DLOPEN=
+AC_CHECK_LIB([dl], [dlopen],
+ [AC_DEFINE([HAVE_LIBDL], [1],
+ [Define if you have the libdl library or equivalent.])
+ LIBADD_DLOPEN="-ldl" libltdl_cv_lib_dl_dlopen="yes"
+ LT_DLLOADERS="$LT_DLLOADERS dlopen.la"],
+ [AC_TRY_LINK([#if HAVE_DLFCN_H
# include <dlfcn.h>
#endif
- ],
- [dlopen(0, 0);],
+ ], [dlopen(0, 0);],
[AC_DEFINE([HAVE_LIBDL], [1],
[Define if you have the libdl library or equivalent.])
libltdl_cv_func_dlopen="yes"
- AC_LIBOBJ([loader-dlopen])],
- [AC_CHECK_LIB([svld], [dlopen],
- [AC_DEFINE([HAVE_LIBDL], [1],
+ LT_DLLOADERS="$LT_DLLOADERS dlopen.la"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [AC_DEFINE([HAVE_LIBDL], [1],
[Define if you have the libdl library or equivalent.])
- LIBADD_DL="-lsvld" libltdl_cv_func_dlopen="yes"
- AC_LIBOBJ([loader-dlopen])],
- [AC_CHECK_LIB([dld], [dld_link],
- [AC_DEFINE([HAVE_DLD], [1],
- [Define if you have the GNU dld library.])
- LIBADD_DL="$LIBADD_DL -ldld"
- AC_LIBOBJ([loader-dld_link])],
- [AC_CHECK_FUNC([_dyld_func_lookup],
- [AC_DEFINE([HAVE_DYLD], [1],
- [Define if you have the _dyld_func_lookup function.])
- AC_LIBOBJ([loader-dyld])])#_dyld_func_lookup
- ])#dld
- ])#svld
- ])#dlfcn.h
- ])#dl
- ])#dld
- ])#shl_load
+ LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes"
+ LT_DLLOADERS="$LT_DLLOADERS dlopen.la"])])])
+if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes
+then
+ lt_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBADD_DLOPEN"
+ AC_CHECK_FUNCS([dlerror])
+ LIBS="$lt_save_LIBS"
+fi
+AC_SUBST([LIBADD_DLOPEN])
+
+LIBADD_SHL_LOAD=
+AC_CHECK_FUNC([shl_load],
+ [AC_DEFINE([HAVE_SHL_LOAD], [1],
+ [Define if you have the shl_load function.])
+ LT_DLLOADERS="$LT_DLLOADERS shl_load.la"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [AC_DEFINE([HAVE_SHL_LOAD], [1],
+ [Define if you have the shl_load function.])
+ LT_DLLOADERS="$LT_DLLOADERS shl_load.la"
+ LIBADD_SHL_LOAD="-ldld"])])
+AC_SUBST([LIBADD_SHL_LOAD])
+
+AC_CHECK_FUNC([_dyld_func_lookup],
+ [AC_DEFINE([HAVE_DYLD], [1],
+ [Define if you have the _dyld_func_lookup function.])
+ LT_DLLOADERS="$LT_DLLOADERS dyld.la"])
case $host_os in
beos*)
- AC_LIBOBJ([loader-load_add_on])
+ LT_DLLOADERS="$LT_DLLOADERS load_add_on.la"
;;
cygwin* | mingw* | os2* | pw32*)
- AC_LIBOBJ([loader-loadlibrary])
+ LT_DLLOADERS="$LT_DLLOADERS loadlibrary.la"
;;
esac
-if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes
-then
- lt_save_LIBS="$LIBS"
- LIBS="$LIBS $LIBADD_DL"
- AC_CHECK_FUNCS([dlerror])
- LIBS="$lt_save_LIBS"
-fi
+AC_CHECK_LIB([dld], [dld_link],
+ [AC_DEFINE([HAVE_DLD], [1],
+ [Define if you have the GNU dld library.])
+ LT_DLLOADERS="$LT_DLLOADERS dld_link.la"])
+AC_SUBST([LIBADD_DLD_LINK])
+
+m4_pattern_allow([^LT_DLPREOPEN$])
+LT_DLPREOPEN=
+for lt_loader in $LT_DLLOADERS; do
+ LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen loaders/$lt_loader "
+done
+AC_SUBST([LT_DLPREOPEN])
+
+dnl This isn't used anymore, but set it for backwards compatibility
+LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD"
+AC_SUBST([LIBADD_DL])
+
AC_LANG_POP
])# AC_LTDL_DLLIB
[libltdl_cv_need_uscore],
[libltdl_cv_need_uscore=unknown
save_LIBS="$LIBS"
- LIBS="$LIBS $LIBADD_DL"
+ LIBS="$LIBS $LIBADD_DLOPEN"
_LT_AC_TRY_DLOPEN_SELF(
[libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes],
[], [libltdl_cv_need_uscore=cross])
/* dlmain.c -- hello test program that uses simulated dynamic linking
- Copyright (C) 1996-1999 Free Software Foundation, Inc.
+ Copyright (C) 1996-1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Libtool.
This program is free software; you can redistribute it and/or modify
#include <string.h>
#endif
+#define lt_preloaded_symbols lt__PROGRAM__LTX_preloaded_symbols
+
struct lt_symlist
{
const char *name;
/* In an ideal world a shared lib would be able to export data */
pnothing = (int*)¬hing;
#endif
- } else
+ } else
printf ("found file: %s\n", s->name);
s ++;
}
/* dlmain.c -- hello test program that uses simulated dynamic linking
- Copyright (C) 1996-1999 Free Software Foundation, Inc.
+ Copyright (C) 1996-1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Libtool.
This program is free software; you can redistribute it and/or modify
#include <string.h>
#endif
+#define lt_preloaded_symbols lt__PROGRAM__LTX_preloaded_symbols
+
struct lt_symlist
{
const char *name;
/* In an ideal world a shared lib would be able to export data */
pnothing = (int*)¬hing;
#endif
- } else
+ } else
printf ("found file: %s\n", s->name);
s ++;
}