From 97688568dea693a1bd1c9f7a2320f316af25a16d Mon Sep 17 00:00:00 2001
From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
Date: Mon, 9 Aug 2004 08:11:54 +0000
Subject: This should fix the dlsym problem Peter van Hoyweghen reported.
 However RTLD_LOCAL still doesn't work. Everything is RTLD_GLOBAL.

---
 ldso/libdl/libdl.c | 51 +++++++++++++++++++--------------------------------
 1 file changed, 19 insertions(+), 32 deletions(-)

(limited to 'ldso/libdl')

diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index f20041bc2..03b7834a0 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -131,7 +131,7 @@ static void __attribute__ ((destructor)) dl_cleanup(void)
 void *dlopen(const char *libname, int flag)
 {
 	struct elf_resolve *tpnt, *tfrom, *tcurr;
-	struct dyn_elf *dyn_chain, *rpnt = NULL;
+	struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr;
 	struct dyn_elf *dpnt;
 	static int dl_init = 0;
 	ElfW(Addr) from;
@@ -175,7 +175,7 @@ void *dlopen(const char *libname, int flag)
 				&& (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
 			tfrom = tpnt;
 	}
-
+	for(rpnt = _dl_symbol_tables; rpnt->next; rpnt=rpnt->next);
 	/* Try to load the specified library */
 #ifdef __SUPPORT_LD_DEBUG__
 	if(_dl_debug)
@@ -192,19 +192,9 @@ void *dlopen(const char *libname, int flag)
 	_dl_memset(dyn_chain, 0, sizeof(struct dyn_elf));
 	dyn_chain->dyn = tpnt;
 	dyn_chain->flags = flag;
-	if (!tpnt->symbol_scope)
-		tpnt->symbol_scope = dyn_chain;
 
 	dyn_chain->next_handle = _dl_handles;
-	_dl_handles = rpnt = dyn_chain;
-
-	if (tpnt->init_flag & INIT_FUNCS_CALLED) {
-		/* If the init and fini stuff has already been run, that means
-		 * the dlopen'd library has already been loaded, and nothing
-		 * further needs to be done. */
-		return (void *) dyn_chain;
-	}
-
+	_dl_handles = dyn_ptr = dyn_chain;
 
 #ifdef __SUPPORT_LD_DEBUG__
 	if(_dl_debug)
@@ -222,35 +212,32 @@ void *dlopen(const char *libname, int flag)
 				lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] +
 						dpnt->d_un.d_val);
 				name = _dl_get_last_path_component(lpntstr);
-
-				if ((tpnt1 = _dl_check_if_named_library_is_loaded(name, 0)))
-					continue;
-
+				tpnt1 = _dl_check_if_named_library_is_loaded(name, 0);
 #ifdef __SUPPORT_LD_DEBUG__
 				if(_dl_debug)
 					fprintf(stderr, "Trying to load '%s', needed by '%s'\n",
 							lpntstr, tcurr->libname);
 #endif
-
-				if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, 0))) {
-					goto oops;
+				dyn_ptr->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
+				_dl_memset (dyn_ptr->next, 0, sizeof (struct dyn_elf));
+				dyn_ptr = dyn_ptr->next;
+				dyn_ptr->dyn = tpnt1;
+				if (!tpnt1) {
+					tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, 0);
+					if (!tpnt1)
+						goto oops;
+					dyn_ptr->dyn = tpnt1;
 				}
-
-				rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
-				_dl_memset (rpnt->next, 0, sizeof (struct dyn_elf));
-				rpnt = rpnt->next;
-				if (!tpnt1->symbol_scope) tpnt1->symbol_scope = rpnt;
-				rpnt->dyn = tpnt1;
-
 			}
 		}
 	}
 
-	/*
-	 * OK, now attach the entire chain at the end
-	 */
-	rpnt->next = _dl_symbol_tables;
-
+	if (dyn_chain->dyn->init_flag & INIT_FUNCS_CALLED) {
+		/* If the init and fini stuff has already been run, that means
+		 * the dlopen'd library has already been loaded, and nothing
+		 * further needs to be done. */
+		return (void *) dyn_chain;
+	}
 #ifdef __mips__
 	/*
 	 * Relocation of the GOT entries for MIPS have to be done
-- 
cgit v1.2.3