From: Gary V. Vaughan Date: Thu, 27 Jan 2000 15:14:34 +0000 (+0000) Subject: * NEWS: Updated. X-Git-Tag: release-1-3d~215 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9e2159f4586feccd13d1ebfd58c929ae70c82adb;p=thirdparty%2Flibtool.git * 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. --- diff --git a/ChangeLog b/ChangeLog index 6b2fb0861..28ec76b4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,39 @@ 2000-01-27 Gary V. Vaughan + * 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. diff --git a/NEWS b/NEWS index 5a2f0be55..ef00dfdff 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ New in 1.3d: 2000-??-??; CVS version 1.3c, Libtool team: * Libtool now allows you to link shared libraries against static code. * New functions lt_dlgetdata, lt_dlsetdata, lt_dlgetinfo, lt_dlforeach in libltdl can be used to store application specific data in handles. +* New functions lt_dladdtype, lt_dlgettypes, lt_dlsettypes in libltdl + can be used for adding new types of module loading. * "-Xcompiler" and "-Wc," does now work in compile mode, too. * Start of support code for cross-compiling to win32. * libltdl can now be built as a dll with win32. diff --git a/doc/libtool.texi b/doc/libtool.texi index e1303d780..74951032b 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -2820,7 +2820,13 @@ The following types are defined in @file{ltdl.h}: @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};} @} @@ -2833,6 +2839,51 @@ The @var{ref_count} attribute is a reference counter that describes how often 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}. @@ -2849,6 +2900,32 @@ and may be called several times. 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 diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index f8186f587..b4c174a22 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -97,6 +97,8 @@ static const char sys_search_path[] = LTDL_SYSSEARCHPATH; 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"; @@ -113,16 +115,6 @@ static const char *last_error = 0; 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 { @@ -131,7 +123,7 @@ 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; @@ -266,28 +258,26 @@ sys_dl_exit LTDL_PARAMS((void)) 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 @@ -300,10 +290,10 @@ sys_dl_close (handle) 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 @@ -384,24 +374,22 @@ sys_shl_exit LTDL_PARAMS((void)) 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; } @@ -410,12 +398,12 @@ sys_shl_close (handle) 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; @@ -453,39 +441,38 @@ sys_dld_exit LTDL_PARAMS((void)) 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); @@ -526,12 +513,12 @@ sys_wll_exit LTDL_PARAMS((void)) /* 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, '.'); @@ -542,11 +529,15 @@ sys_wll_open (handle, 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 @@ -563,24 +554,24 @@ sys_wll_open (handle, filename) 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; } @@ -589,10 +580,10 @@ sys_wll_close (handle) 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; @@ -627,9 +618,8 @@ sys_bedl_exit LTDL_PARAMS((void)) 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; @@ -644,17 +634,17 @@ sys_bedl_open (handle, filename) } 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; } @@ -663,11 +653,11 @@ sys_bedl_close (handle) 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) { @@ -760,16 +750,15 @@ presym_add_symlist (preloaded) 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@"; @@ -779,20 +768,19 @@ presym_open (handle, filename) 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; @@ -801,10 +789,10 @@ presym_close (handle) 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) { @@ -862,6 +850,67 @@ lt_dlinit LTDL_PARAMS((void)) 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; @@ -954,7 +1003,8 @@ tryall_dlopen (handle, filename) } 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; } @@ -1640,7 +1690,7 @@ lt_dlclose (handle) 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); @@ -1695,7 +1745,7 @@ lt_dlsym (handle, symbol) 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); @@ -1709,7 +1759,7 @@ lt_dlsym (handle, symbol) 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; @@ -1822,4 +1872,3 @@ lt_dlforeach (func, data) } return 0; } - diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h index 9b31b2c4b..e36b60d34 100644 --- a/libltdl/ltdl.h +++ b/libltdl/ltdl.h @@ -120,6 +120,8 @@ typedef struct lt_dlhandle_t *lt_dlhandle; typedef lt_ptr_t lt_dlhandle; #endif +typedef lt_ptr_t lt_syshandle; + typedef struct { const char *name; lt_ptr_t address; @@ -131,8 +133,27 @@ typedef struct { int ref_count; /* reference count */ } lt_dlinfo; +typedef int lt_mod_init_t LTDL_PARAMS((void)); +typedef int lt_mod_exit_t LTDL_PARAMS((void)); +typedef lt_syshandle lt_lib_open_t LTDL_PARAMS((const char *filename)); +typedef int lt_lib_close_t LTDL_PARAMS((lt_syshandle handle)); +typedef lt_ptr_t lt_find_sym_t LTDL_PARAMS((lt_syshandle handle, const char *symbol)); + +typedef struct lt_dltype_t { + struct lt_dltype_t *next; + const char *sym_prefix; /* prefix for symbols */ + lt_mod_init_t *mod_init; + lt_mod_exit_t *mod_exit; + lt_lib_open_t *lib_open; + lt_lib_close_t *lib_close; + lt_find_sym_t *find_sym; +} lt_dltype_t; + __BEGIN_DECLS extern int lt_dlinit LTDL_PARAMS((void)); +extern int lt_dladdtype LTDL_PARAMS((lt_dltype_t *dltype)); +extern lt_dltype_t *lt_dlgettypes LTDL_PARAMS((void)); +extern int lt_dlsettypes LTDL_PARAMS((lt_dltype_t *dltypes)); extern int lt_dlpreload LTDL_PARAMS((const lt_dlsymlist *preloaded)); extern int lt_dlpreload_default LTDL_PARAMS((const lt_dlsymlist *preloaded)); extern int lt_dlexit LTDL_PARAMS((void));