[uClibc-cvs] uClibc/ldso/ldso hash.c, 1.13, 1.14 ldso.c, 1.68, 1.69 readelflib1.c, 1.42, 1.43

Erik Andersen andersen at uclibc.org
Tue Aug 19 13:11:10 UTC 2003


Update of /var/cvs/uClibc/ldso/ldso
In directory winder:/tmp/cvs-serv24962/ldso

Modified Files:
	hash.c ldso.c readelflib1.c 
Log Message:
Cool.  Found most of the problem.  Turns out we were inadvertanly loading some
libraries multiple times, wasting memory and causing different libraries to use
different symbol sets, some of which were not properly resolved.

Continue scrubbing ld.so and converting it to use proper types.


Index: readelflib1.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/readelflib1.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- readelflib1.c	19 Aug 2003 06:05:31 -0000	1.42
+++ readelflib1.c	19 Aug 2003 13:11:06 -0000	1.43
@@ -180,7 +180,7 @@
 {
 	char *pnt, *pnt1;
 	struct elf_resolve *tpnt1;
-	char *libname;
+	char *libname, *libname2;
 
 	_dl_internal_error_number = 0;
 	pnt = libname = full_libname;
@@ -190,12 +190,33 @@
 	if (_dl_strlen(full_libname) > 1024)
 		goto goof;
 
-	/* Skip over any initial initial './' path to get the libname */ 
+	/* Skip over any initial initial './' and '/' stuff to 
+	 * get the short form libname with no path garbage */ 
 	pnt1 = _dl_strrchr(pnt, '/');
 	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. */
+	for (tpnt1 = _dl_loaded_modules; tpnt1; tpnt1 = tpnt1->next) {
+
+		/* Skip over any initial initial './' and '/' stuff to 
+		 * get the short form libname with no path garbage */ 
+		libname2 = tpnt1->libname;
+		pnt1 = _dl_strrchr(libname2, '/');
+		if (pnt1) {
+			libname2 = pnt1 + 1;
+		}
+
+		if (_dl_strcmp(libname2, libname) == 0) {
+			/* Well, that was certainly easy */
+			return tpnt1;
+		}
+	}
+	
+
 #if defined (__SUPPORT_LD_DEBUG__)
 	if(_dl_debug) _dl_dprintf(_dl_debug_file, "searching for library: '%s'\n", libname);
 #endif

Index: hash.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/hash.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- hash.c	18 Jun 2003 22:42:23 -0000	1.13
+++ hash.c	19 Aug 2003 13:11:06 -0000	1.14
@@ -123,7 +123,7 @@
 	tpnt->next = NULL;
 	tpnt->init_flag = 0;
 	tpnt->libname = _dl_strdup(libname);
-	tpnt->dynamic_addr = dynamic_addr;
+	tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr;
 	tpnt->dynamic_size = dynamic_size;
 	tpnt->libtype = loaded_file;
 
@@ -135,7 +135,7 @@
 		hash_addr += tpnt->nbucket;
 		tpnt->chains = hash_addr;
 	}
-	tpnt->loadaddr = loadaddr;
+	tpnt->loadaddr = (ElfW(Addr))loadaddr;
 	for (i = 0; i < 24; i++)
 		tpnt->dynamic_info[i] = dynamic_info[i];
 #ifdef __mips__
@@ -285,15 +285,14 @@
 							ELF32_ST_TYPE(symtab[si].st_info) 
 							== STT_NOTYPE) 
 						{	/* nakao */
-							data_result = tpnt->loadaddr + 
+							data_result = (char *)tpnt->loadaddr + 
 							    symtab[si].st_value;	/* nakao */
 							break;	/* nakao */
 						} else	/* nakao */
-							return tpnt->loadaddr + symtab[si].st_value;
+							return (char*)tpnt->loadaddr + symtab[si].st_value;
 					case STB_WEAK:
 						if (!weak_result)
-							weak_result =
-								tpnt->loadaddr + symtab[si].st_value;
+							weak_result = (char *)tpnt->loadaddr + symtab[si].st_value;
 						break;
 					default:	/* Do local symbols need to be examined? */
 						break;

Index: ldso.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/ldso.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -d -r1.68 -r1.69
--- ldso.c	19 Aug 2003 06:05:31 -0000	1.68
+++ ldso.c	19 Aug 2003 13:11:06 -0000	1.69
@@ -142,7 +142,6 @@
 
 static char *_dl_trace_loaded_objects = 0;
 static int (*_dl_elf_main) (int, char **, char **);
-static int (*_dl_elf_init) (void);
 struct r_debug *_dl_debug_addr = NULL;
 unsigned long *_dl_brkp;
 unsigned long *_dl_envp;
@@ -665,7 +664,7 @@
 	tpnt->next = 0;
 	tpnt->libname = 0;
 	tpnt->libtype = program_interpreter;
-	tpnt->loadaddr = (char *) load_addr;
+	tpnt->loadaddr = (ElfW(Addr)) load_addr;
 
 #ifdef ALLOW_ZERO_PLTGOT
 	if (tpnt->dynamic_info[DT_PLTGOT])
@@ -690,17 +689,17 @@
 		tpnt->ppnt = myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
 		for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
 			if (myppnt->p_type == PT_DYNAMIC) {
-				tpnt->dynamic_addr = myppnt->p_vaddr + load_addr;
+				tpnt->dynamic_addr = (ElfW(Dyn) *)myppnt->p_vaddr + load_addr;
 #if defined(__mips__)
 				{
 					int k = 1;
-					Elf32_Dyn *dpnt = (Elf32_Dyn *) tpnt->dynamic_addr;
+					ElfW(Dyn) *dpnt = (ElfW(Dyn) *) tpnt->dynamic_addr;
 
 					while(dpnt->d_tag) {
 						dpnt++;
 						k++;
 					}
-					tpnt->dynamic_size = k * sizeof(Elf32_Dyn);
+					tpnt->dynamic_size = k * sizeof(ElfW(Dyn));
 				}
 #else
 				tpnt->dynamic_size = myppnt->p_filesz;
@@ -1038,8 +1037,7 @@
 		for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag;
 				dpnt++) {
 			if (dpnt->d_tag == DT_NEEDED) {
-				lpntstr = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] +
-					dpnt->d_un.d_val;
+				lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
 				if (_dl_strcmp(lpntstr, "libc.so.6") == 0) {
 					char *name, *msg;
 					name = tcurr->libname;
@@ -1261,15 +1259,17 @@
 		tpnt->init_flag |= INIT_FUNCS_CALLED;
 
 		if (tpnt->dynamic_info[DT_INIT]) {
-			_dl_elf_init = (int (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
-			  
+			void (*dl_elf_func) (void);
+			dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
 #if defined (__SUPPORT_LD_DEBUG__)
 			if(_dl_debug) _dl_dprintf(_dl_debug_file,"\ncalling init: %s\n\n", tpnt->libname);	
 #endif    
-			(*_dl_elf_init) ();
+			(*dl_elf_func) ();
 		}
 		if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {
-			(*_dl_atexit) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+			void (*dl_elf_func) (void);
+			dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+			(*_dl_atexit) (dl_elf_func);
 #if defined (__SUPPORT_LD_DEBUG__)
 			if(_dl_debug && _dl_on_exit)
 			{




More information about the uClibc-cvs mailing list