Factor out the individual loaders, in preparation for preloading

them as libtool modules.  Currently loader-preopen.c is linked
unconditionally and other appropriate loaders discovered by
AC_LTDL_DLLIB are built and linked in:

* libltdl/Makefile.am (libltdl_la_SOURCES): Add loader-preopen
module.
* m4/ltdl.m4 (AC_LTDL_DLLIB): Use AC_LIBOBJ to add appropriate
loaders to libltdl.
* libltdl/lt_system.h (LT_SCOPE): Moved to here.
* libltdl/ltdl.h (lt_dlloader, lt_user_data, lt_module)
(lt_module_open, lt_module_close, lt_find_sym, lt_dlloader_exit)
(struct lt_user_dlloader, lt_dlloader_next, lt_dlloader_find)
(lt_dlloader_name, lt_dlloader_data, lt_dlloader_add)
(lt_dlloader_remove): Moved declarations...
* libltdl/lt_loader.h: ...to here.
* libltdl/ltdl.c: Include lt_loader.h.  Move loader implementation
code from here...
* 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: ...to here.
* tests/cdemo/Makefile.am, tests/demo/Makefile.am,
tests/depdemo/Makefile.am, tests/f77demo/Makefile.am,
tests/mdemo/Makefile.am, tests/mdemo2/Makefile.am,
tests/pdemo/Makefile.am, tests/tagdemo/Makefile.am (AM_CPPFLAGS):
Add -I$(top_srcdir)/../.. so that libltdl include files can be
written as #include <libltdl/lt_dlloader.h> and found correctly.
This commit is contained in:
Gary V. Vaughan 2004-04-13 14:31:05 +00:00
parent 8c775c544a
commit 5dfb0ce7e2
22 changed files with 1374 additions and 1106 deletions

View File

@ -1,3 +1,34 @@
2004-04-13 Gary V. Vaughan <gary@gnu.org>
Factor out the individual loaders, in preparation for preloading
them as libtool modules. Currently loader-preopen.c is linked
unconditionally and other appropriate loaders discovered by
AC_LTDL_DLLIB are built and linked in:
* libltdl/Makefile.am (libltdl_la_SOURCES): Add loader-preopen
module.
* m4/ltdl.m4 (AC_LTDL_DLLIB): Use AC_LIBOBJ to add appropriate
loaders to libltdl.
* libltdl/lt_system.h (LT_SCOPE): Moved to here.
* libltdl/ltdl.h (lt_dlloader, lt_user_data, lt_module)
(lt_module_open, lt_module_close, lt_find_sym, lt_dlloader_exit)
(struct lt_user_dlloader, lt_dlloader_next, lt_dlloader_find)
(lt_dlloader_name, lt_dlloader_data, lt_dlloader_add)
(lt_dlloader_remove): Moved declarations...
* libltdl/lt_loader.h: ...to here.
* libltdl/ltdl.c: Include lt_loader.h. Move loader implementation
code from here...
* 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: ...to here.
* tests/cdemo/Makefile.am, tests/demo/Makefile.am,
tests/depdemo/Makefile.am, tests/f77demo/Makefile.am,
tests/mdemo/Makefile.am, tests/mdemo2/Makefile.am,
tests/pdemo/Makefile.am, tests/tagdemo/Makefile.am (AM_CPPFLAGS):
Add -I$(top_srcdir)/../.. so that libltdl include files can be
written as #include <libltdl/lt_dlloader.h> and found correctly.
2004-04-13 Gary V. Vaughan <gary@gnu.org>
Factor out the mutex handling and error handling into their own

View File

@ -39,6 +39,7 @@ endif
CLEANFILES = libltdl.la libltdlc.la
libltdl_la_SOURCES = ltdl.h ltdl.c \
loader-preopen.c \
lt_error.h lt_error.c lt_mutex.h lt_mutex.c \
lt__private.h lt__alloc.h lt__alloc.c \
lt__pre89.h lt__glibc.h argz.h lt__dirent.h \

84
libltdl/loader-dld_link.c Normal file
View File

@ -0,0 +1,84 @@
/* 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 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__MUTEX_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__MUTEX_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__MUTEX_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
};

121
libltdl/loader-dlopen.c Normal file
View File

@ -0,0 +1,121 @@
/* loader-dlopen.c -- dynamic linking with dlopen/dlsym
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 HAVE_DLFCN_H
# include <dlfcn.h>
#endif
#if HAVE_SYS_DL_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. */
#ifndef LT_LAZY_OR_NOW
# ifdef RTLD_LAZY
# define LT_LAZY_OR_NOW RTLD_LAZY
# else
# ifdef DL_LAZY
# define LT_LAZY_OR_NOW DL_LAZY
# endif
# endif /* !RTLD_LAZY */
#endif
#ifndef LT_LAZY_OR_NOW
# ifdef RTLD_NOW
# define LT_LAZY_OR_NOW RTLD_NOW
# else
# ifdef DL_NOW
# define LT_LAZY_OR_NOW DL_NOW
# endif
# endif /* !RTLD_NOW */
#endif
#ifndef LT_LAZY_OR_NOW
# define LT_LAZY_OR_NOW 0
#endif /* !LT_LAZY_OR_NOW */
#if HAVE_DLERROR
# define DLERROR(arg) dlerror ()
#else
# define DLERROR(arg) LT__STRERROR (arg)
#endif
#define DL__MUTEX_SETERROR(errorcode) \
LT__MUTEX_SETERRORSTR (DLERROR (errorcode))
static lt_module
sys_dl_open (lt_user_data loader_data, const char *filename)
{
lt_module module = dlopen (filename, LT_LAZY_OR_NOW);
if (!module)
{
DL__MUTEX_SETERROR (CANNOT_OPEN);
}
return module;
}
static int
sys_dl_close (lt_user_data loader_data, lt_module module)
{
int errors = 0;
if (dlclose (module) != 0)
{
DL__MUTEX_SETERROR (CANNOT_CLOSE);
++errors;
}
return errors;
}
static void *
sys_dl_sym (lt_user_data loader_data, lt_module module, const char *symbol)
{
void *address = dlsym (module, symbol);
if (!address)
{
DL__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
}
return address;
}
struct lt_user_dlloader lt__sys_dl =
{
# ifdef NEED_USCORE
"_",
# else
0,
# endif
sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };

417
libltdl/loader-dyld.c Normal file
View File

@ -0,0 +1,417 @@
/* loader-dyld.c -- dynamic linking on darwin and OS X
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 HAVE_MACH_O_DYLD_H
# if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
/* Is this correct? Does it still function properly? */
# define __private_extern__ extern
# endif
# include <mach-o/dyld.h>
#endif
#include <mach-o/getsect.h>
/* We have to put some stuff here that isn't in older dyld.h files */
#ifndef ENUM_DYLD_BOOL
# define ENUM_DYLD_BOOL
# undef FALSE
# undef TRUE
enum DYLD_BOOL {
FALSE,
TRUE
};
#endif
#ifndef LC_REQ_DYLD
# define LC_REQ_DYLD 0x80000000
#endif
#ifndef LC_LOAD_WEAK_DYLIB
# 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;
#ifndef NSADDIMAGE_OPTION_NONE
# define NSADDIMAGE_OPTION_NONE 0x0
#endif
#ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
# define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
#endif
#ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
# define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
#endif
#ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
# define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
#endif
#ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
# define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
#endif
#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
# define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
#endif
#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
# define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
#endif
#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
# define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
#endif
#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
# define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
#endif
#define LT__SYMLOOKUP_OPTS (NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW \
| NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR)
#ifdef __BIG_ENDIAN__
# define LT__MAGIC MH_MAGIC
#else
# define LT__MAGIC MH_CIGAM
#endif
#define DYLD__MUTEX_SETERROR(errorcode) \
LT__MUTEX_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__STRERROR (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;
}
}
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;
}
int
lt__sys_dyld_init (void)
{
int errors = 0;
LT__MUTEX_LOCK ();
if (! dyld_cannot_close)
{
if (!_dyld_present ())
{
++errors;
}
else
{
(void) _dyld_func_lookup ("__dyld_NSAddImage",
(unsigned long*) &lt__addimage);
(void) _dyld_func_lookup ("__dyld_NSLookupSymbolInImage",
(unsigned long*)&lt__image_symbol);
(void) _dyld_func_lookup ("__dyld_NSIsSymbolNameDefinedInImage",
(unsigned long*) &lt__image_symbol_p);
(void) _dyld_func_lookup ("__dyld_NSMakePrivateModulePublic",
(unsigned long*) &lt__module_export);
dyld_cannot_close = lt_dladderror ("can't close a dylib");
}
}
LT__MUTEX_UNLOCK ();
return errors;
}
static lt_module
sys_dyld_open (lt_user_data loader_data, const char *filename)
{
lt_module module = 0;
NSObjectFileImage ofi = 0;
if (!filename)
{
return (lt_module) -1;
}
switch (NSCreateObjectFileImageFromFile (filename, &ofi))
{
case NSObjectFileImageSuccess:
module = NSLinkModule (ofi, filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR
| NSLINKMODULE_OPTION_PRIVATE
| NSLINKMODULE_OPTION_BINDNOW);
NSDestroyObjectFileImage (ofi);
if (module)
{
lt__module_export (module);
}
break;
case NSObjectFileImageInappropriateFile:
if (lt__image_symbol_p && lt__image_symbol)
{
module = (lt_module) lt__addimage(filename,
NSADDIMAGE_OPTION_RETURN_ON_ERROR);
}
break;
}
if (!module)
{
DYLD__MUTEX_SETERROR (CANNOT_OPEN);
}
return module;
}
static int
sys_dyld_close (lt_user_data loader_data, lt_module module)
{
int errors = 0;
if (module != (lt_module) -1)
{
const mach_header *mh = (const mach_header *) module;
int flags = 0;
if (mh->magic == LT__MAGIC)
{
DYLD__MUTEX_SETERROR(dyld_cannot_close);
++errors;
}
else
{
#if 1
/* Currently, if a module contains c++ static destructors and it
is unloaded, we get a segfault in atexit(), due to compiler and
dynamic loader differences of opinion, this works around that. */
if ((const struct section *) NULL !=
getsectbynamefromheader (lt__nsmodule_get_header (module),
"__DATA", "__mod_term_func"))
{
flags |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
}
#endif
#ifdef __ppc__
flags |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
#endif
if (!NSUnLinkModule (module, flags))
{
DYLD__MUTEX_SETERRORSTR (CANNOT_CLOSE);
++errors;
}
}
}
return errors;
}
static void *
sys_dyld_sym (lt_user_data loader_data, lt_module module, const char *symbol)
{
NSSymbol *nssym = 0;
mach_header *mh = (mach_header *) module;
char saveError[256] = "Symbol not found";
if (module == (lt_module)-1)
{
void *address, *unused;
_dyld_lookup_and_bind(symbol, (unsigned long*) &address, &unused);
return address;
}
if (mh->magic == LT__MAGIC)
{
if (lt__image_symbol_p && lt__image_symbol)
{
if (lt__image_symbol_p (mh, symbol))
{
nssym = lt__image_symbol (mh, symbol, LT__SYMLOOKUP_OPTS);
}
}
}
else
{
nssym = NSLookupSymbolInModule (module, symbol);
}
if (!nssym)
{
strncpy (saveError, lt__dylderror (SYMBOL_NOT_FOUND), 255);
saveError[255] = 0;
if (!mh)
{
mh = lt__nsmodule_get_header (module);
}
nssym = lt__linkedlib_symbol (symbol, mh);
}
if (!nssym)
{
LT__MUTEX_SETERRORSTR (saveError);
}
return nssym ? NSAddressOfSymbol (nssym) : 0;
}
struct lt_user_dlloader lt__sys_dyld =
{ "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };

View File

@ -0,0 +1,92 @@
/* 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__MUTEX_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__MUTEX_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__MUTEX_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
};

View File

@ -0,0 +1,152 @@
/* loader-loadlibrary.c -- dynamic linking for Win32
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 <windows.h>
/* Forward declaration; required to implement handle search below. */
static lt_dlhandle handles;
static lt_module
sys_wll_open (lt_user_data loader_data, const char *filename)
{
lt_dlhandle cur;
lt_module module = 0;
const char *errormsg = 0;
char *searchname = 0;
char *ext;
char self_name_buf[MAX_PATH];
if (!filename)
{
/* Get the name of main module */
*self_name_buf = 0;
GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
filename = ext = self_name_buf;
}
else
{
ext = strrchr (filename, '.');
}
if (ext)
{
/* FILENAME already has an extension. */
searchname = lt__strdup (filename);
}
else
{
/* Append a `.' to stop Windows from adding an
implicit `.dll' extension. */
searchname = MALLOC (char, 2+ LT_STRLEN (filename));
if (searchname)
sprintf (searchname, "%s.", filename);
}
if (!searchname)
return 0;
#if __CYGWIN__
{
char wpath[MAX_PATH];
cygwin_conv_to_full_win32_path(searchname, wpath);
module = LoadLibrary(wpath);
}
#else
module = LoadLibrary (searchname);
#endif
FREE (searchname);
/* libltdl expects this function to fail if it is unable
to physically load the library. Sadly, LoadLibrary
will search the loaded libraries for a match and return
one of them if the path search load fails.
We check whether LoadLibrary is returning a handle to
an already loaded module, and simulate failure if we
find one. */
LT__MUTEX_LOCK ();
cur = handles;
while (cur)
{
if (!cur->module)
{
cur = 0;
break;
}
if (cur->module == module)
{
break;
}
cur = cur->next;
}
LT__MUTEX_UNLOCK ();
if (cur || !module)
{
LT__MUTEX_SETERROR (CANNOT_OPEN);
module = 0;
}
return module;
}
static int
sys_wll_close (lt_user_data loader_data, lt_module module)
{
int errors = 0;
if (FreeLibrary(module) == 0)
{
LT__MUTEX_SETERROR (CANNOT_CLOSE);
++errors;
}
return errors;
}
static void *
sys_wll_sym (lt_user_data loader_data, lt_module module,const char *symbol)
{
void * address = GetProcAddress (module, symbol);
if (!address)
{
LT__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
}
return address;
}
struct lt_user_dlloader lt__sys_wll = {
0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
};

241
libltdl/loader-preopen.c Normal file
View File

@ -0,0 +1,241 @@
/* 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;
LT__MUTEX_LOCK ();
preloaded_symbols = 0;
if (default_preloaded_symbols)
{
errors = lt_dlpreload (default_preloaded_symbols);
}
LT__MUTEX_UNLOCK ();
return errors;
}
static int
presym_free_symlists (void)
{
lt_dlsymlists_t *lists;
LT__MUTEX_LOCK ();
lists = preloaded_symbols;
while (lists)
{
lt_dlsymlists_t *tmp = lists;
lists = lists->next;
FREE (tmp);
}
preloaded_symbols = 0;
LT__MUTEX_UNLOCK ();
return 0;
}
int
lt__presym_add_symlist (const lt_dlsymlist *preloaded)
{
lt_dlsymlists_t *tmp;
lt_dlsymlists_t *lists;
int errors = 0;
LT__MUTEX_LOCK ();
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:
LT__MUTEX_UNLOCK ();
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;
LT__MUTEX_LOCK ();
lists = preloaded_symbols;
if (!lists)
{
LT__MUTEX_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__MUTEX_SETERROR (FILE_NOT_FOUND);
done:
LT__MUTEX_UNLOCK ();
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__MUTEX_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();
LT__MUTEX_LOCK ();
if (default_preloaded_symbols)
{
errors = lt_dlpreload (default_preloaded_symbols);
}
LT__MUTEX_UNLOCK ();
}
return errors;
}
int
lt_dlpreload_default (const lt_dlsymlist *preloaded)
{
LT__MUTEX_LOCK ();
default_preloaded_symbols = preloaded;
LT__MUTEX_UNLOCK ();
return 0;
}

147
libltdl/loader-shl_load.c Normal file
View File

@ -0,0 +1,147 @@
/* loader-shl_load.c -- dynamic linking with shl_load (HP-UX)
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"
#ifdef HAVE_DL_H
# include <dl.h>
#endif
/* some flags are missing on some systems, so we provide
* harmless defaults.
*
* Mandatory:
* BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
* BIND_DEFERRED - Delay code symbol resolution until actual reference.
*
* Optionally:
* BIND_FIRST - Place the library at the head of the symbol search
* order.
* BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
* unsatisfied symbols as fatal. This flag allows
* binding of unsatisfied code symbols to be deferred
* until use.
* [Perl: For certain libraries, like DCE, deferred
* binding often causes run time problems. Adding
* BIND_NONFATAL to BIND_IMMEDIATE still allows
* unresolved references in situations like this.]
* BIND_NOSTART - Do not call the initializer for the shared library
* when the library is loaded, nor on a future call to
* shl_unload().
* BIND_VERBOSE - Print verbose messages concerning possible
* unsatisfied symbols.
*
* hp9000s700/hp9000s800:
* BIND_RESTRICTED - Restrict symbols visible by the library to those
* present at library load time.
* DYNAMIC_PATH - Allow the loader to dynamically search for the
* library specified by the path argument.
*/
#ifndef DYNAMIC_PATH
# define DYNAMIC_PATH 0
#endif
#ifndef BIND_RESTRICTED
# define BIND_RESTRICTED 0
#endif
#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
lt_module
lt__sys_shl_open (lt_user_data loader_data, const char *filenam)
{
static shl_t self = (shl_t) 0;
lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
/* Since searching for a symbol against a NULL module handle will also
look in everything else that was already loaded and exported with
the -E compiler flag, we always cache a handle saved before any
modules are loaded. */
if (!self)
{
void *address;
shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
}
if (!filename)
{
module = self;
}
else
{
module = shl_load (filename, LT_BIND_FLAGS, 0L);
if (!module)
{
LT__MUTEX_SETERROR (CANNOT_OPEN);
}
}
return module;
}
int
lt__sys_shl_close (lt_user_data loader_data, lt_module module)
{
int errors = 0;
if (module && (shl_unload ((shl_t) (module)) != 0))
{
LT__MUTEX_SETERROR (CANNOT_CLOSE);
++errors;
}
return errors;
}
static void *
sys_shl_sym (lt_user_data loader_data, lt_module module, const char *symbol)
{
void *address = 0;
/* sys_shl_open should never return a NULL module handle */
if (module == (lt_module) 0)
{
LT__MUTEX_SETERROR (INVALID_HANDLE);
}
else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
{
if (!address)
{
LT__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
}
}
return address;
}
struct lt_user_dlloader lt__sys_shl = {
0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
};

View File

@ -1,4 +1,4 @@
/* lt__alloc.c -- internal memory management interface
/* lt__alloc.h -- internal memory management interface
Copyright (C) 2004 Free Software Foundation, Inc.
Originally by Gary V. Vaughan <gary@gnu.org>

View File

@ -110,6 +110,21 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# endif
#endif
/* DLL building support on win32 hosts; mostly to workaround their
ridiculous implementation of data symbol exporting. */
#ifndef LT_SCOPE
# ifdef __WINDOWS__
# ifdef DLL_EXPORT /* defined by libtool (if required) */
# define LT_SCOPE __declspec(dllexport)
# endif
# ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */
# define LT_SCOPE extern __declspec(dllimport)
# endif
# endif
# ifndef LT_SCOPE /* static linking or !__WINDOWS__ */
# define LT_SCOPE extern
# endif
#endif
#ifdef __WINDOWS__
/* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory

File diff suppressed because it is too large Load Diff

View File

@ -125,42 +125,6 @@ LT_SCOPE void * lt_dlcaller_get_data (lt_dlcaller_id key,
lt_dlhandle handle);
/* --- USER MODULE LOADER API --- */
typedef struct lt_dlloader lt_dlloader;
typedef void * lt_user_data;
typedef void * lt_module;
/* Function pointer types for creating user defined module loaders. */
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);
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;
lt_user_data dlloader_data;
};
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_remove (const char *loader_name);
/* --- BINARY COMPATIBILITY WITH OLD LIBLTDL --- */

View File

@ -329,39 +329,56 @@ AC_LANG_PUSH([C])
AC_CHECK_FUNC([shl_load],
[AC_DEFINE([HAVE_SHL_LOAD], [1],
[Define if you have the shl_load function.])],
[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"],
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"],
LIBADD_DL="-ldl" libltdl_cv_lib_dl_dlopen="yes"
AC_LIBOBJ([loader-dlopen])],
[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_CHECK_LIB([svld], [dlopen],
[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],
[Define if you have the libdl library or equivalent.])
LIBADD_DL="-lsvld" libltdl_cv_func_dlopen="yes"],
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_CHECK_FUNC([_dyld_func_lookup],
[AC_DEFINE([HAVE_DYLD], [1],
[Define if you have the _dyld_func_lookup function.])])
])
])
])
])
])
])
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
case $host_os in
beos*)
AC_LIBOBJ([loader-load_add_on])
;;
cygwin* | mingw* | os2* | pw32*)
AC_LIBOBJ([loader-loadlibrary])
;;
esac
if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes
then

View File

@ -1,6 +1,6 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
##
## Copyright (C) 2003 Free Software Foundation
## Copyright (C) 2003, 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
@ -19,6 +19,7 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
ACLOCAL_AMFLAGS = -I ../../m4
AM_CPPFLAGS = -I$(top_srcdir)/../..
noinst_LTLIBRARIES = libfoo.la

View File

@ -1,6 +1,6 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
##
## Copyright (C) 2003 Free Software Foundation
## Copyright (C) 2003, 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
@ -19,6 +19,7 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
ACLOCAL_AMFLAGS = -I ../../m4
AM_CPPFLAGS = -I$(top_srcdir)/../..
# Build a libtool library, libhello.la for installation in libdir.
lib_LTLIBRARIES = libhello.la

View File

@ -1,6 +1,6 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
##
## Copyright (C) 2003 Free Software Foundation
## Copyright (C) 2003, 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
@ -19,6 +19,7 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
ACLOCAL_AMFLAGS = -I ../../m4
AM_CPPFLAGS = -I$(top_srcdir)/../..
SUBDIRS = l1 l2 l3 l4

View File

@ -1,6 +1,6 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
##
## Copyright (C) 2003 Free Software Foundation
## Copyright (C) 2003, 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
@ -19,6 +19,7 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
ACLOCAL_AMFLAGS = -I ../../m4
AM_CPPFLAGS = -I$(top_srcdir)/../..
noinst_LTLIBRARIES = libfoo.la libmix.la

View File

@ -1,6 +1,6 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
##
## Copyright (C) 2003 Free Software Foundation
## Copyright (C) 2003, 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
@ -19,8 +19,7 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
ACLOCAL_AMFLAGS = -I ../../m4
INCLUDES = $(INCLTDL)
AM_CPPFLAGS = -I$(top_srcdir)/../.. $(INCLTDL)
lib_LTLIBRARIES = libsub.la foo1.la libfoo2.la libmlib.la

View File

@ -1,6 +1,6 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
##
## Copyright (C) 2003 Free Software Foundation
## Copyright (C) 2003, 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
@ -19,8 +19,7 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
ACLOCAL_AMFLAGS = -I ../../m4
AM_CPPFLAGS = -I$(top_srcdir)/../../libltdl
AM_CPPFLAGS = -I$(top_srcdir)/../.. -I$(top_srcdir)/../../libltdl
bin_PROGRAMS = mdemo2 mdemo2_static

View File

@ -1,6 +1,6 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
##
## Copyright (C) 2003 Free Software Foundation
## Copyright (C) 2003, 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
@ -19,6 +19,7 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
ACLOCAL_AMFLAGS = -I ../../m4
AM_CPPFLAGS = -I$(top_srcdir)/../..
# Build a libtool library, libhello.la for installation in libdir.
lib_LTLIBRARIES = libhello.la

View File

@ -1,6 +1,6 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
##
## Copyright (C) 2003 Free Software Foundation
## Copyright (C) 2003, 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
@ -19,6 +19,7 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
ACLOCAL_AMFLAGS = -I ../../m4
AM_CPPFLAGS = -I$(top_srcdir)/../..
noinst_LTLIBRARIES = libconv.la
lib_LTLIBRARIES = libfoo.la libbaz.la