From: Gary V. Vaughan Date: Mon, 7 Feb 2000 18:17:21 +0000 (+0000) Subject: * libltdl/ltdl.h (lt_dlloader_data_t): New type for loader X-Git-Tag: release-1-3d~199 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ca76b52bdf3814f388428d612fd9427d8dcbc53;p=thirdparty%2Flibtool.git * libltdl/ltdl.h (lt_dlloader_data_t): New type for loader instance data. (lt_user_dlloader): New lt_dlloader_data_t field. (lt_module_open_t): Add lt_dlloader_data_t parameter. (lt_module_close_t): Add lt_dlloader_data_t parameter. (lt_find_sym_t): Add lt_dlloader_data_t parameter. (lt_dlloader_exit_t): Add lt_dlloader_data_t parameter. * libltdl/ltdl.c: A sprinkling of /*ARGSUSED*/ markers to reassure lint that the unused arguments are intentional. (lt_dlloader_t): New lt_dlloader_data_t field. (lt_dlloader_data): New function to return the contents of the dlloader_data field. (sys_dl_open): Take an additional lt_dlloader_data_t argument. (sys_dl_close): Ditto. (sys_dl_sym): Ditto. (sys_dl): Initialise lt_dlloader_data_t field. (sys_shl_open, sys_shl_close, sys_shl_sym, sys_shl): As above. (sys_wll_open, sys_wll_close, sys_wll_sym, sys_wll): As above. (sys_bedl_open, sys_bedl_close, sys_bedl_sym, sys_bedl): As above. (sys_dld_open, sys_dld_close, sys_dld_sym, sys_dld): As above. (presym_init, presym_exit, presym_open, presym_close, presym_sym, presym): As above. (lt_dlinit): Call presym_init with additional argument. (lt_dlexit): Call dlloader_exit method with additional argument. (tryall_dlopen): Call module_open method with additional argument. (lt_dlclose): Call module_close method with additional argument. (lt_dlsym): Call find_sym method with additional argument. (lt_add_dlloader): Initialise dlloader_data field. (lt_remove_dlloader): Call dlloader_exit method with additional argument. --- diff --git a/ChangeLog b/ChangeLog index 0aaf967d8..6f9344365 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,37 @@ 2000-02-03 Gary V. Vaughan + * libltdl/ltdl.h (lt_dlloader_data_t): New type for loader + instance data. + (lt_user_dlloader): New lt_dlloader_data_t field. + (lt_module_open_t): Add lt_dlloader_data_t parameter. + (lt_module_close_t): Add lt_dlloader_data_t parameter. + (lt_find_sym_t): Add lt_dlloader_data_t parameter. + (lt_dlloader_exit_t): Add lt_dlloader_data_t parameter. + * libltdl/ltdl.c: A sprinkling of /*ARGSUSED*/ markers to + reassure lint that the unused arguments are intentional. + (lt_dlloader_t): New lt_dlloader_data_t field. + (lt_dlloader_data): New function to return the contents of the + dlloader_data field. + (sys_dl_open): Take an additional lt_dlloader_data_t argument. + (sys_dl_close): Ditto. + (sys_dl_sym): Ditto. + (sys_dl): Initialise lt_dlloader_data_t field. + (sys_shl_open, sys_shl_close, sys_shl_sym, sys_shl): As above. + (sys_wll_open, sys_wll_close, sys_wll_sym, sys_wll): As above. + (sys_bedl_open, sys_bedl_close, sys_bedl_sym, sys_bedl): As + above. + (sys_dld_open, sys_dld_close, sys_dld_sym, sys_dld): As above. + (presym_init, presym_exit, presym_open, presym_close, presym_sym, + presym): As above. + (lt_dlinit): Call presym_init with additional argument. + (lt_dlexit): Call dlloader_exit method with additional argument. + (tryall_dlopen): Call module_open method with additional argument. + (lt_dlclose): Call module_close method with additional argument. + (lt_dlsym): Call find_sym method with additional argument. + (lt_add_dlloader): Initialise dlloader_data field. + (lt_remove_dlloader): Call dlloader_exit method with additional + argument. + * libltdl/ltdl.c (find_file): Prevent early release of memory in filename/*pdir. From Jon Leichter diff --git a/doc/libtool.texi b/doc/libtool.texi index ce679b433..f58b8fdc7 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -3264,22 +3264,31 @@ level types. @code{lt_dlloader_t} is a handle for module loader types. @end deftp -@deftypefn {Type} {struct} lt_user_dlloader @{@w{const char *@var{sym_prefix};} @w{lt_module_open_t *@var{module_open};} @w{lt_module_close_t *@var{module_close};} @w{lt_find_sym_t *@var{find_sym};} @w{lt_dlloader_exit_t *@var{dlloader_exit};} @} +@deftp {Type} lt_dlloader_data_t +@code{lt_dlloader_data_t} is used for specifying loader instance data. +@end deftp + +@deftypefn {Type} {struct} lt_user_dlloader @{@w{const char *@var{sym_prefix};} @w{lt_module_open_t *@var{module_open};}@w{lt_module_close_t *@var{module_close};} @w{lt_find_sym_t *@var{find_sym};} @w{lt_dlloader_exit_t *@var{dlloader_exit};} @w{lt_dlloader_data_t @var{dlloader_data};} @} 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_add_dlloader}. +structures and pass it to @code{lt_add_dlloader}. You can pass whatever +you like in the @var{dlloader_data} field, and it will be passed back as +the value of the first parameter to each of the functions specified in +the function pointer fields. @end deftypefn -@deftypefn {Type} lt_module_t lt_module_open_t (@w{const char *@var{filename}}) +@deftypefn {Type} lt_module_t lt_module_open_t (@w{lt_dlloader_data_t @var{loader_data},} @w{const char *@var{filename}}) The type of the loader function for an @code{lt_dlloader_t} module -loader. Implementation of such a function should attempt to load the -named module, and return an @code{lt_module_t} suitable for passing in -to the associated @code{lt_module_close_t} and @code{lt_sym_find_t} -function pointers. If the function fails it should return NULL, and set -the error message with @code{lt_dlseterror}. +loader. The value set in the dlloader_data field of the @code{struct +lt_user_dlloader} structure will be passed into this function in the +@var{loader_data} parameter. Implementation of such a function should +attempt to load the named module, and return an @code{lt_module_t} +suitable for passing in to the associated @code{lt_module_close_t} and +@code{lt_sym_find_t} function pointers. If the function fails it should +return NULL, and set the error message with @code{lt_dlseterror}. @end deftypefn -@deftypefn {Type} int lt_module_close_t (@w{lt_module_t @var{module}}) +@deftypefn {Type} int lt_module_close_t (@w{lt_dlloader_data_t @var{loader_data},} @w{lt_module_t @var{module}}) The type of the unloader function for a user defined module loader. Implementatation of such a function should attempt to release any resources tied up by the @var{module} module, and then unload it @@ -3287,18 +3296,20 @@ from memory. If the function fails for some reason, set the error message with @code{lt_dlseterror} and return non-zero. @end deftypefn -@deftypefn {Type} lt_ptr_t lt_find_sym_t (@w{lt_module_t @var{module},} @w{const char *@var{symbol}}) +@deftypefn {Type} lt_ptr_t lt_find_sym_t (@w{lt_dlloader_data_t @var{loader_data},} @w{lt_module_t @var{module},} @w{const char *@var{symbol}}) The type of the symbol lookup function for a user defined module loader. Implementation of such a function should return the address of the named @var{symbol} in the module @var{module}, or else set the error message with @code{lt_dlseterror} and return NULL if lookup fails. @end deftypefn -@deftypefn {Type} int lt_dlloader_exit_t (void) +@deftypefn {Type} int lt_dlloader_exit_t (@w{lt_dlloader_data_t @var{loader_data}}) The type of the finalisation function for a user defined 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}. +with the loader, including any user specified data in the +@code{dlloader_data} field of the @code{lt_user_dlloader}. If non-NULL, +the function will be called by @code{lt_dlexit}, and +@code{lt_remove_dlloader}. @end deftypefn For example: @@ -3318,6 +3329,7 @@ register_myloader (void) dlloader.module_close = myloader_close; dlloader.find_sym = myloader_find_sym. dlloader.dlloader_exit = myloader_exit; + dlloader.dlloader_data = (lt_dlloader_data_t)myloader_function; /* Add my loader as the default module loader. */ if (lt_add_dlloader (lt_next_dlloader (NULL), &dlloader, "myloader") != 0) @@ -3406,13 +3418,20 @@ the host dependent module loading @sc{api} -- @code{shl_load} and @end example @end deftypefun -@deftypefun char *lt_dlloader_name (@w{lt_dlloader_t *@var{place}}) +@deftypefun const char *lt_dlloader_name (@w{lt_dlloader_t *@var{place}}) Return the identifying name of @var{PLACE}, as obtained from @code{lt_next_dlloader} or @code{lt_find_dlloader}. If this function fails, it will return @code{NULL} and set an error for retrieval with @code{lt_dlerror}. @end deftypefun +@deftypefun lt_dlloader_data_t *lt_dlloader_data (@w{lt_dlloader_t *@var{place}}) +Return the address of the @code{dlloader_data} of @var{PLACE}, as +obtained from @code{lt_next_dlloader} or @code{lt_find_dlloader}. If +this function fails, it will return @code{NULL} and set an error for +retrieval with @code{lt_dlerror}. +@end deftypefun + @subsection Error handling within user module loaders @deftypefun int lt_dladderror (@w{const char *@var{diagnostic}}) diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index a433d264a..7abf7b494 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -93,10 +93,11 @@ struct lt_dlloader_t { struct lt_dlloader_t *next; const char *loader_name; /* identifying name for each loader */ const char *sym_prefix; /* prefix for symbols */ - lt_dlloader_exit_t *dlloader_exit; lt_module_open_t *module_open; lt_module_close_t *module_close; lt_find_sym_t *find_sym; + lt_dlloader_exit_t *dlloader_exit; + lt_dlloader_data_t dlloader_data; }; typedef struct lt_dlhandle_t { @@ -282,8 +283,10 @@ strrchr(str, ch) # endif #endif +/*ARGSUSED*/ static lt_module_t -sys_dl_open (filename) +sys_dl_open (loader_data, filename) + lt_dlloader_data_t loader_data; const char *filename; { lt_module_t module = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW); @@ -297,8 +300,10 @@ sys_dl_open (filename) return module; } +/*ARGSUSED*/ static int -sys_dl_close (module) +sys_dl_close (loader_data, module) + lt_dlloader_data_t loader_data; lt_module_t module; { if (dlclose(module) != 0) { @@ -312,8 +317,10 @@ sys_dl_close (module) return 0; } +/*ARGSUSED*/ static lt_ptr_t -sys_dl_sym (module, symbol) +sys_dl_sym (loader_data, module, symbol) + lt_dlloader_data_t loader_data; lt_module_t module; const char *symbol; { @@ -334,7 +341,7 @@ static struct lt_user_dlloader sys_dl = { # else 0, # endif - sys_dl_open, sys_dl_close, sys_dl_sym, 0 }; + sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 }; #endif #if HAVE_SHL_LOAD @@ -380,8 +387,10 @@ static struct lt_user_dlloader sys_dl = { #define LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH) +/*ARGSUSED*/ static lt_module_t -sys_shl_open (filename) +sys_shl_open (loader_data, filename) + lt_dlloader_data_t loader_data; const char *filename; { lt_module_t module = shl_load(filename, LTDL_BIND_FLAGS, 0L); @@ -391,8 +400,10 @@ sys_shl_open (filename) return module; } +/*ARGSUSED*/ static int -sys_shl_close (module) +sys_shl_close (loader_data, module) + lt_dlloader_data_t loader_data; lt_module_t module; { if (shl_unload((shl_t) (module)) != 0) { @@ -402,8 +413,10 @@ sys_shl_close (module) return 0; } +/*ARGSUSED*/ static lt_ptr_t -sys_shl_sym (module, symbol) +sys_shl_sym (loader_data, module, symbol) + lt_dlloader_data_t loader_data; lt_module_t module; const char *symbol; { @@ -418,7 +431,7 @@ sys_shl_sym (module, symbol) } static struct lt_user_dlloader -sys_shl = { 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0 }; +sys_shl = { 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 }; #undef LTDL_TYPE_TOP #define LTDL_TYPE_TOP &sys_shl @@ -434,8 +447,10 @@ sys_shl = { 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0 }; /* Forward declaration; required to implement handle search below. */ static lt_dlhandle handles; +/*ARGSUSED*/ static lt_module_t -sys_wll_open (filename) +sys_wll_open (loader_data, filename) + lt_dlloader_data_t loader_data; const char *filename; { lt_dlhandle cur; @@ -488,8 +503,10 @@ sys_wll_open (filename) return module; } +/*ARGSUSED*/ static int -sys_wll_close (module) +sys_wll_close (loader_data, module) + lt_dlloader_data_t loader_data; lt_module_t module; { if (FreeLibrary(module) == 0) { @@ -499,8 +516,10 @@ sys_wll_close (module) return 0; } +/*ARGSUSED*/ static lt_ptr_t -sys_wll_sym (module, symbol) +sys_wll_sym (loader_data, module, symbol) + lt_dlloader_data_t loader_data; lt_module_t module; const char *symbol; { @@ -512,7 +531,7 @@ sys_wll_sym (module, symbol) } static struct lt_user_dlloader -sys_wll = { 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0 }; +sys_wll = { 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 }; #endif @@ -522,8 +541,10 @@ sys_wll = { 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0 }; #include +/*ARGSUSED*/ static lt_module_t -sys_bedl_open (filename) +sys_bedl_open (loader_data, filename) + lt_dlloader_data_t loader_data; const char *filename; { image_id image = 0; @@ -544,8 +565,10 @@ sys_bedl_open (filename) return (lt_module_t) image; } +/*ARGSUSED*/ static int -sys_bedl_close (module) +sys_bedl_close (loader_data, module) + lt_dlloader_data_t loader_data; lt_module_t module; { if (unload_add_on((image_id)module) != B_OK) { @@ -555,8 +578,10 @@ sys_bedl_close (module) return 0; } +/*ARGSUSED*/ static lt_ptr_t -sys_bedl_sym (module, symbol) +sys_bedl_sym (loader_data, module, symbol) + lt_dlloader_data_t loader_data; lt_module_t module; const char *symbol; { @@ -572,7 +597,7 @@ sys_bedl_sym (module, symbol) } static struct lt_user_dlloader -sys_bedl = { 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0 }; +sys_bedl = { 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 }; #endif @@ -584,8 +609,10 @@ sys_bedl = { 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0 }; #include #endif +/*ARGSUSED*/ static lt_module_t -sys_dld_open (filename) +sys_dld_open (loader_data, filename) + lt_dlloader_data_t loader_data; const char *filename; { lt_module_t module = strdup(filename); @@ -601,8 +628,10 @@ sys_dld_open (filename) return module; } +/*ARGSUSED*/ static int -sys_dld_close (module) +sys_dld_close (loader_data, module) + lt_dlloader_data_t loader_data; lt_module_t module; { if (dld_unlink_by_file((char*)(module), 1) != 0) { @@ -613,8 +642,10 @@ sys_dld_close (module) return 0; } +/*ARGSUSED*/ static lt_ptr_t -sys_dld_sym (module, symbol) +sys_dld_sym (loader_data, module, symbol) + lt_dlloader_data_t loader_data; lt_module_t module; const char *symbol; { @@ -626,7 +657,7 @@ sys_dld_sym (module, symbol) } static struct lt_user_dlloader -sys_dld = { 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0 }; +sys_dld = { 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 }; #endif @@ -640,8 +671,10 @@ typedef struct lt_dlsymlists_t { static const lt_dlsymlist *default_preloaded_symbols = 0; static lt_dlsymlists_t *preloaded_symbols = 0; +/*ARGSUSED*/ static int -presym_init LTDL_PARAMS((void)) +presym_init (loader_data) + lt_dlloader_data_t loader_data; { preloaded_symbols = 0; if (default_preloaded_symbols) @@ -664,8 +697,10 @@ presym_free_symlists LTDL_PARAMS((void)) return 0; } +/*ARGSUSED*/ static int -presym_exit LTDL_PARAMS((void)) +presym_exit (loader_data) + lt_dlloader_data_t loader_data; { presym_free_symlists(); return 0; @@ -695,8 +730,10 @@ presym_add_symlist (preloaded) return 0; } +/*ARGSUSED*/ static lt_module_t -presym_open (filename) +presym_open (loader_data, filename) + lt_dlloader_data_t loader_data; const char *filename; { lt_dlsymlists_t *lists = preloaded_symbols; @@ -723,8 +760,10 @@ presym_open (filename) return 0; } +/*ARGSUSED*/ static int -presym_close (module) +presym_close (loader_data, module) + lt_dlloader_data_t loader_data; lt_module_t module; { /* Just to silence gcc -Wall */ @@ -732,8 +771,10 @@ presym_close (module) return 0; } +/*ARGSUSED*/ static lt_ptr_t -presym_sym (module, symbol) +presym_sym (loader_data, module, symbol) + lt_dlloader_data_t loader_data; lt_module_t module; const char *symbol; { @@ -750,7 +791,7 @@ presym_sym (module, symbol) } static struct lt_user_dlloader -presym = { 0, presym_open, presym_close, presym_sym, presym_exit }; +presym = { 0, presym_open, presym_close, presym_sym, presym_exit, 0 }; static char *user_search_path = 0; @@ -788,10 +829,10 @@ lt_dlinit LTDL_PARAMS((void)) errors += lt_add_dlloader (lt_next_dlloader(0), &sys_dld, "dld"); #endif errors += lt_add_dlloader (lt_next_dlloader(0), &presym, "dlpreload"); - if (presym_init()) { + if (presym_init(presym.dlloader_data)) { last_error = LT_DLSTRERROR(INIT_LOADER); return 1; - } + } if (errors != 0) { last_error = LT_DLSTRERROR(DLOPEN_NOT_SUPPORTED); @@ -852,7 +893,8 @@ lt_dlexit LTDL_PARAMS((void)) /* close all loaders */ while (loader) { lt_dlloader_t *next = loader->next; - if (loader->dlloader_exit && loader->dlloader_exit()) + lt_dlloader_data_t data = loader->dlloader_data; + if (loader->dlloader_exit && loader->dlloader_exit(data)) errors++; lt_dlfree (loader); loader = next; @@ -898,7 +940,8 @@ tryall_dlopen (handle, filename) } else cur->info.filename = 0; while (loader) { - cur->module = loader->module_open(filename); + lt_dlloader_data_t data = loader->dlloader_data; + cur->module = loader->module_open(data, filename); if (cur->module != 0) break; loader = loader->next; @@ -1579,12 +1622,13 @@ lt_dlclose (handle) handle->info.ref_count--; if (!handle->info.ref_count) { int error; + lt_dlloader_data_t data = handle->loader->dlloader_data; if (handle != handles) last->next = handle->next; else handles = handle->next; - error = handle->loader->module_close(handle->module); + error = handle->loader->module_close(data, handle->module); error += unload_deplibs(handle); if (handle->info.filename) lt_dlfree(handle->info.filename); @@ -1605,6 +1649,7 @@ lt_dlsym (handle, symbol) char lsym[LTDL_SYMBOL_LENGTH]; char *sym; lt_ptr_t address; + lt_dlloader_data_t data; if (!handle) { last_error = LT_DLSTRERROR(INVALID_HANDLE); @@ -1627,6 +1672,7 @@ lt_dlsym (handle, symbol) last_error = LT_DLSTRERROR(BUFFER_OVERFLOW); return 0; } + data = handle->loader->dlloader_data; if (handle->info.name) { const char *saved_error = last_error; @@ -1639,7 +1685,7 @@ lt_dlsym (handle, symbol) strcat(sym, "_LTX_"); strcat(sym, symbol); /* try "modulename_LTX_symbol" */ - address = handle->loader->find_sym(handle->module, sym); + address = handle->loader->find_sym(data, handle->module, sym); if (address) { if (sym != lsym) lt_dlfree(sym); @@ -1653,7 +1699,7 @@ lt_dlsym (handle, symbol) strcat(sym, symbol); } else strcpy(sym, symbol); - address = handle->loader->find_sym(handle->module, sym); + address = handle->loader->find_sym(data, handle->module, sym); if (sym != lsym) lt_dlfree(sym); return address; @@ -1773,6 +1819,7 @@ lt_add_dlloader (place, dlloader, loader_name) node->module_open = dlloader->module_open; node->module_close = dlloader->module_close; node->find_sym = dlloader->find_sym; + node->dlloader_data = dlloader->dlloader_data; if (!loaders) /* If there are no loaders, NODE becomes the list! */ @@ -1839,7 +1886,7 @@ lt_remove_dlloader (loader_name) prev->next = prev->next->next; } if (place->dlloader_exit) - result = place->dlloader_exit (); + result = place->dlloader_exit (place->dlloader_data); lt_dlfree (place); return result; @@ -1861,6 +1908,15 @@ lt_dlloader_name (place) return place ? place->loader_name : 0; } +lt_dlloader_data_t * +lt_dlloader_data (place) + lt_dlloader_t *place; +{ + if (!place) + last_error = LT_DLSTRERROR(INVALID_LOADER); + return place ? &(place->dlloader_data) : 0; +} + lt_dlloader_t * lt_find_dlloader (loader_name) const char *loader_name; diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h index 605f72774..2a2a75b86 100644 --- a/libltdl/ltdl.h +++ b/libltdl/ltdl.h @@ -182,11 +182,13 @@ typedef struct lt_dlloader_t lt_dlloader_t; typedef lt_ptr_t lt_dlloader_t; #endif +typedef lt_ptr_t lt_dlloader_data_t; + /* Function pointer types for creating user defined module loaders. */ -typedef lt_module_t lt_module_open_t LTDL_PARAMS((const char *filename)); -typedef int lt_module_close_t LTDL_PARAMS((lt_module_t handle)); -typedef lt_ptr_t lt_find_sym_t LTDL_PARAMS((lt_module_t handle, const char *symbol)); -typedef int lt_dlloader_exit_t LTDL_PARAMS((void)); +typedef lt_module_t lt_module_open_t LTDL_PARAMS((lt_dlloader_data_t loader_data, const char *filename)); +typedef int lt_module_close_t LTDL_PARAMS((lt_dlloader_data_t loader_data, lt_module_t handle)); +typedef lt_ptr_t lt_find_sym_t LTDL_PARAMS((lt_dlloader_data_t loader_data, lt_module_t handle, const char *symbol)); +typedef int lt_dlloader_exit_t LTDL_PARAMS((lt_dlloader_data_t loader_data)); __BEGIN_DECLS /* Initialisation and finalisation functions for libltdl. */ @@ -227,10 +229,12 @@ struct lt_user_dlloader { lt_module_close_t *module_close; lt_find_sym_t *find_sym; lt_dlloader_exit_t *dlloader_exit; + lt_dlloader_data_t dlloader_data; }; extern lt_dlloader_t *lt_next_dlloader LTDL_PARAMS((lt_dlloader_t *place)); extern const char *lt_dlloader_name LTDL_PARAMS((lt_dlloader_t *place)); +extern lt_dlloader_data_t *lt_dlloader_data LTDL_PARAMS((lt_dlloader_t *place)); extern lt_dlloader_t *lt_find_dlloader LTDL_PARAMS((const char *loader_name)); extern int lt_add_dlloader LTDL_PARAMS((lt_dlloader_t *place, const struct lt_user_dlloader *dlloader, const char *loader_name));