2000-01-27 Gary V. Vaughan <gary@oranda.demon.co.uk>
+ * NEWS: Updated.
+ * doc/libtool.texi (Libltdl interface): Document new entry
+ points.
+ * libltdl/ltdl.c (lt_dltype_t): Use new type definitions for
+ existing fields.
+ (lt_dladdtype): New function to add a new ltdl dynamic loader
+ type to the end of the list of valid types..
+ (lt_dlgettypes): New function to return the complete list of ltdl
+ dynamic loader types.
+ (lt_dlsettypes): New function to replace the list of ltdl dynamic
+ loader types entirely -- e.g. to prepend a new type to the
+ existing list.
+ (sys_dl_open, sys_dl_close, sys_dl_sym): Work with lt_syshandle..
+ (sys_shl_open, sys_shl_close, sys_shl_sym): ditto.
+ (sys_dld_open, sys_dld_close, sys_dld_sym): ditto.
+ (sys_wll_open, sys_wll_close, sys_wll_sym): ditto.
+ (sys_bedl_open, sys_bedl_close, sys_bedl_sym): ditto.
+ (presym_open, presym_close, presym_sym): ditto.
+ (tryall_dlopen): Call lt_lib_open_t functions lt_syshandle
+ compatibly.
+ (lt_dlclose): Call lt_lib_close_t functions lt_syshandle
+ compatibly.
+ (lt_dlsym): Call lt_find_sym_t functions lt_syshandle compatibly.
+ (lt_dltype_t): moved type declaration from here...
+ * libltdl/ltdl.h (lt_dltype_t): ...to here.
+ (lt_syshandle): new type for low level system handles passed by
+ loader functions
+ (lt_mod_init_t): New type for functions implementing the
+ initialisation for an ltdl dynamic loader.
+ (lt_mod_exit_t): Type of exit functions for the same.
+ (lt_lib_open_t): Type of loader functions for the same.
+ (lt_lib_close_t): Type of unloader functions for the same.
+ (lt_find_sym_t): Type of symbol resolver functions for the same.
+
* libltdl/ltdl.c (sys_dl_init, sys_dl_exit, sys_dl_open,
sys_dl_close, sys_dl_sym): Preprocess these away on cygwin to
avoid spurious error messages.
@deftp {Type} lt_dlhandle
@code{lt_dlhandle} is a module "handle".
-Every dlopened module has a handle associated with it.
+Every lt_dlopened module has a handle associated with it.
+@end deftp
+
+@deftp {Type} lt_syshandle
+@code{lt_syshandle} is a generic system module "handle".
+The dynamic module loader type extensions communicate using these low level
+handles.
@end deftp
@deftypefn {Type} {struct} lt_dlinfo @{ @w{char *@var{filename};} @w{char *@var{name};} @w{int @var{ref_count};} @}
the same module is currently loaded.
@end deftypefn
+@deftypefn {Type} {struct} lt_dltype_t @{ @w{struct lt_dltype_t *@var{next};} @w{const char *@var{sym_prefix};} @w{lt_mod_init_t *@var{mod_init};} @w{lt_mod_exit_t *@var{mod_exit};} @w{lt_lib_open_t *@var{lib_open};} @w{lt_lib_close_t *@var{lib_close};} @w{lt_find_sym_t *@var{find_sym};} @}
+@code{lt_dltype_t} is used to store the functions used to access a dynamic
+module loader type. If you want to define a new way to open dynamic modules,
+and have the @code{lt_dlopen} @sc{api} use it, you need to instantiate one of
+these structures and pass it to @code{lt_dladdtype()}.
+@end deftypefn
+
+@deftypefn {Type} int lt_mod_init_t (void)
+The type of an initialisation function for an @code{lt_dltype_t} module
+loader. Implementation of such a function should perform any initialisation
+required by the loader, and return non-zero if an error is encountered. When
+used as part of an @code{lt_dltype_t} registration, if non-NULL, the function
+will be called by @code{lt_dlinit}, or if it is registered after the call to
+@code{lt_dlinit}, the function will be called immediately upon registration.
+@end deftypefn
+
+@deftypefn {Type} int lt_mod_exit_t (void)
+The type of the finalisation function for an @code{lt_dltype_t} module
+loader. Implementation of such a function should free any resources
+associated with the loader. If non-NULL, the function will be called by
+@code{lt_dlexit}.
+@end deftypefn
+
+@deftypefn {Type} lt_syshandle lt_lib_open_t (@w{const char *@var{filename}})
+The type of the loader function for an @code{lt_dltype_t} module loader.
+Implementation of such a function should attempt to load the named module, and
+return an @code{lt_syshandle} suitable for passing in to the associated
+@code{lt_lib_close_t} and @code{lt_sym_find_t} function pointers. If the
+function fails it should return NULL.
+@end deftypefn
+
+@deftypefn {Type} int lt_lib_close_t (@w{lt_syshandle @var{handle}})
+The type of the unloader function for an @code{lt_dltype_t} module loader.
+Implementatation of such a function should attempt to release any resources
+tied up by the @var{handle} module, and then unload it from memory. If the
+function fails for some reason, return non-zero.
+@end deftypefn
+
+@deftypefn {Type} lt_ptr_t lt_find_sym_t (@w{lt_syshandle @var{handle},} @w{const char *@var{symbol}})
+The type of the symbol lookup function for an @code{lt_dltype_t} module
+loader. Implementation of such a function should return the address of the
+named @var{symbol} in the module @var{handle}, or NULL if there is no such
+symbol.
+@end deftypefn
+
@deftp {Type} lt_dlsymlist
@code{lt_dlsymlist} is a symbol list for dlpreopened modules.
This structure is described in @pxref{Dlpreopening}.
Return 0 on success, otherwise the number of errors.
@end deftypefun
+@deftypefun int lt_dladdtype (@w{lt_dltype_t *@var{dltype}})
+Append a new module loader type to the list of all types.
+@var{dltype} should have its @code{next} field set to NULL. If the
+@code{sym_prefix} field is set to NULL, then it will be replaced with a single
+underscore if that is what the platform requires normally (use the empty
+string if you want an unconditional empty prefix). The new type will be added
+to the end of the module loader types list, and hence will be used only if all
+of the preceding methods fail.
+
+If this function is used to add a type after calling @code{lt_dlinit}, then
+the @var{mod_init} function (if any) will be called immediately, otherwise
+it will be called at the same time as the other type initialisation function
+by @code{lt_dlinit}.
+@end deftypefun
+
+@deftypefun lt_dltype_t *lt_dlgettypes (void)
+Return the list of module loader types.
+@end deftypefun
+
+@deftypefun int lt_dlsettypes (@w{lt_dltype_t *@var{dltypes}})
+Change the list of module loader types to be @var{dltypes}.
+This completely replaces the default module loader types determined by libtool
+with the new linked list of types -- which should probably be a superset of
+the original list.
+@end deftypefun
+
@deftypefun int lt_dlexit (void)
Shut down libltdl and close all modules.
This function will only then shut down libltdl when it was called as
static const char unknown_error[] = "unknown error";
static const char dlopen_not_supported_error[] = "dlopen support not available";
+static const char invalid_type_error[] = "invalid dltype";
+static const char init_type_error[] = "dltype initialization failed";
static const char file_not_found_error[] = "file not found";
static const char deplib_not_found_error[] = "dependency library not found";
static const char no_symbols_error[] = "no symbols defined";
LTDL_GLOBAL_DATA lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
LTDL_GLOBAL_DATA void (*lt_dlfree) LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
-typedef struct lt_dltype_t {
- struct lt_dltype_t *next;
- const char *sym_prefix; /* prefix for symbols */
- int (*mod_init) LTDL_PARAMS((void));
- int (*mod_exit) LTDL_PARAMS((void));
- int (*lib_open) LTDL_PARAMS((lt_dlhandle handle, const char *filename));
- int (*lib_close) LTDL_PARAMS((lt_dlhandle handle));
- lt_ptr_t (*find_sym) LTDL_PARAMS((lt_dlhandle handle, const char *symbol));
-} lt_dltype_t;
-
#define LTDL_TYPE_TOP 0
typedef struct lt_dlhandle_t {
lt_dlinfo info;
int depcount; /* number of dependencies */
lt_dlhandle *deplibs; /* dependencies */
- lt_ptr_t handle; /* system handle */
+ lt_syshandle handle; /* system handle */
lt_ptr_t system; /* system specific data */
lt_ptr_t app_private; /* application private data */
} lt_dlhandle_t;
return 0;
}
-static int
-sys_dl_open (handle, filename)
- lt_dlhandle handle;
+static lt_syshandle
+sys_dl_open (filename)
const char *filename;
{
- handle->handle = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
- if (!handle->handle) {
+ lt_ptr_t handle = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
+ if (!handle) {
#if HAVE_DLERROR
last_error = dlerror();
#else
last_error = cannot_open_error;
#endif
- return 1;
}
- return 0;
+ return handle;
}
static int
sys_dl_close (handle)
- lt_dlhandle handle;
+ lt_syshandle handle;
{
- if (dlclose(handle->handle) != 0) {
+ if (dlclose(handle) != 0) {
#if HAVE_DLERROR
last_error = dlerror();
#else
static lt_ptr_t
sys_dl_sym (handle, symbol)
- lt_dlhandle handle;
+ lt_syshandle handle;
const char *symbol;
{
- lt_ptr_t address = dlsym(handle->handle, symbol);
+ lt_ptr_t address = dlsym(handle, symbol);
if (!address)
#if HAVE_DLERROR
return 0;
}
-static int
-sys_shl_open (handle, filename)
- lt_dlhandle handle;
+static lt_syshandle
+sys_shl_open (filename)
const char *filename;
{
- handle->handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
- if (!handle->handle) {
+ lt_syshandle handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
+ if (!handle) {
last_error = cannot_open_error;
- return 1;
}
- return 0;
+ return handle;
}
static int
sys_shl_close (handle)
- lt_dlhandle handle;
+ lt_syshandle handle;
{
- if (shl_unload((shl_t) (handle->handle)) != 0) {
+ if (shl_unload((shl_t) (handle)) != 0) {
last_error = cannot_close_error;
return 1;
}
static lt_ptr_t
sys_shl_sym (handle, symbol)
- lt_dlhandle handle;
+ lt_syshandle handle;
const char *symbol;
{
lt_ptr_t address;
- if (handle->handle && shl_findsym((shl_t*) &(handle->handle),
+ if (handle && shl_findsym((shl_t*) &handle,
symbol, TYPE_UNDEFINED, &address) == 0)
if (address)
return address;
return 0;
}
-static int
-sys_dld_open (handle, filename)
- lt_dlhandle handle;
+static lt_syshandle
+sys_dld_open (filename)
const char *filename;
{
- handle->handle = strdup(filename);
- if (!handle->handle) {
+ lt_syshandle handle = strdup(filename);
+ if (!handle) {
last_error = memory_error;
- return 1;
+ return 0;
}
if (dld_link(filename) != 0) {
last_error = cannot_open_error;
- lt_dlfree(handle->handle);
- return 1;
- }
+ lt_dlfree(handle);
return 0;
+ }
+ return handle;
}
static int
sys_dld_close (handle)
- lt_dlhandle handle;
+ lt_syshandle handle;
{
- if (dld_unlink_by_file((char*)(handle->handle), 1) != 0) {
+ if (dld_unlink_by_file((char*)(handle), 1) != 0) {
last_error = cannot_close_error;
return 1;
}
- lt_dlfree(handle->filename);
+ lt_dlfree(handle);
return 0;
}
static lt_ptr_t
sys_dld_sym (handle, symbol)
- lt_dlhandle handle;
+ lt_syshandle handle;
const char *symbol;
{
lt_ptr_t address = dld_get_func(symbol);
/* Forward declaration; required to implement handle search below. */
static lt_dlhandle handles;
-static int
-sys_wll_open (handle, filename)
- lt_dlhandle handle;
+static lt_syshandle
+sys_wll_open (filename)
const char *filename;
{
lt_dlhandle cur;
+ lt_syshandle handle;
char *searchname = NULL;
char *ext = strrchr(filename, '.');
/* Append a `.' to stop Windows from adding an
implicit `.dll' extension. */
searchname = (char*)lt_dlmalloc(2+ strlen(filename));
+ if (!searchname) {
+ last_error = memory_error;
+ return 0;
+ }
strcpy(searchname, filename);
strcat(searchname, ".");
}
- handle->handle = LoadLibrary(searchname);
+ handle = LoadLibrary(searchname);
lt_dlfree(searchname);
/* libltdl expects this function to fail if it is unable
cur = 0;
break;
}
- if (cur->handle == handle->handle)
+ if (cur->handle == handle)
break;
cur = cur->next;
}
- if (cur || !handle->handle) {
+ if (cur || !handle) {
last_error = cannot_open_error;
- return 1;
+ return 0;
}
- return 0;
+ return handle;
}
static int
sys_wll_close (handle)
- lt_dlhandle handle;
+ lt_syshandle handle;
{
- if (FreeLibrary(handle->handle) == 0) {
+ if (FreeLibrary(handle) == 0) {
last_error = cannot_close_error;
return 1;
}
static lt_ptr_t
sys_wll_sym (handle, symbol)
- lt_dlhandle handle;
+ lt_syshandle handle;
const char *symbol;
{
- lt_ptr_t address = GetProcAddress(handle->handle, symbol);
+ lt_ptr_t address = GetProcAddress(handle, symbol);
if (!address)
last_error = symbol_error;
return 0;
}
-static int
-sys_bedl_open (handle, filename)
- lt_dlhandle handle;
+static lt_syshandle
+sys_bedl_open (filename)
const char *filename;
{
image_id image = 0;
}
if (image <= 0) {
last_error = cannot_open_error;
- return 1;
- }
- handle->handle = (void*) image;
return 0;
+ }
+
+ return (lt_syshandle) image;
}
static int
sys_bedl_close (handle)
- lt_dlhandle handle;
+ lt_syshandle handle;
{
- if (unload_add_on((image_id)handle->handle) != B_OK) {
+ if (unload_add_on((image_id)handle) != B_OK) {
last_error = cannot_close_error;
return 1;
}
static lt_ptr_t
sys_bedl_sym (handle, symbol)
- lt_dlhandle handle;
+ lt_syshandle handle;
const char *symbol;
{
lt_ptr_t address = 0;
- image_id image = (image_id)handle->handle;
+ image_id image = (image_id)handle;
if (get_image_symbol(image, symbol, B_SYMBOL_TYPE_ANY,
&address) != B_OK) {
return 0;
}
-static int
-presym_open (handle, filename)
- lt_dlhandle handle;
+static lt_syshandle
+presym_open (filename)
const char *filename;
{
lt_dlsymlists_t *lists = preloaded_symbols;
if (!lists) {
last_error = no_symbols_error;
- return 1;
+ return 0;
}
if (!filename)
filename = "@PROGRAM@";
while (syms->name) {
if (!syms->address &&
strcmp(syms->name, filename) == 0) {
- handle->handle = (lt_ptr_t) syms;
- return 0;
+ return (lt_syshandle) syms;
}
syms++;
}
lists = lists->next;
}
last_error = file_not_found_error;
- return 1;
+ return 0;
}
static int
presym_close (handle)
- lt_dlhandle handle;
+ lt_syshandle handle;
{
/* Just to silence gcc -Wall */
handle = 0;
static lt_ptr_t
presym_sym (handle, symbol)
- lt_dlhandle handle;
+ lt_syshandle handle;
const char *symbol;
{
- lt_dlsymlist *syms = (lt_dlsymlist*)(handle->handle);
+ lt_dlsymlist *syms = (lt_dlsymlist*)(handle);
syms++;
while (syms->address) {
return 0;
}
+int
+lt_dladdtype (dltype)
+ lt_dltype_t *dltype;
+{
+ lt_dltype_t *type = types;
+
+ if (dltype == 0) { /* diagnose null parameters */
+ last_error = invalid_type_error;
+ return 1;
+ }
+ if (dltype->next != 0) { /* diagnose invalid contents */
+ last_error = invalid_type_error;
+ return 1;
+ }
+
+#ifdef NEED_USCORE
+ if (dltype->sym_prefix == 0)
+ dltype->sym_prefix = "_";
+#else
+ if (dltype->sym_prefix && *dltype->sym_prefix == 0)
+ dltype->sym_prefix = 0;
+#endif
+
+ if (type == 0) {
+ type = dltype;
+ } else {
+ /* This function always appends to the existing list. */
+ while (type->next)
+ type = type->next;
+ type->next = dltype;
+ }
+
+ /* If lt_dlinit() has already been called, then initialize the
+ new type here. */
+ if (initialized && dltype->mod_init)
+ if ((*dltype->mod_init)()) {
+ last_error = init_type_error;
+ return 1;
+ }
+
+ return 0;
+}
+
+lt_dltype_t *
+lt_dlgettypes LTDL_PARAMS((void))
+{
+ return types;
+}
+
+int
+lt_dlsettypes (dltypes)
+ lt_dltype_t *dltypes;
+{
+ if (dltypes == 0) { /* diagnose null parameters */
+ last_error = invalid_type_error;
+ return 1;
+ }
+ types = dltypes;
+ return 0;
+}
+
int
lt_dlpreload (preloaded)
const lt_dlsymlist *preloaded;
} else
cur->info.filename = 0;
while (type) {
- if (type->lib_open(cur, filename) == 0)
+ cur->handle = type->lib_open(filename);
+ if (cur->handle != 0)
break;
type = type->next;
}
last->next = handle->next;
else
handles = handle->next;
- error = handle->type->lib_close(handle);
+ error = handle->type->lib_close(handle->handle);
error += unload_deplibs(handle);
if (handle->info.filename)
lt_dlfree(handle->info.filename);
strcat(sym, "_LTX_");
strcat(sym, symbol);
/* try "modulename_LTX_symbol" */
- address = handle->type->find_sym(handle, sym);
+ address = handle->type->find_sym(handle->handle, sym);
if (address) {
if (sym != lsym)
lt_dlfree(sym);
strcat(sym, symbol);
} else
strcpy(sym, symbol);
- address = handle->type->find_sym(handle, sym);
+ address = handle->type->find_sym(handle->handle, sym);
if (sym != lsym)
lt_dlfree(sym);
return address;
}
return 0;
}
-