From: Eric Andersen Date: Sun, 31 Aug 2003 06:51:54 +0000 (-0000) Subject: Weed out duplicates before trying to load libraries.... Delayed X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=9a927b3cbb4b309f01de9473e5aad69f41df1d9a;p=uclinux-h8%2FuClibc.git Weed out duplicates before trying to load libraries.... Delayed checking for duplicates and returning an alias if an existing lib is already loaded is still correct for the dlopen case. --- diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h index 95de118f5..992a608b1 100644 --- a/ldso/include/dl-elf.h +++ b/ldso/include/dl-elf.h @@ -68,6 +68,7 @@ extern struct elf_resolve * _dl_load_shared_library(int secure, struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname); extern struct elf_resolve * _dl_load_elf_shared_library(int secure, struct dyn_elf **rpnt, char *libname); +extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname); extern int _dl_linux_resolve(void); diff --git a/ldso/include/ld_elf.h b/ldso/include/ld_elf.h index 95de118f5..992a608b1 100644 --- a/ldso/include/ld_elf.h +++ b/ldso/include/ld_elf.h @@ -68,6 +68,7 @@ extern struct elf_resolve * _dl_load_shared_library(int secure, struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname); extern struct elf_resolve * _dl_load_elf_shared_library(int secure, struct dyn_elf **rpnt, char *libname); +extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname); extern int _dl_linux_resolve(void); diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 3df8b1461..2f70621d1 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -166,29 +166,19 @@ search_for_named_library(char *name, int secure, const char *path_list, return NULL; } - -/* - * Used to return error codes back to dlopen et. al. - */ - -unsigned long _dl_error_number; -unsigned long _dl_internal_error_number; -extern char *_dl_ldsopath; - -struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt, - struct elf_resolve *tpnt, char *full_libname) +/* Check if the named library is already loaded... */ +struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname) { - char *pnt, *pnt1; + const char *pnt, *pnt1; struct elf_resolve *tpnt1; - char *libname, *libname2; + const char *libname, *libname2; - _dl_internal_error_number = 0; pnt = libname = full_libname; /* quick hack to ensure mylibname buffer doesn't overflow. don't allow full_libname or any directory to be longer than 1024. */ if (_dl_strlen(full_libname) > 1024) - goto goof; + return NULL; /* Skip over any initial initial './' and '/' stuff to * get the short form libname with no path garbage */ @@ -215,8 +205,47 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt, return tpnt1; } } + return NULL; +} + +/* + * Used to return error codes back to dlopen et. al. + */ + +unsigned long _dl_error_number; +unsigned long _dl_internal_error_number; +extern char *_dl_ldsopath; + +struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt, + struct elf_resolve *tpnt, char *full_libname) +{ + char *pnt, *pnt1; + struct elf_resolve *tpnt1; + char *libname; + + _dl_internal_error_number = 0; + libname = full_libname; + + /* quick hack to ensure mylibname buffer doesn't overflow. don't + allow full_libname or any directory to be longer than 1024. */ + if (_dl_strlen(full_libname) > 1024) + goto goof; + + /* Skip over any initial initial './' and '/' stuff to + * get the short form libname with no path garbage */ + pnt1 = _dl_strrchr(libname, '/'); + if (pnt1) { + libname = pnt1 + 1; + } + + /* Critical step! Weed out duplicates early to avoid + * function aliasing, which wastes memory, and causes + * really bad things to happen with weaks and globals. */ + if ((tpnt1=_dl_check_if_named_library_is_loaded(libname))!=NULL) + return tpnt1; + #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug) _dl_dprintf(_dl_debug_file, "searching for library: '%s'\n", libname); #endif diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 2f8e611ba..b6f236d0b 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -902,6 +902,10 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a *str2 = '\0'; if (!_dl_secure || _dl_strchr(str, '/') == NULL) { + if ((tpnt1 = _dl_check_if_named_library_is_loaded(str))) + { + continue; + } tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str); if (!tpnt1) { #ifdef __LDSO_LDD_SUPPORT__ @@ -978,6 +982,10 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a c = *cp; *cp = '\0'; + if ((tpnt1 = _dl_check_if_named_library_is_loaded(cp2))) + { + continue; + } tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2); if (!tpnt1) { #ifdef __LDSO_LDD_SUPPORT__ @@ -1068,6 +1076,10 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a tpnt = NULL; continue; } + if ((tpnt1 = _dl_check_if_named_library_is_loaded(lpntstr))) + { + continue; + } if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr))) { #ifdef __LDSO_LDD_SUPPORT__ diff --git a/ldso/ldso/readelflib1.c b/ldso/ldso/readelflib1.c index 3df8b1461..2f70621d1 100644 --- a/ldso/ldso/readelflib1.c +++ b/ldso/ldso/readelflib1.c @@ -166,29 +166,19 @@ search_for_named_library(char *name, int secure, const char *path_list, return NULL; } - -/* - * Used to return error codes back to dlopen et. al. - */ - -unsigned long _dl_error_number; -unsigned long _dl_internal_error_number; -extern char *_dl_ldsopath; - -struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt, - struct elf_resolve *tpnt, char *full_libname) +/* Check if the named library is already loaded... */ +struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname) { - char *pnt, *pnt1; + const char *pnt, *pnt1; struct elf_resolve *tpnt1; - char *libname, *libname2; + const char *libname, *libname2; - _dl_internal_error_number = 0; pnt = libname = full_libname; /* quick hack to ensure mylibname buffer doesn't overflow. don't allow full_libname or any directory to be longer than 1024. */ if (_dl_strlen(full_libname) > 1024) - goto goof; + return NULL; /* Skip over any initial initial './' and '/' stuff to * get the short form libname with no path garbage */ @@ -215,8 +205,47 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt, return tpnt1; } } + return NULL; +} + +/* + * Used to return error codes back to dlopen et. al. + */ + +unsigned long _dl_error_number; +unsigned long _dl_internal_error_number; +extern char *_dl_ldsopath; + +struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt, + struct elf_resolve *tpnt, char *full_libname) +{ + char *pnt, *pnt1; + struct elf_resolve *tpnt1; + char *libname; + + _dl_internal_error_number = 0; + libname = full_libname; + + /* quick hack to ensure mylibname buffer doesn't overflow. don't + allow full_libname or any directory to be longer than 1024. */ + if (_dl_strlen(full_libname) > 1024) + goto goof; + + /* Skip over any initial initial './' and '/' stuff to + * get the short form libname with no path garbage */ + pnt1 = _dl_strrchr(libname, '/'); + if (pnt1) { + libname = pnt1 + 1; + } + + /* Critical step! Weed out duplicates early to avoid + * function aliasing, which wastes memory, and causes + * really bad things to happen with weaks and globals. */ + if ((tpnt1=_dl_check_if_named_library_is_loaded(libname))!=NULL) + return tpnt1; + #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug) _dl_dprintf(_dl_debug_file, "searching for library: '%s'\n", libname); #endif