? autom4te.cache ? COPYING ? aix.patch ? patches ? libtool-1.4-1.4b.diff.gz ? libtool-1.4.tar.gz ? libtool-1.4-1.4b.tar.xdp.gz ? ltdldemo ? INSTALL ? mkinstalldirs ? missing ? cygwin-patches.tar.bz2 ? libtool-1.4b.tar.gz ? dyld.patch ? install-sh ? cdemo/autom4te.cache ? demo/autom4te.cache ? depdemo/autom4te.cache ? libltdl/autom4te.cache ? libltdl/config-h.in ? mail/accounts2 ? mail/accounts ? mdemo/autom4te.cache ? pdemo/autom4te.cache ? tagdemo/autom4te.cache Index: ltdl.m4 =================================================================== RCS file: /cvsroot/libtool/libtool/ltdl.m4,v retrieving revision 1.29 diff -u -r1.29 ltdl.m4 --- ltdl.m4 2001/08/01 06:50:16 1.29 +++ ltdl.m4 2001/08/04 10:15:52 @@ -46,13 +46,13 @@ AC_REQUIRE([AC_LTDL_FUNC_ARGZ]) AC_CHECK_HEADERS([ctype.h errno.h malloc.h memory.h stdlib.h stdio.h]) -AC_CHECK_HEADERS([dl.h sys/dl.h dld.h]) +AC_CHECK_HEADERS([dl.h sys/dl.h dld.h sys/ldr.h]) AC_CHECK_HEADERS([string.h strings.h], [break]) AC_CHECK_FUNCS([strchr index], [break]) AC_CHECK_FUNCS([strrchr rindex], [break]) AC_CHECK_FUNCS([memcpy bcopy], [break]) -AC_CHECK_FUNCS([memmove strcmp]) +AC_CHECK_FUNCS([loadquery memmove strcmp]) ])# AC_LIB_LTDL Index: libltdl/README =================================================================== RCS file: /cvsroot/libtool/libtool/libltdl/README,v retrieving revision 1.2 diff -u -r1.2 README --- libltdl/README 1999/07/17 09:00:53 1.2 +++ libltdl/README 2001/08/04 10:15:52 @@ -7,3 +7,20 @@ * load_add_on (BeOS) * GNU DLD (emulates dynamic linking for static libraries) * libtool's dlpreopen + +Notes for AIX + The current AIX dlopen approach can not distinguish symbols + that are not available at all and such that are statically linked to + the binary and made available to the dynamically loaded shared library + by re-exporting. + + Especially libm and libstdc++ are searched over and over again + although they are hardlinked to the executable. + + 'must_recheck_notfound' is initialized to 0. If at least one + ld_user_dlloader demands a re-check, unresolved symbols are never + ignored. + This makes only sense for platforms where the executable can + not be dlopen'd, but the executables can export symbols from + statically linked libraries to shared libraries which are loaded + dynamically. Is there any candidate besides AIX? Index: libltdl/ltdl.c =================================================================== RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.c,v retrieving revision 1.142 diff -u -r1.142 ltdl.c --- libltdl/ltdl.c 2001/08/01 06:50:16 1.142 +++ libltdl/ltdl.c 2001/08/04 10:16:06 @@ -87,6 +87,11 @@ #include "ltdl.h" +/* FIXME: This ought to be a configure test: */ +#if defined(_AIX) +# define LTDL_SHARED_DOT_A 1 +#endif + @@ -655,9 +660,11 @@ #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag)) #define LT_DLRESIDENT_FLAG (0x01 << 0) +#define LT_DLNOTFOUND_FLAG (0x01 << 1) /* ...add more flags here... */ #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG) +#define LT_DLIS_NOTFOUND(handle) LT_DLGET_FLAG(handle, LT_DLNOTFOUND_FLAG) #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] @@ -863,6 +870,10 @@ # include #endif +#if HAVE_SYS_LDR_H +# include +#endif + #ifdef RTLD_GLOBAL # define LT_GLOBAL RTLD_GLOBAL #else @@ -904,6 +915,152 @@ # define DLERROR(arg) LT_DLSTRERROR (arg) #endif +static int sys_dl_init LT_PARAMS((void)); +static lt_module sys_dl_open LT_PARAMS((lt_user_data loader_data, + const char *filename)); +static int sys_dl_close LT_PARAMS((lt_user_data loader_data, + lt_module module)); +static lt_ptr sys_dl_sym LT_PARAMS((lt_user_data loader_data, + lt_module module, + const char *symbol)); + +int +sys_dl_init () +{ + int errors = 0; +#ifdef HAVE_LOADQUERY + char* buffer = 0; + size_t buf_size = 512; + lt_dlhandle handle = 0; + int ret; + + do + { + buf_size *= 2; + buffer = LT_EREALLOC (char, buffer, buf_size); + if (!buffer) + { + ++errors; + goto done; + } + ret = loadquery (L_GETINFO, buffer, buf_size); + } + while ((ret == -1) && (errno == ENOMEM)); + + if (ret >= 0) + { + struct ld_info *info = (struct ld_info*) buffer; + + do + { + int already_listed = 0; + const char *libname = info->ldinfo_filename; + const char *modname; + + if (!libname) + { + ++errors; + goto done; + } + modname = &info->ldinfo_filename[1+ LT_STRLEN (libname)]; + + LT_DLMUTEX_LOCK (); + { + lt_dlhandle cur = 0; + for (cur = handles; cur; cur = cur->next) + { + if (cur->info.filename && + !strcmp (cur->info.filename, libname)) + { + already_listed = 1; + break; + } + } + } + LT_DLMUTEX_UNLOCK (); + + if (!already_listed) + { + const char *end = 0; + const char *start = strrchr (libname, '/'); + size_t len = LT_STRLEN (start); + + handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (!handle) + { + ++errors; + goto done; + } + memset (handle, 0, sizeof (struct lt_dlhandle_struct)); + + if (start) + { + ++start; + } + else + { + start = libname; + } + + end = strrchr (start, '.'); + if (!end) + { + end = &start[len]; + } + else + { + len = end - start; + } + + handle->info.name = LT_EMALLOC (char, 1+ len); + if (!handle->info.name) + { + ++errors; + goto done; + } + strncpy (handle->info.name, start, len); + handle->info.name[len] = LT_EOS_CHAR; + + handle->info.filename = lt_estrdup (libname); + if (!handle->info.filename) + { + ++errors; + goto done; + } + + LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); + handle->info.ref_count = 1; + handle->loader = lt_dlloader_find ("dlopen"); + handle->module + = dlopen (libname, LT_GLOBAL | LT_LAZY_OR_NOW); + + LT_DLMUTEX_LOCK (); + handle->next = handles; + handles = handle; + LT_DLMUTEX_UNLOCK (); + } + + info = (struct ld_info*)(((char*)info)+info->ldinfo_next); + } + while (info->ldinfo_next != 0); + } + + done: + LT_DLFREE (buffer); + if (errors) + { + if (handle) + { + LT_DLFREE (handle->info.name); + LT_DLFREE (handle->info.filename); + LT_DLFREE (handle); + } + } +#endif /* HAVE_LOADQUERY */ + + return errors; +} + static lt_module sys_dl_open (loader_data, filename) lt_user_data loader_data; @@ -958,6 +1115,11 @@ # else 0, # endif +# ifdef _AIX + 0, +# else + 1, +# endif sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 }; @@ -1091,7 +1253,7 @@ } static struct lt_user_dlloader sys_shl = { - 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 + 0, 1, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 }; #endif /* HAVE_SHL_LOAD */ @@ -1230,7 +1392,7 @@ } static struct lt_user_dlloader sys_wll = { - 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 + 0, 1, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 }; #endif /* __WINDOWS__ */ @@ -1310,7 +1472,7 @@ } static struct lt_user_dlloader sys_bedl = { - 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 + 0, 1, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 }; #endif /* __BEOS__ */ @@ -1383,7 +1545,7 @@ } static struct lt_user_dlloader sys_dld = { - 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 + 0, 1, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 }; #endif /* HAVE_DLD */ @@ -1577,7 +1739,7 @@ } static struct lt_user_dlloader presym = { - 0, presym_open, presym_close, presym_sym, presym_exit, 0 + 0, 1, presym_open, presym_close, presym_sym, presym_exit, 0 }; @@ -1603,10 +1765,13 @@ static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1, lt_ptr data2)); + +static lt_dlhandle search_by_name LT_PARAMS((const char *name)); +static int not_found_entry LT_PARAMS((const char *name)); -static int canonicalize_path LT_PARAMS((const char *path, +static int canonicalize_path LT_PARAMS((const char *path, char **pcanonical)); -static int argzize_path LT_PARAMS((const char *path, +static int argzize_path LT_PARAMS((const char *path, char **pargz, size_t *pargz_len)); static FILE *find_file LT_PARAMS((const char *search_path, @@ -1632,10 +1797,11 @@ static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); -static char *user_search_path= 0; -static lt_dlloader *loaders = 0; -static lt_dlhandle handles = 0; -static int initialized = 0; +static char *user_search_path = 0; +static lt_dlloader *loaders = 0; +static lt_dlhandle handles = 0; +static int initialized = 0; +static int must_recheck_notfound = 0; /* Initialize libltdl. */ int @@ -1653,6 +1819,12 @@ #if HAVE_LIBDL && !defined(__CYGWIN__) errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen"); + + if (sys_dl_init () != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); + ++errors; + } #endif #if HAVE_SHL_LOAD errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen"); @@ -1975,7 +2147,94 @@ return 1; } +static lt_dlhandle +search_by_name (name) + const char *name; +{ + lt_dlhandle result = 0; + lt_dlhandle cur; + const char *la; + + LT_DLMUTEX_LOCK (); + for (cur = handles; cur; cur = cur->next) + { + if (cur->info.name && name && (strcmp (cur->info.name, name) == 0)) + { + if (cur->info.filename) + { + la = strrchr (cur->info.filename, '.'); + if (!la || (strcmp (la, ".la") != 0)) + { + result = cur; + break; + } + } + } + } + LT_DLMUTEX_UNLOCK (); + + return result; +} + +static int +not_found_entry (name) + const char *name; +{ + int errors = 0; + int my_recheck; + lt_dlhandle handle; + + LT_DLMUTEX_LOCK (); + my_recheck = must_recheck_notfound; + LT_DLMUTEX_UNLOCK (); + + if (!my_recheck) + { + handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + + if (!handle) + { + ++errors; + goto done; + } + + memset (handle, 0, sizeof (struct lt_dlhandle_struct)); + LT_DLSET_FLAG (handle, LT_DLNOTFOUND_FLAG); + + handle->info.filename = lt_estrdup (name); + if (!handle->info.filename) + { + ++errors; + goto done; + } + + handle->info.name = lt_estrdup (name); + if (!handle->info.name) + { + ++errors; + goto done; + } + + LT_DLMUTEX_LOCK (); + handle->next = handles; + handles = handle; + LT_DLMUTEX_UNLOCK (); + } + done: + if (errors) + { + if (handle) + { + LT_DLFREE (handle->info.name); + LT_DLFREE (handle->info.filename); + } + LT_DLFREE (handle); + } + + return errors; +} + static int canonicalize_path (path, pcanonical) const char *path; @@ -2010,7 +2269,7 @@ #ifdef LT_DIRSEP_CHAR && (path[src] != LT_DIRSEP_CHAR) #endif - ) + ) { canonical[dest++] = path[src]; } @@ -2823,6 +3082,41 @@ return handle; } + LT_DLMUTEX_LOCK (); + if (!must_recheck_notfound) + { + tmp[len] = LT_EOS_CHAR; + + /* Find by info.name in the list. */ + handle = search_by_name (tmp); + if (handle) + { + if (LT_DLIS_NOTFOUND (handle)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + handle = 0; + } + else + { + LT_DLMUTEX_SETERROR (saved_error); + } + LT_DLFREE (tmp); + return handle; + } + } + LT_DLMUTEX_UNLOCK (); + +#ifdef LTDL_SHARED_DOT_A + strcat (tmp, ".a"); + handle = lt_dlopen (tmp); + if (handle) + { + LT_DLMUTEX_SETERROR (saved_error); + LT_DLFREE (tmp); + return handle; + } +#endif /* LTDL_SHARED_DOT_A */ + #ifdef LTDL_SHLIB_EXT /* try "filename.EXT" */ if (LT_STRLEN(shlib_ext) > 3) @@ -2856,6 +3150,13 @@ return handle; } + tmp[len] = LT_EOS_CHAR; + if (not_found_entry (tmp) != 0) + { + LT_DLFREE (tmp); + return 0; + } + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); LT_DLFREE (tmp); return 0; @@ -3558,6 +3859,8 @@ node->dlloader_data = dlloader->dlloader_data; LT_DLMUTEX_LOCK (); + must_recheck_notfound |= dlloader->notfound_recheck; + if (!loaders) { /* If there are no loaders, NODE becomes the list! */ Index: libltdl/ltdl.h =================================================================== RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.h,v retrieving revision 1.56 diff -u -r1.56 ltdl.h --- libltdl/ltdl.h 2001/08/01 06:50:16 1.56 +++ libltdl/ltdl.h 2001/08/04 10:16:06 @@ -276,6 +276,7 @@ struct lt_user_dlloader { const char *sym_prefix; + int notfound_recheck; lt_module_open *module_open; lt_module_close *module_close; lt_find_sym *find_sym;