*** empty log message ***

This commit is contained in:
Thomas Tanner 1999-01-12 20:42:47 +00:00
parent 0ba577eb78
commit 89aa144652
6 changed files with 344 additions and 172 deletions

View File

@ -1,3 +1,17 @@
1999-01-12 Thomas Tanner <tanner@gmx.de>
* ltmain.in: before using LN_S remove the symlink
* libltdl/ltdl.c: support multiple symbol lists, moved library-
and file searching to separate functions, renamed "preload_libs"
to "dl_dependency_libs", set the LT_SYMBOL_OVERHEAD to the correct
value (7), fix to support lt_dlsym() for not-libtool modules again,
check for invalid handles, when using strdup() check whether
it fails
* libltdl/ltdl.h: declare the lt_dlsymlist type for lt_dlpreopen()
* mdemo/README: rewritten
* mdemo/configure.in: check only for math.h (string.h is no longer
necessary)
1999-01-12 Gary V. Vaughan <gvaughan@oranda.demon.co.uk>
* configure.in (ltdl-install): Fixed up the indentation so that

View File

@ -55,7 +55,8 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "ltdl.h"
static const char *unknown_error = "unknown error";
static const char *not_supported_error = "dlopen support not available";
static const char *dlopen_not_supported_error = "dlopen support not available";
static const char *dlpreopen_not_supported_error = "dlpreopen support not available";
static const char *file_not_found_error = "file not found";
static const char *no_symbols_error = "no symbols defined";
static const char *symbol_error = "symbol not found";
@ -83,6 +84,8 @@ typedef struct lt_dlhandle_t {
char *filename; /* file name */
char *name; /* module name */
int usage; /* usage */
int depcount; /* number of dependencies */
lt_dlhandle *deps; /* dependencies */
lt_ptr_t handle; /* system handle */
lt_ptr_t system; /* system specific data */
} lt_dlhandle_t;
@ -381,11 +384,16 @@ dld_open (handle, filename)
lt_dlhandle handle;
const char *filename;
{
if (dld_link(filename) != 0) {
last_error = unknown_error;
handle->handle = strdup(filename);
if (!handle->handle) {
last_error = no_memory_error;
return 1;
}
if (dld_link(filename) != 0) {
last_error = unknown_error;
free(handle->handle);
return 1;
}
handle->handle = strdup(filename);
return 0;
}
@ -491,23 +499,70 @@ wll = { LT_DLTYPE_TOP, wll_init, wll_exit,
/* emulate dynamic linking using dld_preloaded_symbols */
struct lt_dlsymlist
{
char *name;
lt_ptr_t address;
};
typedef struct lt_dlsymlists_t {
struct lt_dlsymlists_t *next;
lt_dlsymlist *syms;
} lt_dlsymlists_t;
static struct lt_dlsymlist *preloaded_symbols;
static lt_dlsymlists_t *preloaded_symbols;
static int
dldpre_init ()
{
preloaded_symbols = 0;
return 0;
}
static void
dldpre_free_symlists ()
{
lt_dlsymlists_t *lists = preloaded_symbols;
while (lists) {
lt_dlsymlists_t *tmp = lists;
lists = lists->next;
free(tmp);
}
preloaded_symbols = 0;
}
static int
dldpre_exit ()
{
dldpre_free_symlists();
return 0;
}
static int
dldpre_add_symlist (preloaded)
lt_dlsymlist *preloaded;
{
lt_dlsymlists_t *tmp;
lt_dlsymlists_t *lists = preloaded_symbols;
while (lists) {
if (lists->syms == preloaded)
return 0;
lists = lists->next;
}
tmp = (lt_dlsymlists_t*) malloc(sizeof(lt_dlsymlists_t));
if (!tmp) {
last_error = memory_error;
return 1;
}
tmp->syms = preloaded;
tmp->next = 0;
if (!preloaded_symbols)
preloaded_symbols = tmp;
else {
/* append to the end */
lists = preloaded_symbols;
while (lists->next)
lists = lists->next;
lists->next = tmp;
}
return 0;
}
@ -516,27 +571,31 @@ dldpre_open (handle, filename)
lt_dlhandle handle;
const char *filename;
{
struct lt_dlsymlist *s = preloaded_symbols;
lt_dlsymlists_t *lists = preloaded_symbols;
if (!filename) {
last_error = file_not_found_error;
return 1;
}
if (!s) {
if (!lists) {
last_error = no_symbols_error;
return 1;
}
while (s->name) {
if (!s->address && !strcmp(s->name, filename))
break;
s++;
while (lists) {
lt_dlsymlist *syms = lists->syms;
while (syms->name) {
if (!syms->address &&
strcmp(syms->name, filename) == 0) {
handle->handle = syms;
return 0;
}
syms++;
}
lists = lists->next;
}
if (!s->name) {
last_error = file_not_found_error;
return 1;
}
handle->handle = s;
return 0;
last_error = file_not_found_error;
return 1;
}
static int
@ -551,17 +610,17 @@ dldpre_sym (handle, symbol)
lt_dlhandle handle;
const char *symbol;
{
struct lt_dlsymlist *s = (struct lt_dlsymlist*)(handle->handle);
lt_dlsymlist *syms = (lt_dlsymlist*)(handle->handle);
#if NEED_USCORE
/* lt_dlsym will have prepended a `_', but we don't need it */
symbol++;
#endif
s++;
while (s->address) {
if (strcmp(s->name, symbol) == 0)
return s->address;
s++;
syms++;
while (syms->address) {
if (syms->address && strcmp(syms->name, symbol) == 0)
return syms->address;
syms++;
}
last_error = symbol_error;
return 0;
@ -605,7 +664,7 @@ lt_dlinit ()
}
}
if (typecount == 0) {
last_error = not_supported_error;
last_error = dlopen_not_supported_error;
return 1;
}
last_error = 0;
@ -613,16 +672,20 @@ lt_dlinit ()
return 0;
}
struct lt_dlsymlist *
int
lt_dlpreopen (preloaded)
struct lt_dlsymlist *preloaded;
lt_dlsymlist *preloaded;
{
#if HAVE_DLPREOPEN
struct lt_dlsymlist *prev = preloaded_symbols;
preloaded_symbols = preloaded;
return prev;
if (preloaded)
return dldpre_add_symlist(preloaded);
else {
dldpre_free_symlists();
return 0;
}
#else
return 0;
last_error = dlpreopen_not_supported_error;
return 1;
#endif
}
@ -692,19 +755,25 @@ tryall_dlopen (handle, filename)
return 0;
}
(*handle)->filename = strdup(filename);
if (!(*handle)->filename)
return 1;
while (type) {
if (type->lib_open(*handle, filename) == 0)
break;
type = type->next;
}
if (!type)
if (!type) {
free((*handle)->filename);
return 1;
}
(*handle)->type = type;
(*handle)->filename = strdup(filename);
last_error = saved_error;
return 0;
}
#undef FILENAME_MAX
/* max. filename length */
#ifndef FILENAME_MAX
#define FILENAME_MAX 1024
#endif
@ -746,24 +815,153 @@ find_module (handle, dir, libdir, dlname, old_name)
}
if (*old_name && tryall_dlopen(handle, old_name) == 0)
return 0;
last_error = file_not_found_error;
return 1;
}
static int
find_library (handle, filename, have_dir, basename, search_path)
lt_dlhandle *handle;
const char *filename;
int have_dir;
const char *basename;
const char *search_path;
{
char dir[FILENAME_MAX], fullname[FILENAME_MAX];
const char *p, *next;
if (tryall_dlopen(handle, filename) == 0)
return 0;
if (have_dir && !search_path) {
last_error = file_not_found_error;
return 1;
}
/* try other directories */
/* search_path is a colon-separated
list of search directories */
p = search_path;
while (p) {
next = strchr(p, ':');
if (next) {
if (next - p + 1 >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 1;
}
strncpy(dir, p, next - p);
dir[next - p] = '\0';
p = next+1;
} else {
if (strlen(p)+1 >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 1;
}
strcpy(dir, p);
p = 0;
}
if (!*dir)
continue;
strcat(dir, "/");
if (strlen(dir)+strlen(basename) < FILENAME_MAX) {
strcpy(fullname, dir);
strcat(fullname, basename);
if (tryall_dlopen(handle, fullname) == 0)
return 0;
}
}
last_error = file_not_found_error;
return 1;
}
#undef READTEXT_MODE
/* fopen() mode flags for reading a text file */
#ifdef _WIN32
#define READTEXT_MODE "rt"
#else
#define READTEXT_MODE "r"
#endif
static FILE *
find_file (filename, basename, have_dir, search_path)
const char *filename;
int have_dir;
const char *basename;
const char *search_path;
{
char dir[FILENAME_MAX], fullname[FILENAME_MAX];
const char *p, *next;
FILE *file;
file = fopen(filename, READTEXT_MODE);
if (file)
return file;
if (have_dir && !search_path) {
last_error = file_not_found_error;
return 0;
}
/* try other directories */
/* search_path is a colon-separated
list of search directories */
p = search_path;
while (p) {
next = strchr(p, ':');
if (next) {
if (next - p + 1 >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 0;
}
strncpy(dir, p, next - p);
dir[next - p] = '\0';
p = next+1;
} else {
if (strlen(p)+1 >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 0;
}
strcpy(dir, p);
p = 0;
}
if (!*dir)
continue;
strcat(dir, "/");
if (strlen(dir)+strlen(basename) < FILENAME_MAX) {
strcpy(fullname, dir);
strcat(fullname, basename);
file = fopen(fullname, READTEXT_MODE);
if (file)
return file;
}
}
last_error = file_not_found_error;
return 0;
}
static int
load_deplibs(handle, deplibs)
lt_dlhandle *handle;
const char *deplibs;
{
/* FIXME: load deplibs */
return 0;
}
static int
unload_deplibs(handle)
lt_dlhandle *handle;
{
/* FIXME: unload deplibs */
return 0;
}
lt_dlhandle
lt_dlopen (filename)
const char *filename;
{
lt_dlhandle handle;
FILE *file;
char dir[FILENAME_MAX], tmp[FILENAME_MAX];
char dir[FILENAME_MAX];
const char *basename, *ext, *search_path;
const char *saved_error = last_error;
@ -783,49 +981,33 @@ lt_dlopen (filename)
ext = strrchr(basename, '.');
if (ext && strcmp(ext, ".la") == 0) {
char dlname[FILENAME_MAX], old_name[FILENAME_MAX];
char libdir[FILENAME_MAX], preload[FILENAME_MAX];
char libdir[FILENAME_MAX], deplibs[FILENAME_MAX];
char tmp[FILENAME_MAX];
char *name;
FILE *file;
int i;
dlname[0] = old_name[0] = libdir[0] = preload[0] = '\0';
dlname[0] = old_name[0] = libdir[0] = deplibs[0] = '\0';
file = fopen(filename, READTEXT_MODE);
if (!file && !*dir && search_path) {
/* try other directories */
const char *p, *next;
/* search_path is a colon-separated
list of search directories */
p = search_path;
while (!file && p) {
next = strchr(p, ':');
if (next) {
if (next - p + 1 >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 0;
}
strncpy(dir, p, next - p);
dir[next - p] = '\0';
p = next+1;
} else {
if (strlen(p)+1 >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 0;
}
strcpy(dir, p);
p = 0;
}
if (!*dir)
continue;
strcat(dir, "/");
if (strlen(dir)+strlen(basename) < FILENAME_MAX) {
strcpy(tmp, dir);
strcat(tmp, basename);
file = fopen(tmp, READTEXT_MODE);
}
}
/* extract the module name from the file name */
if (strlen(basename) >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 0;
}
strcpy(tmp, basename);
tmp[ext - basename] = '\0';
/* canonicalize the module name */
for (i = 0; i < ext - basename; i++)
if (!isalnum(tmp[i]))
tmp[i] = '_';
name = strdup(tmp);
if (!name) {
last_error = memory_error;
return 0;
}
file = find_file(filename, *dir, basename, search_path);
if (!file) {
last_error = file_not_found_error;
free(name);
return 0;
}
while (!feof(file)) {
@ -840,34 +1022,29 @@ lt_dlopen (filename)
if (strncmp(tmp, "libdir=", 7) == 0)
trim(libdir, &tmp[7]);
else
if (strncmp(tmp, "preload_libs=", 13) == 0)
trim(preload, &tmp[13]);
if (strncmp(tmp, "dl_dependency_libs=", 20) == 0)
trim(deplibs, &tmp[20]);
}
fclose(file);
/* FIXME: preload required libraries */
handle = (lt_dlhandle) malloc(sizeof(lt_dlhandle_t));
if (!handle) {
last_error = memory_error;
free(name);
return 0;
}
if (load_deplibs(handle, deplibs)) {
free(handle);
free(name);
return 0;
}
if (find_module(&handle, dir, libdir, dlname, old_name)) {
unload_deplibs(handle);
free(handle);
last_error = file_not_found_error;
free(name);
return 0;
}
/* extract the module name from the file name */
if (strlen(basename) >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 0;
}
strcpy(tmp, basename);
tmp[ext - basename] = '\0';
/* canonicalize the module name */
for (i = 0; i < ext - basename; i++)
if (!isalnum(tmp[i]))
tmp[i] = '_';
handle->name = strdup(tmp);
handle->name = name;
} else {
/* not a libtool module */
handle = (lt_dlhandle) malloc(sizeof(lt_dlhandle_t));
@ -875,49 +1052,10 @@ lt_dlopen (filename)
last_error = memory_error;
return 0;
}
if (tryall_dlopen(&handle, filename)) {
int error = 1;
if (!*dir && search_path) {
/* try other directories */
const char *p, *next;
/* search_path is a colon-separated
list of search directories */
p = search_path;
while (error && p) {
next = strchr(p, ':');
if (next) {
if (next - p + 1 >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 0;
}
strncpy(dir, p, next - p);
dir[next - p] = '\0';
p = next+1;
} else {
if (strlen(p)+1 >= FILENAME_MAX) {
last_error = buffer_overflow_error;
return 0;
}
strcpy(dir, p);
p = 0;
}
if (!*dir)
continue;
strcat(dir, "/");
if (strlen(dir)+strlen(basename) < FILENAME_MAX) {
strcpy(tmp, dir);
strcat(tmp, basename);
error = tryall_dlopen(&handle, tmp);
}
}
}
if (error) {
free(handle);
last_error = file_not_found_error;
return 0;
}
if (find_library(&handle, filename, *dir,
basename, search_path)) {
free(handle);
return 0;
}
handle->name = 0;
}
@ -953,6 +1091,7 @@ lt_dlclose (handle)
else
handles = handle->next;
error = handle->type->lib_close(handle);
error += unload_deplibs(handle);
free(handle->filename);
if (handle->name)
free(handle->name);
@ -967,42 +1106,55 @@ lt_dlclose (handle)
#define LT_SYMBOL_LENGTH 256
#undef LT_SYMBOL_OVERHEAD
/* This accounts for the _LTX_ separator and the initial underscore */
#define LT_SYMBOL_OVERHEAD 10
/* This accounts for the initial underscore, the _LTX_ separator */
/* and the string terminator */
#define LT_SYMBOL_OVERHEAD 7
lt_ptr_t
lt_dlsym (handle, symbol)
lt_dlhandle handle;
const char *symbol;
{
int lensym = strlen(symbol), lenhand = strlen(handle->name);
char lsym[LT_SYMBOL_LENGTH];
char *sym = ((lensym + lenhand + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
? lsym
: malloc(lensym + lenhand + LT_SYMBOL_OVERHEAD));
int lensym, lenhand;
char lsym[LT_SYMBOL_LENGTH];
char *sym;
lt_ptr_t address;
if (sym == 0) {
if (!handle) {
last_error = invalid_handle_error;
return 0;
}
lensym = strlen(symbol);
if (handle->name)
lenhand = strlen(handle->name);
else
lenhand = 0;
if (lensym + lenhand + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
sym = lsym;
else
sym = malloc(lensym + lenhand + LT_SYMBOL_OVERHEAD);
if (!sym) {
last_error = buffer_overflow_error;
return 0;
}
if (handle->name) {
/* this is a libtool module */
#ifdef NEED_USCORE
/* this is a libtool module */
/* prefix symbol with leading underscore */
strcpy(sym, "_");
strcat(sym, handle->name);
/* prefix symbol with leading underscore */
strcpy(sym, "_");
strcat(sym, handle->name);
#else
/* this is a libtool module */
strcpy(sym, handle->name);
strcpy(sym, handle->name);
#endif
strcat(sym, "_LTX_");
strcat(sym, symbol);
/* try "modulename_LTX_symbol" */
address = handle->type->find_sym(handle, sym);
if (address) {
if (sym != lsym)
free(sym);
return address;
strcat(sym, "_LTX_");
strcat(sym, symbol);
/* try "modulename_LTX_symbol" */
address = handle->type->find_sym(handle, sym);
if (address) {
if (sym != lsym)
free(sym);
return address;
}
}
/* otherwise try "symbol" */
#ifdef NEED_USCORE

View File

@ -68,16 +68,21 @@ typedef struct lt_dlhandle_t *lt_dlhandle;
typedef lt_ptr_t lt_dlhandle;
#endif
typedef struct {
char *name;
lt_ptr_t address;
} lt_dlsymlist;
__BEGIN_DECLS
_LTDLL_EXTERN int lt_dlinit __P((void));
_LTDLL_EXTERN struct lt_dlsymlist *lt_dlpreopen __P((struct lt_dlsymlist *preloaded));
_LTDLL_EXTERN int lt_dlpreopen __P((lt_dlsymlist *preloaded));
_LTDLL_EXTERN int lt_dlexit __P((void));
_LTDLL_EXTERN lt_dlhandle lt_dlopen __P((const char *filename));
_LTDLL_EXTERN int lt_dlclose __P((lt_dlhandle handle));
_LTDLL_EXTERN lt_ptr_t lt_dlsym __P((lt_dlhandle handle, const char *name));
_LTDLL_EXTERN const char *lt_dlerror __P((void));
extern struct lt_dlsymlist dld_preloaded_symbols[];
extern lt_dlsymlist dld_preloaded_symbols[];
#define lt_dlpreopen_default() (lt_dlpreopen(dld_preloaded_symbols))
__END_DECLS

View File

@ -1703,8 +1703,8 @@ EOF
# Create links to the real library.
for linkname in $linknames; do
if test "$realname" != "$linkname"; then
$show "(cd $output_objdir && $LN_S $realname $linkname)"
$run eval '(cd $output_objdir && $LN_S $realname $linkname)' || exit $?
$show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
$run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
fi
done
@ -2355,8 +2355,8 @@ libdir='$install_libdir'\
# Do a symbolic link so that the libtool archive can be found in
# LD_LIBRARY_PATH before the program is installed.
$show "(cd $output_objdir && $LN_S ../$outputname $outputname)"
$run eval "(cd $output_objdir && $LN_S ../$outputname $outputname)" || exit $?
$show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
$run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
;;
esac
exit 0

View File

@ -1,9 +1,10 @@
This is mdemo, an example package that uses GNU libtool with an
Automake-generated environment to build two simple libraries and programs.
Automake-generated environment to build two simple modules and
a program.
It demonstrates how to build both dynamic and static libraries
that can be dlopened. You'll need a wrapper (libltdl)
for your dlopen functions. We prefix all exported symbols with "libname_LTX_".
When dlopening these static libraries, we cut the prefix off to
get the real name.
that can be dlopened. mdemo uses libtool's portable dlopen
wrapper called "libltdl".
All exported symbols are prefixed with "libname_LTX_" to avoid
symbols conflicts, especially when linking statically.
libltdl will automatically cut the prefix off to get the real name.

View File

@ -6,7 +6,7 @@ AC_PROG_CC
AC_EXEEXT
AM_PROG_LIBTOOL
AC_CHECK_HEADERS(string.h math.h)
AC_CHECK_HEADERS(math.h)
AC_CHECK_LIB(m, cos, LIBADD_M="-lm", LIBADD_M=)
AC_SUBST(LIBADD_M)