summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-08-31 06:51:54 +0000
committerEric Andersen <andersen@codepoet.org>2003-08-31 06:51:54 +0000
commit9a927b3cbb4b309f01de9473e5aad69f41df1d9a (patch)
tree6e036157779d5b9a24bcca42f994028826736e6a
parent1e680eeea6df1fb580163689bfc9edb547f5daab (diff)
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.
-rw-r--r--ldso/include/dl-elf.h1
-rw-r--r--ldso/include/ld_elf.h1
-rw-r--r--ldso/ldso/dl-elf.c59
-rw-r--r--ldso/ldso/ldso.c12
-rw-r--r--ldso/ldso/readelflib1.c59
5 files changed, 102 insertions, 30 deletions
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