[uClibc-cvs] uClibc/ldso/ldso dl-elf.c, 1.65, 1.66 dl-hash.c, 1.17, 1.18 dl-startup.c, 1.5, 1.6 ldso.c, 1.92, 1.93

Erik Andersen andersen at uclibc.org
Sat Feb 14 11:30:33 UTC 2004


Update of /var/cvs/uClibc/ldso/ldso
In directory nail:/tmp/cvs-serv9702/ldso

Modified Files:
	dl-elf.c dl-hash.c dl-startup.c ldso.c 
Log Message:
Joakim Tjernlund writes:

Hi it is me again.

This is the latest ldso patch. the NEW weak symbol handling works now
with a little special handling in _dl_find_hash(). You get to chose
if you want the new or old handling :)

There was 2 missing _dl_check_if_named_library_is_loaded() calls in _dlopen().

I then disabled the _dl_check_if_named_library_is_loaded() in dl-elf.c since
it is rendundant.

Question, why does some _dl_linux_resolver(), like i386, have 2 calls
to _dl_find_hash()? I think that is wrong, isn't it?

I really hope you can check this out soon ...



Index: ldso.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/ldso.c,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -d -r1.92 -r1.93
--- ldso.c	10 Feb 2004 13:31:43 -0000	1.92
+++ ldso.c	14 Feb 2004 11:30:31 -0000	1.93
@@ -609,12 +609,12 @@
 	   up each symbol individually. */
 
 
-	_dl_brkp = (unsigned long *) (intptr_t) _dl_find_hash("___brk_addr", NULL, NULL, symbolrel);
+	_dl_brkp = (unsigned long *) (intptr_t) _dl_find_hash("___brk_addr", NULL, 0);
 
 	if (_dl_brkp) {
 		*_dl_brkp = brk_addr;
 	}
-	_dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", NULL, NULL, symbolrel);
+	_dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", NULL, 0);
 
 	if (_dl_envp) {
 		*_dl_envp = (unsigned long) envp;
@@ -638,10 +638,10 @@
 
 	}
 #endif
-	_dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", NULL, NULL, symbolrel);
+	_dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", NULL, 0);
 #if defined (__SUPPORT_LD_DEBUG__)
 	_dl_on_exit = (int (*)(void (*)(int, void *),void*))
-		(intptr_t) _dl_find_hash("on_exit", NULL, NULL, symbolrel);
+		(intptr_t) _dl_find_hash("on_exit", NULL, 0);
 #endif
 
 	/* Notify the debugger we have added some objects. */

Index: dl-elf.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/dl-elf.c,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -d -r1.65 -r1.66
--- dl-elf.c	10 Feb 2004 06:54:27 -0000	1.65
+++ dl-elf.c	14 Feb 2004 11:30:31 -0000	1.66
@@ -255,12 +255,13 @@
 	if (pnt1) {
 		libname = pnt1 + 1;
 	}
-
+#if 0
 	/* 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, trace_loaded_objects))!=NULL)
 		return tpnt1;
+#endif
 
 #if defined (__SUPPORT_LD_DEBUG__)
 	if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfind library='%s'; searching\n", libname);

Index: dl-startup.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/dl-startup.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- dl-startup.c	10 Feb 2004 13:31:43 -0000	1.5
+++ dl-startup.c	14 Feb 2004 11:30:31 -0000	1.6
@@ -513,11 +513,10 @@
 				/* We only do a partial dynamic linking right now.  The user
 				   is not supposed to define any symbols that start with a
 				   '_dl', so we can do this with confidence. */
-				if (!symname || symname[0] != '_' ||
-						symname[1] != 'd' || symname[2] != 'l' || symname[3] != '_')
-				{
+				if (!symname || !_dl_symbol(symname)) {
 					continue;
 				}
+
 				symbol_addr = load_addr + symtab[symtab_index].st_value;
 
 				if (!symbol_addr) {

Index: dl-hash.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/dl-hash.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- dl-hash.c	10 Feb 2004 11:47:57 -0000	1.17
+++ dl-hash.c	14 Feb 2004 11:30:31 -0000	1.18
@@ -154,7 +154,7 @@
  * relocations or when we call an entry in the PLT table for the first time.
  */
 char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
-	struct elf_resolve *f_tpnt, enum caller_type caller_type)
+		    int type_class)
 {
 	struct elf_resolve *tpnt;
 	int si;
@@ -163,23 +163,12 @@
 	Elf32_Sym *symtab;
 	unsigned long elf_hash_number, hn;
 	char *weak_result;
-	struct dyn_elf *rpnt, first;
+	struct dyn_elf *rpnt;
 	const ElfW(Sym) *sym;
 
 	weak_result = 0;
 	elf_hash_number = _dl_elf_hash(name);
 
-	/* A quick little hack to make sure that any symbol in the executable
-	   will be preferred to one in a shared library.  This is necessary so
-	   that any shared library data symbols referenced in the executable
-	   will be seen at the same address by the executable, shared libraries
-	   and dynamically loaded code. -Rob Ryan (robr at cmu.edu) */
-	if (_dl_symbol_tables && rpnt1) {
-		first = (*_dl_symbol_tables);
-		first.next = rpnt1;
-		rpnt1 = (&first);
-	}
-
 	/*
 	 * The passes are so that we can first search the regular symbols
 	 * for whatever module was specified, and then search anything
@@ -187,39 +176,35 @@
 	 * starting the first dlopened module, and anything above that
 	 * is just the next one in the chain.
 	 */
+	if (rpnt1 == NULL)
+		rpnt1 = _dl_symbol_tables;
+
 	for (pass = 0; (1 == 1); pass++) {
 
 		/*
 		 * If we are just starting to search for RTLD_GLOBAL, setup
 		 * the pointer for the start of the search.
 		 */
-		if (pass == 1) {
+		if (pass == 1)
 			rpnt1 = _dl_handles;
-		}
 
 		/*
 		 * Anything after this, we need to skip to the next module.
 		 */
-		else if (pass >= 2) {
+		else if (pass >= 2)
 			rpnt1 = rpnt1->next_handle;
-		}
 
 		/*
-		 * Make sure we still have a module, and make sure that this
-		 * module was loaded with RTLD_GLOBAL.
+		 * Make sure we still have a module.
 		 */
-		if (pass != 0) {
 			if (rpnt1 == NULL)
 				break;
-			//if ((rpnt1->flags & RTLD_GLOBAL) == 0)
-				//continue;
-		}
 
-		for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) {
+		for (rpnt = rpnt1; rpnt; rpnt = rpnt->next) {
 			tpnt = rpnt->dyn;
 
 			/* Don't search the executable when resolving a copy reloc. */
-			if (tpnt->libtype == elf_executable && caller_type == copyrel)
+			if ((type_class &  ELF_RTYPE_CLASS_COPY) && tpnt->libtype == elf_executable)
 				continue;
 
 			/*
@@ -236,19 +221,25 @@
 					continue;
 				if (ELF32_ST_TYPE(sym->st_info) > STT_FUNC)
 					continue;
-				if (sym->st_shndx == SHN_UNDEF && caller_type != copyrel)
+				if (type_class & (sym->st_shndx == SHN_UNDEF))
 					continue;
 				if (_dl_strcmp(strtab + sym->st_name, name) != 0)
 					continue;
 
 				switch (ELF32_ST_BIND(sym->st_info)) {
 					case STB_WEAK:
-//Disable this to match current glibc behavior.  Of course,
-//this doesn't actually work yet and will cause segfaults...
-#if 1
+#ifndef __LIBDL_SHARED__
+/* 
+Due to a special hack in libdl.c, one must handle the _dl_ symbols
+according to the OLD weak symbol scheme. This stuff can be deleted
+once that hack has been fixed.
+*/
+
+						if(_dl_symbol((char *)name)) {
 						if (!weak_result)
 							weak_result = (char *)tpnt->loadaddr + sym->st_value;
 						break;
+						}
 #endif
 					case STB_GLOBAL:
 						return (char*)tpnt->loadaddr + sym->st_value;




More information about the uClibc-cvs mailing list